diff --git a/nsspursrc/vm/cogitMIPSEL.c b/nsspursrc/vm/cogitMIPSEL.c deleted file mode 100644 index 5537a19d6a..0000000000 --- a/nsspursrc/vm/cogitMIPSEL.c +++ /dev/null @@ -1,30759 +0,0 @@ -/* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.2997 uuid: 2d21044e-f2db-40ea-91da-ba273faf9093 - from - StackToRegisterMappingCogit VMMaker.oscog-eem.2997 uuid: 2d21044e-f2db-40ea-91da-ba273faf9093 - */ -static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.2997 uuid: 2d21044e-f2db-40ea-91da-ba273faf9093 " __DATE__ ; -char *__cogitBuildInfo = __buildInfo; - - - -#include "sqConfig.h" -#include -#include -#include -#include -#include "sqPlatformSpecific.h" -#include "sqMemoryAccess.h" -#include "sqCogStackAlignment.h" -#include "dispdbg.h" -#include "cogmethod.h" -#include "nssendcache.h" -#if COGMTVM -#include "cointerpmt.h" -#else -#include "cointerp.h" -#endif -#include "cogit.h" -#include - - -/*** Constants ***/ -#define A0 4 -#define A1 5 -#define A2 6 -#define A3 7 -#define ABICalleeSavedRegisterMask 0xFF0000 -#define ABICallerSavedRegisterMask 0x300FF00 -#define ABIResultReg 2 -#define ADDIU 9 -#define ADDU 33 -#define AddCheckOverflowCqR 162 -#define AddCheckOverflowRR 163 -#define AddCqR 106 -#define AddCqRR 123 -#define AddCwR 114 -#define AddRdRd 132 -#define AddRR 100 -#define AddRRR 126 -#define AlignmentNops 3 -#define AltBlockCreationBytecodeSize 3 -#define AltFirstSpecialSelector 80 -#define AltNumSpecialSelectors 32 -#define AND 36 -#define ANDI 12 -#define AndCqR 108 -#define AndCqRR 124 -#define AndCwR 116 -#define AndRR 102 -#define AnnotationShift 5 -#define Arg0Reg 17 -#define Arg1Reg 18 -#define ArithmeticShiftRightCqR 91 -#define ArithmeticShiftRightCqRR 128 -#define ArithmeticShiftRightRR 92 -#define AT 1 -#define BadRegisterSet 1 -#define BEQ 4 -#define BGEZ 1 -#define BGTZ 7 -#define BLEZ 6 -#define BLTZ 0 -#define BlockCreationBytecodeSize 4 -#define BNE 5 -#define BREAK 13 -#define BranchTemp 11 -#define BrEqualRR 167 -#define BrLongEqualRR 177 -#define BrLongNotEqualRR 178 -#define BrNotEqualRR 168 -#define BrSignedGreaterEqualRR 176 -#define BrSignedGreaterRR 175 -#define BrSignedLessEqualRR 174 -#define BrSignedLessRR 173 -#define BrUnsignedGreaterEqualRR 172 -#define BrUnsignedGreaterRR 171 -#define BrUnsignedLessEqualRR 170 -#define BrUnsignedLessRR 169 -#define BytecodeSetHasDirectedSuperSend 1 -#define Call 6 -#define CallerSavedRegisterMask 0x0 -#define CallFull 7 -#if !defined(CheckRememberedInTrampoline) /* Allow this to be overridden on the compiler command line */ -# define CheckRememberedInTrampoline 0 -#endif -#define ClassArray 7 -#define ClassArrayCompactIndex 51 -#define ClassBlockClosureCompactIndex 37 -#define ClassFloatCompactIndex 34 -#define ClassMethodContextCompactIndex 36 -#define ClassReg 19 -#define ClosureFirstCopiedValueIndex 3 -#define ClosureIndex 4 -#define ClosureNumArgsIndex 2 -#define ClosureOuterContextIndex 0 -#define ClosureStartPCIndex 1 -#define ClzRR 157 -#define CMBlock 3 -#define CMClosedPIC 4 -#define CMFree 1 -#define CMMaxUsageCount 7 -#define CMMethod 2 -#define CMOpenPIC 5 -#define Cmp 8 -#define CmpC32R 113 -#define CmpCqR 105 -#define CmpCwR 112 -#define CmpRdRd 131 -#define CmpRR 99 -#define CompletePrimitive 4 -#define ConcreteVarBaseReg 22 -#define ConstZero 1 -#define ConvertRRd 145 -#define Debug DEBUGVM -#define DIV 26 -#define DisplacementMask 0x1F -#define DisplacementX2N 0 -#define DivRdRd 135 -#define DivRR 159 -#undef DPFPReg0 -#undef DPFPReg1 -#undef DPFPReg2 -#undef DPFPReg3 -#undef DPFPReg4 -#undef DPFPReg5 -#undef DPFPReg6 -#undef DPFPReg7 -#define EncounteredUnknownBytecode -6 -#undef Extra0Reg -#undef Extra2Reg -#define Fill32 4 -#define FirstAnnotation 64 -#define FirstJump 12 -#define FirstSpecialSelector 176 -#define FoxCallerSavedIP 4 -#define FoxIFSavedIP -16 -#define FoxMethod -4 -#define FoxMFReceiver -12 -#define FoxSavedFP 0 -#define FoxThisContext -8 -#define FP 30 -#define FPReg 30 -#define GCModeBecome 8 -#define GCModeFull 1 -#define GCModeNewSpace 2 -#define HasBytecodePC 5 -#define HeaderIndex 0 -#define HintLoad 0 -#define HintStore 1 -#if !defined(IMMUTABILITY) /* Allow this to be overridden on the compiler command line */ -# define IMMUTABILITY 1 -#endif -#define InFullBlock 2 -#define InstanceSpecificationIndex 2 -#define InstructionPointerIndex 1 -#define InsufficientCodeSpace -2 -#define InVanillaBlock 1 -#define IsAbsPCReference 3 -#define IsAnnotationExtension 1 -#define IsDirectedSuperBindingSend 10 -#define IsDirectedSuperSend 9 -#define IsDisplacementX2N 0 -#define IsNSDynamicSuperSend 12 -#define IsNSSelfSend 11 -#define IsNSSendCall 6 -#define IsObjectReference 2 -#define IsRelativeCall 4 -#define IsSendCall 7 -#define IsSuperSend 8 -#define J 2 -#define JAL 3 -#define JALR 9 -#define JR 8 -#define Jump 16 -#define JumpAbove 33 -#define JumpAboveOrEqual 32 -#define JumpBelow 31 -#define JumpBelowOrEqual 34 -#define JumpCarry 25 -#define JumpFPEqual 35 -#define JumpFPGreater 39 -#define JumpFPGreaterOrEqual 40 -#define JumpFPLess 37 -#define JumpFPLessOrEqual 38 -#define JumpFPNotEqual 36 -#define JumpFPOrdered 41 -#define JumpFPUnordered 42 -#define JumpFull 12 -#define JumpGreater 29 -#define JumpGreaterOrEqual 28 -#define JumpLess 27 -#define JumpLessOrEqual 30 -#define JumpLong 13 -#define JumpLongNonZero 15 -#define JumpLongZero 14 -#define JumpNegative 19 -#define JumpNoCarry 26 -#define JumpNonNegative 20 -#define JumpNonZero 18 -#define JumpNoOverflow 22 -#define JumpOverflow 21 -#define JumpR 10 -#define JumpZero 17 -#define Label 1 -#define LargeContextSlots 62 -#define LastJump 42 -#define LB 32 -#define LBU 36 -#define LH 33 -#define LHU 37 -#define LinkReg 31 -#define Literal 2 -#define LoadEffectiveAddressMwrR 88 -#define LogicalShiftLeftCqR 95 -#define LogicalShiftLeftCqRR 129 -#define LogicalShiftLeftRR 96 -#define LogicalShiftRightCqR 93 -#define LogicalShiftRightCqRR 130 -#define LogicalShiftRightRR 94 -#define LookupRuleDynamicSuper 0x101 -#define LookupRuleImplicit 0x100 -#define LookupRuleSelf 0 -#define LowcodeVM 0 -#define LUI 15 -#define LW 35 -#define MapEnd 0 -#define MaxCompiledPrimitiveIndex 575 -#define MaxCPICCases 6 -#define MaxMethodSize 65535 -#define MaxNegativeErrorCode -8 -#define MaxStackAllocSize 1572864 -#define MaxStackCheckOffset 0xFFF -#define MaxX2NDisplacement 992 -#define MethodCacheClass 2 -#define MethodCacheMask 0x7FC -#define MethodCacheMethod 3 -#define MethodCacheSelector 1 -#define MethodIndex 3 -#define MethodTooBig -4 -#define MFHI 16 -#define MFLO 18 -#define MFMethodFlagHasContextFlag 1 -#define MFMethodFlagIsBlockFlag 2 -#define MoveAbR 48 -#define MoveAwR 44 -#define MoveC32R 71 -#define MoveCqR 69 -#define MoveCwR 70 -#define MoveHighR 161 -#define MoveLowR 160 -#define MoveM16rR 57 -#define MoveM64rRd 75 -#define MoveMbrR 65 -#define MoveMwrR 50 -#define MoveRAb 49 -#define MoveRAw 46 -#define MoveRdM64r 76 -#define MoveRdRd 74 -#define MoveRM16r 58 -#define MoveRMbr 66 -#define MoveRMwr 51 -#define MoveRR 43 -#define MoveRXbrR 68 -#define MoveRXwrR 53 -#define MoveXbrRR 67 -#define MoveXwrRR 52 -#define MULT 24 -#define MULTIPLEBYTECODESETS 1 -#define MulCheckOverflowRR 164 -#define MulRdRd 134 -#define MulRR 158 -#define NativePopR 84 -#define NativePushR 85 -#define NativeRetN 86 -#define NativeSPReg 29 -#define NeedsMergeFixupFlag 2 -#define NeedsNonMergeFixupFlag 1 -#define NegateR 89 -#define NewspeakVM 1 -#define Nop 5 -#define NoReg -1 -#define NotFullyInitialized -1 -#define NSCClassTagIndex 0 -#define NSCEnclosingObjectIndex 1 -#define NSCNumArgsIndex 4 -#define NSCTargetIndex 2 -#define NumObjRefsInRuntime 0 -#define NumOopsPerNSC 6 -#define NumSendTrampolines 4 -#define NumSpecialSelectors 32 -#define NumStoreTrampolines 5 -#define NumTrampolines (83 + (COGMTVM ? 1 : 0) + (IMMUTABILITY ? 5 : 0)) -#define OneInstruction 4 -#define OR 37 -#define ORI 13 -#define OrCqR 109 -#define OrCqRR 125 -#define OrCwR 117 -#define OrRR 103 -#define Overflow 8 -#define OverflowTemp1 9 -#define OverflowTemp2 10 -#undef PCReg -#define PopR 80 -#define PREF 51 -#define PrefetchAw 87 -#define PrimCallCollectsProfileSamples 8 -#define PrimCallDoNotJIT 16 -#define PrimCallMayEndureCodeCompaction 4 -#define PrimCallNeedsNewMethod 1 -#define PrimCallNeedsPrimitiveFunction 2 -#define PrimCallOnSmalltalkStack 64 -#define PrimErrNoMemory 9 -#define PrimNumberExternalCall 117 -#define PrimNumberFFICall 120 -#define PushCq 82 -#define PushCw 83 -#define PushR 81 -#define R0 0 -#define R28 28 -#define RA 31 -#define REGIMM 1 -#define ReceiverIndex 5 -#define ReceiverResultReg 16 -#define RetN 9 -#define RISCTempReg 1 -#define SB 40 -#define SelectorCannotInterpret 34 -#define SelectorDoesNotUnderstand 20 -#define SenderIndex 0 -#define SendNumArgsReg 20 -#define SH 41 -#define ShouldNotJIT -8 -#define SignExtend16RR 152 -#define SignExtend8RR 151 -#define SistaV1BytecodeSet 0 -#define SistaVM 0 -#define SLL 0 -#define SLLV 4 -#define SLT 42 -#define SLTI 10 -#define SLTIU 11 -#define SLTU 43 -#define SmallContextSlots 22 -#define SP 29 -#define SPECIAL 0 -#define SPReg 29 -#define SPURVM 1 -#define SqrtRd 136 -#define SRA 3 -#define SRAV 7 -#define SRL 2 -#define SRLV 6 -#define SSBaseOffset 1 -#define SSConstant 2 -#define SSRegister 3 -#define SSSpill 4 -#define StackPointerIndex 2 -#define Stop 11 -#define SUBU 35 -#define SubCheckOverflowCqR 165 -#define SubCheckOverflowRR 166 -#define SubCqR 107 -#define SubCwR 115 -#define SubRdRd 133 -#define SubRR 101 -#define SubRRR 127 -#define SW 43 -#define T2 10 -#define TargetReg 25 -#define TempReg 21 -#define TempVectReadBarrier 0 -#define TstCqR 110 -#define UnfailingPrimitive 3 -#define UnimplementedPrimitive -7 -#define ValueIndex 1 -#define VarBaseReg 22 -#define XOR 38 -#define XORI 14 -#define XorCqR 111 -#define XorCwR 118 -#define XorRR 104 -#define YoungSelectorInPIC -5 -#define ZR 0 - -typedef struct _AbstractInstruction { - unsigned char opcode; - unsigned char machineCodeSize; - unsigned char maxSize; - unsigned char annotation; - unsigned int machineCode[7]; - usqInt operands[3]; - usqInt address; - struct _AbstractInstruction *dependent; - } AbstractInstruction; - -#define CogMIPSELCompiler AbstractInstruction -#define CogAbstractInstruction AbstractInstruction - - -typedef struct { - AbstractInstruction *fakeHeader; - AbstractInstruction *fillInstruction; - sqInt numArgs; - sqInt numCopied; - sqInt numInitialNils; - sqInt startpc; - AbstractInstruction *entryLabel; - AbstractInstruction *stackCheckLabel; - sqInt span; - sqInt hasInstVarRef; - } BlockStart; - -#define CogBlockStart BlockStart - - -typedef struct _BytecodeDescriptor { - sqInt (*generator)(void); - sqInt NoDbgRegParms (*spanFunction)(struct _BytecodeDescriptor *,sqInt,sqInt,sqInt); - sqInt NoDbgRegParms (*needsFrameFunction)(sqInt); - signed char stackDelta; - unsigned char opcode; - unsigned char numBytes; - unsigned isBranchTrue : 1; - unsigned isBranchFalse : 1; - unsigned isReturn : 1; - unsigned isBlockCreation : 1; - unsigned isMapped : 1; - unsigned isMappedInBlock : 1; - unsigned isExtension : 1; - unsigned isInstVarRef : 1; - unsigned is1ByteInstVarStore : 1; - unsigned hasIRC : 1; - unsigned hasUnsafeJump : 1; - } BytecodeDescriptor; - -#define CogBytecodeDescriptor BytecodeDescriptor - - -typedef struct { - sqInt (*primitiveGenerator)(void); - sqInt primNumArgs; - } PrimitiveDescriptor; - -#define CogPrimitiveDescriptor PrimitiveDescriptor - - -typedef struct { - char type; - char spilled; - signed char liveRegister; - signed char registerr; - sqInt offset; - sqInt constant; - sqInt bcptr; - } SimStackEntry; - -#define CogSimStackEntry SimStackEntry - - -typedef struct { - AbstractInstruction *targetInstruction; - unsigned char simStackPtr; - char isTargetOfBackwardBranch; - unsigned short instructionIndex; -#if LowcodeVM - short simNativeStackPtr; - unsigned short simNativeStackSize; -#endif - } BytecodeFixup; - -#define CogSSBytecodeFixup BytecodeFixup -#define CogBytecodeFixup BytecodeFixup - - -typedef struct { - sqInt isReceiverResultRegLive; - CogSimStackEntry *ssEntry; - } CogSSOptStatus; - - - -/*** Function Prototypes ***/ - - -#if !PRODUCTION && defined(PlatformNoDbgRegParms) -# define NoDbgRegParms PlatformNoDbgRegParms -#endif - -#if !defined(NoDbgRegParms) -# define NoDbgRegParms /*empty*/ -#endif - - - -#if !defined(NeverInline) -# define NeverInline /*empty*/ -#endif - -static AbstractInstruction * NoDbgRegParms addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *anInstruction); -static sqInt NoDbgRegParms availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask); -static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask); -static void NoDbgRegParms cloneLiteralFrom(AbstractInstruction * self_in_cloneLiteralFrom, AbstractInstruction *existingLiteral); -static sqInt NoDbgRegParms genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer); -static sqInt NoDbgRegParms genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers); -static sqInt NoDbgRegParms genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers); -static sqInt NoDbgRegParms genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers); -static AbstractInstruction * NoDbgRegParms genSwapRRScratch(AbstractInstruction * self_in_genSwapRRScratch, sqInt regA, sqInt regB, sqInt regTmp); -static void NoDbgRegParms genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister); -static void NoDbgRegParms initializeSharableLiteral(AbstractInstruction * self_in_initializeSharableLiteral, sqInt literal); -static void NoDbgRegParms initializeUniqueLiteral(AbstractInstruction * self_in_initializeUniqueLiteral, sqInt literal); -static sqInt NoDbgRegParms isWithinMwOffsetRange(AbstractInstruction * self_in_isWithinMwOffsetRange, sqInt anAddress); -static AbstractInstruction * NoDbgRegParms jmpTarget(AbstractInstruction * self_in_jmpTarget, AbstractInstruction *anAbstractInstruction); -static void NoDbgRegParms resolveJumpTarget(AbstractInstruction * self_in_resolveJumpTarget); -static sqInt NoDbgRegParms rewriteCallFullAttarget(AbstractInstruction * self_in_rewriteCallFullAttarget, sqInt callSiteReturnAddress, sqInt callTargetAddress); -static sqInt NoDbgRegParms rewriteJumpFullAttarget(AbstractInstruction * self_in_rewriteJumpFullAttarget, sqInt callSiteReturnAddress, sqInt callTargetAddress); -static CogMethod * NoDbgRegParms cmHomeMethod(CogBlockMethod * self_in_cmHomeMethod); -static sqInt NoDbgRegParms isBranch(BytecodeDescriptor * self_in_isBranch); -static AbstractInstruction * NoDbgRegParms gAddCqR(sqInt quickConstant, sqInt reg); -static AbstractInstruction * NoDbgRegParms gAddCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); -static AbstractInstruction * NoDbgRegParms gAndCqR(sqInt quickConstant, sqInt reg); -static AbstractInstruction * NoDbgRegParms gAndCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); -static AbstractInstruction * NoDbgRegParms gArithmeticShiftRightCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); -extern sqInt abortOffset(void); -static void addCleanBlockStarts(void); -extern void addCogMethodsToHeapMap(void); -static sqInt NoDbgRegParms addressIsInCurrentCompilation(sqInt address); -static sqInt NoDbgRegParms addressIsInFixups(BytecodeFixup *address); -static sqInt NoDbgRegParms addressOfEndOfCaseinCPIC(sqInt n, CogMethod *cPIC); -static void alignMethodZoneBase(void); -static sqInt NoDbgRegParms alignUptoRoutineBoundary(sqInt anAddress); -static sqInt allMachineCodeObjectReferencesValid(void); -static sqInt allMethodsHaveCorrectHeader(void); -static AbstractInstruction * NoDbgRegParms annotateAbsolutePCRef(AbstractInstruction *abstractInstruction); -static AbstractInstruction * NoDbgRegParms annotateBytecode(AbstractInstruction *abstractInstruction); -static AbstractInstruction * NoDbgRegParms annotateobjRef(AbstractInstruction *abstractInstruction, sqInt anOop); -static void NoDbgRegParms assertSaneJumpTarget(AbstractInstruction *jumpTarget); -static void assertValidDualZone(void); -static sqInt NoDbgRegParms availableRegisterOrNoneIn(sqInt liveRegsMask); -static sqInt NoDbgRegParms blockDispatchTargetsForperformarg(CogMethod *cogMethod, usqInt (*binaryFunction)(sqInt mcpc, sqInt arg), sqInt arg); -extern sqInt bytecodePCForstartBcpcin(sqInt mcpc, sqInt startbcpc, CogBlockMethod *cogMethod); -static AbstractInstruction * NoDbgRegParms CallNewspeakSend(sqInt callTarget); -static AbstractInstruction * NoDbgRegParms CallRTregistersToBeSavedMask(sqInt callTarget, sqInt registersToBeSaved); -static AbstractInstruction * NoDbgRegParms gCall(sqInt callTarget); -static AbstractInstruction * NoDbgRegParms gCmpCqR(sqInt quickConstant, sqInt reg); -extern void callCogCodePopReceiver(void); -extern void callCogCodePopReceiverAndClassRegs(void); -static sqInt NoDbgRegParms ceCPICMissreceiver(CogMethod *cPIC, sqInt receiver); -extern void ceFree(void *pointer); -static void* NoDbgRegParms ceMalloc(size_t size); -static sqInt NoDbgRegParms ceSICMiss(sqInt receiver); -static sqInt NoDbgRegParms checkIfValidOopRefAndTargetpccogMethod(sqInt annotation, char *mcpc, sqInt cogMethod); -static sqInt NoDbgRegParms checkIfValidOopRefpccogMethod(sqInt annotation, char *mcpc, CogMethod *cogMethod); -extern sqInt checkIntegrityOfObjectReferencesInCode(sqInt gcModes); -static sqInt NoDbgRegParms checkMaybeObjRefInClosedPIC(sqInt maybeObject); -static sqInt NoDbgRegParms checkValidObjectReferencesInClosedPIC(CogMethod *cPIC); -static sqInt NoDbgRegParms NeverInline cleanUpFailingCogCodeConstituents(CogMethod *cogMethodArg); -static sqInt NoDbgRegParms closedPICRefersToUnmarkedObject(CogMethod *cPIC); -extern char * codeEntryFor(char *address); -extern char * codeEntryNameFor(char *address); -extern sqInt cogCodeBase(void); -extern sqInt cogCodeConstituents(sqInt withDetails); -static void NoDbgRegParms cogExtendPICCaseNMethodtagisMNUCase(CogMethod *cPIC, sqInt caseNMethod, sqInt caseNTag, sqInt isMNUCase); -extern void cogitPostGCAction(sqInt gcMode); -extern sqInt cogMethodDoesntLookKosher(CogMethod *cogMethod); -extern CogMethod * cogMNUPICSelectorreceivermethodOperandnumArgs(sqInt selector, sqInt rcvr, sqInt methodOperand, sqInt numArgs); -static CogMethod * NoDbgRegParms cogOpenPICSelectornumArgs(sqInt selector, sqInt numArgs); -static CogMethod * NoDbgRegParms cogPICSelectornumArgsCase0MethodCase1MethodtagisMNUCase(sqInt selector, sqInt numArgs, CogMethod *case0CogMethod, sqInt case1MethodOrNil, sqInt case1Tag, sqInt isMNUCase); -extern CogMethod * cogselector(sqInt aMethodObj, sqInt aSelectorOop); -static sqInt NoDbgRegParms collectCogConstituentForAnnotationMcpcBcpcMethod(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *cogMethodArg); -static sqInt NoDbgRegParms collectCogMethodConstituent(CogMethod *cogMethod); -extern void compactCogCompiledCode(void); -static void compactPICsWithFreedTargets(void); -static AbstractInstruction * compileAbort(void); -static sqInt NoDbgRegParms compileBlockDispatchFromto(sqInt lowBlockStartIndex, sqInt highBlockStartIndex); -static void NoDbgRegParms compileBlockEntry(BlockStart *blockStart); -static void NoDbgRegParms compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt resultRegOrNone, sqInt regMask); -static AbstractInstruction * compileCPICEntry(void); -static void compileEntry(void); -static sqInt compileMethodBody(void); -static sqInt NoDbgRegParms compilePICAbort(sqInt numArgs); -static AbstractInstruction * NoDbgRegParms compileStackOverflowCheck(sqInt canContextSwitch); -static void NoDbgRegParms compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone); -static void computeEntryOffsets(void); -static void computeFullBlockEntryOffsets(void); -static usqInt computeGoodVarBaseAddress(void); -static void computeMaximumSizes(void); -static sqInt NoDbgRegParms configureCPICCase0Case1MethodtagisMNUCasenumArgsdelta(CogMethod *cPIC, CogMethod *case0CogMethod, sqInt case1Method, sqInt case1Tag, sqInt isMNUCase, sqInt numArgs, sqInt addrDelta); -static sqInt NoDbgRegParms configureMNUCPICmethodOperandnumArgsdelta(CogMethod *cPIC, sqInt methodOperand, sqInt numArgs, sqInt addrDelta); -static sqInt NoDbgRegParms cPICCompactAndIsNowEmpty(CogMethod *cPIC); -static sqInt NoDbgRegParms cPICHasForwardedClass(CogMethod *cPIC); -static sqInt NoDbgRegParms cPICHasFreedTargets(CogMethod *cPIC); -static usqInt cPICPrototypeCaseOffset(void); -static sqInt NoDbgRegParms cPICHasTarget(CogMethod *cPIC, CogMethod *targetMethod); -static sqInt NoDbgRegParms createCPICData(CogMethod *cPIC); -static AbstractInstruction * NoDbgRegParms gDivRRQuoRem(sqInt rDivisor, sqInt rDividend, sqInt rQuotient, sqInt rRemainder); -extern sqInt defaultCogCodeSize(void); -static sqInt NoDbgRegParms deltaToSkipPrimAndErrorStoreInheader(sqInt aMethodObj, sqInt aMethodHeader); -static sqInt NoDbgRegParms endPCOf(sqInt aMethod); -extern void enterCogCodePopReceiver(void); -static sqInt NoDbgRegParms entryPointTagIsSelector(sqInt entryPoint); -static sqInt NoDbgRegParms expectedClosedPICPrototype(CogMethod *cPIC); -static sqInt extABytecode(void); -static sqInt extBBytecode(void); -static sqInt NoDbgRegParms fillInBlockHeadersAt(sqInt startAddress); -static void NoDbgRegParms fillInMethodHeadersizeselector(CogMethod *method, sqInt size, sqInt selector); -static sqInt NoDbgRegParms findBackwardBranchIsBackwardBranchMcpcBcpcMatchingBcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *targetBcpc); -static usqInt NoDbgRegParms findBlockMethodWithEntrystartBcpc(sqInt blockEntryMcpc, sqInt startBcpc); -static usqInt NoDbgRegParms findMapLocationForMcpcinMethod(usqInt targetMcpc, CogMethod *cogMethod); -extern CogBlockMethod * findMethodForStartBcpcinHomeMethod(sqInt startbcpc, CogMethod *cogMethod); -static sqInt NoDbgRegParms findIsBackwardBranchMcpcBcpcMatchingMcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *targetMcpc); -static sqInt NoDbgRegParms firstMappedPCFor(CogMethod *cogMethod); -static sqInt firstPrototypeMethodOop(void); -static BytecodeFixup * NoDbgRegParms fixupAt(sqInt fixupPC); -extern void followForwardedLiteralsIn(CogMethod *cogMethod); -extern void followForwardedMethods(void); -static sqInt NoDbgRegParms followMaybeObjRefInClosedPICAt(sqInt mcpc); -static sqInt NoDbgRegParms followMethodReferencesInClosedPIC(CogMethod *cPIC); -extern void followMovableLiteralsAndUpdateYoungReferrers(void); -extern void freeCogMethod(CogMethod *cogMethod); -extern void freeUnmarkedMachineCode(void); -static AbstractInstruction * NoDbgRegParms genCallMustBeBooleanFor(sqInt boolean); -static AbstractInstruction * NoDbgRegParms genConditionalBranchoperand(sqInt opcode, sqInt operandOne); -static void (*genEnilopmartForandandforCallcalled(sqInt regArg1, sqInt regArg2OrNone, sqInt regArg3OrNone, sqInt forCall, char *trampolineName))(void) ; -static void NoDbgRegParms genEnilopmartReturn(sqInt forCall); -static void NoDbgRegParms NeverInline generateCaptureCStackPointers(sqInt captureFramePointer); -static void generateClosedPICPrototype(void); -static CogMethod * NoDbgRegParms generateCogMethod(sqInt selector); -static sqInt NoDbgRegParms generateMapAtstart(usqInt addressOrNull, usqInt startAddress); -static void generateNewspeakRuntime(void); -static void generateNewspeakSendTrampolines(void); -static void generateOpenPICPrototype(void); -static void generateRunTimeTrampolines(void); -static void generateStackPointerCapture(void); -static void generateTrampolines(void); -static BytecodeDescriptor * NoDbgRegParms generatorForPC(sqInt pc); -static void genGetLeafCallStackPointers(void); -static usqInt NoDbgRegParms genInnerPICAbortTrampoline(char *name); -static void (*genInvokeInterpretTrampoline(void))(void) ; -static void NoDbgRegParms genLoadInlineCacheWithSelector(sqInt selectorIndex); -static usqInt NoDbgRegParms genNSSendTrampolineFornumArgsenclosingObjectCheckcalled(void *aRoutine, sqInt numArgs, sqInt eoCheckFlag, char *aString); -static usqInt genReturnToInterpreterTrampoline(void); -static sqInt NoDbgRegParms genSmalltalkToCStackSwitch(sqInt pushLinkReg); -static usqInt NoDbgRegParms genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(void *aRoutine, char *trampolineName, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone, sqInt appendBoolean); -static void NoDbgRegParms genTrampolineReturn(sqInt lnkRegWasPushed); -static AbstractInstruction * NoDbgRegParms gen(sqInt opcode); -static AbstractInstruction * NoDbgRegParms genoperand(sqInt opcode, sqInt operand); -static AbstractInstruction * NoDbgRegParms genoperandoperand(sqInt opcode, sqInt operandOne, sqInt operandTwo); -static AbstractInstruction * NoDbgRegParms genoperandoperandoperand(sqInt opcode, sqInt operandOne, sqInt operandTwo, sqInt operandThree); -static sqInt NoDbgRegParms getLiteral(sqInt litIndex); -static sqInt NoDbgRegParms incrementUsageOfTargetIfLinkedSendmcpcignored(sqInt annotation, char *mcpc, sqInt superfluity); -static sqInt initialClosedPICUsageCount(void); -static void initializeBackend(void); -extern void initializeCodeZoneFromupTo(sqInt startAddress, sqInt endAddress); -static sqInt initialMethodUsageCount(void); -static sqInt initialOpenPICUsageCount(void); -static sqInt NoDbgRegParms inverseBranchFor(sqInt opcode); -static sqInt NoDbgRegParms isPCMappedAnnotation(sqInt annotation); -extern sqInt isPCWithinMethodZone(void *address); -extern sqInt isSendReturnPC(sqInt retpc); -static AbstractInstruction * NoDbgRegParms gJumpFPEqual(void *jumpTarget); -static AbstractInstruction * NoDbgRegParms gJumpFPGreaterOrEqual(void *jumpTarget); -static AbstractInstruction * NoDbgRegParms gJumpFPGreater(void *jumpTarget); -static AbstractInstruction * NoDbgRegParms gJumpFPNotEqual(void *jumpTarget); -static AbstractInstruction * NoDbgRegParms gLogicalShiftLeftCqR(sqInt quickConstant, sqInt reg); -static AbstractInstruction * NoDbgRegParms gLogicalShiftLeftCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); -static AbstractInstruction * NoDbgRegParms gLogicalShiftRightCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); -static AbstractInstruction * lastOpcode(void); -extern void linkNSSendCacheclassTagenclosingObjecttargetcaller(NSSendCache *nsSendCache, sqInt classTag, sqInt enclosingObject, CogMethod *targetMethod, CogMethod *callingMethod); -extern void linkSendAtintooffsetreceiver(sqInt callSiteReturnAddress, CogMethod *sendingMethod, CogMethod *targetMethod, sqInt theEntryOffset, sqInt receiver); -static BytecodeDescriptor * loadBytesAndGetDescriptor(void); -static void NoDbgRegParms loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc); -static AbstractInstruction * NoDbgRegParms gMoveCwR(sqInt wordConstant, sqInt reg); -static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); -static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg); -static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC); -static void mapObjectReferencesInGeneratedRuntime(void); -static void mapObjectReferencesInMachineCodeForBecome(void); -static void mapObjectReferencesInMachineCodeForFullGC(void); -static void mapObjectReferencesInMachineCodeForYoungGC(void); -extern void mapObjectReferencesInMachineCode(sqInt gcMode); -extern void markAndTraceMachineCodeOfMarkedMethods(void); -static void markAndTraceObjectReferencesInGeneratedRuntime(void); -static sqInt NoDbgRegParms markAndTraceOrFreeCogMethodfirstVisit(CogMethod *cogMethod, sqInt firstVisit); -static sqInt NoDbgRegParms markAndTraceOrFreePICTargetin(sqInt entryPoint, CogMethod *cPIC); -static sqInt NoDbgRegParms markLiteralsAndUnlinkIfUnmarkedSendpcmethod(sqInt annotation, char *mcpc, sqInt cogMethod); -static sqInt NoDbgRegParms markLiteralspcmethod(sqInt annotation, char *mcpc, CogMethod *cogMethod); -extern void markMethodAndReferents(CogBlockMethod *aCogMethod); -extern usqInt maxCogMethodAddress(void); -static sqInt maybeAllocAndInitIRCs(void); -static sqInt NoDbgRegParms maybeFreeCogMethodDoesntLookKosher(CogMethod *cogMethod); -static sqInt mclassIsSmallInteger(void); -extern usqInt mcPCForBackwardBranchstartBcpcin(sqInt bcpc, sqInt startbcpc, CogBlockMethod *cogMethod); -static sqInt methodNumArgs(void); -static sqInt NoDbgRegParms methodhasSameCodeAscheckPenultimate(sqInt methodA, sqInt methodB, sqInt comparePenultimateLiteral); -extern sqInt mnuOffset(void); -static AbstractInstruction * NoDbgRegParms gNativePopR(sqInt reg); -static AbstractInstruction * NoDbgRegParms gNativePushR(sqInt reg); -static AbstractInstruction * NoDbgRegParms gNativeRetN(sqInt offset); -static sqInt NoDbgRegParms needsFrameIfImmutability(sqInt stackDelta); -static sqInt NoDbgRegParms needsFrameIfInBlock(sqInt stackDelta); -static sqInt NoDbgRegParms needsFrameNever(sqInt stackDelta); -static sqInt NoDbgRegParms noAssertMethodClassAssociationOf(sqInt methodPointer); -static sqInt noCogMethodsMaximallyMarked(void); -static sqInt NoDbgRegParms noTargetsFreeInClosedPIC(CogMethod *cPIC); -static AbstractInstruction * NoDbgRegParms gOrCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); -static sqInt NoDbgRegParms outputInstructionsAt(sqInt startAddress); -static sqInt NoDbgRegParms outputInstructionsForGeneratedRuntimeAt(sqInt startAddress); -static AbstractInstruction * NoDbgRegParms gPushCw(sqInt wordConstant); -extern sqInt patchToOpenPICFornumArgsreceiver(sqInt selector, sqInt numArgs, sqInt receiver); -static sqInt picAbortDiscriminatorValue(void); -static sqInt picInterpretAbortOffset(void); -static AbstractInstruction * previousInstruction(void); -extern void printCogMethodFor(void *address); -extern void printTrampolineTable(void); -static sqInt processorHasDivQuoRemAndMClassIsSmallInteger(void); -static sqInt processorHasMultiplyAndMClassIsSmallInteger(void); -static void NoDbgRegParms recordGeneratedRunTimeaddress(char *aString, sqInt address); -extern sqInt recordPrimTraceFunc(void); -static void recordRunTimeObjectReferences(void); -static sqInt NoDbgRegParms registerMaskFor(sqInt reg); -static sqInt NoDbgRegParms registerMaskForandand(sqInt reg1, sqInt reg2, sqInt reg3); -static void NoDbgRegParms relocateCallsAndSelfReferencesInMethod(CogMethod *cogMethod); -static void NoDbgRegParms relocateCallsInClosedPIC(CogMethod *cPIC); -static sqInt NoDbgRegParms relocateIfCallOrMethodReferencemcpcdelta(sqInt annotation, char *mcpc, CogMethod *refDeltaArg); -static sqInt NoDbgRegParms remapIfObjectRefpchasYoung(sqInt annotation, char *mcpc, CogMethod *hasYoungPtr); -static sqInt NoDbgRegParms remapMaybeObjRefInClosedPICAt(sqInt mcpc); -static void NoDbgRegParms rewriteCPICCaseAttagobjReftarget(sqInt followingAddress, sqInt newTag, sqInt newObjRef, sqInt newTarget); -static AbstractInstruction * NoDbgRegParms gSubRRR(sqInt subReg, sqInt fromReg, sqInt destReg); -static sqInt scanForCleanBlocks(void); -extern void setBreakMethod(sqInt anObj); -extern void setSelectorOfto(CogMethod *cogMethod, sqInt aSelectorOop); -static sqInt NoDbgRegParms spanForCleanBlockStartingAt(sqInt startPC); -static usqInt NoDbgRegParms stackCheckOffsetOfBlockAtisMcpc(sqInt blockEntryMcpc, sqInt mcpc); -static sqInt subsequentPrototypeMethodOop(void); -extern sqInt traceLinkedSendOffset(void); -static sqInt NoDbgRegParms trampolineArgConstant(sqInt booleanOrInteger); -static char * NoDbgRegParms trampolineNamenumArgs(char *routinePrefix, sqInt numArgs); -static char * NoDbgRegParms trampolineNamenumArgslimit(char *routinePrefix, int numArgs, sqInt argsLimit); -static char * NoDbgRegParms trampolineNamenumRegArgs(char *routinePrefix, sqInt numArgs); -static sqInt unknownBytecode(void); -extern void unlinkAllSends(void); -static sqInt NoDbgRegParms unlinkIfFreeOrLinkedSendpcof(sqInt annotation, char *mcpc, CogMethod *theSelector); -static sqInt NoDbgRegParms unlinkIfInvalidClassSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity); -static sqInt NoDbgRegParms unlinkIfLinkedSendToFreepcignored(sqInt annotation, char *mcpc, sqInt superfluity); -static sqInt NoDbgRegParms unlinkIfLinkedSendpcif(sqInt annotation, char *mcpc, CogMethod *criterionArg); -static sqInt NoDbgRegParms unlinkIfLinkedSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity); -static sqInt NoDbgRegParms unlinkIfLinkedSendpcto(sqInt annotation, char *mcpc, sqInt theCogMethod); -extern void unlinkSendsLinkedForInvalidClasses(void); -extern void unlinkSendsOfisMNUSelector(sqInt selector, sqInt isMNUSelector); -extern void unlinkSendsToFree(void); -extern void unlinkSendsToMethodsSuchThatAndFreeIf(sqInt (*criterion)(CogMethod *), sqInt freeIfTrue); -extern void unlinkSendsToandFreeIf(sqInt targetMethodObject, sqInt freeIfTrue); -extern void voidCogCompiledCode(void); -static void zeroOpcodeIndex(void); -static void zeroOpcodeIndexForNewOpcodes(void); -static sqInt NoDbgRegParms counters(CogMethod * self_in_counters); -static void NoDbgRegParms addToOpenPICList(CogMethod *anOpenPIC); -static void NoDbgRegParms addToUnpairedMethodList(CogMethod *aCogMethod); -static void NoDbgRegParms addToYoungReferrers(CogMethod *cogMethod); -static usqInt NoDbgRegParms allocate(sqInt numBytes); -extern CogMethod * cogMethodContaining(usqInt mcpc); -static void compactCompiledCode(void); -static void NoDbgRegParms ensureInYoungReferrers(CogMethod *cogMethod); -static CogMethod * NoDbgRegParms findPreviouslyCompiledVersionOfwith(sqInt aMethodObj, sqInt aSelectorOop); -static void followForwardedLiteralsInOpenPICList(void); -static void NoDbgRegParms freeMethod(CogMethod *cogMethod); -static void freeOlderMethodsForCompaction(void); -extern sqInt kosherYoungReferrers(void); -static sqInt NoDbgRegParms mcpcisAtStackCheckOfBlockMethodIn(sqInt mcpc, CogMethod *cogMethod); -extern CogMethod * methodFor(void *address); -extern sqInt methodsCompiledToMachineCodeInto(sqInt arrayObj); -extern sqInt numMethods(void); -extern sqInt numMethodsOfType(sqInt cogMethodType); -static sqInt NoDbgRegParms occurrencesInYoungReferrers(CogMethod *cogMethod); -static CogMethod * NoDbgRegParms openPICWithSelector(sqInt aSelector); -static void planCompaction(void); -extern void printCogMethods(void); -extern void printCogMethodsOfType(sqInt cmType); -extern void printCogMethodsWithMethod(sqInt methodOop); -extern void printCogMethodsWithPrimitive(sqInt primIdx); -extern void printCogMethodsWithSelector(sqInt selectorOop); -extern void printCogYoungReferrers(void); -extern sqInt printOpenPICList(void); -extern sqInt pruneYoungReferrers(void); -static sqInt relocateAndPruneYoungReferrers(void); -static sqInt relocateMethodsPreCompaction(void); -static sqInt NoDbgRegParms removeFromOpenPICList(CogMethod *anOpenPIC); -static sqInt NoDbgRegParms removeFromUnpairedMethodList(CogMethod *aCogMethod); -static sqInt NoDbgRegParms roundUpLength(sqInt numBytes); -static void voidOpenPICList(void); -static void voidUnpairedMethodList(void); -static void voidYoungReferrersPostTenureAll(void); -EXPORT(char *) whereIsMaybeCodeThing(sqInt anOop); -static sqInt NoDbgRegParms addiuRRC(AbstractInstruction * self_in_addiuRRC, sqInt destReg, sqInt srcReg, sqInt imm); -static sqInt NoDbgRegParms adduRRR(AbstractInstruction * self_in_adduRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms andiRRC(AbstractInstruction * self_in_andiRRC, sqInt destReg, sqInt srcReg, sqInt imm); -static sqInt NoDbgRegParms andRRR(AbstractInstruction * self_in_andRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms beqRRoffset(AbstractInstruction * self_in_beqRRoffset, sqInt leftReg, sqInt rightReg, sqInt offset); -static sqInt NoDbgRegParms bgezRoffset(AbstractInstruction * self_in_bgezRoffset, sqInt cmpReg, sqInt offset); -static sqInt NoDbgRegParms bgtzRoffset(AbstractInstruction * self_in_bgtzRoffset, sqInt cmpReg, sqInt offset); -static sqInt NoDbgRegParms blezRoffset(AbstractInstruction * self_in_blezRoffset, sqInt cmpReg, sqInt offset); -static sqInt NoDbgRegParms bltzRoffset(AbstractInstruction * self_in_bltzRoffset, sqInt cmpReg, sqInt offset); -static sqInt NoDbgRegParms bneRRoffset(AbstractInstruction * self_in_bneRRoffset, sqInt leftReg, sqInt rightReg, sqInt offset); -static sqInt NoDbgRegParms callInstructionByteSize(AbstractInstruction * self_in_callInstructionByteSize); -static usqInt NoDbgRegParms callTargetFromReturnAddress(AbstractInstruction * self_in_callTargetFromReturnAddress, sqInt callSiteReturnAddress); -static sqInt NoDbgRegParms clzRRR(AbstractInstruction * self_in_clzRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms cmpC32RTempByteSize(AbstractInstruction * self_in_cmpC32RTempByteSize); -static sqInt NoDbgRegParms computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize); -static sqInt NoDbgRegParms concretizeAddCheckOverflowCqR(AbstractInstruction * self_in_concretizeAddCheckOverflowCqR); -static sqInt NoDbgRegParms concretizeAddCheckOverflowRR(AbstractInstruction * self_in_concretizeAddCheckOverflowRR); -static sqInt NoDbgRegParms concretizeAddCqR(AbstractInstruction * self_in_concretizeAddCqR); -static sqInt NoDbgRegParms concretizeAddCwR(AbstractInstruction * self_in_concretizeAddCwR); -static sqInt NoDbgRegParms concretizeAddRRDest(AbstractInstruction * self_in_concretizeAddRRDest, sqInt destReg); -static usqInt NoDbgRegParms concretizeAlignmentNops(AbstractInstruction * self_in_concretizeAlignmentNops); -static sqInt NoDbgRegParms concretizeAndCqR(AbstractInstruction * self_in_concretizeAndCqR); -static sqInt NoDbgRegParms concretizeAndCqRDest(AbstractInstruction * self_in_concretizeAndCqRDest, sqInt destReg); -static sqInt NoDbgRegParms concretizeAndCwR(AbstractInstruction * self_in_concretizeAndCwR); -static sqInt NoDbgRegParms concretizeAndRR(AbstractInstruction * self_in_concretizeAndRR); -static sqInt NoDbgRegParms concretizeArithmeticShiftRightCqR(AbstractInstruction * self_in_concretizeArithmeticShiftRightCqR); -static sqInt NoDbgRegParms concretizeArithmeticShiftRightRR(AbstractInstruction * self_in_concretizeArithmeticShiftRightRR); -static sqInt NoDbgRegParms concretizeAt(AbstractInstruction * self_in_concretizeAt, sqInt actualAddress); -static sqInt NoDbgRegParms concretizeBrEqualRR(AbstractInstruction * self_in_concretizeBrEqualRR); -static sqInt NoDbgRegParms concretizeBrLongEqualRR(AbstractInstruction * self_in_concretizeBrLongEqualRR); -static sqInt NoDbgRegParms concretizeBrLongNotEqualRR(AbstractInstruction * self_in_concretizeBrLongNotEqualRR); -static sqInt NoDbgRegParms concretizeBrNotEqualRR(AbstractInstruction * self_in_concretizeBrNotEqualRR); -static sqInt NoDbgRegParms concretizeBrSignedGreaterEqualRR(AbstractInstruction * self_in_concretizeBrSignedGreaterEqualRR); -static sqInt NoDbgRegParms concretizeBrSignedGreaterRR(AbstractInstruction * self_in_concretizeBrSignedGreaterRR); -static sqInt NoDbgRegParms concretizeBrSignedLessEqualRR(AbstractInstruction * self_in_concretizeBrSignedLessEqualRR); -static sqInt NoDbgRegParms concretizeBrSignedLessRR(AbstractInstruction * self_in_concretizeBrSignedLessRR); -static sqInt NoDbgRegParms concretizeBrUnsignedGreaterEqualRR(AbstractInstruction * self_in_concretizeBrUnsignedGreaterEqualRR); -static sqInt NoDbgRegParms concretizeBrUnsignedGreaterRR(AbstractInstruction * self_in_concretizeBrUnsignedGreaterRR); -static sqInt NoDbgRegParms concretizeBrUnsignedLessEqualRR(AbstractInstruction * self_in_concretizeBrUnsignedLessEqualRR); -static sqInt NoDbgRegParms concretizeBrUnsignedLessRR(AbstractInstruction * self_in_concretizeBrUnsignedLessRR); -static sqInt NoDbgRegParms concretizeCall(AbstractInstruction * self_in_concretizeCall); -static sqInt NoDbgRegParms concretizeCallFull(AbstractInstruction * self_in_concretizeCallFull); -static sqInt NoDbgRegParms concretizeClzRR(AbstractInstruction * self_in_concretizeClzRR); -static sqInt NoDbgRegParms concretizeCmpCqR(AbstractInstruction * self_in_concretizeCmpCqR); -static sqInt NoDbgRegParms concretizeCmpCwR(AbstractInstruction * self_in_concretizeCmpCwR); -static sqInt NoDbgRegParms concretizeCmpRR(AbstractInstruction * self_in_concretizeCmpRR); -static sqInt NoDbgRegParms concretizeDivRR(AbstractInstruction * self_in_concretizeDivRR); -static sqInt NoDbgRegParms concretizeFill32(AbstractInstruction * self_in_concretizeFill32); -static sqInt NoDbgRegParms concretizeJump(AbstractInstruction * self_in_concretizeJump); -static sqInt NoDbgRegParms concretizeJumpFull(AbstractInstruction * self_in_concretizeJumpFull); -static sqInt NoDbgRegParms concretizeJumpLong(AbstractInstruction * self_in_concretizeJumpLong); -static sqInt NoDbgRegParms concretizeJumpLongNonZero(AbstractInstruction * self_in_concretizeJumpLongNonZero); -static sqInt NoDbgRegParms concretizeJumpLongZero(AbstractInstruction * self_in_concretizeJumpLongZero); -static sqInt NoDbgRegParms concretizeJumpNonZero(AbstractInstruction * self_in_concretizeJumpNonZero); -static sqInt NoDbgRegParms concretizeJumpNoOverflow(AbstractInstruction * self_in_concretizeJumpNoOverflow); -static sqInt NoDbgRegParms concretizeJumpOverflow(AbstractInstruction * self_in_concretizeJumpOverflow); -static sqInt NoDbgRegParms concretizeJumpR(AbstractInstruction * self_in_concretizeJumpR); -static sqInt NoDbgRegParms concretizeJumpSignedGreaterEqual(AbstractInstruction * self_in_concretizeJumpSignedGreaterEqual); -static sqInt NoDbgRegParms concretizeJumpSignedGreaterThan(AbstractInstruction * self_in_concretizeJumpSignedGreaterThan); -static sqInt NoDbgRegParms concretizeJumpSignedLessEqual(AbstractInstruction * self_in_concretizeJumpSignedLessEqual); -static sqInt NoDbgRegParms concretizeJumpSignedLessThan(AbstractInstruction * self_in_concretizeJumpSignedLessThan); -static sqInt NoDbgRegParms concretizeJumpUnsignedGreaterEqual(AbstractInstruction * self_in_concretizeJumpUnsignedGreaterEqual); -static sqInt NoDbgRegParms concretizeJumpUnsignedGreaterThan(AbstractInstruction * self_in_concretizeJumpUnsignedGreaterThan); -static sqInt NoDbgRegParms concretizeJumpUnsignedLessEqual(AbstractInstruction * self_in_concretizeJumpUnsignedLessEqual); -static sqInt NoDbgRegParms concretizeJumpUnsignedLessThan(AbstractInstruction * self_in_concretizeJumpUnsignedLessThan); -static sqInt NoDbgRegParms concretizeJumpZero(AbstractInstruction * self_in_concretizeJumpZero); -static sqInt NoDbgRegParms concretizeLoadEffectiveAddressMwrR(AbstractInstruction * self_in_concretizeLoadEffectiveAddressMwrR); -static sqInt NoDbgRegParms concretizeLogicalShiftLeftCqR(AbstractInstruction * self_in_concretizeLogicalShiftLeftCqR); -static sqInt NoDbgRegParms concretizeLogicalShiftLeftRR(AbstractInstruction * self_in_concretizeLogicalShiftLeftRR); -static sqInt NoDbgRegParms concretizeLogicalShiftRightCqR(AbstractInstruction * self_in_concretizeLogicalShiftRightCqR); -static sqInt NoDbgRegParms concretizeLogicalShiftRightRR(AbstractInstruction * self_in_concretizeLogicalShiftRightRR); -static sqInt NoDbgRegParms concretizeMoveAbR(AbstractInstruction * self_in_concretizeMoveAbR); -static sqInt NoDbgRegParms concretizeMoveAwR(AbstractInstruction * self_in_concretizeMoveAwR); -static sqInt NoDbgRegParms concretizeMoveCqR(AbstractInstruction * self_in_concretizeMoveCqR); -static sqInt NoDbgRegParms concretizeMoveCwR(AbstractInstruction * self_in_concretizeMoveCwR); -static sqInt NoDbgRegParms concretizeMoveHighR(AbstractInstruction * self_in_concretizeMoveHighR); -static sqInt NoDbgRegParms concretizeMoveLowR(AbstractInstruction * self_in_concretizeMoveLowR); -static sqInt NoDbgRegParms concretizeMoveM16rR(AbstractInstruction * self_in_concretizeMoveM16rR); -static sqInt NoDbgRegParms concretizeMoveMbrR(AbstractInstruction * self_in_concretizeMoveMbrR); -static sqInt NoDbgRegParms concretizeMoveMwrR(AbstractInstruction * self_in_concretizeMoveMwrR); -static sqInt NoDbgRegParms concretizeMoveRAb(AbstractInstruction * self_in_concretizeMoveRAb); -static sqInt NoDbgRegParms concretizeMoveRAw(AbstractInstruction * self_in_concretizeMoveRAw); -static sqInt NoDbgRegParms concretizeMoveRM16r(AbstractInstruction * self_in_concretizeMoveRM16r); -static sqInt NoDbgRegParms concretizeMoveRMbr(AbstractInstruction * self_in_concretizeMoveRMbr); -static sqInt NoDbgRegParms concretizeMoveRMwr(AbstractInstruction * self_in_concretizeMoveRMwr); -static sqInt NoDbgRegParms concretizeMoveRR(AbstractInstruction * self_in_concretizeMoveRR); -static sqInt NoDbgRegParms concretizeMoveRXbrR(AbstractInstruction * self_in_concretizeMoveRXbrR); -static sqInt NoDbgRegParms concretizeMoveRXwrR(AbstractInstruction * self_in_concretizeMoveRXwrR); -static sqInt NoDbgRegParms concretizeMoveXbrRR(AbstractInstruction * self_in_concretizeMoveXbrRR); -static sqInt NoDbgRegParms concretizeMoveXwrRR(AbstractInstruction * self_in_concretizeMoveXwrRR); -static sqInt NoDbgRegParms concretizeMulCheckOverflowRR(AbstractInstruction * self_in_concretizeMulCheckOverflowRR); -static sqInt NoDbgRegParms concretizeNegateR(AbstractInstruction * self_in_concretizeNegateR); -static sqInt NoDbgRegParms concretizeNop(AbstractInstruction * self_in_concretizeNop); -static sqInt NoDbgRegParms concretizeOrCqR(AbstractInstruction * self_in_concretizeOrCqR); -static sqInt NoDbgRegParms concretizeOrCqRR(AbstractInstruction * self_in_concretizeOrCqRR); -static sqInt NoDbgRegParms concretizeOrCwR(AbstractInstruction * self_in_concretizeOrCwR); -static sqInt NoDbgRegParms concretizeOrRR(AbstractInstruction * self_in_concretizeOrRR); -static sqInt NoDbgRegParms concretizePopR(AbstractInstruction * self_in_concretizePopR); -static sqInt NoDbgRegParms concretizePrefetchAw(AbstractInstruction * self_in_concretizePrefetchAw); -static sqInt NoDbgRegParms concretizePushCq(AbstractInstruction * self_in_concretizePushCq); -static sqInt NoDbgRegParms concretizePushCw(AbstractInstruction * self_in_concretizePushCw); -static sqInt NoDbgRegParms concretizePushR(AbstractInstruction * self_in_concretizePushR); -static sqInt NoDbgRegParms concretizeRetN(AbstractInstruction * self_in_concretizeRetN); -static sqInt NoDbgRegParms concretizeStop(AbstractInstruction * self_in_concretizeStop); -static sqInt NoDbgRegParms concretizeSubCheckOverflowCqR(AbstractInstruction * self_in_concretizeSubCheckOverflowCqR); -static sqInt NoDbgRegParms concretizeSubCheckOverflowRR(AbstractInstruction * self_in_concretizeSubCheckOverflowRR); -static sqInt NoDbgRegParms concretizeSubCqR(AbstractInstruction * self_in_concretizeSubCqR); -static sqInt NoDbgRegParms concretizeSubCwR(AbstractInstruction * self_in_concretizeSubCwR); -static sqInt NoDbgRegParms concretizeSubRRDest(AbstractInstruction * self_in_concretizeSubRRDest, sqInt destReg); -static sqInt NoDbgRegParms concretizeTstCqR(AbstractInstruction * self_in_concretizeTstCqR); -static sqInt NoDbgRegParms concretizeTstCwR(AbstractInstruction * self_in_concretizeTstCwR); -static sqInt NoDbgRegParms concretizeUnimplemented(AbstractInstruction * self_in_concretizeUnimplemented); -static sqInt NoDbgRegParms concretizeXorCwR(AbstractInstruction * self_in_concretizeXorCwR); -static sqInt NoDbgRegParms concretizeXorRR(AbstractInstruction * self_in_concretizeXorRR); -static sqInt NoDbgRegParms dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize); -static sqInt NoDbgRegParms divRR(AbstractInstruction * self_in_divRR, sqInt dividendReg, sqInt divisorReg); -static sqInt NoDbgRegParms fullCallsAreRelative(AbstractInstruction * self_in_fullCallsAreRelative); -static sqInt NoDbgRegParms functionAtAddress(AbstractInstruction * self_in_functionAtAddress, sqInt mcpc); -static sqInt NoDbgRegParms genDivRRQuoRem(AbstractInstruction * self_in_genDivRRQuoRem, sqInt abstractRegDivisor, sqInt abstractRegDividend, sqInt abstractRegQuotient, sqInt abstractRegRemainder); -static AbstractInstruction * NoDbgRegParms genMulRR(AbstractInstruction * self_in_genMulRR, sqInt regSource, sqInt regDest); -static void NoDbgRegParms genPushRegisterArgsForAbortMissNumArgs(AbstractInstruction * self_in_genPushRegisterArgsForAbortMissNumArgs, sqInt numArgs); -static void NoDbgRegParms genPushRegisterArgsForNumArgsscratchReg(AbstractInstruction * self_in_genPushRegisterArgsForNumArgsscratchReg, sqInt numArgs, sqInt ignored); -static sqInt NoDbgRegParms genRemoveNArgsFromStack(AbstractInstruction * self_in_genRemoveNArgsFromStack, sqInt n); -static sqInt NoDbgRegParms genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask); -static sqInt NoDbgRegParms genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask); -static AbstractInstruction * NoDbgRegParms genSubstituteReturnAddress(AbstractInstruction * self_in_genSubstituteReturnAddress, sqInt retpc); -static usqInt NoDbgRegParms high16BitsOf(AbstractInstruction * self_in_high16BitsOf, usqInt word); -static usqInt NoDbgRegParms inlineCacheTagAt(AbstractInstruction * self_in_inlineCacheTagAt, usqInt callSiteReturnAddress); -static sqInt NoDbgRegParms instructionSizeAt(AbstractInstruction * self_in_instructionSizeAt, sqInt pc); -static sqInt NoDbgRegParms isCallPrecedingReturnPC(AbstractInstruction * self_in_isCallPrecedingReturnPC, sqInt mcpc); -static sqInt NoDbgRegParms isJump(AbstractInstruction * self_in_isJump); -static sqInt NoDbgRegParms isJumpAt(AbstractInstruction * self_in_isJumpAt, sqInt pc); -static sqInt NoDbgRegParms isPCDependent(AbstractInstruction * self_in_isPCDependent); -static sqInt NoDbgRegParms isShortOffset(AbstractInstruction * self_in_isShortOffset, sqInt offset); -static sqInt NoDbgRegParms itypersrteitherImmediate(AbstractInstruction * self_in_itypersrteitherImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate); -static sqInt NoDbgRegParms itypersrtsignedImmediate(AbstractInstruction * self_in_itypersrtsignedImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate); -static sqInt NoDbgRegParms itypersrtunsignedImmediate(AbstractInstruction * self_in_itypersrtunsignedImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate); -static sqInt NoDbgRegParms jA(AbstractInstruction * self_in_jA, sqInt target); -static sqInt NoDbgRegParms jalA(AbstractInstruction * self_in_jalA, sqInt target); -static sqInt NoDbgRegParms jalR(AbstractInstruction * self_in_jalR, sqInt targetReg); -static sqInt NoDbgRegParms jR(AbstractInstruction * self_in_jR, sqInt targetReg); -static sqInt NoDbgRegParms jtypetarget(AbstractInstruction * self_in_jtypetarget, sqInt op, sqInt target); -static sqInt NoDbgRegParms jumpLongByteSize(AbstractInstruction * self_in_jumpLongByteSize); -static sqInt NoDbgRegParms jumpLongConditionalByteSize(AbstractInstruction * self_in_jumpLongConditionalByteSize); -static usqInt NoDbgRegParms jumpLongConditionalTargetBeforeFollowingAddress(AbstractInstruction * self_in_jumpLongConditionalTargetBeforeFollowingAddress, sqInt mcpc); -static usqInt NoDbgRegParms jumpLongTargetBeforeFollowingAddress(AbstractInstruction * self_in_jumpLongTargetBeforeFollowingAddress, sqInt mcpc); -static sqInt NoDbgRegParms jumpShortByteSize(AbstractInstruction * self_in_jumpShortByteSize); -static usqInt NoDbgRegParms jumpTargetPCAt(AbstractInstruction * self_in_jumpTargetPCAt, sqInt pc); -static sqInt NoDbgRegParms lbRbaseoffset(AbstractInstruction * self_in_lbRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset); -static sqInt NoDbgRegParms lbuRbaseoffset(AbstractInstruction * self_in_lbuRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset); -static sqInt NoDbgRegParms lhRbaseoffset(AbstractInstruction * self_in_lhRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset); -static sqInt NoDbgRegParms lhuRbaseoffset(AbstractInstruction * self_in_lhuRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset); -static usqInt NoDbgRegParms literalAtAddress(AbstractInstruction * self_in_literalAtAddress, sqInt mcpc); -static sqInt NoDbgRegParms literalAtAddressput(AbstractInstruction * self_in_literalAtAddressput, sqInt mcpc, sqInt newLiteral); -static usqInt NoDbgRegParms literalBeforeFollowingAddress(AbstractInstruction * self_in_literalBeforeFollowingAddress, sqInt followingAddress); -static sqInt NoDbgRegParms loadLiteralByteSize(AbstractInstruction * self_in_loadLiteralByteSize); -static sqInt NoDbgRegParms loadPICLiteralByteSize(AbstractInstruction * self_in_loadPICLiteralByteSize); -static usqInt NoDbgRegParms low16BitsOf(AbstractInstruction * self_in_low16BitsOf, usqInt word); -static sqInt NoDbgRegParms luiRC(AbstractInstruction * self_in_luiRC, sqInt destReg, sqInt imm); -static sqInt NoDbgRegParms lwRbaseoffset(AbstractInstruction * self_in_lwRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset); -static sqInt NoDbgRegParms machineCodeBytes(AbstractInstruction * self_in_machineCodeBytes); -static sqInt NoDbgRegParms machineCodeWords(AbstractInstruction * self_in_machineCodeWords); -static sqInt NoDbgRegParms mfhiR(AbstractInstruction * self_in_mfhiR, sqInt destReg); -static sqInt NoDbgRegParms mfloR(AbstractInstruction * self_in_mfloR, sqInt destReg); -static sqInt NoDbgRegParms mipsbreak(AbstractInstruction * self_in_mipsbreak, sqInt code); -static sqInt NoDbgRegParms multRR(AbstractInstruction * self_in_multRR, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms nop(AbstractInstruction * self_in_nop); -static AbstractInstruction * NoDbgRegParms noteFollowingConditionalBranch(AbstractInstruction * self_in_noteFollowingConditionalBranch, AbstractInstruction *branch); -static AbstractInstruction * NoDbgRegParms noteFollowingOverflowBranch(AbstractInstruction * self_in_noteFollowingOverflowBranch, AbstractInstruction *branch); -static usqInt NoDbgRegParms nsSendCacheAt(AbstractInstruction * self_in_nsSendCacheAt, sqInt callSiteReturnAddress); -static sqInt NoDbgRegParms numIntRegArgs(AbstractInstruction * self_in_numIntRegArgs); -static sqInt NoDbgRegParms opcodeAtAddress(AbstractInstruction * self_in_opcodeAtAddress, sqInt mcpc); -static sqInt NoDbgRegParms oriRRC(AbstractInstruction * self_in_oriRRC, sqInt destReg, sqInt srcReg, sqInt imm); -static sqInt NoDbgRegParms orRRR(AbstractInstruction * self_in_orRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static void NoDbgRegParms padIfPossibleWithStopsFromto(AbstractInstruction * self_in_padIfPossibleWithStopsFromto, sqInt startAddr, sqInt endAddr); -static sqInt NoDbgRegParms prefRoffsethint(AbstractInstruction * self_in_prefRoffsethint, sqInt baseReg, sqInt offset, sqInt hint); -static sqInt NoDbgRegParms pushLinkRegisterByteSize(AbstractInstruction * self_in_pushLinkRegisterByteSize); -static AbstractInstruction * NoDbgRegParms relocateCallBeforeReturnPCby(AbstractInstruction * self_in_relocateCallBeforeReturnPCby, sqInt retpc, sqInt delta); -static AbstractInstruction * NoDbgRegParms relocateJumpLongBeforeFollowingAddressby(AbstractInstruction * self_in_relocateJumpLongBeforeFollowingAddressby, sqInt pc, sqInt delta); -static void NoDbgRegParms relocateJumpLongConditionalBeforeFollowingAddressby(AbstractInstruction * self_in_relocateJumpLongConditionalBeforeFollowingAddressby, sqInt pc, sqInt delta); -static AbstractInstruction * NoDbgRegParms relocateMethodReferenceBeforeAddressby(AbstractInstruction * self_in_relocateMethodReferenceBeforeAddressby, sqInt pc, sqInt delta); -static sqInt NoDbgRegParms rewriteCallAttarget(AbstractInstruction * self_in_rewriteCallAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress); -static void NoDbgRegParms rewriteConditionalJumpLongAttarget(AbstractInstruction * self_in_rewriteConditionalJumpLongAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress); -static void NoDbgRegParms rewriteCPICJumpAttarget(AbstractInstruction * self_in_rewriteCPICJumpAttarget, usqInt addressFollowingJump, usqInt jumpTargetAddr); -static sqInt NoDbgRegParms rewriteInlineCacheAttagtarget(AbstractInstruction * self_in_rewriteInlineCacheAttagtarget, usqInt callSiteReturnAddress, sqInt cacheTag, usqInt callTargetAddress); -static void NoDbgRegParms rewriteInlineCacheTagat(AbstractInstruction * self_in_rewriteInlineCacheTagat, sqInt cacheTag, usqInt callSiteReturnAddress); -static void NoDbgRegParms rewriteITypeBranchAtAddresstarget(AbstractInstruction * self_in_rewriteITypeBranchAtAddresstarget, sqInt mcpc, sqInt newTarget); -static void NoDbgRegParms rewriteJTypeAtAddressdelta(AbstractInstruction * self_in_rewriteJTypeAtAddressdelta, sqInt mcpc, sqInt delta); -static void NoDbgRegParms rewriteJTypeAtAddresstarget(AbstractInstruction * self_in_rewriteJTypeAtAddresstarget, sqInt mcpc, sqInt newTarget); -static sqInt NoDbgRegParms rewriteJumpLongAttarget(AbstractInstruction * self_in_rewriteJumpLongAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress); -static sqInt NoDbgRegParms rtAtAddress(AbstractInstruction * self_in_rtAtAddress, sqInt mcpc); -static sqInt NoDbgRegParms rtypersrtrdsafunct(AbstractInstruction * self_in_rtypersrtrdsafunct, sqInt op, sqInt rs, sqInt rt, sqInt rd, sqInt sa, sqInt funct); -static sqInt NoDbgRegParms sbRbaseoffset(AbstractInstruction * self_in_sbRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset); -static sqInt NoDbgRegParms setsConditionCodesFor(AbstractInstruction * self_in_setsConditionCodesFor, sqInt aConditionalJumpOpcode); -static sqInt NoDbgRegParms shRbaseoffset(AbstractInstruction * self_in_shRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset); -static usqInt NoDbgRegParms sizePCDependentInstructionAt(AbstractInstruction * self_in_sizePCDependentInstructionAt, sqInt eventualAbsoluteAddress); -static sqInt NoDbgRegParms sllRRC(AbstractInstruction * self_in_sllRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount); -static sqInt NoDbgRegParms sllvRRR(AbstractInstruction * self_in_sllvRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms sltiRRC(AbstractInstruction * self_in_sltiRRC, sqInt destReg, sqInt leftReg, sqInt imm); -static sqInt NoDbgRegParms sltiuRRC(AbstractInstruction * self_in_sltiuRRC, sqInt destReg, sqInt leftReg, sqInt imm); -static sqInt NoDbgRegParms sltRRR(AbstractInstruction * self_in_sltRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms sltuRRR(AbstractInstruction * self_in_sltuRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms sraRRC(AbstractInstruction * self_in_sraRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount); -static sqInt NoDbgRegParms sravRRR(AbstractInstruction * self_in_sravRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms srlRRC(AbstractInstruction * self_in_srlRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount); -static sqInt NoDbgRegParms srlvRRR(AbstractInstruction * self_in_srlvRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms stop(AbstractInstruction * self_in_stop); -static void NoDbgRegParms stopsFromto(AbstractInstruction * self_in_stopsFromto, sqInt startAddr, sqInt endAddr); -static sqInt NoDbgRegParms storeLiteralbeforeFollowingAddress(AbstractInstruction * self_in_storeLiteralbeforeFollowingAddress, sqInt literal, sqInt followingAddress); -static sqInt NoDbgRegParms subuRRR(AbstractInstruction * self_in_subuRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms swRbaseoffset(AbstractInstruction * self_in_swRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset); -static usqInt NoDbgRegParms targetFromITypeAtAddress(AbstractInstruction * self_in_targetFromITypeAtAddress, usqInt mcpc); -static usqInt NoDbgRegParms targetFromJTypeAtAddress(AbstractInstruction * self_in_targetFromJTypeAtAddress, usqInt mcpc); -static sqInt NoDbgRegParms xoriRRC(AbstractInstruction * self_in_xoriRRC, sqInt destReg, sqInt srcReg, sqInt imm); -static sqInt NoDbgRegParms xorRRR(AbstractInstruction * self_in_xorRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms zoneCallsAreRelative(AbstractInstruction * self_in_zoneCallsAreRelative); -static sqInt NoDbgRegParms checkValidObjectReference(sqInt anOop); -static AbstractInstruction * NoDbgRegParms genCmpClassFloatCompactIndexR(sqInt reg); -static AbstractInstruction * NoDbgRegParms genCmpClassMethodContextCompactIndexR(sqInt reg); -static sqInt NoDbgRegParms genGetMethodHeaderOfintoscratch(sqInt methodReg, sqInt headerReg, sqInt scratchReg); -static sqInt NoDbgRegParms genLoadSlotsourceRegdestReg(sqInt index, sqInt sourceReg, sqInt destReg); -static sqInt genPrimitiveAdd(void); -static sqInt genPrimitiveBitAnd(void); -static sqInt genPrimitiveBitOr(void); -static sqInt genPrimitiveBitShift(void); -static sqInt genPrimitiveBitXor(void); -static sqInt genPrimitiveClass(void); -static sqInt genPrimitiveDiv(void); -static sqInt genPrimitiveDivide(void); -static sqInt genPrimitiveEqual(void); -static sqInt genPrimitiveGreaterOrEqual(void); -static sqInt genPrimitiveGreaterThan(void); -static sqInt genPrimitiveHighBit(void); -static sqInt genPrimitiveIdentical(void); -static sqInt genPrimitiveLessOrEqual(void); -static sqInt genPrimitiveLessThan(void); -static sqInt genPrimitiveMod(void); -static sqInt genPrimitiveMultiply(void); -static sqInt genPrimitiveNewMethod(void); -static sqInt genPrimitiveNotEqual(void); -static sqInt genPrimitiveNotIdentical(void); -static sqInt genPrimitiveQuo(void); -static sqInt genPrimitiveSubtract(void); -static sqInt NoDbgRegParms genSmallIntegerComparison(sqInt jumpOpcode); -static sqInt NoDbgRegParms genSmallIntegerComparisonorDoubleComparisoninvert(sqInt jumpOpcode, AbstractInstruction * NoDbgRegParms (*jumpFPOpcodeGenerator)(void *), sqInt invertComparison); -static sqInt NoDbgRegParms isUnannotatableConstant(CogSimStackEntry *simStackEntry); -static sqInt NoDbgRegParms classForInlineCacheTag(sqInt inlineCacheTag); -static sqInt NoDbgRegParms genAddSmallIntegerTagsTo(sqInt aRegister); -static sqInt NoDbgRegParms genClearAndSetSmallIntegerTagsIn(sqInt scratchReg); -static void NoDbgRegParms genConvertCharacterToSmallIntegerInReg(sqInt reg); -static sqInt NoDbgRegParms genConvertIntegerInRegtoSmallIntegerInReg(sqInt srcReg, sqInt destReg); -static sqInt NoDbgRegParms genConvertIntegerToSmallIntegerInReg(sqInt reg); -static void NoDbgRegParms genConvertSmallIntegerToCharacterInReg(sqInt reg); -static sqInt NoDbgRegParms genConvertSmallIntegerToIntegerInReg(sqInt reg); -static sqInt NoDbgRegParms genGetHashFieldNonImmOfasSmallIntegerInto(sqInt instReg, sqInt destReg); -static sqInt NoDbgRegParms genGetHashFieldNonImmOfinto(sqInt instReg, sqInt destReg); -static AbstractInstruction * NoDbgRegParms genGetInlineCacheClassTagFromintoforEntry(sqInt sourceReg, sqInt destReg, sqInt forEntry); -static sqInt NoDbgRegParms genGetOverflowSlotsOfinto(sqInt srcReg, sqInt destReg); -static AbstractInstruction * NoDbgRegParms genJumpIsSmallIntegerValuescratch(sqInt aRegister, sqInt scratchReg); -static AbstractInstruction * NoDbgRegParms genJumpNotSmallIntegerInScratchReg(sqInt aRegister); -static AbstractInstruction * NoDbgRegParms genJumpNotSmallIntegerValuescratch(sqInt aRegister, sqInt scratchReg); -static AbstractInstruction * NoDbgRegParms genJumpNotSmallInteger(sqInt aRegister); -static AbstractInstruction * NoDbgRegParms genJumpSmallInteger(sqInt aRegister); -static sqInt genPrimitiveAtPut(void); -static sqInt NoDbgRegParms genPrimitiveAtPutSigned(sqInt signedVersion); -static sqInt NoDbgRegParms genPrimitiveAtSigned(sqInt signedVersion); -static sqInt genPrimitiveIdentityHash(void); -static sqInt genPrimitiveImmediateAsInteger(void); -static sqInt genPrimitiveMirrorNew(void); -static sqInt genPrimitiveMirrorNewWithArg(void); -static sqInt genPrimitiveNew(void); -static sqInt genPrimitiveNewWithArg(void); -static sqInt genPrimitiveShallowCopy(void); -static sqInt genPrimitiveStringAt(void); -static sqInt genPrimitiveStringAtPut(void); -static sqInt NoDbgRegParms genRemoveSmallIntegerTagsInScratchReg(sqInt scratchReg); -static sqInt NoDbgRegParms genShiftAwaySmallIntegerTagsInScratchReg(sqInt scratchReg); -static sqInt NoDbgRegParms getLiteralCountOfplusOneinBytesintoscratch(sqInt methodReg, sqInt plusOne, sqInt inBytes, sqInt litCountReg, sqInt scratchReg); -static sqInt NoDbgRegParms inlineCacheTagForInstance(sqInt oop); -static AbstractInstruction * NoDbgRegParms jumpNotSmallIntegerUnsignedValueInRegister(sqInt reg); -static sqInt NoDbgRegParms markAndTraceCacheTagLiteralinatpc(sqInt literal, CogMethod *cogMethodOrNil, usqInt address); -static sqInt numSmallIntegerBits(void); -static sqInt NoDbgRegParms validInlineCacheTag(usqInt classIndexOrTagPattern); -static sqInt NoDbgRegParms checkValidDerivedObjectReference(sqInt bodyAddress); -static sqInt NoDbgRegParms checkValidOopReference(sqInt anOop); -static sqInt NoDbgRegParms couldBeDerivedObject(sqInt bodyAddress); -static sqInt NoDbgRegParms couldBeObject(sqInt literal); -static usqInt NoDbgRegParms genActiveContextTrampolineLargeinBlockcalled(sqInt isLarge, sqInt isInBlock, char *aString); -static AbstractInstruction * NoDbgRegParms genCheckRememberedBitOfscratch(sqInt objReg, sqInt scratchReg); -static sqInt NoDbgRegParms genConvertCharacterToCodeInReg(sqInt reg); -static sqInt NoDbgRegParms genConvertIntegerToCharacterInReg(sqInt reg); -static sqInt NoDbgRegParms genCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(sqInt bcpc, sqInt numArgs, sqInt numCopied, sqInt ctxtNumArgs, sqInt isLargeCtxt, sqInt isInBlock); -static sqInt NoDbgRegParms genEnsureObjInRegNotForwardedscratchReg(sqInt reg, sqInt scratch); -static sqInt NoDbgRegParms genEnsureOopInRegNotForwardedscratchReg(sqInt reg, sqInt scratch); -static sqInt NoDbgRegParms genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(sqInt reg, sqInt scratch, void *fwdJumpTarget, void *nonFwdJumpTargetOrZero); -static sqInt NoDbgRegParms genEnsureOopInRegNotForwardedscratchRegupdatingMwr(sqInt reg, sqInt scratch, sqInt offset, sqInt baseReg); -static sqInt NoDbgRegParms genEnsureOopInRegNotForwardedscratchRegupdatingSlotin(sqInt reg, sqInt scratch, sqInt index, sqInt objReg); -static void generateObjectRepresentationTrampolines(void); -static sqInt NoDbgRegParms genGetActiveContextLargeinBlock(sqInt isLarge, sqInt isInBlock); -static sqInt NoDbgRegParms genGetActiveContextNumArgslargeinBlock(sqInt numArgs, sqInt isLargeContext, sqInt isInBlock); -static sqInt NoDbgRegParms genGetBitsofFormatByteOfinto(sqInt mask, sqInt sourceReg, sqInt destReg); -static sqInt NoDbgRegParms genGetClassIndexOfNonImminto(sqInt sourceReg, sqInt destReg); -static sqInt NoDbgRegParms genGetClassObjectOfClassIndexintoscratchReg(sqInt instReg, sqInt destReg, sqInt scratchReg); -static sqInt NoDbgRegParms genGetClassObjectOfintoscratchRegmayBeAForwarder(sqInt instReg, sqInt destReg, sqInt scratchReg, sqInt mayBeForwarder); -static AbstractInstruction * NoDbgRegParms genGetClassTagOfintoscratchReg(sqInt instReg, sqInt destReg, sqInt scratchReg); -static sqInt NoDbgRegParms genGetCompactClassIndexNonImmOfinto(sqInt instReg, sqInt destReg); -static sqInt NoDbgRegParms genGetDoubleValueOfinto(sqInt srcReg, sqInt destFPReg); -static sqInt NoDbgRegParms genGetFormatOfinto(sqInt srcReg, sqInt destReg); -static sqInt NoDbgRegParms genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(sqInt sourceReg, sqInt destReg, sqInt scratchRegOrNone); -static sqInt NoDbgRegParms genGetNumSlotsOfinto(sqInt srcReg, sqInt destReg); -static sqInt NoDbgRegParms genGetRawSlotSizeOfNonImminto(sqInt sourceReg, sqInt destReg); -static AbstractInstruction * NoDbgRegParms genJumpImmediate(sqInt aRegister); -#if IMMUTABILITY -static AbstractInstruction * NoDbgRegParms genJumpImmutablescratchReg(sqInt sourceReg, sqInt scratchReg); -#endif /* IMMUTABILITY */ -#if IMMUTABILITY -static AbstractInstruction * NoDbgRegParms genJumpMutablescratchReg(sqInt sourceReg, sqInt scratchReg); -#endif /* IMMUTABILITY */ -static AbstractInstruction * NoDbgRegParms genJumpNotCharacterInScratchReg(sqInt reg); -static sqInt NoDbgRegParms genNewArrayOfSizeinitialized(sqInt size, sqInt initialize); -static sqInt NoDbgRegParms genNoPopCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(sqInt bcpc, sqInt numArgs, sqInt numCopied, sqInt ctxtNumArgs, sqInt isLargeCtxt, sqInt isInBlock); -static sqInt genPrimitiveAsCharacter(void); -static sqInt genPrimitiveAt(void); -static sqInt NoDbgRegParms genPrimitiveIdenticalOrNotIf(sqInt orNot); -static sqInt genPrimitiveIntegerAt(void); -static sqInt genPrimitiveIntegerAtPut(void); -static sqInt genPrimitiveObjectAt(void); -static sqInt genPrimitiveSize(void); -static sqInt NoDbgRegParms genSetSmallIntegerTagsIn(sqInt scratchReg); -static usqInt genStoreCheckContextReceiverTrampoline(void); -static sqInt NoDbgRegParms genStoreCheckReceiverRegvalueRegscratchReginFrame(sqInt destReg, sqInt valueReg, sqInt scratchReg, sqInt inFrame); -static sqInt NoDbgRegParms genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt inFrame, sqInt needsStoreCheck); -static sqInt NoDbgRegParms genStoreSourceRegslotIndexintoNewObjectInDestReg(sqInt sourceReg, sqInt index, sqInt destReg); -#if IMMUTABILITY -static usqInt NoDbgRegParms genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex); -#endif /* IMMUTABILITY */ -#if IMMUTABILITY -static sqInt NoDbgRegParms genStoreWithImmutabilityAndStoreCheckSourceRegslotIndexdestRegscratchRegneedRestoreRcvr(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt needRestoreRcvr); -#endif /* IMMUTABILITY */ -#if IMMUTABILITY -static sqInt NoDbgRegParms genStoreWithImmutabilityButNoStoreCheckSourceRegslotIndexdestRegscratchRegneedRestoreRcvr(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt needRestoreRcvr); -#endif /* IMMUTABILITY */ -#if IMMUTABILITY -static sqInt NoDbgRegParms genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt needsStoreCheck, sqInt needRestoreRcvr); -#endif /* IMMUTABILITY */ -static sqInt getActiveContextAllocatesInMachineCode(void); -static sqInt NoDbgRegParms inlineCacheTagIsYoung(sqInt cacheTag); -static AbstractInstruction * NoDbgRegParms jumpNotCharacterUnsignedValueInRegister(sqInt reg); -static sqInt NoDbgRegParms markAndTraceLiteralinatpc(sqInt literal, CogMethod *cogMethodOrNil, usqInt address); -static void NoDbgRegParms markAndTraceLiteralinat(sqInt literal, CogMethod *cogMethod, sqInt *address); -static void NoDbgRegParms markAndTraceUpdatedLiteralin(sqInt objOop, CogMethod *cogMethodOrNil); -static sqInt NoDbgRegParms maybeCompileRetryOnPrimitiveFail(sqInt primIndex); -static sqInt NoDbgRegParms maybeShiftClassTagRegisterForMethodCacheProbe(sqInt classTagReg); -static sqInt numCharacterBits(void); -extern sqInt numRegArgs(void); -static sqInt NoDbgRegParms remapObject(sqInt objOop); -static sqInt NoDbgRegParms remapOop(sqInt objOop); -static sqInt NoDbgRegParms shouldAnnotateObjectReference(sqInt anOop); -static sqInt NoDbgRegParms slotOffsetOfInstVarIndex(sqInt index); -static SimStackEntry * NoDbgRegParms ensureSpilledAtfrom(SimStackEntry * self_in_ensureSpilledAtfrom, sqInt baseOffset, sqInt baseRegister); -static sqInt NoDbgRegParms isSameEntryAs(SimStackEntry * self_in_isSameEntryAs, CogSimStackEntry *ssEntry); -static sqInt NoDbgRegParms mayBeAForwarder(SimStackEntry * self_in_mayBeAForwarder); -static void NoDbgRegParms popToReg(SimStackEntry * self_in_popToReg, sqInt reg); -static sqInt NoDbgRegParms registerMask(SimStackEntry * self_in_registerMask); -static sqInt NoDbgRegParms registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone); -static sqInt NoDbgRegParms registerOrNone(SimStackEntry * self_in_registerOrNone); -static void NoDbgRegParms storeToReg(SimStackEntry * self_in_storeToReg, sqInt reg); -static sqInt NoDbgRegParms isMergeFixup(BytecodeFixup * self_in_isMergeFixup); -static AbstractInstruction * NoDbgRegParms checkLiteralforInstruction(sqInt literal, AbstractInstruction *anInstruction); -static AbstractInstruction * NoDbgRegParms checkQuickConstantforInstruction(sqInt literal, AbstractInstruction *anInstruction); -extern sqInt cogMethodHasExternalPrim(CogMethod *aCogMethod); -extern sqInt cogMethodHasMachineCodePrim(CogMethod *aCogMethod); -static sqInt compileBlockDispatch(void); -static void compileGetErrorCode(void); -static sqInt NoDbgRegParms compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags); -static sqInt NoDbgRegParms compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)); -static sqInt NoDbgRegParms compileOnStackExternalPrimitive(void (*primitiveRoutine)(void)); -static AbstractInstruction * NoDbgRegParms compileOpenPICMethodCacheProbeForwithShiftbaseRegOrNone(sqInt selector, sqInt shift, sqInt baseRegOrNone); -static void NoDbgRegParms compileOpenPICnumArgs(sqInt selector, sqInt numArgs); -static AbstractInstruction * NoDbgRegParms compilePerformMethodCacheProbeForwithShiftbaseRegOrNone(sqInt selectorReg, sqInt shift, sqInt baseRegOrNone); -static sqInt compilePrimitive(void); -static sqInt extendedPushBytecode(void); -static sqInt extendedStoreAndPopBytecode(void); -static sqInt extendedStoreBytecode(void); -static sqInt NoDbgRegParms frameOffsetOfTemporary(sqInt index); -static sqInt genExtendedSendBytecode(void); -static sqInt genExtendedSuperBytecode(void); -static sqInt genExtJumpIfFalse(void); -static sqInt genExtJumpIfTrue(void); -static sqInt genExtNopBytecode(void); -static sqInt genExtPushIntegerBytecode(void); -static sqInt genExtPushLiteralBytecode(void); -static sqInt genExtPushLiteralVariableBytecode(void); -static sqInt genExtPushPseudoVariableOrOuterBytecode(void); -static sqInt genExtPushReceiverVariableBytecode(void); -static sqInt genExtReturnTopFromBlock(void); -static sqInt genExtSendAbsentDynamicSuperBytecode(void); -static sqInt genExtSendAbsentImplicitBytecode(void); -static sqInt genExtSendAbsentOuterBytecode(void); -static sqInt genExtSendAbsentSelfBytecode(void); -static sqInt genExtSendBytecode(void); -static sqInt genExtSendSuperBytecode(void); -static sqInt genExtStoreAndPopLiteralVariableBytecode(void); -static sqInt genExtStoreAndPopReceiverVariableBytecode(void); -static sqInt genExtStoreLiteralVariableBytecode(void); -static sqInt genExtStoreReceiverVariableBytecode(void); -static sqInt genExtUnconditionalJump(void); -static sqInt genFastPrimFail(void); -static void NoDbgRegParms genFastPrimTraceUsingand(sqInt r1, sqInt r2); -static sqInt genLongJumpIfFalse(void); -static sqInt genLongJumpIfTrue(void); -static sqInt genLongPushTemporaryVariableBytecode(void); -static sqInt genLongStoreAndPopTemporaryVariableBytecode(void); -static sqInt genLongStoreTemporaryVariableBytecode(void); -static sqInt genLongUnconditionalBackwardJump(void); -static sqInt genLongUnconditionalForwardJump(void); -static sqInt NoDbgRegParms genLookupForPerformNumArgs(sqInt numArgs); -static usqInt NoDbgRegParms genMustBeBooleanTrampolineForcalled(sqInt boolean, char *trampolineName); -static void NoDbgRegParms genPrimReturnEnterCogCodeEnilopmart(sqInt profiling); -static sqInt genPushConstantFalseBytecode(void); -static sqInt genPushConstantNilBytecode(void); -static sqInt genPushConstantOneBytecode(void); -static sqInt genPushConstantTrueBytecode(void); -static sqInt genPushConstantZeroBytecode(void); -static sqInt genPushLiteralConstantBytecode(void); -static sqInt genPushLiteralVariable16CasesBytecode(void); -static sqInt genPushLiteralVariableBytecode(void); -static sqInt genPushQuickIntegerConstantBytecode(void); -static sqInt genPushReceiverVariableBytecode(void); -static sqInt genPushTemporaryVariableBytecode(void); -extern sqInt genQuickReturnConst(void); -extern sqInt genQuickReturnInstVar(void); -extern sqInt genQuickReturnSelf(void); -static sqInt genReturnFalse(void); -static sqInt genReturnNil(void); -static sqInt genReturnTrue(void); -static sqInt genSecondExtendedSendBytecode(void); -static sqInt NoDbgRegParms genSendAbsentDynamicSupernumArgs(sqInt selectorIndex, sqInt numArgs); -static sqInt genSendAbsentImplicit0ArgsBytecode(void); -static sqInt NoDbgRegParms genSendAbsentImplicitnumArgs(sqInt selectorIndex, sqInt numArgs); -static sqInt NoDbgRegParms genSendAbsentOuternumArgsdepth(sqInt selectorIndex, sqInt numArgs, sqInt depth); -static sqInt NoDbgRegParms genSendAbsentSelfnumArgs(sqInt selectorIndex, sqInt numArgs); -static sqInt genSendLiteralSelector0ArgsBytecode(void); -static sqInt genSendLiteralSelector1ArgBytecode(void); -static sqInt genSendLiteralSelector2ArgsBytecode(void); -static sqInt genShortJumpIfFalse(void); -static sqInt genShortJumpIfTrue(void); -static sqInt genShortUnconditionalJump(void); -static sqInt genSpecialSelectorEqualsEquals(void); -static sqInt genSpecialSelectorNotEqualsEquals(void); -static sqInt genSpecialSelectorSend(void); -static sqInt genStoreAndPopReceiverVariableBytecode(void); -static sqInt genStoreAndPopRemoteTempLongBytecode(void); -static sqInt genStoreAndPopTemporaryVariableBytecode(void); -static sqInt genStoreRemoteTempLongBytecode(void); -extern sqInt mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj); -static sqInt numSpecialSelectors(void); -static usqInt NoDbgRegParms pcDataForBlockEntryMethod(sqInt blockEntryMcpc, sqInt cogMethod); -static sqInt NoDbgRegParms pcDataForAnnotationMcpcBcpcMethod(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *cogMethodArg); -static PrimitiveDescriptor * primitiveGeneratorOrNil(void); -static sqInt NoDbgRegParms v3BlockCodeSize(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt NoDbgRegParms v3LongForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt NoDbgRegParms v3LongBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt NoDbgRegParms v3ShortForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt NoDbgRegParms v4BlockCodeSize(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt NoDbgRegParms v4LongForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt NoDbgRegParms v4LongBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static BlockStart * NoDbgRegParms addBlockStartAtnumArgsnumCopiedspan(sqInt bytecodepc, sqInt numArgs, sqInt numCopied, sqInt span); -static void NoDbgRegParms adjustArgumentsForPerform(sqInt numArgs); -static sqInt NoDbgRegParms allocateRegForStackEntryAtnotConflictingWith(sqInt index, sqInt regMask); -static sqInt NoDbgRegParms allocateRegNotConflictingWith(sqInt regMask); -static sqInt NoDbgRegParms anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n); -extern void callCogCodePopReceiverArg0Regs(void); -extern void callCogCodePopReceiverArg1Arg0Regs(void); -static sqInt NoDbgRegParms compileAbstractInstructionsFromthrough(sqInt start, sqInt end); -static sqInt compileBlockBodies(void); -static void NoDbgRegParms compileBlockFrameBuild(BlockStart *blockStart); -static void NoDbgRegParms compileBlockFramelessEntry(BlockStart *blockStart); -static CogMethod * NoDbgRegParms compileCogMethod(sqInt selector); -static sqInt compileEntireMethod(void); -static void compileFrameBuild(void); -#if IMMUTABILITY -static void compileTwoPathFrameBuild(void); -#endif /* IMMUTABILITY */ -static void compileTwoPathFramelessInit(void); -static sqInt NoDbgRegParms cPICMissTrampolineFor(sqInt numArgs); -static sqInt doubleExtendedDoAnythingBytecode(void); -static sqInt duplicateTopBytecode(void); -static BytecodeFixup * NoDbgRegParms ensureFixupAt(sqInt targetPC); -static BytecodeFixup * NoDbgRegParms ensureNonMergeFixupAt(sqInt targetPC); -static void ensureReceiverResultRegContainsSelf(void); -static void NoDbgRegParms evaluateat(BytecodeDescriptor *descriptor, sqInt pc); -static sqInt NoDbgRegParms eventualTargetOf(sqInt targetBytecodePC); -static sqInt NoDbgRegParms freeAnyRegNotConflictingWith(sqInt regMask); -static sqInt genBlockReturn(void); -static void (*genCallPICEnilopmartNumArgs(sqInt numArgs))(void) ; -static sqInt genCallPrimitiveBytecode(void); -static sqInt genExternalizePointersForPrimitiveCall(void); -static AbstractInstruction * genExternalizeStackPointerForFastPrimitiveCall(void); -static sqInt genExtPushClosureBytecode(void); -static void generateEnilopmarts(void); -static sqInt NoDbgRegParms generateInstructionsAt(sqInt eventualAbsoluteAddress); -static void generateMissAbortTrampolines(void); -static void generateSendTrampolines(void); -static void generateTracingTrampolines(void); -static sqInt NoDbgRegParms genForwardersInlinedIdenticalOrNotIf(sqInt orNot); -static sqInt NoDbgRegParms genIdenticalNoBranchArgIsConstantrcvrIsConstantargRegrcvrRegorNotIf(sqInt argIsConstant, sqInt rcvrIsConstant, sqInt argReg, sqInt rcvrRegOrNone, sqInt orNot); -static sqInt NoDbgRegParms genInlinedIdenticalOrNotIf(sqInt orNot); -static sqInt NoDbgRegParms genJumpBackTo(sqInt targetBytecodePC); -static sqInt NoDbgRegParms genJumpIfto(sqInt boolean, sqInt targetBytecodePC); -static sqInt NoDbgRegParms genJumpTo(sqInt targetBytecodePC); -static sqInt NoDbgRegParms genMarshalledSendnumArgssendTable(sqInt selectorIndex, sqInt numArgs, sqInt *sendTable); -static usqInt NoDbgRegParms genMethodAbortTrampolineFor(sqInt numArgs); -static sqInt NoDbgRegParms genNSSendnumArgsdepthsendTable(sqInt selectorIndex, sqInt numArgs, sqInt depth, sqInt *sendTable); -static usqInt NoDbgRegParms genPICAbortTrampolineFor(sqInt numArgs); -static usqInt NoDbgRegParms genPICMissTrampolineFor(sqInt numArgs); -static sqInt genPopStackBytecode(void); -static sqInt genPrimitiveClosureValue(void); -static sqInt genPrimitivePerform(void); -static sqInt genPushActiveContextBytecode(void); -static sqInt genPushClosureCopyCopiedValuesBytecode(void); -static sqInt NoDbgRegParms genPushEnclosingObjectAt(sqInt level); -static sqInt NoDbgRegParms genPushLiteralIndex(sqInt literalIndex); -static sqInt NoDbgRegParms genPushLiteralVariable(sqInt literalIndex); -static sqInt NoDbgRegParms genPushLiteral(sqInt literal); -static sqInt NoDbgRegParms genPushMaybeContextReceiverVariable(sqInt slotIndex); -static sqInt genPushNewArrayBytecode(void); -static sqInt genPushReceiverBytecode(void); -static sqInt NoDbgRegParms genPushReceiverVariable(sqInt index); -static void genPushRegisterArgs(void); -static sqInt genPushRemoteTempLongBytecode(void); -static sqInt NoDbgRegParms genPushTemporaryVariable(sqInt index); -static sqInt genReturnReceiver(void); -static sqInt genReturnTopFromBlock(void); -static sqInt genReturnTopFromMethod(void); -static sqInt NoDbgRegParms genSendDirectedSupernumArgs(sqInt selectorIndex, sqInt numArgs); -static sqInt NoDbgRegParms genSendSupernumArgs(sqInt selectorIndex, sqInt numArgs); -static usqInt NoDbgRegParms genSendTrampolineFornumArgscalledargargargarg(void *aRoutine, sqInt numArgs, char *aString, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3); -static sqInt NoDbgRegParms genSendnumArgs(sqInt selectorIndex, sqInt numArgs); -static sqInt genSpecialSelectorArithmetic(void); -static sqInt genSpecialSelectorClass(void); -static sqInt genSpecialSelectorComparison(void); -static sqInt genStaticallyResolvedSpecialSelectorComparison(void); -static sqInt NoDbgRegParms genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt litVarIndex, sqInt needsStoreCheck, sqInt needsImmCheck); -static sqInt NoDbgRegParms genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt slotIndex, sqInt needsStoreCheck, sqInt needsImmCheck); -static sqInt NoDbgRegParms genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt slotIndex, sqInt needsStoreCheck, sqInt needsImmCheck); -static sqInt NoDbgRegParms genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt remoteTempIndex, sqInt needsStoreCheck); -static sqInt NoDbgRegParms genStorePopTemporaryVariable(sqInt popBoolean, sqInt tempIndex); -static sqInt genUpArrowReturn(void); -static sqInt NoDbgRegParms genVanillaInlinedIdenticalOrNotIf(sqInt orNot); -static void NoDbgRegParms initSimStackForFramefulMethod(sqInt startpc); -static void NoDbgRegParms initSimStackForFramelessBlock(sqInt startpc); -static void NoDbgRegParms initSimStackForFramelessMethod(sqInt startpc); -static sqInt NoDbgRegParms isNonForwarderReceiver(sqInt reg); -static sqInt liveRegisters(void); -static sqInt NoDbgRegParms mapDeadDescriptorIfNeeded(BytecodeDescriptor *descriptor); -static void NoDbgRegParms marshallAbsentReceiverSendArguments(sqInt numArgs); -static void NoDbgRegParms marshallSendArguments(sqInt numArgs); -static sqInt maybeCompilingFirstPassOfBlockWithInitialPushNil(void); -static sqInt NoDbgRegParms mergeWithFixupIfRequired(BytecodeFixup *fixup); -static sqInt NoDbgRegParms methodAbortTrampolineFor(sqInt numArgs); -static sqInt methodFoundInvalidPostScan(void); -static sqInt NoDbgRegParms needsFrameIfExtBGT2(sqInt stackDelta); -static sqInt NoDbgRegParms needsFrameIfMod16GENumArgs(sqInt stackDelta); -static sqInt NoDbgRegParms needsFrameIfStackGreaterThanOne(sqInt stackDelta); -static sqInt NoDbgRegParms numberOfSpillsInTopNItems(sqInt n); -static sqInt NoDbgRegParms picAbortTrampolineFor(sqInt numArgs); -static sqInt prevInstIsPCAnnotated(void); -static sqInt receiverIsInReceiverResultReg(void); -static void NoDbgRegParms reinitializeFixupsFromthrough(sqInt start, sqInt end); -static sqInt NoDbgRegParms scanBlock(BlockStart *blockStart); -static sqInt scanMethod(void); -static void NoDbgRegParms ssAllocateRequiredRegMaskupThroughupThroughNative(sqInt requiredRegsMask, sqInt stackPtr, sqInt nativeStackPtr); -static void NoDbgRegParms ssFlushUpThroughReceiverVariable(sqInt slotIndex); -static void NoDbgRegParms ssFlushUpThroughTemporaryVariable(sqInt tempIndex); -static void NoDbgRegParms ssPop(sqInt n); -static sqInt NoDbgRegParms ssPushAnnotatedConstant(sqInt literal); -static sqInt NoDbgRegParms ssPushBaseoffset(sqInt reg, sqInt offset); -static sqInt NoDbgRegParms ssPushConstant(sqInt literal); -static sqInt NoDbgRegParms ssPushDesc(SimStackEntry simStackEntry); -static sqInt NoDbgRegParms ssPushRegister(sqInt reg); -static void NoDbgRegParms ssPush(sqInt n); -static SimStackEntry ssSelfDescriptor(void); -static void NoDbgRegParms ssStoreAndReplacePoptoReg(sqInt popBoolean, sqInt reg); -static sqInt NoDbgRegParms ssStorePoptoPreferredReg(sqInt popBoolean, sqInt preferredReg); -static void NoDbgRegParms ssStorePoptoReg(sqInt popBoolean, sqInt reg); -static CogSimStackEntry * ssTop(void); -static CogSimStackEntry * NoDbgRegParms ssValue(sqInt n); -static sqInt NoDbgRegParms stackEntryIsBoolean(CogSimStackEntry *simStackEntry); -static sqInt tempsValidAndVolatileEntriesSpilled(void); -static sqInt NoDbgRegParms tryCollapseTempVectorInitializationOfSize(sqInt slots); -static sqInt NoDbgRegParms v3or4PushNilSizenumInitialNils(sqInt aMethodObj, sqInt numInitialNils); -static sqInt NoDbgRegParms v3or4NumPushNils(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt violatesEnsureSpilledSpillAssert(void); -static void voidReceiverResultRegContainsSelf(void); - - -/*** Variables ***/ -static AbstractInstruction * abstractOpcodes; -static usqInt baseAddress; -static sqInt blockCount; -static AbstractInstruction * blockEntryLabel; -static AbstractInstruction * blockEntryNoContextSwitch; -static BlockStart * blockStarts; -static sqInt breakBlock; -static sqInt breakMethod; -static sqInt byte0; -static sqInt byte1; -static sqInt byte2; -static sqInt byte3; -static sqInt bytecodePC; -static sqInt bytecodeSetOffset; -static sqInt ceByteSizeOfTrampoline; -static sqInt ceCPICMissTrampoline; -static sqInt ceEnclosingObjectTrampoline; -static sqInt ceFetchContextInstVarTrampoline; -static sqInt ceFFICalloutTrampoline; -static sqInt ceFloatObjectOfTrampoline; -static sqInt ceFloatValueOfTrampoline; -static sqInt ceFlushICache; -static sqInt ceFreeTrampoline; -static sqInt ceInlineNewHashTrampoline; -static sqInt ceInstantiateClassIndexableSizeTrampoline; -static sqInt ceInstantiateClassTrampoline; -static sqInt ceLargeActiveContextInBlockTrampoline; -static sqInt ceLargeActiveContextInMethodTrampoline; -static sqInt ceMallocTrampoline; -static sqInt ceMethodAbortTrampoline; -static sqInt ceNewHashTrampoline; -static sqInt ceNonLocalReturnTrampoline; -static sqInt cePICAbortTrampoline; -static sqInt cePositive32BitIntegerTrampoline; -static sqInt cePositive32BitValueOfTrampoline; -static sqInt cePositive64BitIntegerTrampoline; -static sqInt cePositive64BitValueOfTrampoline; -static sqInt cePrimReturnEnterCogCode; -static sqInt cePrimReturnEnterCogCodeProfiling; -static sqInt ceReapAndResetErrorCodeTrampoline; -static sqInt ceScheduleScavengeTrampoline; -static sqInt ceSendMustBeBooleanAddFalseTrampoline; -static sqInt ceSendMustBeBooleanAddTrueTrampoline; -static sqInt ceSigned32BitIntegerTrampoline; -static sqInt ceSigned32BitValueOfTrampoline; -static sqInt ceSigned64BitIntegerTrampoline; -static sqInt ceSigned64BitValueOfTrampoline; -static sqInt ceSmallActiveContextInBlockTrampoline; -static sqInt ceSmallActiveContextInMethodTrampoline; -static sqInt ceStoreCheckContextReceiverTrampoline; -static sqInt ceStoreCheckTrampoline; -static sqInt ceStoreContextInstVarTrampoline; -static sqInt ceTraceBlockActivationTrampoline; -static sqInt ceTraceLinkedSendTrampoline; -static sqInt ceTraceStoreTrampoline; -static sqInt checkedEntryAlignment; -static sqInt closedPICSize; -static sqInt codeBase; -static sqInt codeModified; -static sqInt cogConstituentIndex; -static sqInt compactionInProgress; -static sqInt compilationPass; -static sqInt compilationTrace; -static sqInt cPICCaseSize; -static sqInt cPICEndOfCodeOffset; -static sqInt cPICEndSize; -static CogMethod * cPICPrototype; -static sqInt currentCallCleanUpSize; -static sqInt deadCode; -static sqInt debugBytecodePointers; -static sqInt debugFixupBreaks; -static sqInt debugOpcodeIndices; -static sqInt debugStackPointers; -static sqInt directedSendUsesBinding; -static sqInt directedSuperBindingSendTrampolines[NumSendTrampolines]; -static sqInt directedSuperSendTrampolines[NumSendTrampolines]; -static sqInt disassemblingMethod; -static sqInt dynamicSuperSendTrampolines[NumSendTrampolines]; -static AbstractInstruction * endCPICCase0; -static sqInt endPC; -static AbstractInstruction * entry; -static sqInt entryPointMask; -static CogMethod * enumeratingCogMethod; -static sqInt expectedFPAlignment; -static sqInt expectedSPAlignment; -static sqInt extA; -static sqInt extB; -static sqInt firstCPICCaseOffset; -static sqInt firstSend; -static BytecodeFixup * fixups; -static AbstractInstruction * fullBlockEntry; -static AbstractInstruction * fullBlockNoContextSwitchEntry; -static BytecodeDescriptor generatorTable[512] = { - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushReceiverBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantTrueBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantFalseBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantNilBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushQuickIntegerConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushQuickIntegerConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushQuickIntegerConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushQuickIntegerConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genReturnReceiver, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genReturnTrue, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genReturnFalse, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genReturnNil, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genReturnTopFromMethod, 0, needsFrameIfInBlock, -1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genReturnTopFromBlock, 0, needsFrameNever, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 }, - { extendedPushBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { extendedStoreBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 0, 0, 0 }, - { extendedStoreAndPopBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 0, 0, 0 }, - { genExtendedSendBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { doubleExtendedDoAnythingBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genExtendedSuperBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0 }, - { genSecondExtendedSendBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genPopStackBytecode, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { duplicateTopBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushActiveContextBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushNewArrayBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genCallPrimitiveBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushClosureCopyCopiedValuesBytecode, v3BlockCodeSize, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genLongUnconditionalBackwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genLongUnconditionalBackwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genLongUnconditionalBackwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genLongUnconditionalBackwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genLongUnconditionalForwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genLongUnconditionalForwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genLongUnconditionalForwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genLongUnconditionalForwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genLongJumpIfTrue, v3LongForwardBranchDistance, 0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genLongJumpIfTrue, v3LongForwardBranchDistance, 0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genLongJumpIfTrue, v3LongForwardBranchDistance, 0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genLongJumpIfTrue, v3LongForwardBranchDistance, 0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genLongJumpIfFalse, v3LongForwardBranchDistance, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genLongJumpIfFalse, v3LongForwardBranchDistance, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genLongJumpIfFalse, v3LongForwardBranchDistance, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genLongJumpIfFalse, v3LongForwardBranchDistance, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, AddRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, SubRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpLess, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpGreater, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpLessOrEqual, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpGreaterOrEqual, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpZero, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpNonZero, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, AndRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, OrRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorEqualsEquals, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorClass, 0, needsFrameIfStackGreaterThanOne, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorNotEqualsEquals, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushReceiverBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtPushPseudoVariableOrOuterBytecode, 0, needsFrameIfExtBGT2, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantZeroBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantOneBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, AddRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, SubRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpLess, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpGreater, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpLessOrEqual, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpGreaterOrEqual, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpZero, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpNonZero, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, AndRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, OrRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorEqualsEquals, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorClass, 0, needsFrameIfStackGreaterThanOne, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorNotEqualsEquals, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genSendAbsentImplicit0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0 }, - { genSendAbsentImplicit0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0 }, - { genSendAbsentImplicit0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0 }, - { genSendAbsentImplicit0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0 }, - { genSendAbsentImplicit0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0 }, - { genSendAbsentImplicit0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0 }, - { genSendAbsentImplicit0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0 }, - { genSendAbsentImplicit0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0 }, - { genSendAbsentImplicit0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0 }, - { genSendAbsentImplicit0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0 }, - { genSendAbsentImplicit0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0 }, - { genSendAbsentImplicit0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0 }, - { genSendAbsentImplicit0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0 }, - { genSendAbsentImplicit0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0 }, - { genSendAbsentImplicit0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0 }, - { genSendAbsentImplicit0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genReturnReceiver, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genReturnTopFromMethod, 0, needsFrameIfInBlock, -1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genExtReturnTopFromBlock, 0, needsFrameNever, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, - { duplicateTopBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPopStackBytecode, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtNopBytecode, 0, needsFrameNever, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 }, - { extABytecode, 0, needsFrameNever, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 }, - { extBBytecode, 0, needsFrameNever, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 }, - { genExtPushReceiverVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genExtPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtPushLiteralBytecode, 0, needsFrameNever, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtPushIntegerBytecode, 0, needsFrameNever, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genLongPushTemporaryVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushNewArrayBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtStoreReceiverVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 0, 0, 0 }, - { genExtStoreLiteralVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 0, 0, 0, 0 }, - { genLongStoreTemporaryVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtStoreAndPopReceiverVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 0, 0, 0 }, - { genExtStoreAndPopLiteralVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 0, 0, 0, 0 }, - { genLongStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtSendBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genExtSendSuperBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genExtSendAbsentImplicitBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0 }, - { genExtSendAbsentDynamicSuperBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0 }, - { genExtUnconditionalJump, v4LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genExtJumpIfTrue, v4LongBranchDistance, 0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genExtJumpIfFalse, v4LongBranchDistance, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genExtSendAbsentSelfBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 }, - { genCallPrimitiveBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtPushClosureBytecode, v4BlockCodeSize, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, - { genExtSendAbsentOuterBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 } -}; -static sqInt guardPageSize; -static sqInt hasMovableLiteral; -static sqInt hasYoungReferent; -static sqInt implicitReceiverSendTrampolines[NumSendTrampolines]; -static sqInt inBlock; -static sqInt indexOfIRC; -static sqInt initialPC; -static sqInt introspectionData; -static sqInt introspectionDataIndex; -static int labelCounter; -static sqInt lastSend; -static usqInt limitAddress; -static sqInt maxLitIndex; -static sqInt methodAbortTrampolines[4]; -static sqInt methodBytesFreedSinceLastCompaction; -static sqInt methodCount; -static sqInt methodHeader; -static sqInt methodObj; -static sqInt methodOrBlockNumArgs; -static sqInt methodOrBlockNumTemps; -static usqIntptr_t minValidCallAddress; -static usqInt mzFreeStart; -static sqInt needsFrame; -static AbstractInstruction * noCheckEntry; -static sqInt numAbstractOpcodes; -static sqInt numExtB; -static sqInt numIRCs; -static usqInt objectReferencesInRuntime[NumObjRefsInRuntime+1]; -static sqInt opcodeIndex; -static CogMethod *openPICList = 0; -static sqInt openPICSize; -static sqInt ordinarySendTrampolines[NumSendTrampolines]; -static sqInt outerSendTrampolines[NumSendTrampolines]; -static sqInt picAbortTrampolines[4]; -static AbstractInstruction * picInterpretAbort; -static sqInt picMissTrampolines[4]; -static AbstractInstruction * picMNUAbort; -static BytecodeDescriptor * prevBCDescriptor; -static AbstractInstruction * primInvokeInstruction; -static PrimitiveDescriptor primitiveGeneratorTable[MaxCompiledPrimitiveIndex+1] = { - { 0, -1 }, - { genPrimitiveAdd, 1 }, - { genPrimitiveSubtract, 1 }, - { genPrimitiveLessThan, 1 }, - { genPrimitiveGreaterThan, 1 }, - { genPrimitiveLessOrEqual, 1 }, - { genPrimitiveGreaterOrEqual, 1 }, - { genPrimitiveEqual, 1 }, - { genPrimitiveNotEqual, 1 }, - { genPrimitiveMultiply, 1 }, - { genPrimitiveDivide, 1 }, - { genPrimitiveMod, 1 }, - { genPrimitiveDiv, 1 }, - { genPrimitiveQuo, 1 }, - { genPrimitiveBitAnd, 1 }, - { genPrimitiveBitOr, 1 }, - { genPrimitiveBitXor, 1 }, - { genPrimitiveBitShift, 1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveAt, 1 }, - { genPrimitiveAtPut, 2 }, - { genPrimitiveSize, 0 }, - { genPrimitiveStringAt, 1 }, - { genPrimitiveStringAtPut, 2 }, - { genFastPrimFail, -1 }, - { genFastPrimFail, -1 }, - { genFastPrimFail, -1 }, - { genPrimitiveObjectAt, 1 }, - { 0, -1 }, - { genPrimitiveNew, -1 }, - { genPrimitiveNewWithArg, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveIdentityHash, 0 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveNewMethod, 2 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitivePerform, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveIdentical, 1 }, - { genPrimitiveClass, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveShallowCopy, 0 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveIntegerAt, 1 }, - { genPrimitiveIntegerAtPut, 2 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveNotIdentical, 1 }, - { genPrimitiveAsCharacter, -1 }, - { genPrimitiveImmediateAsInteger, 0 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveIdentityHash, 0 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genFastPrimFail, -1 }, - { genFastPrimFail, -1 }, - { 0, -1 }, - { genPrimitiveClosureValue, 0 }, - { genPrimitiveClosureValue, 1 }, - { genPrimitiveClosureValue, 2 }, - { genPrimitiveClosureValue, 3 }, - { genPrimitiveClosureValue, 4 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveClosureValue, 0 }, - { genPrimitiveClosureValue, 1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveHighBit, 0 } -}; -static sqInt primitiveIndex; -static AbstractInstruction * primSetFunctionLabel; -static sqInt processorLock; -static sqInt receiverTags; -static sqInt regArgsHaveBeenPushed; -static sqInt runtimeObjectRefIndex; -static sqInt selfSendTrampolines[NumSendTrampolines]; -static AbstractInstruction * sendMiss; -static sqInt simNativeStackPtr; -static sqInt simSpillBase; -static SimStackEntry simStack[70]; -static sqInt simStackPtr; -static AbstractInstruction * stackCheckLabel; -static AbstractInstruction * stackOverflowCall; -static sqInt superSendTrampolines[NumSendTrampolines]; -static sqInt tempOop; -static sqInt theIRCs; -static char *trampolineAddresses[NumTrampolines*2]; -static sqInt trampolineTableIndex; -static sqInt uncheckedEntryAlignment; -static usqInt unpairedMethodList; -static sqInt useTwoPaths; -static sqInt varBaseAddress; -static usqInt youngReferrers; -static AbstractInstruction aMethodLabel; -static AbstractInstruction * const backEnd = &aMethodLabel; -#if DUAL_MAPPED_CODE_ZONE -static void (*ceFlushDCache)(usqIntptr_t from, usqIntptr_t to); -#endif -#if IMMUTABILITY -static sqInt ceStoreTrampolines[5];; -#endif -#if DUAL_MAPPED_CODE_ZONE -static sqInt codeToDataDelta; -#else -# define codeToDataDelta 0 -#endif -static AbstractInstruction * const methodLabel = &aMethodLabel; -sqInt blockNoContextSwitchOffset; -sqInt breakPC; -sqInt cbEntryOffset; -sqInt cbNoSwitchEntryOffset; -sqInt ceBaseFrameReturnTrampoline; -sqInt ceCannotResumeTrampoline; -sqInt ceCheckForInterruptTrampoline; -sqInt ceReturnToInterpreterTrampoline; -sqInt cFramePointerInUse; -sqInt cmEntryOffset; -sqInt cmNoCheckEntryOffset; -usqInt methodZoneBase; -sqInt missOffset; -int traceFlags = 8 /* prim trace log on by default */; -sqInt traceStores; -void (*ceCall0ArgsPIC)(void); -void (*ceCall1ArgsPIC)(void); -void (*ceCall2ArgsPIC)(void); -void (*ceCallCogCodePopReceiverAndClassRegs)(void); -void (*ceCallCogCodePopReceiverArg0Regs)(void); -void (*ceCallCogCodePopReceiverArg1Arg0Regs)(void); -void (*ceCallCogCodePopReceiverReg)(void); -void (*ceCaptureCStackPointers)(void); -void (*ceEnterCogCodePopReceiverReg)(void); -usqIntptr_t (*ceGetFP)(void); -usqIntptr_t (*ceGetSP)(void); -void (*ceInvokeInterpret)(void); -#if COGMTVM -usqIntptr_t (*ceTryLockVMOwner)(usqIntptr_t); -#endif -void (*realCECallCogCodePopReceiverAndClassRegs)(void); -void (*realCECallCogCodePopReceiverArg0Regs)(void); -void (*realCECallCogCodePopReceiverArg1Arg0Regs)(void); -void (*realCECallCogCodePopReceiverReg)(void); -void (*realCEEnterCogCodePopReceiverReg)(void); - - -/*** Macros ***/ -#define inlineCacheValueForSelectorin(backEnd,selector,aCogMethod) (selector) -#define roundUpToMethodAlignment(ignored,numBytes) ((numBytes) + 7 & -8) -#define cPICNumCases stackCheckOffset -#define cPICNumCasesHack hack hack hack i.e. the getter macro does all the work -#define abstractInstructionAt(index) (&abstractOpcodes[index]) -#define addressIsInInstructions(address) (!((usqInt)(address) & (BytesPerWord-1)) \ - && (address) >= &abstractOpcodes[0] \ - && (address) < &abstractOpcodes[opcodeIndex]) -#define allocateBlockStarts(numBlocks) do { \ - blockStarts = (numBlocks) ? alloca(sizeof(BlockStart) * (numBlocks)) : 0; \ -} while (0) -#define assertValidDualZoneReadAddress(address) 0 -#define assertValidDualZoneWriteAddress(address) 0 -#define backEnd() backEnd -#define blockAlignment() 8 -#define blockStartAt(index) (&blockStarts[index]) -#define breakOnImplicitReceiver() (traceFlags & 64) -#define ceBaseFrameReturnPC() ceBaseFrameReturnTrampoline -#define ceCannotResumePC() ((usqInt)ceCannotResumeTrampoline) -#define ceCheckForInterruptTrampoline() ceCheckForInterruptTrampoline -#define ceReturnToInterpreterPC() ((usqInt)ceReturnToInterpreterTrampoline) -#define codeByteAtput(address,value) byteAtput((address) + codeToDataDelta, value) -#define codeLong32Atput(address,value) long32Atput((address) + codeToDataDelta, value) -#define codeLong64Atput(address,value) long64Atput((address) + codeToDataDelta, value) -#define codeLongAtput(address,value) longAtput((address) + codeToDataDelta, value) -#define codeMemcpy(dest,src,bytes) memcpy(dest,src,bytes) -#define codeMemmove(dest,src,bytes) memmove((char *)(dest)+codeToDataDelta,src,bytes) -#define cr() putchar('\n') -#define entryOffset() cmEntryOffset -#define generatorAt(index) (&generatorTable[index]) -#define getCodeToDataDelta() codeToDataDelta -#define getIsObjectReference() 2 -#define halt() warning("halt") -#define haltmsg(msg) warning("halt: " msg) -#define interpretOffset() missOffset -#define maxCogCodeSize() (16*1024*1024) -#define maybeBreakGeneratingFromto(address,end) 0 -#define maybeBreakGeneratingInstructionWithIndex(i) 0 -#define maybeHaltIfDebugPC() 0 -#define methodLabel() methodLabel -#define methodZoneBase() methodZoneBase -#define minCallAddress() minValidCallAddress -#define minCogMethodAddress() methodZoneBase -#define noCheckEntryOffset() cmNoCheckEntryOffset -#define noContextSwitchBlockEntryOffset() blockNoContextSwitchOffset -#define notYetImplemented() warning("not yet implemented") -#define null 0 -#define printNum(n) printf("%" PRIdSQINT, (sqInt) (n)) -#define printOnTrace() (traceFlags & 1) -#define print(aString) printf("%s", aString) -#define recordBlockTrace() (traceFlags & 4) -#define recordEventTrace() (traceFlags & 16) -#define recordOverflowTrace() (traceFlags & 32) -#define recordPrimTrace() (traceFlags & 8) -#define recordSendTrace() (traceFlags & 2) -#define reportError(n) warning("compilation error") -#define setHasMovableLiteral(b) (hasMovableLiteral = (b)) -#define setHasYoungReferent(b) (hasYoungReferent = (b)) -#define tryLockVMOwnerTo(value) ceTryLockVMOwner(value) -#define varBaseAddress() varBaseAddress -#define nextOpenPIC methodObject -#define nextOpenPICHack hack hack hack i.e. the getter macro does all the work -#define freeStart() mzFreeStart -#define limitZony() ((CogMethod *)mzFreeStart) -#define methodBytesFreedSinceLastCompaction() methodBytesFreedSinceLastCompaction -#define youngReferrers() youngReferrers -#define flushDCacheFromto(me,startAddress,endAddress) 0 -#define flushICacheFromto(me,startAddress,endAddress) cacheflush((char*) startAddress, endAddress - startAddress, ICACHE) -#define maybeConstant(sse) ((sse)->constant) -#define fullBlockEntryOffset() cbEntryOffset -#define fullBlockNoContextSwitchEntryOffset() cbNoSwitchEntryOffset -#define fixupAtIndex(index) (&fixups[index]) -#define simNativeStackAt(index) (simNativeStack + (index)) -#define simSelf() simStack -#define simStackAt(index) (simStack + (index)) -#define traceDescriptor(ign) 0 -#define traceFixupmerge(igu,ana) 0 -#define traceMerge(ign) 0 -#define traceSimStack() 0 -#define traceSpill(ign) 0 -#define allocatype(numElements, elementType) alloca((numElements)*sizeof(elementType)) -#define numElementsIn(anArray) (sizeof(anArray)/sizeof(anArray[0])) -#define oopisGreaterThanOrEqualTo(anOop,otherOop) ((usqInt)(anOop) >= (usqInt)(otherOop)) -#define oopisGreaterThanOrEqualToandLessThanOrEqualTo(anOop,baseOop,limitOop) ((usqInt)(anOop) >= (usqInt)(baseOop) && (usqInt)(anOop) <= (usqInt)(limitOop)) -#define oopisGreaterThanOrEqualToandLessThan(anOop,baseOop,limitOop) ((usqInt)(anOop) >= (usqInt)(baseOop) && (usqInt)(anOop) < (usqInt)(limitOop)) -#define oopisGreaterThan(anOop,otherOop) ((usqInt)(anOop) > (usqInt)(otherOop)) -#define oopisGreaterThanandLessThan(anOop,baseOop,limitOop) ((usqInt)(anOop) > (usqInt)(baseOop) && (usqInt)(anOop) < (usqInt)(limitOop)) -#define oopisLessThanOrEqualTo(anOop,otherOop) ((usqInt)(anOop) <= (usqInt)(otherOop)) -#define oopisLessThan(anOop,otherOop) ((usqInt)(anOop) < (usqInt)(otherOop)) - - - /* CogAbstractInstruction>>#addDependent: */ -static AbstractInstruction * NoDbgRegParms -addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *anInstruction) -{ - if (!(((self_in_addDependent->dependent)) == null)) { - (anInstruction->dependent = (self_in_addDependent->dependent)); - } - return ((self_in_addDependent->dependent) = anInstruction); -} - - -/* Answer an unused abstract register in the liveRegMask. - Subclasses with more registers can override to answer them. */ - - /* CogAbstractInstruction>>#availableFloatRegisterOrNoneFor: */ -static sqInt NoDbgRegParms -availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask) -{ - if (!(((liveRegsMask & (1U << DPFPReg0)) != 0))) { - return DPFPReg0; - } - if (!(((liveRegsMask & (1U << DPFPReg1)) != 0))) { - return DPFPReg1; - } - if (!(((liveRegsMask & (1U << DPFPReg2)) != 0))) { - return DPFPReg2; - } - if (!(((liveRegsMask & (1U << DPFPReg3)) != 0))) { - return DPFPReg3; - } - if (!(((liveRegsMask & (1U << DPFPReg4)) != 0))) { - return DPFPReg4; - } - if (!(((liveRegsMask & (1U << DPFPReg5)) != 0))) { - return DPFPReg5; - } - if (!(((liveRegsMask & (1U << DPFPReg6)) != 0))) { - return DPFPReg6; - } - if (!(((liveRegsMask & (1U << DPFPReg7)) != 0))) { - return DPFPReg7; - } - return NoReg; -} - - -/* Answer an unused abstract register in the liveRegMask. - Subclasses with more registers can override to answer them. - N.B. Do /not/ allocate TempReg. */ - - /* CogAbstractInstruction>>#availableRegisterOrNoneFor: */ -static sqInt NoDbgRegParms -availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask) -{ - if (!(((liveRegsMask & (1U << Arg1Reg)) != 0))) { - return Arg1Reg; - } - if (!(((liveRegsMask & (1U << Arg0Reg)) != 0))) { - return Arg0Reg; - } - if (!(((liveRegsMask & (1U << SendNumArgsReg)) != 0))) { - return SendNumArgsReg; - } - if (!(((liveRegsMask & (1U << ClassReg)) != 0))) { - return ClassReg; - } - if (!(((liveRegsMask & (1U << ReceiverResultReg)) != 0))) { - return ReceiverResultReg; - } - return NoReg; -} - - -/* For out-of-line literal support, clone a literal from a literal. */ - - /* CogAbstractInstruction>>#cloneLiteralFrom: */ -static void NoDbgRegParms -cloneLiteralFrom(AbstractInstruction * self_in_cloneLiteralFrom, AbstractInstruction *existingLiteral) -{ - assert((((existingLiteral->opcode)) == Literal) - && ((((self_in_cloneLiteralFrom->dependent)) == null) - && (((self_in_cloneLiteralFrom->address)) == null))); - (self_in_cloneLiteralFrom->opcode) = Literal; - (self_in_cloneLiteralFrom->annotation) = (existingLiteral->annotation); - ((self_in_cloneLiteralFrom->operands))[0] = (((existingLiteral->operands))[0]); - ((self_in_cloneLiteralFrom->operands))[1] = (((existingLiteral->operands))[1]); - ((self_in_cloneLiteralFrom->operands))[2] = (((existingLiteral->operands))[2]); -} - - -/* Load the stack pointer register with that of the C stack, effecting - a switch to the C stack. Used when machine code calls into the - CoInterpreter run-time (e.g. to invoke interpreter primitives). */ - - /* CogAbstractInstruction>>#genLoadCStackPointer */ -static sqInt NoDbgRegParms -genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer) -{ - AbstractInstruction *anInstruction; - - /* begin checkLiteral:forInstruction: */ - cStackPointerAddress(); - anInstruction = genoperandoperand(MoveAwR, cStackPointerAddress(), NativeSPReg); - return 0; -} - - -/* Load the frame and stack pointer registers with those of the C stack, - effecting a switch to the C stack. Used when machine code calls into - the CoInterpreter run-time (e.g. to invoke interpreter primitives). - N.B. CoInterpreter stack layout dictates that the stack pointer should be - loaded first. - The stack zone is allocated on the C stack before the interpreter runs and - hence before CStackPointer and CFramePointer are captured. So when running - in machine - code the native stack pointer and frame pointer appear to be on a colder - part of the - stack to CStackPointer and CFramePointer. When CStackPointerhas been set - and the frame pointer is still in machine code the current frame looks - like it has lots of - stack. If the frame pointer was set to CFramePointer before hand then it - would be beyond the stack pointer for that one instruction. */ - - /* CogAbstractInstruction>>#genLoadCStackPointers */ -static sqInt NoDbgRegParms -genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkLiteral:forInstruction: */ - cStackPointerAddress(); - anInstruction = genoperandoperand(MoveAwR, cStackPointerAddress(), NativeSPReg); - /* begin checkLiteral:forInstruction: */ - cFramePointerAddress(); - anInstruction1 = genoperandoperand(MoveAwR, cFramePointerAddress(), FPReg); - return 0; -} - - -/* Switch back to the Smalltalk stack. Assign SPReg first - because typically it is used immediately afterwards. */ - - /* CogAbstractInstruction>>#genLoadStackPointers */ -static sqInt NoDbgRegParms -genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkLiteral:forInstruction: */ - stackPointerAddress(); - anInstruction = genoperandoperand(MoveAwR, stackPointerAddress(), SPReg); - /* begin checkLiteral:forInstruction: */ - framePointerAddress(); - anInstruction1 = genoperandoperand(MoveAwR, framePointerAddress(), FPReg); - return 0; -} - - -/* Save the frame and stack pointer registers to the framePointer - and stackPointer variables. Used to save the machine code frame - for use by the run-time when calling into the CoInterpreter run-time. */ - - /* CogAbstractInstruction>>#genSaveStackPointers */ -static sqInt NoDbgRegParms -genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkLiteral:forInstruction: */ - framePointerAddress(); - anInstruction = genoperandoperand(MoveRAw, FPReg, framePointerAddress()); - /* begin checkLiteral:forInstruction: */ - stackPointerAddress(); - anInstruction1 = genoperandoperand(MoveRAw, SPReg, stackPointerAddress()); - return 0; -} - - -/* Generic register swap code. Subclasses for processors that have a true - exchange operation will override to use it. */ - - /* CogAbstractInstruction>>#genSwapR:R:Scratch: */ -static AbstractInstruction * NoDbgRegParms -genSwapRRScratch(AbstractInstruction * self_in_genSwapRRScratch, sqInt regA, sqInt regB, sqInt regTmp) -{ - AbstractInstruction *first; - - first = genoperandoperand(MoveRR, regA, regTmp); - genoperandoperand(MoveRR, regB, regA); - genoperandoperand(MoveRR, TempReg, regB); - return first; -} - - /* CogAbstractInstruction>>#genWriteCResultIntoReg: */ -static void NoDbgRegParms -genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister) -{ - if ((abstractRegister != NoReg) - && (abstractRegister != ABIResultReg)) { - genoperandoperand(MoveRR, ABIResultReg, abstractRegister); - } -} - - -/* For out-of-line literal support, initialize a sharable literal. */ - - /* CogAbstractInstruction>>#initializeSharableLiteral: */ -static void NoDbgRegParms -initializeSharableLiteral(AbstractInstruction * self_in_initializeSharableLiteral, sqInt literal) -{ - (self_in_initializeSharableLiteral->opcode) = Literal; - - /* separate := nil for Slang */ - (self_in_initializeSharableLiteral->annotation) = null; - (self_in_initializeSharableLiteral->address) = null; - (self_in_initializeSharableLiteral->dependent) = null; - ((self_in_initializeSharableLiteral->operands))[0] = literal; - ((self_in_initializeSharableLiteral->operands))[1] = (1 + (((sqInt)((usqInt)(BytesPerOop) << 1)))); - ((self_in_initializeSharableLiteral->operands))[2] = -1; -} - - -/* For out-of-line literal support, initialize an unsharable literal. */ - - /* CogAbstractInstruction>>#initializeUniqueLiteral: */ -static void NoDbgRegParms -initializeUniqueLiteral(AbstractInstruction * self_in_initializeUniqueLiteral, sqInt literal) -{ - (self_in_initializeUniqueLiteral->opcode) = Literal; - - /* separate := nil for Slang */ - (self_in_initializeUniqueLiteral->annotation) = null; - (self_in_initializeUniqueLiteral->address) = null; - (self_in_initializeUniqueLiteral->dependent) = null; - ((self_in_initializeUniqueLiteral->operands))[0] = literal; - ((self_in_initializeUniqueLiteral->operands))[1] = (0 + (((sqInt)((usqInt)(BytesPerOop) << 1)))); - ((self_in_initializeUniqueLiteral->operands))[2] = -1; -} - - -/* Answer if an address can be accessed using the offset in a MoveMw:r:R: or - similar instruction. - We assume this is true for 32-bit processors and expect 64-bit processors - to answer false - for values in the interpreter or the object memory. */ - - /* CogAbstractInstruction>>#isWithinMwOffsetRange: */ -static sqInt NoDbgRegParms -isWithinMwOffsetRange(AbstractInstruction * self_in_isWithinMwOffsetRange, sqInt anAddress) -{ - return 1; -} - - -/* Set the target of a jump instruction. These all have the target in the - first operand. */ - - /* CogAbstractInstruction>>#jmpTarget: */ -static AbstractInstruction * NoDbgRegParms -jmpTarget(AbstractInstruction * self_in_jmpTarget, AbstractInstruction *anAbstractInstruction) -{ - ((self_in_jmpTarget->operands))[0] = (((usqInt)anAbstractInstruction)); - return anAbstractInstruction; -} - - /* CogAbstractInstruction>>#resolveJumpTarget */ -static void NoDbgRegParms -resolveJumpTarget(AbstractInstruction * self_in_resolveJumpTarget) -{ - BytecodeFixup *fixup; - - assert(isJump(self_in_resolveJumpTarget)); - fixup = ((BytecodeFixup *) (((self_in_resolveJumpTarget->operands))[0])); - if (addressIsInFixups(fixup)) { - assert(addressIsInInstructions((fixup->targetInstruction))); - jmpTarget(self_in_resolveJumpTarget, (fixup->targetInstruction)); - } -} - - -/* Rewrite a CallFull instruction to call a different target. This variant is - used to rewrite cached primitive calls. - Answer the extent of the code change which is used to compute the range of - the icache to flush. - This defaults to rewriteCallAt:target:; processors that differentiate - between Call and CallFull will override. */ - - /* CogAbstractInstruction>>#rewriteCallFullAt:target: */ -static sqInt NoDbgRegParms -rewriteCallFullAttarget(AbstractInstruction * self_in_rewriteCallFullAttarget, sqInt callSiteReturnAddress, sqInt callTargetAddress) -{ - return rewriteCallAttarget(self_in_rewriteCallFullAttarget, callSiteReturnAddress, callTargetAddress); -} - - -/* Rewrite a JumpFull instruction to jump to a different target. This variant - is used to rewrite cached primitive calls. - Answer the extent of the code change which is used to compute the range of - the icache to flush. - This defaults to rewriteJumpLongAt:target:; processors that differentiate - between Jump and JumpFull will override. */ - - /* CogAbstractInstruction>>#rewriteJumpFullAt:target: */ -static sqInt NoDbgRegParms -rewriteJumpFullAttarget(AbstractInstruction * self_in_rewriteJumpFullAttarget, sqInt callSiteReturnAddress, sqInt callTargetAddress) -{ - return rewriteJumpLongAttarget(self_in_rewriteJumpFullAttarget, callSiteReturnAddress, callTargetAddress); -} - - /* CogBlockMethod>>#cmHomeMethod */ -static CogMethod * NoDbgRegParms -cmHomeMethod(CogBlockMethod * self_in_cmHomeMethod) -{ - return ((CogMethod *) ((((usqInt)self_in_cmHomeMethod)) - ((self_in_cmHomeMethod->homeOffset)))); -} - - /* CogBytecodeDescriptor>>#isBranch */ -static sqInt NoDbgRegParms -isBranch(BytecodeDescriptor * self_in_isBranch) -{ - return (((self_in_isBranch->spanFunction)) != null) - && (!((self_in_isBranch->isBlockCreation))); -} - - /* Cogit>>#AddCq:R: */ -static AbstractInstruction * NoDbgRegParms -gAddCqR(sqInt quickConstant, sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, quickConstant, reg); - return anInstruction; -} - - -/* N.B. if the condition codes don't require setting and three address - arithmetic is unavailable, then LoadEffectiveAddressMw:r:R: can be used - instead. - */ - - /* Cogit>>#AddCq:R:R: */ -static AbstractInstruction * NoDbgRegParms -gAddCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction * first; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(AddCqRR, quickConstant, srcReg, destReg); - return anInstruction2; - if (srcReg == destReg) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, quickConstant, destReg); - return anInstruction; - } - first = genoperandoperand(MoveRR, srcReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AddCqR, quickConstant, destReg); - return first; -} - - /* Cogit>>#AndCq:R: */ -static AbstractInstruction * NoDbgRegParms -gAndCqR(sqInt quickConstant, sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, quickConstant, reg); - return anInstruction; -} - - /* Cogit>>#AndCq:R:R: */ -static AbstractInstruction * NoDbgRegParms -gAndCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction * first; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(AndCqRR, quickConstant, srcReg, destReg); - return anInstruction2; - if (srcReg == destReg) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, quickConstant, destReg); - return anInstruction; - } - first = genoperandoperand(MoveRR, srcReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, quickConstant, destReg); - return first; -} - - -/* destReg := (signed)srcReg >> quickConstant */ - - /* Cogit>>#ArithmeticShiftRightCq:R:R: */ -static AbstractInstruction * NoDbgRegParms -gArithmeticShiftRightCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) -{ - AbstractInstruction * first; - - return genoperandoperandoperand(ArithmeticShiftRightCqRR, quickConstant, srcReg, destReg); - first = genoperandoperand(MoveRR, srcReg, destReg); - genoperandoperand(ArithmeticShiftRightCqR, quickConstant, destReg); - return first; -} - - /* Cogit>>#abortOffset */ -sqInt -abortOffset(void) -{ - return missOffset; -} - - /* Cogit>>#addCleanBlockStarts */ -static void -addCleanBlockStarts(void) -{ - sqInt i; - sqInt iLimiT; - sqInt lit; - sqInt startPCOrNil; - - for (i = 1, iLimiT = (literalCountOf(methodObj)); i <= iLimiT; i += 1) { - lit = fetchPointerofObject(i, methodObj); - startPCOrNil = startPCOrNilOfLiteralin(lit, methodObj); - if (!(startPCOrNil == null)) { - maxLitIndex = ((maxLitIndex < i) ? i : maxLitIndex); - addBlockStartAtnumArgsnumCopiedspan(startPCOrNil - 1, argumentCountOfClosure(lit), copiedValueCountOfClosure(lit), spanForCleanBlockStartingAt(startPCOrNil - 1)); - } - } -} - - -/* Perform an integrity/leak check using the heapMap. - Set a bit at each cog method's header. */ - - /* Cogit>>#addCogMethodsToHeapMap */ -void -addCogMethodsToHeapMap(void) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - heapMapAtWordPut(cogMethod, 1); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* Cogit>>#addressIsInCurrentCompilation: */ -static sqInt NoDbgRegParms -addressIsInCurrentCompilation(sqInt address) -{ - return ((((usqInt)address)) >= ((methodLabel->address))) - && ((((usqInt)address)) < ((((youngReferrers()) < (((methodLabel->address)) + MaxMethodSize)) ? (youngReferrers()) : (((methodLabel->address)) + MaxMethodSize)))); -} - - /* Cogit>>#addressIsInFixups: */ -static sqInt NoDbgRegParms -addressIsInFixups(BytecodeFixup *address) -{ - return (BytecodeFixup *)address >= fixups && (BytecodeFixup *)address < (fixups + numAbstractOpcodes); -} - - -/* calculate the end of the n'th case statement - which is complicated - because we have case 1 right at the top of our CPIC and then build up from - the last one. Yes I know this sounds strange, but trust me - I'm an - Engineer, we do things backwards all the emit - */ - - /* Cogit>>#addressOfEndOfCase:inCPIC: */ -static sqInt NoDbgRegParms -addressOfEndOfCaseinCPIC(sqInt n, CogMethod *cPIC) -{ - assert((n >= 1) - && (n <= MaxCPICCases)); - return (n == 1 - ? (((sqInt)cPIC)) + firstCPICCaseOffset - : ((((sqInt)cPIC)) + firstCPICCaseOffset) + (((MaxCPICCases + 1) - n) * cPICCaseSize)); -} - - -/* Align methodZoneBase to that for the start of a method. */ - - /* Cogit>>#alignMethodZoneBase */ -static void -alignMethodZoneBase(void) -{ - usqInt oldBase; - - oldBase = methodZoneBase; - methodZoneBase = roundUpToMethodAlignment(backEnd(), methodZoneBase); - stopsFromto(backEnd, oldBase, methodZoneBase - 1); -} - - /* Cogit>>#alignUptoRoutineBoundary: */ -static sqInt NoDbgRegParms -alignUptoRoutineBoundary(sqInt anAddress) -{ - return (((anAddress + 7) | 7) - 7); -} - - -/* Check that all methods have valid selectors, and that all linked sends are - to valid targets and have valid cache tags - */ - - /* Cogit>>#allMachineCodeObjectReferencesValid */ -static sqInt -allMachineCodeObjectReferencesValid(void) -{ - CogMethod *cogMethod; - sqInt ok; - - ok = 1; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - if (!(asserta(checkValidOopReference((cogMethod->selector))))) { - ok = 0; - } - if (!(asserta((cogMethodDoesntLookKosher(cogMethod)) == 0))) { - ok = 0; - } - } - if ((((cogMethod->cmType)) == CMMethod) - || (((cogMethod->cmType)) == CMOpenPIC)) { - if (!(asserta((mapForperformUntilarg(cogMethod, checkIfValidOopRefAndTargetpccogMethod, cogMethod)) == 0))) { - ok = 0; - } - } - if ((((cogMethod->cmType)) == CMMethod) - && (1)) { - if (((cogMethod->nextMethodOrIRCs)) != 0) { - if (((cogMethod->nextMethodOrIRCs)) > limitAddress) { - if (!(asserta(checkValidDerivedObjectReference((cogMethod->nextMethodOrIRCs))))) { - ok = 0; - } - } - } - } - if (((cogMethod->cmType)) == CMClosedPIC) { - if (!(asserta(noTargetsFreeInClosedPIC(cogMethod)))) { - ok = 0; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return ok; -} - - /* Cogit>>#allMethodsHaveCorrectHeader */ -static sqInt -allMethodsHaveCorrectHeader(void) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - if (!(((cogMethod->objectHeader)) == (nullHeaderForMachineCodeMethod()))) { - return 0; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return 1; -} - - /* Cogit>>#annotateAbsolutePCRef: */ -static AbstractInstruction * NoDbgRegParms -annotateAbsolutePCRef(AbstractInstruction *abstractInstruction) -{ - (abstractInstruction->annotation = IsAbsPCReference); - return abstractInstruction; -} - - /* Cogit>>#annotateBytecode: */ -static AbstractInstruction * NoDbgRegParms -annotateBytecode(AbstractInstruction *abstractInstruction) -{ - (abstractInstruction->annotation = HasBytecodePC); - return abstractInstruction; -} - - /* Cogit>>#annotate:objRef: */ -static AbstractInstruction * NoDbgRegParms -annotateobjRef(AbstractInstruction *abstractInstruction, sqInt anOop) -{ - if (shouldAnnotateObjectReference(anOop)) { - setHasMovableLiteral(1); - if (isYoungObject(anOop)) { - setHasYoungReferent(1); - } - (abstractInstruction->annotation = IsObjectReference); - } - return abstractInstruction; -} - - /* Cogit>>#assertSaneJumpTarget: */ -static void NoDbgRegParms -assertSaneJumpTarget(AbstractInstruction *jumpTarget) -{ - assert((closedPICSize == null) - || ((openPICSize == null) - || ((addressIsInInstructions(jumpTarget)) - || ((((((usqInt)jumpTarget)) >= codeBase) && ((((usqInt)jumpTarget)) <= ((((sqInt)(limitZony()))) + (((closedPICSize < openPICSize) ? openPICSize : closedPICSize))))))))); -} - - -/* {self firstInvalidDualZoneAddress. self firstInvalidDualZoneAddress + - codeToDataDelta } - */ -/* {self firstInvalidDualZoneAddress hex. (self firstInvalidDualZoneAddress + - codeToDataDelta) hex } - */ -/* {(objectMemory longAt: self firstInvalidDualZoneAddress) hex. - (objectMemory longAt: self firstInvalidDualZoneAddress + codeToDataDelta) - hex } - */ -/* self armDisassembleDualZoneAnomalies */ -/* self armPrintDualZoneAnomalies */ - - /* Cogit>>#assertValidDualZone */ -static void -assertValidDualZone(void) -{ -} - - -/* Answer an unused abstract register in the registerMask, or NoReg if none. */ - - /* Cogit>>#availableRegisterOrNoneIn: */ -static sqInt NoDbgRegParms -availableRegisterOrNoneIn(sqInt liveRegsMask) -{ - sqInt reg; - - if (liveRegsMask != 0) { - for (reg = 0; reg <= 0x1F; reg += 1) { - if (((liveRegsMask & (1U << reg)) != 0)) { - return reg; - } - } - } - return NoReg; -} - - -/* Evaluate binaryFunction with the block start mcpc and supplied arg for - each entry in the block dispatch. If the function answers non-zero answer - the value - it answered. Used to update back-references to the home method in - compaction. */ - - /* Cogit>>#blockDispatchTargetsFor:perform:arg: */ -static sqInt NoDbgRegParms -blockDispatchTargetsForperformarg(CogMethod *cogMethod, usqInt (*binaryFunction)(sqInt mcpc, sqInt arg), sqInt arg) -{ - sqInt blockEntry; - usqInt end; - sqInt pc; - sqInt result; - usqInt targetpc; - - if (((cogMethod->blockEntryOffset)) == 0) { - return null; - } - blockEntry = ((cogMethod->blockEntryOffset)) + (((sqInt)cogMethod)); - pc = blockEntry; - end = (mapEndFor(cogMethod)) - 1; - while (pc < end) { - if (isJumpAt(backEnd, pc)) { - targetpc = jumpTargetPCAt(backEnd, pc); - if (targetpc < blockEntry) { - result = binaryFunction(targetpc, arg); - if (result != 0) { - return result; - } - } - } - pc += 4 /* instructionSizeAt: */; - } - return 0; -} - - -/* Answer the zero-relative bytecode pc matching the machine code pc argument - in cogMethod, given the start of the bytecodes for cogMethod's block or - method object. */ - - /* Cogit>>#bytecodePCFor:startBcpc:in: */ -sqInt -bytecodePCForstartBcpcin(sqInt mcpc, sqInt startbcpc, CogBlockMethod *cogMethod) -{ - sqInt aMethodHeader; - sqInt aMethodHeader1; - sqInt aMethodObj; - sqInt annotation; - sqInt bcpc; - sqInt bsOffset; - sqInt byte; - BytecodeDescriptor *descriptor; - sqInt distance; - sqInt endbcpc; - CogMethod *homeMethod; - sqInt isBackwardBranch; - sqInt isInBlock; - sqInt latestContinuation; - usqInt map; - sqInt mapByte; - usqInt mcpc1; - sqInt nExts; - sqInt nextBcpc; - sqInt result; - sqInt targetPC; - - latestContinuation = 0; - /* begin mapFor:bcpc:performUntil:arg: */ - assert(((cogMethod->stackCheckOffset)) > 0); - - /* The stack check maps to the start of the first bytecode, - the first bytecode being effectively after frame build. */ - mcpc1 = (((usqInt)cogMethod)) + ((cogMethod->stackCheckOffset)); - result = findIsBackwardBranchMcpcBcpcMatchingMcpc(null, (0 + (((int)((usqInt)(HasBytecodePC) << 1)))), (((char *) mcpc1)), startbcpc, (((void *)mcpc))); - if (result != 0) { - return result; - } - - /* In both CMMethod and CMBlock cases find the start of the map and - skip forward to the bytecode pc map entry for the stack check. */ - bcpc = startbcpc; - if (((cogMethod->cmType)) == CMMethod) { - /* begin cmIsFullBlock */ - isInBlock = 0; - homeMethod = ((CogMethod *) cogMethod); - assert(startbcpc == (startPCOfMethodHeader((homeMethod->methodHeader)))); - map = ((((usqInt)homeMethod)) + ((homeMethod->blockSize))) - 1; - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert((annotation == IsAbsPCReference) - || ((annotation == IsObjectReference) - || ((annotation == IsRelativeCall) - || (annotation == IsDisplacementX2N)))); - latestContinuation = startbcpc; - aMethodObj = (homeMethod->methodObject); - endbcpc = (numBytesOf(aMethodObj)) - 1; - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader) - ? 0x100 - : 0) -# else - 0 -# endif - ; - bcpc += deltaToSkipPrimAndErrorStoreInheader(aMethodObj, (homeMethod->methodHeader)); - } - else { - isInBlock = 1; - assert(bcpc == ((cogMethod->startpc))); - homeMethod = cmHomeMethod(cogMethod); - map = findMapLocationForMcpcinMethod((((usqInt)cogMethod)) + (sizeof(CogBlockMethod)), homeMethod); - assert(map != 0); - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert(((((usqInt)(annotation)) >> AnnotationShift) == HasBytecodePC) - || ((((usqInt)(annotation)) >> AnnotationShift) == IsDisplacementX2N)); - while (((annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift)) != HasBytecodePC) { - map -= 1; - } - - /* skip fiducial; i.e. the map entry for the pc immediately following the method header. */ - map -= 1; - aMethodObj = (homeMethod->methodObject); - bcpc = startbcpc - ( -#if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet((homeMethod->methodHeader)) - ? AltBlockCreationBytecodeSize - : BlockCreationBytecodeSize) -#else // MULTIPLEBYTECODESETS - BlockCreationBytecodeSize -#endif - ); - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader1 = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader1) - ? 0x100 - : 0) -# else - 0 -# endif - ; - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - endbcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, -1, aMethodObj)) - : 0)); - bcpc = startbcpc; - } - nExts = 0; - while ((((usqInt)((byteAt(map)))) >> AnnotationShift) != HasBytecodePC) { - map -= 1; - } - map -= 1; - while (((mapByte = byteAt(map))) != MapEnd) { - - /* defensive; we exit on bcpc */ - if (mapByte >= FirstAnnotation) { - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - mcpc1 += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if (annotation >= HasBytecodePC) { - if ((annotation == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - while (1) { - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - if (isInBlock) { - if (bcpc >= endbcpc) { - return 0; - } - } - else { - if (((descriptor->isReturn)) - && (bcpc >= latestContinuation)) { - return 0; - } - if ((isBranch(descriptor)) - || ((descriptor->isBlockCreation))) { - /* begin latestContinuationPCFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj); - targetPC = (bcpc + ((descriptor->numBytes))) + (((distance < 0) ? 0 : distance)); - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - /* latestContinuation = */ latestContinuation; - } - nextBcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) - : 0)); - if (((descriptor->isMapped)) - || (isInBlock - && ((descriptor->isMappedInBlock)))) break; - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - isBackwardBranch = (isBranch(descriptor)) - && ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) < 0)); - result = findIsBackwardBranchMcpcBcpcMatchingMcpc(descriptor, ((isBackwardBranch - ? (((sqInt)((usqInt)(annotation) << 1))) + 1 - : ((sqInt)((usqInt)(annotation) << 1)))), (((char *) mcpc1)), ((isBackwardBranch - ? bcpc - (2 * nExts) - : bcpc)), (((void *)mcpc))); - if (result != 0) { - return result; - } - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - } - else { - assert(((((usqInt)(mapByte)) >> AnnotationShift) == IsDisplacementX2N) - || ((((usqInt)(mapByte)) >> AnnotationShift) == IsAnnotationExtension)); - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc1 += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - return 0; -} - - /* Cogit>>#CallNewspeakSend: */ -static AbstractInstruction * NoDbgRegParms -CallNewspeakSend(sqInt callTarget) -{ - AbstractInstruction *abstractInstruction; - - /* begin annotateNewspeakSend: */ - abstractInstruction = genoperand(Call, callTarget); - (abstractInstruction->annotation = IsNSSendCall); - return abstractInstruction; -} - - /* Cogit>>#CallRT:registersToBeSavedMask: */ -static AbstractInstruction * NoDbgRegParms -CallRTregistersToBeSavedMask(sqInt callTarget, sqInt registersToBeSaved) -{ - AbstractInstruction *abstractInstruction; - sqInt callerSavedRegsToBeSaved; - AbstractInstruction *lastInst; - sqInt reg; - sqInt registersToBePushed; - - reg = 0; - callerSavedRegsToBeSaved = CallerSavedRegisterMask & registersToBeSaved; - registersToBePushed = callerSavedRegsToBeSaved; - reg = 0; - while (registersToBePushed != 0) { - if (((registersToBePushed & 1) != 0)) { - genoperand(PushR, reg); - } - reg += 1; - registersToBePushed = (registersToBePushed) >> 1; - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, callTarget); - (abstractInstruction->annotation = IsRelativeCall); - lastInst = abstractInstruction; - while (reg > 0) { - reg -= 1; - if (((callerSavedRegsToBeSaved & (1U << reg)) != 0)) { - lastInst = genoperand(PopR, reg); - } - } - return lastInst; -} - - /* Cogit>>#Call: */ -static AbstractInstruction * NoDbgRegParms -gCall(sqInt callTarget) -{ - return genoperand(Call, callTarget); -} - - /* Cogit>>#CmpCq:R: */ -static AbstractInstruction * NoDbgRegParms -gCmpCqR(sqInt quickConstant, sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, quickConstant, reg); - return anInstruction; -} - - -/* This is a static version of ceCallCogCodePopReceiverReg - for break-pointing when debugging in C. */ -/* This exists only for break-pointing. */ - - /* Cogit>>#callCogCodePopReceiver */ -void -callCogCodePopReceiver(void) -{ - realCECallCogCodePopReceiverReg(); - error("what??"); -} - - -/* This is a static version of ceCallCogCodePopReceiverAndClassRegs - for break-pointing when debugging in C. */ -/* This exists only for break-pointing. */ - - /* Cogit>>#callCogCodePopReceiverAndClassRegs */ -void -callCogCodePopReceiverAndClassRegs(void) -{ - realCECallCogCodePopReceiverAndClassRegs(); -} - - -/* Code entry closed PIC miss. A send has fallen - through a closed (finite) polymorphic inline cache. - Either extend it or patch the send site to an open PIC. - The stack looks like: - receiver - args - sp=> sender return address */ - - /* Cogit>>#ceCPICMiss:receiver: */ -static sqInt NoDbgRegParms -ceCPICMissreceiver(CogMethod *cPIC, sqInt receiver) -{ - sqInt cacheTag; - sqInt errorSelectorOrNil; - sqInt methodOrSelectorIndex; - sqInt newTargetMethodOrNil; - sqInt outerReturn; - sqInt result; - sqInt selector; - - if (isOopForwarded(receiver)) { - return ceSendFromInLineCacheMiss(cPIC); - } - outerReturn = stackTop(); - assert(!(((inlineCacheTagAt(backEnd, outerReturn)) == (picAbortDiscriminatorValue())))); - if (((cPIC->cPICNumCases)) < MaxCPICCases) { - /* begin lookup:for:methodAndErrorSelectorInto: */ - selector = (cPIC->selector); - methodOrSelectorIndex = lookupOrdinaryreceiver(selector, receiver); - if ((((usqInt)methodOrSelectorIndex)) > (maxLookupNoMNUErrorCode())) { - if (!(isOopCompiledMethod(methodOrSelectorIndex))) { - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = SelectorCannotInterpret; - goto l1; - } - if ((!(methodHasCogMethod(methodOrSelectorIndex))) - && (methodShouldBeCogged(methodOrSelectorIndex))) { - - /* We assume cog:selector: will *not* reclaim the method zone */ - cogselector(methodOrSelectorIndex, selector); - } - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = null; - goto l1; - } - if (methodOrSelectorIndex == SelectorDoesNotUnderstand) { - methodOrSelectorIndex = lookupMNUreceiver(splObj(SelectorDoesNotUnderstand), receiver); - if ((((usqInt)methodOrSelectorIndex)) > (maxLookupNoMNUErrorCode())) { - assert(isOopCompiledMethod(methodOrSelectorIndex)); - if ((!(methodHasCogMethod(methodOrSelectorIndex))) - && (methodShouldBeCogged(methodOrSelectorIndex))) { - - /* We assume cog:selector: will *not* reclaim the method zone */ - cogselector(methodOrSelectorIndex, splObj(SelectorDoesNotUnderstand)); - } - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = SelectorDoesNotUnderstand; - goto l1; - } - newTargetMethodOrNil = null; - errorSelectorOrNil = SelectorDoesNotUnderstand; - goto l1; - } - newTargetMethodOrNil = null; - errorSelectorOrNil = methodOrSelectorIndex; - l1: /* end lookup:for:methodAndErrorSelectorInto: */; - } - else { - newTargetMethodOrNil = (errorSelectorOrNil = null); - } - assert(outerReturn == (stackTop())); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - cacheTag = inlineCacheTagForInstance(receiver); - if ((((cPIC->cPICNumCases)) >= MaxCPICCases) - || (((errorSelectorOrNil != null) - && (errorSelectorOrNil != SelectorDoesNotUnderstand)) - || ((newTargetMethodOrNil == null) - || (isYoung(newTargetMethodOrNil))))) { - result = patchToOpenPICFornumArgsreceiver((cPIC->selector), (cPIC->cmNumArgs), receiver); - assert(!result); - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - return ceSendFromInLineCacheMiss(cPIC); - } - cogExtendPICCaseNMethodtagisMNUCase(cPIC, newTargetMethodOrNil, cacheTag, errorSelectorOrNil == SelectorDoesNotUnderstand); - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - executeCogPICfromLinkedSendWithReceiverandCacheTag(cPIC, receiver, inlineCacheTagAt(backEnd, outerReturn)); - return null; -} - - /* Cogit>>#ceFree: */ -void -ceFree(void *pointer) -{ - free(pointer); -} - - /* Cogit>>#ceMalloc: */ -static void* NoDbgRegParms -ceMalloc(size_t size) -{ - return malloc(size); -} - - -/* An in-line cache check in a method has failed. The failing entry check has - jumped to the ceMethodAbort abort call at the start of the method which - has called this routine. - If possible allocate a closed PIC for the current and existing classes. - The stack looks like: - receiver - args - sender return address - sp=> ceMethodAbort call return address - So we can find the method that did the failing entry check at - ceMethodAbort call return address - missOffset - and we can find the send site from the outer return address. */ - - /* Cogit>>#ceSICMiss: */ -static sqInt NoDbgRegParms -ceSICMiss(sqInt receiver) -{ - sqInt cacheTag; - usqInt entryPoint; - sqInt errorSelectorOrNil; - sqInt extent; - usqInt innerReturn; - sqInt methodOrSelectorIndex; - sqInt newTargetMethodOrNil; - usqInt outerReturn; - CogMethod *pic; - sqInt result; - sqInt selector; - CogMethod *targetMethod; - - - /* Whether we can relink to a PIC or not we need to pop off the inner return and identify the target method. */ - innerReturn = ((usqInt)(popStack())); - targetMethod = ((CogMethod *) (innerReturn - missOffset)); - if (isOopForwarded(receiver)) { - return ceSendFromInLineCacheMiss(targetMethod); - } - outerReturn = ((usqInt)(stackTop())); - assert(((outerReturn >= methodZoneBase) && (outerReturn <= (freeStart())))); - entryPoint = callTargetFromReturnAddress(backEnd, outerReturn); - assert(((targetMethod->selector)) != (nilObject())); - assert(((((sqInt)targetMethod)) + cmEntryOffset) == entryPoint); - /* begin lookup:for:methodAndErrorSelectorInto: */ - selector = (targetMethod->selector); - methodOrSelectorIndex = lookupOrdinaryreceiver(selector, receiver); - if ((((usqInt)methodOrSelectorIndex)) > (maxLookupNoMNUErrorCode())) { - if (!(isOopCompiledMethod(methodOrSelectorIndex))) { - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = SelectorCannotInterpret; - goto l1; - } - if ((!(methodHasCogMethod(methodOrSelectorIndex))) - && (methodShouldBeCogged(methodOrSelectorIndex))) { - - /* We assume cog:selector: will *not* reclaim the method zone */ - cogselector(methodOrSelectorIndex, selector); - } - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = null; - goto l1; - } - if (methodOrSelectorIndex == SelectorDoesNotUnderstand) { - methodOrSelectorIndex = lookupMNUreceiver(splObj(SelectorDoesNotUnderstand), receiver); - if ((((usqInt)methodOrSelectorIndex)) > (maxLookupNoMNUErrorCode())) { - assert(isOopCompiledMethod(methodOrSelectorIndex)); - if ((!(methodHasCogMethod(methodOrSelectorIndex))) - && (methodShouldBeCogged(methodOrSelectorIndex))) { - - /* We assume cog:selector: will *not* reclaim the method zone */ - cogselector(methodOrSelectorIndex, splObj(SelectorDoesNotUnderstand)); - } - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = SelectorDoesNotUnderstand; - goto l1; - } - newTargetMethodOrNil = null; - errorSelectorOrNil = SelectorDoesNotUnderstand; - goto l1; - } - newTargetMethodOrNil = null; - errorSelectorOrNil = methodOrSelectorIndex; - l1: /* end lookup:for:methodAndErrorSelectorInto: */; - assert(outerReturn == (stackTop())); - cacheTag = inlineCacheTagForInstance(receiver); - if (((errorSelectorOrNil != null) - && (errorSelectorOrNil != SelectorDoesNotUnderstand)) - || (((inlineCacheTagAt(backEnd, outerReturn)) == 0 /* picAbortDiscriminatorValue */) - || ((newTargetMethodOrNil == null) - || (isYoung(newTargetMethodOrNil))))) { - result = patchToOpenPICFornumArgsreceiver((targetMethod->selector), (targetMethod->cmNumArgs), receiver); - assert(!result); - return ceSendFromInLineCacheMiss(targetMethod); - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - pic = openPICWithSelector((targetMethod->selector)); - if ((pic == null) - || (!1)) { - - /* otherwise attempt to create a closed PIC for the two cases. */ - pic = cogPICSelectornumArgsCase0MethodCase1MethodtagisMNUCase((targetMethod->selector), (targetMethod->cmNumArgs), targetMethod, newTargetMethodOrNil, cacheTag, errorSelectorOrNil == SelectorDoesNotUnderstand); - if ((((((sqInt)pic)) >= MaxNegativeErrorCode) && ((((sqInt)pic)) <= -1))) { - - /* For some reason the PIC couldn't be generated, most likely a lack of code memory. - Continue as if this is an unlinked send. */ - if ((((sqInt)pic)) == InsufficientCodeSpace) { - callForCogCompiledCodeCompaction(); - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - return ceSendFromInLineCacheMiss(targetMethod); - } - } - extent = (((pic->cmType)) == CMOpenPIC - ? rewriteInlineCacheAttagtarget(backEnd, outerReturn, inlineCacheValueForSelectorin(backEnd, (targetMethod->selector), mframeHomeMethodExport()), (((sqInt)pic)) + cmEntryOffset) - : rewriteCallAttarget(backEnd, outerReturn, (((sqInt)pic)) + cmEntryOffset)); - /* begin assertValidDualZoneFrom:to: */ - (((usqInt)pic)) + closedPICSize; -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, (((usqInt)pic)) + cmNoCheckEntryOffset, codeToDataDelta); -# endif - flushICacheFromto(backEnd, ((usqInt)pic), (((usqInt)pic)) + closedPICSize); - flushICacheFromto(backEnd, (((usqInt)outerReturn)) - extent, ((usqInt)outerReturn)); - executeCogPICfromLinkedSendWithReceiverandCacheTag(pic, receiver, inlineCacheTagAt(backEnd, outerReturn)); - return null; -} - - -/* Check for a valid object reference, if any, at a map entry. Answer a code - unique to each error for debugging. */ - - /* Cogit>>#checkIfValidOopRefAndTarget:pc:cogMethod: */ -static sqInt NoDbgRegParms -checkIfValidOopRefAndTargetpccogMethod(sqInt annotation, char *mcpc, sqInt cogMethod) -{ - usqInt cacheAddress; - usqInt cacheTag1; - sqInt classTag; - sqInt enclosingObject; - sqInt entryPoint; - usqInt entryPoint1; - usqInt entryPoint2; - usqInt literal; - char *mcpc1; - NSSendCache *nsSendCache; - CogMethod * nsTargetMethod; - sqInt offset1; - sqInt *sendTable1; - sqInt tagCouldBeObj; - CogMethod *targetMethod1; - - if (annotation == IsObjectReference) { - literal = literalBeforeFollowingAddress(backEnd, ((usqInt)mcpc)); - if (!(asserta(checkValidOopReference(literal)))) { - return 1; - } - if ((couldBeObject(literal)) - && (isReallyYoungObject(literal))) { - if (!(asserta(((((CogMethod *) cogMethod))->cmRefersToYoung)))) { - return 2; - } - } - } - if (annotation == IsNSSendCall) { - /* begin nsSendCacheFromReturnAddress: */ - mcpc1 = ((char *) (((sqInt)mcpc))); - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc1)); - assert(entryPoint1 < methodZoneBase); - cacheAddress = ((usqInt)(nsSendCacheAt(backEnd, mcpc1))); - assert(isInOldSpace(cacheAddress)); - nsSendCache = ((NSSendCache *) cacheAddress); - if (!(asserta(checkValidOopReference((nsSendCache->selector))))) { - return 9; - } - classTag = (nsSendCache->classTag); - if (!(asserta((classTag == 0) - || (validInlineCacheTag(classTag))))) { - return 10; - } - enclosingObject = (nsSendCache->enclosingObject); - if (!(asserta((enclosingObject == 0) - || (checkValidOopReference(enclosingObject))))) { - return 11; - } - entryPoint = (nsSendCache->target); - if (entryPoint != 0) { - nsTargetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - if (!(asserta(((nsTargetMethod->cmType)) == CMMethod))) { - return 12; - } - } - } - if (annotation >= IsSendCall) { - if (!(asserta((((((CogMethod *) cogMethod))->cmType)) == CMMethod))) { - return 3; - } - /* begin entryCacheTagAndCouldBeObjectAt:annotation:into: */ - cacheTag1 = inlineCacheTagAt(backEnd, ((sqInt)mcpc)); - - /* in-line cache tags are the selectors of sends if sends are unlinked, - the selectors of super sends (entry offset = cmNoCheckEntryOffset), - the selectors of open PIC sends (entry offset = cmEntryOffset, target is an Open PIC) - or in-line cache tags (classes, class indices, immediate bit patterns, etc). - Note that selectors can be immediate so there is no guarantee that they - are markable/remappable objects. */ - entryPoint2 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - tagCouldBeObj = entryPointTagIsSelector(entryPoint2); - entryPoint = entryPoint2; - if (tagCouldBeObj) { - if (couldBeObject(cacheTag1)) { - if (!(asserta(checkValidOopReference(cacheTag1)))) { - return 4; - } - } - else { - if (!(asserta(validInlineCacheTag(cacheTag1)))) { - return 5; - } - } - if ((couldBeObject(cacheTag1)) - && (isReallyYoungObject(cacheTag1))) { - if (!(asserta(((((CogMethod *) cogMethod))->cmRefersToYoung)))) { - return 6; - } - } - } - else { - if (!(asserta(validInlineCacheTag(cacheTag1)))) { - return 9; - } - } - if (entryPoint > methodZoneBase) { - - /* It's a linked send; find which kind. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - if (annotation == IsNSSelfSend) { - offset1 = cmEntryOffset; - sendTable1 = selfSendTrampolines; - } - else { - if (annotation == IsNSDynamicSuperSend) { - offset1 = cmEntryOffset; - sendTable1 = dynamicSuperSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (!(asserta((((targetMethod1->cmType)) == CMMethod) - || ((((targetMethod1->cmType)) == CMClosedPIC) - || (((targetMethod1->cmType)) == CMOpenPIC))))) { - return 10; - } - } - } - return 0; -} - - -/* Check for a valid object reference, if any, at a map entry. Answer a code - unique to each error for debugging. */ - - /* Cogit>>#checkIfValidOopRef:pc:cogMethod: */ -static sqInt NoDbgRegParms -checkIfValidOopRefpccogMethod(sqInt annotation, char *mcpc, CogMethod *cogMethod) -{ - usqInt cacheAddress; - sqInt enclosingObject; - usqInt entryPoint; - usqInt entryPoint1; - usqInt literal; - char *mcpc1; - NSSendCache *nsSendCache; - usqInt offset; - sqInt offset1; - usqInt selectorOrCacheTag; - sqInt *sendTable; - - if (annotation == IsObjectReference) { - literal = literalBeforeFollowingAddress(backEnd, ((usqInt)mcpc)); - if (!(checkValidOopReference(literal))) { - print("object ref leak in CM "); - printHex(((sqInt)cogMethod)); - print(" @ "); - printHex(((sqInt)mcpc)); - cr(); - return 1; - } - } - if (annotation == IsNSSendCall) { - /* begin nsSendCacheFromReturnAddress: */ - mcpc1 = ((char *) (((sqInt)mcpc))); - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc1)); - assert(entryPoint1 < methodZoneBase); - cacheAddress = ((usqInt)(nsSendCacheAt(backEnd, mcpc1))); - assert(isInOldSpace(cacheAddress)); - nsSendCache = ((NSSendCache *) cacheAddress); - if (!(checkValidOopReference((nsSendCache->selector)))) { - print("selector leak in CM "); - printHex(((sqInt)cogMethod)); - print(" @ "); - printHex(((sqInt)mcpc)); - cr(); - return 1; - } - if (((enclosingObject = (nsSendCache->enclosingObject))) != 0) { - if (!(checkValidOopReference(enclosingObject))) { - print("enclosing object leak in CM "); - printHex(((sqInt)cogMethod)); - print(" @ "); - printHex(((sqInt)mcpc)); - cr(); - return 1; - } - } - } - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint <= methodZoneBase) { - offset = entryPoint; - } - else { - /* begin offsetAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable = directedSuperBindingSendTrampolines; - } - else { - if (annotation == IsNSSelfSend) { - offset1 = cmEntryOffset; - sendTable = selfSendTrampolines; - } - else { - if (annotation == IsNSDynamicSuperSend) { - offset1 = cmEntryOffset; - sendTable = dynamicSuperSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable = superSendTrampolines; - } - } - } - } - } - offset = offset1; - } - selectorOrCacheTag = inlineCacheTagAt(backEnd, ((sqInt)mcpc)); - if ((entryPoint > methodZoneBase) - && ((offset != cmNoCheckEntryOffset) - && ((((((CogMethod *) (entryPoint - offset)))->cmType)) != CMOpenPIC))) { - - /* linked non-super send, cacheTag is a cacheTag */ - if (!(validInlineCacheTag(selectorOrCacheTag))) { - print("cache tag leak in CM "); - printHex(((sqInt)cogMethod)); - print(" @ "); - printHex(((sqInt)mcpc)); - cr(); - return 1; - } - } - else { - - /* unlinked send or super send; cacheTag is a selector unless 64-bit, in which case it is an index. */ - if (!(checkValidOopReference(selectorOrCacheTag))) { - print("selector leak in CM "); - printHex(((sqInt)cogMethod)); - print(" @ "); - printHex(((sqInt)mcpc)); - cr(); - return 1; - } - } - } - return 0; -} - - -/* Answer if all references to objects in machine-code are valid. */ - - /* Cogit>>#checkIntegrityOfObjectReferencesInCode: */ -sqInt -checkIntegrityOfObjectReferencesInCode(sqInt gcModes) -{ - CogMethod *cogMethod; - sqInt count; - sqInt ok; - - cogMethod = ((CogMethod *) methodZoneBase); - ok = 1; - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - if ((cogMethod->cmRefersToYoung)) { - if (((count = occurrencesInYoungReferrers(cogMethod))) != 1) { - print("young referrer CM "); - printHex(((sqInt)cogMethod)); - if (count == 0) { - print(" is not in youngReferrers"); - cr(); - } - else { - print(" is in youngReferrers "); - printNum(count); - print(" times!"); - cr(); - } - ok = 0; - } - } - if (!(checkValidOopReference((cogMethod->selector)))) { - print("object leak in CM "); - printHex(((sqInt)cogMethod)); - print(" selector"); - cr(); - ok = 0; - } - if (((cogMethod->cmType)) == CMMethod) { - assert(((cogMethod->objectHeader)) == (nullHeaderForMachineCodeMethod())); - if (!(checkValidObjectReference((cogMethod->methodObject)))) { - print("object leak in CM "); - printHex(((sqInt)cogMethod)); - print(" methodObject"); - cr(); - ok = 0; - } - if (!(isOopCompiledMethod((cogMethod->methodObject)))) { - print("non-method in CM "); - printHex(((sqInt)cogMethod)); - print(" methodObject"); - cr(); - ok = 0; - } - if ((mapForperformUntilarg(cogMethod, checkIfValidOopRefpccogMethod, cogMethod)) != 0) { - ok = 0; - } - if (((isYoungObject((cogMethod->methodObject))) - || (isYoung((cogMethod->selector)))) - && (!((cogMethod->cmRefersToYoung)))) { - print("CM "); - printHex(((sqInt)cogMethod)); - print(" refers to young but not marked as such"); - cr(); - ok = 0; - } - } - else { - if (((cogMethod->cmType)) == CMClosedPIC) { - if (!(checkValidObjectReferencesInClosedPIC(cogMethod))) { - ok = 0; - } - } - else { - if (((cogMethod->cmType)) == CMOpenPIC) { - if ((mapForperformUntilarg(cogMethod, checkIfValidOopRefpccogMethod, cogMethod)) != 0) { - ok = 0; - } - } - } - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return ok; -} - - /* Cogit>>#checkMaybeObjRefInClosedPIC: */ -static sqInt NoDbgRegParms -checkMaybeObjRefInClosedPIC(sqInt maybeObject) -{ - if (maybeObject == 0) { - return 1; - } - if (!(couldBeObject(maybeObject))) { - return 1; - } - return checkValidObjectReference(maybeObject); -} - - /* Cogit>>#checkValidObjectReferencesInClosedPIC: */ -static sqInt NoDbgRegParms -checkValidObjectReferencesInClosedPIC(CogMethod *cPIC) -{ - sqInt i; - sqInt ok; - sqInt pc; - - ok = 1; - - /* first we check the obj ref at the beginning of the CPIC */ - pc = (((sqInt)cPIC)) + firstCPICCaseOffset; - if (!(checkMaybeObjRefInClosedPIC(literalBeforeFollowingAddress(backEnd, pc - (jumpLongByteSize(backEnd)))))) { - print("object leak in CPIC "); - printHex(((sqInt)cPIC)); - print(" @ "); - printHex(pc - (jumpLongByteSize(backEnd))); - cr(); - ok = 0; - } - - /* For each case we check any object reference at the end address - sizeof(conditional instruction) and then increment the end address by case size */ - pc = addressOfEndOfCaseinCPIC((cPIC->cPICNumCases), cPIC); - for (i = 2; i <= ((cPIC->cPICNumCases)); i += 1) { - if (!(checkMaybeObjRefInClosedPIC(literalBeforeFollowingAddress(backEnd, (pc - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */)))) { - print("object leak in CPIC "); - printHex(((sqInt)cPIC)); - print(" @ "); - printHex(pc - 16 /* jumpLongConditionalByteSize */); - cr(); - ok = 0; - } - pc += cPICCaseSize; - } - return ok; -} - - -/* i.e. this should never be called, so keep it out of the main path. */ - - /* Cogit>>#cleanUpFailingCogCodeConstituents: */ -static sqInt NoDbgRegParms NeverInline -cleanUpFailingCogCodeConstituents(CogMethod *cogMethodArg) -{ - CogMethod *cogMethod; - - cogMethod = cogMethodArg; - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMClosedPIC) { - (cogMethod->methodObject = 0); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - popRemappableOop(); - return null; -} - - -/* Answer if the ClosedPIC refers to any unmarked objects or freed/freeable - target methods, - applying markAndTraceOrFreeCogMethod:firstVisit: to those targets to - determine if freed/freeable. - */ - - /* Cogit>>#closedPICRefersToUnmarkedObject: */ -static sqInt NoDbgRegParms -closedPICRefersToUnmarkedObject(CogMethod *cPIC) -{ - sqInt i; - usqInt object; - sqInt pc; - - if (!((isImmediate((cPIC->selector))) - || (isMarked((cPIC->selector))))) { - return 1; - } - pc = addressOfEndOfCaseinCPIC(1, cPIC); - if (couldBeObject((object = literalBeforeFollowingAddress(backEnd, pc - (jumpLongByteSize(backEnd)))))) { - if (!(isMarked(object))) { - return 1; - } - } - if (markAndTraceOrFreePICTargetin(jumpLongTargetBeforeFollowingAddress(backEnd, pc), cPIC)) { - return 1; - } - for (i = 2; i <= ((cPIC->cPICNumCases)); i += 1) { - pc = addressOfEndOfCaseinCPIC(i, cPIC); - if (couldBeObject((object = literalBeforeFollowingAddress(backEnd, (pc - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */)))) { - if (!(isMarked(object))) { - return 1; - } - } - if (markAndTraceOrFreePICTargetin(jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc), cPIC)) { - return 1; - } - } - return 0; -} - - /* Cogit>>#codeEntryFor: */ -char * -codeEntryFor(char *address) -{ - sqInt i; - - for (i = 0; i <= (trampolineTableIndex - 3); i += 2) { - if (((address >= (trampolineAddresses[i + 1])) && (address <= ((trampolineAddresses[i + 3]) - 1)))) { - return trampolineAddresses[i + 1]; - } - } - return null; -} - - /* Cogit>>#codeEntryNameFor: */ -char * -codeEntryNameFor(char *address) -{ - sqInt i; - - for (i = 0; i <= (trampolineTableIndex - 3); i += 2) { - if (((address >= (trampolineAddresses[i + 1])) && (address <= ((trampolineAddresses[i + 3]) - 1)))) { - return trampolineAddresses[i]; - } - } - return null; -} - - /* Cogit>>#cogCodeBase */ -sqInt -cogCodeBase(void) -{ - return codeBase; -} - - -/* Answer the contents of the code zone as an array of pair-wise element, - address in ascending address order. - Answer a string for a runtime routine or abstract label (beginning, end, - etc), a CompiledMethod for a CMMethod, - or a selector (presumably a Symbol) for a PIC. - If withDetails is true - - answer machine-code to bytecode pc mapping information for methods - - answer class, target pair information for closed PIC - N.B. Since the class tag for the first case of a closed PIC is stored at - the send site, it must be collected - by scanning methods (see - collectCogConstituentFor:Annotation:Mcpc:Bcpc:Method:). Since closed PICs - are never shared they always come after the method that references them, - so we don't need an extra pass - to collect the first case class tags, which are (temporarily) assigned to - each closed PIC's methodObject field. - But we do need to reset the methodObject fields to zero. This is done in - createPICData:, unless memory - runs out, in which case it is done by cleanUpFailingCogCodeConstituents:. */ - - /* Cogit>>#cogCodeConstituents: */ -sqInt -cogCodeConstituents(sqInt withDetails) -{ - CogMethod *cogMethod; - sqInt constituents; - sqInt count; - sqInt i; - sqInt label; - sqInt profileData; - sqInt value; - - - /* + 3 for start, freeStart and end */ - count = (trampolineTableIndex / 2) + 3; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - count += 1; - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - constituents = instantiateClassindexableSize(classArray(), count * 2); - if (!constituents) { - return constituents; - } - pushRemappableOop(constituents); - if ((((label = stringForCString("CogCode"))) == null) - || (((value = positive32BitIntegerFor(codeBase))) == null)) { - popRemappableOop(); - return null; - } - storePointerUncheckedofObjectwithValue(0, constituents, label); - storePointerUncheckedofObjectwithValue(1, constituents, value); - for (i = 0; i < trampolineTableIndex; i += 2) { - if ((((label = stringForCString(trampolineAddresses[i]))) == null) - || (((value = positive32BitIntegerFor(((usqInt)(trampolineAddresses[i + 1]))))) == null)) { - popRemappableOop(); - return null; - } - storePointerUncheckedofObjectwithValue(2 + i, constituents, label); - storePointerUncheckedofObjectwithValue(3 + i, constituents, value); - } - count = trampolineTableIndex + 2; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - profileData = (((cogMethod->cmType)) == CMMethod - ? (cogMethod->methodObject) - : (withDetails - && (((cogMethod->cmType)) == CMClosedPIC) - ? createCPICData(cogMethod) - : (cogMethod->selector))); - if (!profileData) { - return cleanUpFailingCogCodeConstituents(cogMethod); - } - storePointerUncheckedofObjectwithValue(count, constituents, profileData); - if (withDetails) { - value = collectCogMethodConstituent(cogMethod); - } - else { - value = positive32BitIntegerFor(((usqInt)cogMethod)); - } - if (!value) { - return cleanUpFailingCogCodeConstituents(cogMethod); - } - storePointerUncheckedofObjectwithValue(count + 1, constituents, value); - count += 2; - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if ((((label = stringForCString("CCFree"))) == null) - || (((value = positive32BitIntegerFor(mzFreeStart))) == null)) { - popRemappableOop(); - return null; - } - storePointerUncheckedofObjectwithValue(count, constituents, label); - storePointerUncheckedofObjectwithValue(count + 1, constituents, value); - if ((((label = stringForCString("CCEnd"))) == null) - || (((value = positive32BitIntegerFor(limitAddress))) == null)) { - popRemappableOop(); - return null; - } - storePointerUncheckedofObjectwithValue(count + 2, constituents, label); - storePointerUncheckedofObjectwithValue(count + 3, constituents, value); - constituents = popRemappableOop(); - beRootIfOld(constituents); - return constituents; -} - - -/* Extend the cPIC with the supplied case. If caseNMethod is cogged dispatch - direct to - its unchecked entry-point. If caseNMethod is not cogged, jump to the fast - interpreter dispatch, and if isMNUCase then dispatch to fast MNU - invocation and mark the cPIC as - having the MNU case for cache flushing. */ - - /* Cogit>>#cogExtendPIC:CaseNMethod:tag:isMNUCase: */ -static void NoDbgRegParms -cogExtendPICCaseNMethodtagisMNUCase(CogMethod *cPIC, sqInt caseNMethod, sqInt caseNTag, sqInt isMNUCase) -{ - sqInt address; - sqInt operand; - CogBlockMethod * self_in_cpicHasMNUCase; - sqInt target; - - compilationBreakpointclassTagisMNUCase((cPIC->selector), caseNTag, isMNUCase); - assert(!(inlineCacheTagIsYoung(caseNTag))); - assert((caseNMethod != null) - && (!(isYoung(caseNMethod)))); - if ((!isMNUCase) - && (methodHasCogMethod(caseNMethod))) { - - /* this isn't an MNU and we have an already cogged method to jump to */ - operand = 0; - target = (((sqInt)(cogMethodOf(caseNMethod)))) + cmNoCheckEntryOffset; - } - else { - operand = caseNMethod; - if (isMNUCase) { - - /* this is an MNU so tag the CPIC header and setup a jump to the MNUAbort */ - /* begin cpicHasMNUCase: */ - self_in_cpicHasMNUCase = ((CogBlockMethod *) (((CogMethod *) ((((usqInt)cPIC)) + codeToDataDelta)))); - (self_in_cpicHasMNUCase->cpicHasMNUCaseOrCMIsFullBlock) = 1; - target = (((sqInt)cPIC)) + (sizeof(CogMethod)); - } - else { - - /* setup a jump to the interpretAborth so we can cog the target method */ - target = (((sqInt)cPIC)) + (picInterpretAbortOffset()); - } - } - address = addressOfEndOfCaseinCPIC(((cPIC->cPICNumCases)) + 1, cPIC); - rewriteCPICCaseAttagobjReftarget(address, caseNTag, operand, target); - /* begin rewriteCPIC:caseJumpTo: */ - rewriteCPICJumpAttarget(backEnd, (((((sqInt)cPIC)) + firstCPICCaseOffset) - (jumpLongByteSize(backEnd))) - 8 /* loadLiteralByteSize */, address - cPICCaseSize); - ((((CogMethod *) ((((usqInt)cPIC)) + codeToDataDelta)))->cPICNumCases = ((cPIC->cPICNumCases)) + 1); - flushICacheFromto(backEnd, ((usqInt)cPIC), (((usqInt)cPIC)) + closedPICSize); - /* begin assertValidDualZoneFrom:to: */ - (((usqInt)cPIC)) + closedPICSize; -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, (((usqInt)cPIC)) + cmNoCheckEntryOffset, codeToDataDelta); -# endif -} - - /* Cogit>>#cogitPostGCAction: */ -void -cogitPostGCAction(sqInt gcMode) -{ - -# if SPURVM - if (gcMode == GCModeBecome) { - followForwardedLiteralsInOpenPICList(); - } -# endif - assert(allMethodsHaveCorrectHeader()); - assert(((!(gcMode & (GCModeFull + GCModeNewSpace)))) - || (kosherYoungReferrers())); - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - -/* Check that the header fields onf a non-free method are consistent with - the type. Answer 0 if it is ok, otherwise answer a code for the error. */ - - /* Cogit>>#cogMethodDoesntLookKosher: */ -sqInt -cogMethodDoesntLookKosher(CogMethod *cogMethod) -{ - if (((((cogMethod->blockSize)) & (BytesPerWord - 1)) != 0) - || ((((cogMethod->blockSize)) < (sizeof(CogMethod))) - || (((cogMethod->blockSize)) >= 0x8000))) { - return 1; - } - if (((cogMethod->cmType)) == CMFree) { - return 2; - } - if (((cogMethod->cmType)) == CMMethod) { - if (!((((cogMethod->methodHeader)) & 1))) { - return 11; - } - if (!(couldBeObject((cogMethod->methodObject)))) { - return 12; - } - if ((((cogMethod->stackCheckOffset)) > 0) - && (((cogMethod->stackCheckOffset)) < cmNoCheckEntryOffset)) { - return 13; - } - if (((cogMethod->nextMethodOrIRCs)) != 0) { - if (((cogMethod->nextMethodOrIRCs)) < limitAddress) { - - /* check the nextMethod (unpairedMethodList) unless we're compacting. */ - if (!(compactionInProgress - || (((cogMethod->nextMethodOrIRCs)) == (((usqInt)(methodFor(((void *)((cogMethod->nextMethodOrIRCs)))))))))) { - return 15; - } - } - else { - if (!(couldBeDerivedObject((cogMethod->nextMethodOrIRCs)))) { - return 16; - } - } - } - return 0; - } - if (((cogMethod->cmType)) == CMOpenPIC) { - if (((cogMethod->blockSize)) != openPICSize) { - return 21; - } - if (((cogMethod->methodHeader)) != 0) { - return 22; - } - if (((cogMethod->objectHeader)) >= 0) { - if (!((((cogMethod->methodObject)) == 0) - || (compactionInProgress - || (((cogMethod->methodObject)) == (((usqInt)(methodFor(((void *)((cogMethod->methodObject))))))))))) { - return 23; - } - } - if (((cogMethod->stackCheckOffset)) != 0) { - return 24; - } - return 0; - } - if (((cogMethod->cmType)) == CMClosedPIC) { - if (((cogMethod->blockSize)) != closedPICSize) { - return 0x1F; - } - if (!(((((cogMethod->cPICNumCases)) >= 1) && (((cogMethod->cPICNumCases)) <= MaxCPICCases)))) { - return 32; - } - if (((cogMethod->methodHeader)) != 0) { - return 33; - } - if (((cogMethod->methodObject)) != 0) { - return 34; - } - return 0; - } - return 9; -} - - -/* Attempt to create a one-case PIC for an MNU. - The tag for the case is at the send site and so doesn't need to be - generated. - */ - - /* Cogit>>#cogMNUPICSelector:receiver:methodOperand:numArgs: */ -CogMethod * -cogMNUPICSelectorreceivermethodOperandnumArgs(sqInt selector, sqInt rcvr, sqInt methodOperand, sqInt numArgs) -{ - CogMethod * actualPIC; - usqInt startAddress; - CogMethod * writablePIC; - - if ((isYoung(selector)) - || ((inlineCacheTagForInstance(rcvr)) == 0 /* picAbortDiscriminatorValue */)) { - return 0; - } - compilationBreakpointclassTagisMNUCase(selector, fetchClassTagOf(rcvr), 1); - assert(endCPICCase0 != null); - startAddress = allocate(closedPICSize); - if (startAddress == 0) { - callForCogCompiledCodeCompaction(); - return 0; - } - maybeBreakGeneratingFromto(startAddress, startAddress + closedPICSize); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - - /* memcpy the prototype across to our allocated space; because anything else would be silly */ - writablePIC = ((CogMethod *) ((((usqInt)startAddress)) + codeToDataDelta)); - codeMemcpy(writablePIC, cPICPrototype, closedPICSize); - /* begin fillInCPICHeader:numArgs:numCases:hasMNUCase:selector: */ - assert(!(isYoung(selector))); - (writablePIC->cmType = CMClosedPIC); - (writablePIC->objectHeader = 0); - (writablePIC->blockSize = closedPICSize); - (writablePIC->methodObject = 0); - (writablePIC->methodHeader = 0); - (writablePIC->selector = selector); - (writablePIC->cmNumArgs = numArgs); - (writablePIC->cmHasMovableLiteral = 0); - (writablePIC->cmRefersToYoung = 0); - (writablePIC->cmUsageCount = initialClosedPICUsageCount()); - /* begin cpicHasMNUCase: */ - ((((CogBlockMethod *) writablePIC))->cpicHasMNUCaseOrCMIsFullBlock) = 1; - (writablePIC->cPICNumCases = 1); - (writablePIC->blockEntryOffset = 0); - assert(((writablePIC->cmType)) == CMClosedPIC); - assert(((writablePIC->selector)) == selector); - assert(((writablePIC->cmNumArgs)) == numArgs); - assert(((writablePIC->cPICNumCases)) == 1); - assert(closedPICSize == (roundUpLength(closedPICSize))); - /* begin maybeEnableSingleStep */ - configureMNUCPICmethodOperandnumArgsdelta((actualPIC = ((CogMethod *) startAddress)), methodOperand, numArgs, startAddress - (((usqInt)cPICPrototype))); - flushICacheFromto(backEnd, startAddress, startAddress + closedPICSize); - assert((callTargetFromReturnAddress(backEnd, startAddress + missOffset)) == (picAbortTrampolineFor(numArgs))); - /* begin assertValidDualZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, startAddress + cmNoCheckEntryOffset, codeToDataDelta); -# endif - return actualPIC; -} - - -/* Create an Open PIC. Temporarily create a direct call of - ceSendFromOpenPIC:. Should become a probe of the first-level method lookup - cache followed by a - call of ceSendFromOpenPIC: if the probe fails. */ - - /* Cogit>>#cogOpenPICSelector:numArgs: */ -static CogMethod * NoDbgRegParms -cogOpenPICSelectornumArgs(sqInt selector, sqInt numArgs) -{ - sqInt codeSize; - sqInt end; - sqInt fixupSize; - sqInt mapSize; - sqInt opcodeSize; - CogMethod *pic; - usqInt startAddress; - - compilationBreakpointisMNUCase(selector, 0); - startAddress = allocate(openPICSize); - if (startAddress == 0) { - return ((CogMethod *) InsufficientCodeSpace); - } - (methodLabel->address = startAddress); - (methodLabel->dependent = null); - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 100; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - compileOpenPICnumArgs(selector, numArgs); - computeMaximumSizes(); - concretizeAt(methodLabel, startAddress); - codeSize = generateInstructionsAt(startAddress + (sizeof(CogMethod))); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - mapSize = generateMapAtstart((startAddress + openPICSize) - 1, startAddress + cmNoCheckEntryOffset); - assert((((entry->address)) - startAddress) == cmEntryOffset); - assert(((roundUpLength((sizeof(CogMethod)) + codeSize)) + (roundUpLength(mapSize))) <= openPICSize); - end = outputInstructionsAt(startAddress + (sizeof(CogMethod))); - /* begin fillInOPICHeader:numArgs:selector: */ - pic = ((CogMethod *) ((((usqInt)startAddress)) + codeToDataDelta)); - (pic->cmType = CMOpenPIC); - (pic->objectHeader = 0); - (pic->blockSize = openPICSize); - addToOpenPICList(pic); - (pic->methodHeader = 0); - (pic->selector = selector); - (pic->cmNumArgs = numArgs); - (pic->cmHasMovableLiteral = isNonImmediate(selector)); - if ((pic->cmRefersToYoung = isYoung(selector))) { - addToYoungReferrers(pic); - } - (pic->cmUsageCount = initialOpenPICUsageCount()); - /* begin cpicHasMNUCase: */ - ((((CogBlockMethod *) pic))->cpicHasMNUCaseOrCMIsFullBlock) = 0; - (pic->cPICNumCases = 0); - (pic->blockEntryOffset = 0); - flushICacheFromto(backEnd, (((usqInt)pic)) - codeToDataDelta, ((((usqInt)pic)) - codeToDataDelta) + openPICSize); - assert(((pic->cmType)) == CMOpenPIC); - assert(((pic->selector)) == selector); - assert(((pic->cmNumArgs)) == numArgs); - assert((callTargetFromReturnAddress(backEnd, ((((sqInt)pic)) - codeToDataDelta) + missOffset)) == (picAbortTrampolineFor(numArgs))); - assert(openPICSize == (roundUpLength(openPICSize))); - /* begin assertValidDualZoneFrom:to: */ - ((((usqInt)pic)) - codeToDataDelta) + openPICSize; -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, ((((usqInt)pic)) - codeToDataDelta) + cmNoCheckEntryOffset, codeToDataDelta); -# endif - /* begin maybeEnableSingleStep */ - return ((CogMethod *) startAddress); -} - - -/* Attempt to create a two-case PIC for case0CogMethod and - case1Method,case1Tag. The tag for case0CogMethod is at the send site and - so doesn't need to be generated. - case1Method may be any of - - a Cog method; link to its unchecked entry-point - - a CompiledMethod; link to ceInterpretMethodFromPIC: - - a CompiledMethod; link to ceMNUFromPICMNUMethod:receiver: */ - - /* Cogit>>#cogPICSelector:numArgs:Case0Method:Case1Method:tag:isMNUCase: */ -static CogMethod * NoDbgRegParms -cogPICSelectornumArgsCase0MethodCase1MethodtagisMNUCase(sqInt selector, sqInt numArgs, CogMethod *case0CogMethod, sqInt case1MethodOrNil, sqInt case1Tag, sqInt isMNUCase) -{ - CogMethod * actualPIC; - usqInt startAddress; - CogMethod * writablePIC; - - if (isYoung(selector)) { - return ((CogMethod *) YoungSelectorInPIC); - } - compilationBreakpointclassTagisMNUCase(selector, case1Tag, isMNUCase); - startAddress = allocate(closedPICSize); - if (startAddress == 0) { - return ((CogMethod *) InsufficientCodeSpace); - } - maybeBreakGeneratingFromto(startAddress, startAddress + closedPICSize); - - /* memcpy the prototype across to our allocated space; because anything else would be silly */ - writablePIC = ((CogMethod *) ((((usqInt)startAddress)) + codeToDataDelta)); - codeMemcpy(writablePIC, cPICPrototype, closedPICSize); - /* begin fillInCPICHeader:numArgs:numCases:hasMNUCase:selector: */ - assert(!(isYoung(selector))); - (writablePIC->cmType = CMClosedPIC); - (writablePIC->objectHeader = 0); - (writablePIC->blockSize = closedPICSize); - (writablePIC->methodObject = 0); - (writablePIC->methodHeader = 0); - (writablePIC->selector = selector); - (writablePIC->cmNumArgs = numArgs); - (writablePIC->cmHasMovableLiteral = 0); - (writablePIC->cmRefersToYoung = 0); - (writablePIC->cmUsageCount = initialClosedPICUsageCount()); - /* begin cpicHasMNUCase: */ - ((((CogBlockMethod *) writablePIC))->cpicHasMNUCaseOrCMIsFullBlock) = isMNUCase; - (writablePIC->cPICNumCases = 2); - (writablePIC->blockEntryOffset = 0); - assert(((writablePIC->cmType)) == CMClosedPIC); - assert(((writablePIC->selector)) == selector); - assert(((writablePIC->cmNumArgs)) == numArgs); - assert(((writablePIC->cPICNumCases)) == 2); - assert(closedPICSize == (roundUpLength(closedPICSize))); - /* begin maybeEnableSingleStep */ - configureCPICCase0Case1MethodtagisMNUCasenumArgsdelta((actualPIC = ((CogMethod *) startAddress)), case0CogMethod, case1MethodOrNil, case1Tag, isMNUCase, numArgs, startAddress - (((usqInt)cPICPrototype))); - assert((callTargetFromReturnAddress(backEnd, startAddress + missOffset)) == (picAbortTrampolineFor(numArgs))); - return actualPIC; -} - - -/* Attempt to produce a machine code method for the bytecode method - object aMethodObj. N.B. If there is no code memory available do *NOT* - attempt to reclaim the method zone. Certain clients (e.g. ceSICMiss:) - depend on the zone remaining constant across method generation. */ - - /* Cogit>>#cog:selector: */ -CogMethod * -cogselector(sqInt aMethodObj, sqInt aSelectorOop) -{ - CogMethod *cogMethod; - sqInt selector; - - - /* inline exclude:selector: */ - if (methodHasCogMethod(aMethodObj)) { - cogMethod = cogMethodOf(aMethodObj); - assert(!((((cogMethod->selector)) == aSelectorOop))); - if (((cogMethod->selector)) == aSelectorOop) { - return cogMethod; - } - if ((methodClassAssociationOf(aMethodObj)) != (nilObject())) { - extern void *firstIndexableField(sqInt); - /* begin warnMultiple:selectors: */ - fprintf(stderr, "Warning, attempt to use method with selector %.*s and selector %.*s\n", ((int) (numBytesOf((cogMethod->selector)))), ((char *) (firstIndexableField((cogMethod->selector)))), ((int) (numBytesOf(aSelectorOop))), ((char *) (firstIndexableField(aSelectorOop)))); - return null; - } - } - assert(!((isOopCompiledMethod(ultimateLiteralOf(aMethodObj))))); - - /* coInterpreter stringOf: selector */ - selector = (aSelectorOop == (nilObject()) - ? maybeSelectorOfMethod(aMethodObj) - : aSelectorOop); - if (!(selector == null)) { - compilationBreakpointisMNUCase(selector, 0); - } - if (aMethodObj == breakMethod) { - haltmsg("Compilation of breakMethod"); - } - cogMethod = findPreviouslyCompiledVersionOfwith(aMethodObj, aSelectorOop); - if (!(cogMethod == null)) { - if (!(methodHasCogMethod(aMethodObj))) { - assert((rawHeaderOf(aMethodObj)) == ((cogMethod->methodHeader))); - (cogMethod->methodObject = aMethodObj); - rawHeaderOfput(aMethodObj, ((sqInt)cogMethod)); - } - return cogMethod; - } - if (methodUsesAlternateBytecodeSet(aMethodObj)) { - if ((numElementsIn(generatorTable)) <= 0x100) { - return null; - } - bytecodeSetOffset = 0x100; - } - else { - bytecodeSetOffset = 0; - } - ensureNoForwardedLiteralsIn(aMethodObj); - methodObj = aMethodObj; - methodHeader = methodHeaderOf(aMethodObj); - receiverTags = receiverTagBitsForMethod(methodObj); - cogMethod = compileCogMethod(aSelectorOop); - if ((((((sqInt)cogMethod)) >= MaxNegativeErrorCode) && ((((sqInt)cogMethod)) <= -1))) { - if ((((sqInt)cogMethod)) == InsufficientCodeSpace) { - callForCogCompiledCodeCompaction(); - } - return null; - } - return cogMethod; -} - - /* Cogit>>#collectCogConstituentFor:Annotation:Mcpc:Bcpc:Method: */ -static sqInt NoDbgRegParms -collectCogConstituentForAnnotationMcpcBcpcMethod(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *cogMethodArg) -{ - sqInt address; - sqInt annotation; - usqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - - if (!descriptor) { - return 0; - } - if (!((descriptor->isMapped))) { - return 0; - } - address = positive32BitIntegerFor(((usqInt)mcpc)); - if (!address) { - return PrimErrNoMemory; - } - storePointerUncheckedofObjectwithValue(cogConstituentIndex, topRemappableOop(), address); - storePointerUncheckedofObjectwithValue(cogConstituentIndex + 1, topRemappableOop(), (((usqInt)bcpc << 1) | 1)); - - /* Collect any first case classTags for closed PICs. */ - cogConstituentIndex += 2; - if (((!(isBackwardBranchAndAnnotation & 1))) - && (((((usqInt)(isBackwardBranchAndAnnotation)) >> 1) >= IsSendCall) - || ((((usqInt)(isBackwardBranchAndAnnotation)) >> 1) == IsNSSendCall))) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* send is linked */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - annotation = ((usqInt)(isBackwardBranchAndAnnotation)) >> 1; - /* begin offsetAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - if (annotation == IsNSSelfSend) { - offset1 = cmEntryOffset; - sendTable1 = selfSendTrampolines; - } - else { - if (annotation == IsNSDynamicSuperSend) { - offset1 = cmEntryOffset; - sendTable1 = dynamicSuperSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (((targetMethod1->cmType)) == CMClosedPIC) { - (targetMethod1->methodObject = classForInlineCacheTag(inlineCacheTagAt(backEnd, mcpc))); - } - } - } - return 0; -} - - -/* Answer a description of the mapping between machine code pointers and - bytecode pointers for the Cog Method. - First value is the address of the cog method. - Following values are pairs of machine code pc and bytecode pc */ - - /* Cogit>>#collectCogMethodConstituent: */ -static sqInt NoDbgRegParms -collectCogMethodConstituent(CogMethod *cogMethod) -{ - sqInt address; - sqInt aMethodHeader; - sqInt aMethodHeader1; - sqInt aMethodObj; - sqInt annotation; - sqInt bcpc; - sqInt bsOffset; - sqInt byte; - sqInt cm; - CogBlockMethod *cogBlockMethod; - sqInt data; - BytecodeDescriptor *descriptor; - sqInt distance; - sqInt endbcpc; - sqInt errCode; - CogMethod *homeMethod; - sqInt isBackwardBranch; - sqInt isInBlock; - sqInt latestContinuation; - usqInt map; - sqInt mapByte; - usqInt mcpc; - sqInt nExts; - sqInt nextBcpc; - sqInt nSlots; - sqInt result; - sqInt startbcpc; - sqInt targetPC; - - latestContinuation = 0; - if (!(((cogMethod->cmType)) == CMMethod)) { - return positive32BitIntegerFor(((usqInt)cogMethod)); - } - cogBlockMethod = ((CogBlockMethod *) cogMethod); - if (((cogBlockMethod->stackCheckOffset)) == 0) { - - /* isFrameless ? */ - return positive32BitIntegerFor(((usqInt)cogMethod)); - } - cm = (cogMethod->methodObject); - - /* +1 for first address */ - nSlots = ((((byteSizeOf(cm)) - (startPCOfMethod(cm))) * 2) + (minSlotsForShortening())) + 1; - data = instantiateClassindexableSize(splObj(ClassArray), nSlots); - if (!data) { - return null; - } - pushRemappableOop(data); - address = positive32BitIntegerFor(((usqInt)cogMethod)); - if (!address) { - popRemappableOop(); - return null; - } - storePointerUncheckedofObjectwithValue(0, topRemappableOop(), address); - cogConstituentIndex = 1; - /* begin mapFor:bcpc:performUntil:arg: */ - startbcpc = startPCOfMethod((cogMethod->methodObject)); - assert(((cogBlockMethod->stackCheckOffset)) > 0); - - /* The stack check maps to the start of the first bytecode, - the first bytecode being effectively after frame build. */ - mcpc = (((usqInt)cogBlockMethod)) + ((cogBlockMethod->stackCheckOffset)); - result = collectCogConstituentForAnnotationMcpcBcpcMethod(null, (0 + (((int)((usqInt)(HasBytecodePC) << 1)))), (((char *) mcpc)), startbcpc, (((void *)cogMethod))); - if (result != 0) { - errCode = result; - goto l7; - } - - /* In both CMMethod and CMBlock cases find the start of the map and - skip forward to the bytecode pc map entry for the stack check. */ - bcpc = startbcpc; - if (((cogBlockMethod->cmType)) == CMMethod) { - /* begin cmIsFullBlock */ - isInBlock = 0; - homeMethod = ((CogMethod *) cogBlockMethod); - assert(startbcpc == (startPCOfMethodHeader((homeMethod->methodHeader)))); - map = ((((usqInt)homeMethod)) + ((homeMethod->blockSize))) - 1; - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert((annotation == IsAbsPCReference) - || ((annotation == IsObjectReference) - || ((annotation == IsRelativeCall) - || (annotation == IsDisplacementX2N)))); - latestContinuation = startbcpc; - aMethodObj = (homeMethod->methodObject); - endbcpc = (numBytesOf(aMethodObj)) - 1; - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader) - ? 0x100 - : 0) -# else - 0 -# endif - ; - bcpc += deltaToSkipPrimAndErrorStoreInheader(aMethodObj, (homeMethod->methodHeader)); - } - else { - isInBlock = 1; - assert(bcpc == ((cogBlockMethod->startpc))); - homeMethod = cmHomeMethod(cogBlockMethod); - map = findMapLocationForMcpcinMethod((((usqInt)cogBlockMethod)) + (sizeof(CogBlockMethod)), homeMethod); - assert(map != 0); - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert(((((usqInt)(annotation)) >> AnnotationShift) == HasBytecodePC) - || ((((usqInt)(annotation)) >> AnnotationShift) == IsDisplacementX2N)); - while (((annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift)) != HasBytecodePC) { - map -= 1; - } - - /* skip fiducial; i.e. the map entry for the pc immediately following the method header. */ - map -= 1; - aMethodObj = (homeMethod->methodObject); - bcpc = startbcpc - ( -#if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet((homeMethod->methodHeader)) - ? AltBlockCreationBytecodeSize - : BlockCreationBytecodeSize) -#else // MULTIPLEBYTECODESETS - BlockCreationBytecodeSize -#endif - ); - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader1 = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader1) - ? 0x100 - : 0) -# else - 0 -# endif - ; - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - endbcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, -1, aMethodObj)) - : 0)); - bcpc = startbcpc; - } - nExts = 0; - while ((((usqInt)((byteAt(map)))) >> AnnotationShift) != HasBytecodePC) { - map -= 1; - } - map -= 1; - while (((mapByte = byteAt(map))) != MapEnd) { - - /* defensive; we exit on bcpc */ - if (mapByte >= FirstAnnotation) { - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if (annotation >= HasBytecodePC) { - if ((annotation == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - while (1) { - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - if (isInBlock) { - if (bcpc >= endbcpc) { - errCode = 0; - goto l7; - } - } - else { - if (((descriptor->isReturn)) - && (bcpc >= latestContinuation)) { - errCode = 0; - goto l7; - } - if ((isBranch(descriptor)) - || ((descriptor->isBlockCreation))) { - /* begin latestContinuationPCFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj); - targetPC = (bcpc + ((descriptor->numBytes))) + (((distance < 0) ? 0 : distance)); - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - /* latestContinuation = */ latestContinuation; - } - nextBcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) - : 0)); - if (((descriptor->isMapped)) - || (isInBlock - && ((descriptor->isMappedInBlock)))) break; - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - isBackwardBranch = (isBranch(descriptor)) - && ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) < 0)); - result = collectCogConstituentForAnnotationMcpcBcpcMethod(descriptor, ((isBackwardBranch - ? (((sqInt)((usqInt)(annotation) << 1))) + 1 - : ((sqInt)((usqInt)(annotation) << 1)))), (((char *) mcpc)), ((isBackwardBranch - ? bcpc - (2 * nExts) - : bcpc)), (((void *)cogMethod))); - if (result != 0) { - errCode = result; - goto l7; - } - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - } - else { - assert(((((usqInt)(mapByte)) >> AnnotationShift) == IsDisplacementX2N) - || ((((usqInt)(mapByte)) >> AnnotationShift) == IsAnnotationExtension)); - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - errCode = 0; - l7: /* end mapFor:bcpc:performUntil:arg: */; - if (errCode != 0) { - popRemappableOop(); - return null; - } - if (cogConstituentIndex < nSlots) { - shortentoIndexableSize(topRemappableOop(), cogConstituentIndex); - } - return popRemappableOop(); -} - - /* Cogit>>#compactCogCompiledCode */ -void -compactCogCompiledCode(void) -{ - assertValidDualZone(); - assert(noCogMethodsMaximallyMarked()); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - markActiveMethodsAndReferents(); - freeOlderMethodsForCompaction(); - compactPICsWithFreedTargets(); - planCompaction(); - updateStackZoneReferencesToCompiledCodePreCompaction(); - relocateMethodsPreCompaction(); - assertValidDualZone(); - compactCompiledCode(); - stopsFromto(backEnd, freeStart(), (youngReferrers()) - 1); - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), ((usqInt)(youngReferrers()))); - assert(allMethodsHaveCorrectHeader()); - assert(kosherYoungReferrers()); - assertValidDualZone(); -} - - /* Cogit>>#compactPICsWithFreedTargets */ -static void -compactPICsWithFreedTargets(void) -{ - CogMethod *cogMethod; - sqInt count; - - cogMethod = ((CogMethod *) methodZoneBase); - count = 0; - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) == CMClosedPIC) - && (cPICCompactAndIsNowEmpty(cogMethod))) { - ((((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)))->cmType = CMFree); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - count += 1; - } - assert(count == (numMethods())); -} - - -/* The start of a CogMethod has a call to a run-time abort routine that - either handles an in-line cache failure or a stack overflow. The routine - selects the - path depending on ReceiverResultReg; if zero it takes the stack overflow - path; if nonzero the in-line cache miss path. Neither of these paths - returns. The abort routine must be called; In the callee the method is - located by - adding the relevant offset to the return address of the call. - - N.B. This code must match that in compilePICAbort: so that the offset of - the return address of the call is the same in methods and closed PICs. */ - - /* Cogit>>#compileAbort */ -static AbstractInstruction * -compileAbort(void) -{ - AbstractInstruction *anInstruction; - sqInt callTarget; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 0, ReceiverResultReg); - stackOverflowCall = anInstruction; - - /* If there is a link register it must be saved (pushed onto the stack) before it - is smashed by the abort call, and hence needs to be manually handled here */ - sendMiss = genoperand(PushR, LinkReg); - /* begin Call: */ - callTarget = methodAbortTrampolineFor(methodOrBlockNumArgs); - return genoperand(Call, callTarget); -} - - /* Cogit>>#compileBlockDispatchFrom:to: */ -static sqInt NoDbgRegParms -compileBlockDispatchFromto(sqInt lowBlockStartIndex, sqInt highBlockStartIndex) -{ - AbstractInstruction *anInstruction; - BlockStart *blockStart; - sqInt halfWay; - AbstractInstruction *jmp; - - if (lowBlockStartIndex == highBlockStartIndex) { - blockStart = blockStartAt(lowBlockStartIndex); - genoperand(Jump, ((sqInt)((blockStart->entryLabel)))); - return null; - } - halfWay = (highBlockStartIndex + lowBlockStartIndex) / 2; - assert(((halfWay >= lowBlockStartIndex) && (halfWay <= highBlockStartIndex))); - - /* N.B. FLAGS := TempReg - startpc */ - blockStart = blockStartAt(halfWay); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)(((blockStart->startpc)) + 1) << 1) | 1); - anInstruction = genoperandoperand(CmpCqR, (((usqInt)(((blockStart->startpc)) + 1) << 1) | 1), TempReg); - if (lowBlockStartIndex == halfWay) { - genConditionalBranchoperand(JumpLessOrEqual, ((sqInt)((blockStart->entryLabel)))); - compileBlockDispatchFromto(halfWay + 1, highBlockStartIndex); - return null; - } - if ((halfWay + 1) == highBlockStartIndex) { - blockStart = blockStartAt(highBlockStartIndex); - genConditionalBranchoperand(JumpGreater, ((sqInt)((blockStart->entryLabel)))); - return compileBlockDispatchFromto(lowBlockStartIndex, halfWay); - } - jmp = genConditionalBranchoperand(JumpGreater, ((sqInt)0)); - compileBlockDispatchFromto(lowBlockStartIndex, halfWay); - if (halfWay == highBlockStartIndex) { - blockStart = blockStartAt(highBlockStartIndex); - jmpTarget(jmp, (blockStart->entryLabel)); - } - else { - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileBlockDispatchFromto(halfWay + 1, highBlockStartIndex); - } - return 0; -} - - -/* Compile a block's entry. This looks like a dummy CogBlockMethod header - (for frame parsing) - followed by either a frame build, if a frame is required, or nothing. The - CogMethodHeader's objectHeader field is a back pointer to the method, but - this can't be filled in until code generation. */ - - /* Cogit>>#compileBlockEntry: */ -static void NoDbgRegParms -compileBlockEntry(BlockStart *blockStart) -{ - AbstractInstruction *abstractInstruction; - sqInt alignment; - - /* begin AlignmentNops: */ - alignment = blockAlignment(); - genoperand(AlignmentNops, alignment); - (blockStart->fakeHeader = genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - switch (sizeof(CogBlockMethod)) { - case 8: - genoperand(Fill32, 0); - genoperand(Fill32, 0); - break; - case 12: - genoperand(Fill32, 0); - genoperand(Fill32, 0); - genoperand(Fill32, 0); - break; - case 16: - genoperand(Fill32, 0); - genoperand(Fill32, 0); - genoperand(Fill32, 0); - genoperand(Fill32, 0); - break; - default: - error("Case not found and no otherwise clause"); - } - (blockStart->entryLabel = genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (needsFrame) { - compileBlockFrameBuild(blockStart); - if (recordBlockTrace()) { - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceTraceBlockActivationTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - } - } - else { - compileBlockFramelessEntry(blockStart); - } -} - - -/* Generate a call to aRoutine with up to 4 arguments. If resultRegOrNone is - not NoReg assign the C result to resultRegOrNone. If saveRegs, save all - registers. Hack: a negative arg value indicates an abstract register, a - non-negative value - indicates a constant. */ - - /* Cogit>>#compileCallFor:numArgs:arg:arg:arg:arg:resultReg:regsToSave: */ -static void NoDbgRegParms -compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt resultRegOrNone, sqInt regMask) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - const int cStackAlignment = STACK_ALIGN_BYTES; - sqInt delta; - sqInt numRegsPushed; - usqInt regMaskCopy; - sqInt regsToSave; - sqInt wordsPushedModAlignment; - - regsToSave = (resultRegOrNone == NoReg - ? regMask - : ((regMask | (1U << resultRegOrNone)) - (1U << resultRegOrNone))); - if (cStackAlignment > BytesPerWord) { - /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ - regMaskCopy = ((usqInt)regsToSave); - numRegsPushed = 0; - while (regMaskCopy != 0) { - numRegsPushed += regMaskCopy & 1; - regMaskCopy = ((regMaskCopy) >> 1); - } - if ((numRegsPushed == 0) - && ((numIntRegArgs(((AbstractInstruction *) backEnd))) >= numArgs)) { - goto l1; - } - wordsPushedModAlignment = (numRegsPushed + ((((numArgs - (numIntRegArgs(((AbstractInstruction *) backEnd)))) < 0) ? 0 : (numArgs - (numIntRegArgs(((AbstractInstruction *) backEnd))))))) % (cStackAlignment / BytesPerWord); - if (wordsPushedModAlignment != 0) { - delta = (cStackAlignment / BytesPerWord) - wordsPushedModAlignment; - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, delta * BytesPerWord, SPReg); - } - l1: /* end genAlignCStackSavingRegisters:numArgs:wordAlignment: */; - } - genSaveRegs(backEnd, regsToSave); - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - if (numArgs == 0) { - goto l13; - } - if (regOrConst0 < NoReg) { - /* begin MoveCq:R: */ - anInstruction4 = genoperandoperand(MoveCqR, -2 - regOrConst0, A0); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, regOrConst0, A0); - } - if (numArgs == 1) { - goto l13; - } - if (regOrConst1 < NoReg) { - /* begin MoveCq:R: */ - anInstruction11 = genoperandoperand(MoveCqR, -2 - regOrConst1, A1); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, regOrConst1, A1); - } - if (numArgs == 2) { - goto l13; - } - if (regOrConst2 < NoReg) { - /* begin MoveCq:R: */ - anInstruction21 = genoperandoperand(MoveCqR, -2 - regOrConst2, A2); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, regOrConst2, A2); - } - if (numArgs == 3) { - goto l13; - } - if (regOrConst3 < NoReg) { - /* begin MoveCq:R: */ - anInstruction3 = genoperandoperand(MoveCqR, -2 - regOrConst3, A3); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, regOrConst3, A3); - } - l13: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin checkLiteral:forInstruction: */ - anInstruction2 = genoperand(CallFull, ((usqInt)aRoutine)); - genWriteCResultIntoReg(backEnd, resultRegOrNone); - assert(numArgs <= 4); - genRestoreRegs(backEnd, regsToSave); -} - - -/* Compile the cache tag computation and the first comparison. Answer the - address of that comparison. */ - - /* Cogit>>#compileCPICEntry */ -static AbstractInstruction * -compileCPICEntry(void) -{ - entry = genGetInlineCacheClassTagFromintoforEntry(ReceiverResultReg, TempReg, 1); - /* begin CmpR:R: */ - assert(!((ClassReg == SPReg))); - genoperandoperand(CmpRR, ClassReg, TempReg); - return genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -} - - -/* The entry code to a method checks that the class of the current receiver - matches that in the inline cache. Other non-obvious elements are that its - alignment must be - different from the alignment of the noCheckEntry so that the method map - machinery can distinguish normal and super sends (super sends bind to the - noCheckEntry). */ - - /* Cogit>>#compileEntry */ -static void -compileEntry(void) -{ - AbstractInstruction *anInstruction1; - AbstractInstruction * inst; - - entry = genGetInlineCacheClassTagFromintoforEntry(ReceiverResultReg, TempReg, 1); - /* begin CmpR:R: */ - assert(!((ClassReg == SPReg))); - genoperandoperand(CmpRR, ClassReg, TempReg); - genConditionalBranchoperand(JumpNonZero, ((sqInt)sendMiss)); - noCheckEntry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - if (((traceFlags & 0x100) == 0x100)) { - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - /* begin checkLiteral:forInstruction: */ - anInstruction1 = genoperand(CallFull, ceTraceLinkedSendTrampoline); - /* begin PopR: */ - genoperand(PopR, LinkReg); - } -} - - -/* Compile the top-level method body. */ - - /* Cogit>>#compileMethodBody */ -static sqInt -compileMethodBody(void) -{ - if (endPC < initialPC) { - return 0; - } - return compileAbstractInstructionsFromthrough(initialPC + (deltaToSkipPrimAndErrorStoreInheader(methodObj, methodHeader)), endPC); -} - - -/* The start of a PIC has a call to a run-time abort routine that either - handles a dispatch to an - interpreted method or a dispatch of an MNU case. The routine selects the - path by testing - ClassReg, which holds the inline cache tag; if equal to the - picAbortDiscriminatorValue (zero) - it takes the MNU path; if nonzero the dispatch to interpreter path. - Neither of these paths - returns. The abort routine must be called; In the callee the PIC is - located by adding the - relevant offset to the return address of the call. - - N.B. This code must match that in compileAbort so that the offset of the - return address of - the call is the same in methods and closed PICs. */ - - /* Cogit>>#compilePICAbort: */ -static sqInt NoDbgRegParms -compilePICAbort(sqInt numArgs) -{ - AbstractInstruction *anInstruction; - sqInt callTarget; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 0 /* picAbortDiscriminatorValue */, ClassReg); - picMNUAbort = anInstruction; - - /* If there is a link register it must be saved (pushed onto the stack) before it - is smashed by the abort call, and hence needs to be manually handled here */ - picInterpretAbort = genoperand(PushR, LinkReg); - /* begin Call: */ - callTarget = picAbortTrampolineFor(numArgs); - genoperand(Call, callTarget); - return 0; -} - - -/* Compile the compare of stackLimit against the stack pointer, jumping to - the stackOverflowCall if - the stack pointer is below the limit. Answer a bytecode annotated label - that follows the sequence. - - The stack check functions both as a genuine stack limit check to prevent - calls overflowing stack pages, - and as an event/context-switch break out. To cause an event check - (including a check for a required - context switch), stackLimit is set to the highest possible value, and - hence all stack limit checks will - fail. A path in the stack overflow abort then arranges to call event - checking if it has been requested. - - Certain block activations (e.g. valueNoContextSwitch:) must not context - switch, and in that - case, SendNumArgs is set to zero to communicate to the stack overflow - abort that it should - not perform event/context-switch (yet). */ - - /* Cogit>>#compileStackOverflowCheck: */ -static AbstractInstruction * NoDbgRegParms -compileStackOverflowCheck(sqInt canContextSwitch) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction * jumpSkip; - AbstractInstruction * label; - - /* begin checkLiteral:forInstruction: */ - stackLimitAddress(); - anInstruction1 = genoperandoperand(MoveAwR, stackLimitAddress(), TempReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, SPReg); - if (canContextSwitch) { - genConditionalBranchoperand(JumpBelow, ((sqInt)stackOverflowCall)); - label = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - else { - jumpSkip = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 0, SendNumArgsReg); - genoperand(Jump, ((sqInt)stackOverflowCall)); - jmpTarget(jumpSkip, (label = genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - } - /* begin annotateBytecode: */ - (label->annotation = HasBytecodePC); - return label; -} - - -/* Generate a trampoline with up to four arguments. Generate either a call or - a jump to aRoutine - as requested by callJumpBar. If generating a call and resultRegOrNone is - not NoReg pass the C - result back in resultRegOrNone. - Hack: a negative value indicates an abstract register, a non-negative - value indicates a constant. */ - - /* Cogit>>#compileTrampolineFor:numArgs:arg:arg:arg:arg:regsToSave:pushLinkReg:resultReg: */ -static void NoDbgRegParms -compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone) -{ - genSmalltalkToCStackSwitch(pushLinkReg); - compileCallFornumArgsargargargargresultRegregsToSave(aRoutine, numArgs, regOrConst0, regOrConst1, regOrConst2, regOrConst3, resultRegOrNone, regMask); - genLoadStackPointers(backEnd); - genTrampolineReturn(pushLinkReg); -} - - -/* Generate the entry code for a method to determine cmEntryOffset and - cmNoCheckEntryOffset. We - need cmNoCheckEntryOffset up front to be able to generate the map starting - from cmNoCheckEntryOffset */ -/* stack allocate the various collections so that they - are effectively garbage collected on return. */ - - /* Cogit>>#computeEntryOffsets */ -static void -computeEntryOffsets(void) -{ - sqInt fixupSize; - sqInt opcodeSize; - AbstractInstruction *sendMissCall; - - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 24; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - methodOrBlockNumArgs = 0; - sendMissCall = compileAbort(); - compileEntry(); - computeMaximumSizes(); - generateInstructionsAt(methodZoneBase + (sizeof(CogMethod))); - cmEntryOffset = ((entry->address)) - methodZoneBase; - cmNoCheckEntryOffset = ((noCheckEntry->address)) - methodZoneBase; - missOffset = (((sendMissCall->address)) + ((sendMissCall->machineCodeSize))) - methodZoneBase; - entryPointMask = BytesPerWord - 1; - while ((cmEntryOffset & entryPointMask) == (cmNoCheckEntryOffset & entryPointMask)) { - entryPointMask = (entryPointMask + entryPointMask) + 1; - } - if (entryPointMask >= (roundUpToMethodAlignment(backEnd(), 1))) { - error("cannot differentiate checked and unchecked entry-points with current cog method alignment"); - } - checkedEntryAlignment = cmEntryOffset & entryPointMask; - uncheckedEntryAlignment = cmNoCheckEntryOffset & entryPointMask; - assert(checkedEntryAlignment != uncheckedEntryAlignment); -} - - -/* Generate the entry code for a method to determine cmEntryOffset and - cmNoCheckEntryOffset. We - need cmNoCheckEntryOffset up front to be able to generate the map starting - from cmNoCheckEntryOffset */ -/* stack allocate the various collections so that they - are effectively garbage collected on return. */ - - /* Cogit>>#computeFullBlockEntryOffsets */ -static void -computeFullBlockEntryOffsets(void) -{ - } - - -/* While we order variables in the CoInterpreter in order of dynamic - frequency, and hence - expect that stackPointer will be output first, C optimizers and linkers - may get their own - ideas and ``improve upon'' this ordering. So we cannot depend on - stackPointer being - at the lowest address of the variables we want to access through - VarBaseReg. Here we - choose the minimum amongst a set to try to choose a varBaseAddress that is - just less - than but iwht in range of all variables we want to access through it. */ - - /* Cogit>>#computeGoodVarBaseAddress */ -static usqInt -computeGoodVarBaseAddress(void) -{ - usqInt minAddress; - - - /* stackLimit is e.g. lowest using the clang toolchain on MacOS X */ - minAddress = stackLimitAddress(); - if ((stackPointerAddress()) < minAddress) { - minAddress = stackPointerAddress(); - } - if ((framePointerAddress()) < minAddress) { - minAddress = framePointerAddress(); - } - if ((instructionPointerAddress()) < minAddress) { - minAddress = instructionPointerAddress(); - } - if ((argumentCountAddress()) < minAddress) { - minAddress = argumentCountAddress(); - } - if ((primFailCodeAddress()) < minAddress) { - minAddress = primFailCodeAddress(); - } - return minAddress; -} - - -/* This pass assigns maximum sizes to all abstract instructions and - eliminates jump fixups. - It hence assigns the maximum address an instruction will occur at which - allows the next - pass to conservatively size jumps. */ - - /* Cogit>>#computeMaximumSizes */ -static void -computeMaximumSizes(void) -{ - AbstractInstruction *abstractInstruction; - sqInt i; - sqInt relativeAddress; - - relativeAddress = 0; - for (i = 0; i < opcodeIndex; i += 1) { - maybeBreakGeneratingInstructionWithIndex(i); - abstractInstruction = abstractInstructionAt(i); - (abstractInstruction->address = relativeAddress); - (abstractInstruction->maxSize = computeMaximumSize(abstractInstruction)); - relativeAddress += (abstractInstruction->maxSize); - } -} - - -/* Configure a copy of the prototype CPIC for a two-case PIC for - case0CogMethod and - case1Method - case1Tag. - The tag for case0CogMethod is at the send site and so doesn't need to be - generated. case1Method may be any of - - a Cog method; jump to its unchecked entry-point - - a CompiledMethod; jump to the ceInterpretFromPIC trampoline - - nil; call ceMNUFromPIC - addDelta is the address change from the prototype to the new CPIC - location, needed - because the loading of the CPIC label at the end may use a literal instead - of a pc relative load. */ -/* self disassembleFrom: cPIC asInteger + (self sizeof: CogMethod) to: cPIC - asInteger + closedPICSize - */ - - /* Cogit>>#configureCPIC:Case0:Case1Method:tag:isMNUCase:numArgs:delta: */ -static sqInt NoDbgRegParms -configureCPICCase0Case1MethodtagisMNUCasenumArgsdelta(CogMethod *cPIC, CogMethod *case0CogMethod, sqInt case1Method, sqInt case1Tag, sqInt isMNUCase, sqInt numArgs, sqInt addrDelta) -{ - sqInt caseEndAddress; - int operand; - sqInt targetEntry; - - assert(case1Method != null); - rewriteCallAttarget(backEnd, (((sqInt)cPIC)) + missOffset, picAbortTrampolineFor(numArgs)); - assert(!(inlineCacheTagIsYoung(case1Tag))); - if ((!isMNUCase) - && (methodHasCogMethod(case1Method))) { - operand = 0; - targetEntry = (((sqInt)(cogMethodOf(case1Method)))) + cmNoCheckEntryOffset; - } - else { - - /* We do not scavenge PICs, hence we cannot cache the MNU method if it is in new space. */ - operand = ((case1Method == null) - || (isYoungObject(case1Method)) - ? 0 - : case1Method); - targetEntry = (case1Method == null - ? (((sqInt)cPIC)) + (sizeof(CogMethod)) - : (((sqInt)cPIC)) + (picInterpretAbortOffset())); - } - rewriteJumpLongAttarget(backEnd, (((sqInt)cPIC)) + firstCPICCaseOffset, (((sqInt)case0CogMethod)) + cmNoCheckEntryOffset); - - /* update the cpic case */ - caseEndAddress = addressOfEndOfCaseinCPIC(2, cPIC); - rewriteCPICCaseAttagobjReftarget(caseEndAddress, case1Tag, operand, ((sqInt)((isMNUCase - ? (((sqInt)cPIC)) + (sizeof(CogMethod)) - : targetEntry)))); - relocateMethodReferenceBeforeAddressby(backEnd, ((((sqInt)cPIC)) + cPICEndOfCodeOffset) - (jumpLongByteSize(backEnd)), addrDelta); - rewriteJumpLongAttarget(backEnd, (((sqInt)cPIC)) + cPICEndOfCodeOffset, cPICMissTrampolineFor(numArgs)); - return 0; -} - - -/* Configure a copy of the prototype CPIC for a one-case MNU CPIC that calls - ceMNUFromPIC for - case0Tag The tag for case0 is at the send site and so doesn't need to be - generated. addDelta is the address change from the prototype to the new - CPIC location, needed - because the loading of the CPIC label at the end may be a literal instead - of a pc-relative load. */ -/* adjust the jump at missOffset, the ceAbortXArgs */ - - /* Cogit>>#configureMNUCPIC:methodOperand:numArgs:delta: */ -static sqInt NoDbgRegParms -configureMNUCPICmethodOperandnumArgsdelta(CogMethod *cPIC, sqInt methodOperand, sqInt numArgs, sqInt addrDelta) -{ - int operand; - sqInt target; - - rewriteCallAttarget(backEnd, (((sqInt)cPIC)) + missOffset, picAbortTrampolineFor(numArgs)); - - /* set the jump to the case0 method */ - operand = ((methodOperand == null) - || (isYoungObject(methodOperand)) - ? 0 - : methodOperand); - rewriteJumpLongAttarget(backEnd, (((sqInt)cPIC)) + firstCPICCaseOffset, (((sqInt)cPIC)) + (sizeof(CogMethod))); - storeLiteralbeforeFollowingAddress(backEnd, operand, ((((sqInt)cPIC)) + firstCPICCaseOffset) - (jumpLongByteSize(backEnd))); - rewriteJumpLongAttarget(backEnd, (((sqInt)cPIC)) + cPICEndOfCodeOffset, cPICMissTrampolineFor(numArgs)); - relocateMethodReferenceBeforeAddressby(backEnd, ((((sqInt)cPIC)) + cPICEndOfCodeOffset) - (jumpLongByteSize(backEnd)), addrDelta); - /* begin rewriteCPIC:caseJumpTo: */ - target = addressOfEndOfCaseinCPIC(2, cPIC); - rewriteCPICJumpAttarget(backEnd, (((((sqInt)cPIC)) + firstCPICCaseOffset) - (jumpLongByteSize(backEnd))) - 8 /* loadLiteralByteSize */, target); - return 0; -} - - -/* Scan the CPIC for target methods that have been freed and eliminate them. - Since the first entry cannot be eliminated, answer that the PIC should be - freed if the first entry is to a free target. Answer if the PIC is now - empty or should be freed. */ - - /* Cogit>>#cPICCompactAndIsNowEmpty: */ -static sqInt NoDbgRegParms -cPICCompactAndIsNowEmpty(CogMethod *cPIC) -{ - usqInt entryPoint; - sqInt followingAddress; - sqInt i; - sqInt methods[MaxCPICCases]; - sqInt pc; - int tags[MaxCPICCases]; - CogMethod *targetMethod; - sqInt targets[MaxCPICCases]; - sqInt used; - sqInt valid; - - used = 0; - for (i = 1; i <= ((cPIC->cPICNumCases)); i += 1) { - pc = addressOfEndOfCaseinCPIC(i, cPIC); - entryPoint = (i == 1 - ? jumpLongTargetBeforeFollowingAddress(backEnd, pc) - : jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc)); - - /* Collect all target triples except for triples whose entry-point is a freed method */ - valid = 1; - if (!(((((usqInt)cPIC)) <= (((usqInt)entryPoint))) - && (((((usqInt)cPIC)) + ((cPIC->blockSize))) >= (((usqInt)entryPoint))))) { - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - assert((((targetMethod->cmType)) == CMMethod) - || (((targetMethod->cmType)) == CMFree)); - if (((targetMethod->cmType)) == CMFree) { - if (i == 1) { - return 1; - } - valid = 0; - } - } - if (valid) { - tags[used] = ((i > 1 - ? (/* begin literal32BeforeFollowingAddress: */ - (followingAddress = pc - 16 /* jumpLongConditionalByteSize */), - literalBeforeFollowingAddress(((AbstractInstruction *) backEnd), followingAddress)) - : 0)); - targets[used] = entryPoint; - methods[used] = (literalBeforeFollowingAddress(backEnd, pc - ((i == 1 - ? jumpLongByteSize(backEnd) - : 24)))); - used += 1; - } - } - if (used == ((cPIC->cPICNumCases))) { - return 0; - } - if (used == 0) { - return 1; - } - ((((CogMethod *) ((((usqInt)cPIC)) + codeToDataDelta)))->cPICNumCases = used); - if (used == 1) { - pc = addressOfEndOfCaseinCPIC(2, cPIC); - /* begin rewriteCPIC:caseJumpTo: */ - rewriteCPICJumpAttarget(backEnd, (((((sqInt)cPIC)) + firstCPICCaseOffset) - (jumpLongByteSize(backEnd))) - 8 /* loadLiteralByteSize */, pc); - return 0; - } - for (i = 1; i < used; i += 1) { - pc = addressOfEndOfCaseinCPIC(i + 1, cPIC); - rewriteCPICCaseAttagobjReftarget(pc, tags[i], methods[i], targets[i]); - } - /* begin rewriteCPIC:caseJumpTo: */ - rewriteCPICJumpAttarget(backEnd, (((((sqInt)cPIC)) + firstCPICCaseOffset) - (jumpLongByteSize(backEnd))) - 8 /* loadLiteralByteSize */, pc - cPICCaseSize); - return 0; -} - - -/* The first case in a CPIC doesn't have a class reference so we need only - step over actually usd subsequent cases. - */ - - /* Cogit>>#cPICHasForwardedClass: */ -static sqInt NoDbgRegParms -cPICHasForwardedClass(CogMethod *cPIC) -{ - usqInt classIndex; - sqInt i; - sqInt pc; - - - /* start by finding the address of the topmost case, the cPICNumCases'th one */ - pc = (addressOfEndOfCaseinCPIC((cPIC->cPICNumCases), cPIC)) - 16 /* jumpLongConditionalByteSize */; - for (i = 2; i <= ((cPIC->cPICNumCases)); i += 1) { - /* begin literal32BeforeFollowingAddress: */ - classIndex = literalBeforeFollowingAddress(((AbstractInstruction *) backEnd), pc); - if (isForwardedClassIndex(classIndex)) { - return 1; - } - pc += cPICCaseSize; - } - return 0; -} - - -/* scan the CPIC for target methods that have been freed. */ - - /* Cogit>>#cPICHasFreedTargets: */ -static sqInt NoDbgRegParms -cPICHasFreedTargets(CogMethod *cPIC) -{ - usqInt entryPoint; - sqInt i; - sqInt pc; - CogMethod *targetMethod; - - for (i = 1; i <= ((cPIC->cPICNumCases)); i += 1) { - pc = addressOfEndOfCaseinCPIC(i, cPIC); - - /* Find target from jump. Ignore jumps to the interpret and MNU calls within this PIC */ - entryPoint = (i == 1 - ? jumpLongTargetBeforeFollowingAddress(backEnd, pc) - : jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc)); - if (!(((((usqInt)cPIC)) <= (((usqInt)entryPoint))) - && (((((usqInt)cPIC)) + ((cPIC->blockSize))) >= (((usqInt)entryPoint))))) { - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - assert((((targetMethod->cmType)) == CMMethod) - || (((targetMethod->cmType)) == CMFree)); - if (((targetMethod->cmType)) == CMFree) { - return 1; - } - } - } - return 0; -} - - -/* Whimsey; we want 16rCA5E10 + cPICPrototypeCaseOffset to be somewhere in - the middle of the zone. - */ - - /* Cogit>>#cPICPrototypeCaseOffset */ -static usqInt -cPICPrototypeCaseOffset(void) -{ - return ((methodZoneBase + (youngReferrers())) / 2) - 13262352; -} - - -/* Are any of the jumps from this CPIC to targetMethod? */ - - /* Cogit>>#cPIC:HasTarget: */ -static sqInt NoDbgRegParms -cPICHasTarget(CogMethod *cPIC, CogMethod *targetMethod) -{ - sqInt i; - sqInt pc; - sqInt target; - - target = (((usqInt)targetMethod)) + cmNoCheckEntryOffset; - - /* Since this is a fast test doing simple compares we don't need to care that some - cases have nonsense addresses in there. Just zip on through. */ - /* First jump is unconditional; subsequent ones are conditional */ - pc = (((sqInt)cPIC)) + firstCPICCaseOffset; - if (target == (jumpLongTargetBeforeFollowingAddress(backEnd, pc))) { - return 1; - } - for (i = 2; i <= MaxCPICCases; i += 1) { - pc += cPICCaseSize; - if (target == (jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc))) { - return 1; - } - } - return 0; -} - - -/* Answer an Array of the PIC's selector, followed by class and - targetMethod/doesNotUnderstand: for each entry in the PIC. - */ - - /* Cogit>>#createCPICData: */ -static sqInt NoDbgRegParms -createCPICData(CogMethod *cPIC) -{ - sqInt class; - usqInt entryPoint; - sqInt i; - sqInt pc; - sqInt picData; - sqInt target; - CogMethod *targetMethod; - - assert((((cPIC->methodObject)) == 0) - || (addressCouldBeOop((cPIC->methodObject)))); - picData = instantiateClassindexableSize(classArray(), (((cPIC->cPICNumCases)) * 2) + 1); - if (!picData) { - return picData; - } - storePointerUncheckedofObjectwithValue(0, picData, (cPIC->selector)); - for (i = 1; i <= ((cPIC->cPICNumCases)); i += 1) { - pc = addressOfEndOfCaseinCPIC(i, cPIC); - if (i == 1) { - - /* first case may have been collected and stored here by collectCogConstituentFor:Annotation:Mcpc:Bcpc:Method: */ - class = (cPIC->methodObject); - if (class == 0) { - class = nilObject(); - } - entryPoint = jumpLongTargetBeforeFollowingAddress(backEnd, pc); - } - else { - class = classForInlineCacheTag(literalBeforeFollowingAddress(backEnd, pc - 16 /* jumpLongConditionalByteSize */)); - entryPoint = jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc); - } - if (((((usqInt)cPIC)) <= (((usqInt)entryPoint))) - && (((((usqInt)cPIC)) + ((cPIC->blockSize))) >= (((usqInt)entryPoint)))) { - target = splObj(SelectorDoesNotUnderstand); - } - else { - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - assert(((targetMethod->cmType)) == CMMethod); - target = (targetMethod->methodObject); - } - storePointerUncheckedofObjectwithValue((i * 2) - 1, picData, class); - storePointerUncheckedofObjectwithValue(i * 2, picData, target); - } - beRootIfOld(picData); - (cPIC->methodObject = 0); - return picData; -} - - -/* Division is a little weird on some processors. Defer to the backEnd - to allow it to generate any special code it may need to. */ - - /* Cogit>>#DivR:R:Quo:Rem: */ -static AbstractInstruction * NoDbgRegParms -gDivRRQuoRem(sqInt rDivisor, sqInt rDividend, sqInt rQuotient, sqInt rRemainder) -{ - genDivRRQuoRem(backEnd, rDivisor, rDividend, rQuotient, rRemainder); - return abstractInstructionAt(opcodeIndex - 1); -} - - -/* Return the default number of bytes to allocate for native code at startup. - The actual value can be set via vmParameterAt: and/or a preference in the - ini file. */ - - /* Cogit>>#defaultCogCodeSize */ -sqInt -defaultCogCodeSize(void) -{ - return 0x180000; -} - - -/* Answer the number of bytecodes to skip to get to the first bytecode - past the primitive call and any store of the error code. */ - - /* Cogit>>#deltaToSkipPrimAndErrorStoreIn:header: */ -static sqInt NoDbgRegParms -deltaToSkipPrimAndErrorStoreInheader(sqInt aMethodObj, sqInt aMethodHeader) -{ - return (((primitiveIndexOfMethodheader(aMethodObj, aMethodHeader)) > 0) - && ((longStoreBytecodeForHeader(aMethodHeader)) == (fetchByteofObject((startPCOfMethod(aMethodObj)) + (sizeOfCallPrimitiveBytecode(aMethodHeader)), aMethodObj))) - ? (sizeOfCallPrimitiveBytecode(aMethodHeader)) + (sizeOfLongStoreTempBytecode(aMethodHeader)) - : 0); -} - - /* Cogit>>#endPCOf: */ -static sqInt NoDbgRegParms -endPCOf(sqInt aMethod) -{ - sqInt bsOffset; - sqInt byte; - BytecodeDescriptor *descriptor; - sqInt distance; - sqInt end; - sqInt latestContinuation; - sqInt nExts; - sqInt pc; - sqInt prim; - sqInt targetPC; - - pc = (latestContinuation = startPCOfMethod(aMethod)); - if (((prim = primitiveIndexOf(aMethod))) > 0) { - if (isQuickPrimitiveIndex(prim)) { - return pc - 1; - } - } - /* begin bytecodeSetOffsetFor: */ - bsOffset = -# if MULTIPLEBYTECODESETS - (methodUsesAlternateBytecodeSet(aMethod) - ? 0x100 - : 0) -# else - (assert(!((methodUsesAlternateBytecodeSet(aMethod)))), - 0) -# endif - ; - nExts = 0; - end = numBytesOf(aMethod); - while (pc <= end) { - byte = fetchByteofObject(pc, aMethod); - descriptor = generatorAt(byte + bsOffset); - if (((descriptor->isReturn)) - && (pc >= latestContinuation)) { - end = pc; - } - if ((isBranch(descriptor)) - || ((descriptor->isBlockCreation))) { - distance = ((descriptor->spanFunction))(descriptor, pc, nExts, aMethod); - targetPC = (pc + ((descriptor->numBytes))) + distance; - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - if ((descriptor->isBlockCreation)) { - pc += distance; - } - } - else { - /* latestContinuation = */ latestContinuation; - } - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - pc += (descriptor->numBytes); - } - return end; -} - - -/* This is a static version of ceEnterCogCodePopReceiverReg - for break-pointing when debugging in C. */ -/* This exists only for break-pointing. */ - - /* Cogit>>#enterCogCodePopReceiver */ -void -enterCogCodePopReceiver(void) -{ - realCEEnterCogCodePopReceiverReg(); - error("what??"); -} - - -/* Answer if the entryPoint's tag is expected to be a selector reference, as - opposed to a class tag. - */ - - /* Cogit>>#entryPointTagIsSelector: */ -static sqInt NoDbgRegParms -entryPointTagIsSelector(sqInt entryPoint) -{ - return (entryPoint < methodZoneBase) - || (((entryPoint & entryPointMask) == uncheckedEntryAlignment) - || (((entryPoint & entryPointMask) == checkedEntryAlignment) - && ((((((CogMethod *) (entryPoint - cmEntryOffset)))->cmType)) == CMOpenPIC))); -} - - -/* Use asserts to check if the ClosedPICPrototype is as expected from - compileClosedPICPrototype, and can be updated as required via - rewriteCPICCaseAt:tag:objRef:target:. If all asserts pass, answer - 0, otherwise answer a bit mask identifying all the errors. */ -/* self disassembleFrom: methodZoneBase + (self sizeof: CogMethod) to: - methodZoneBase + closedPICSize - */ - - /* Cogit>>#expectedClosedPICPrototype: */ -static sqInt NoDbgRegParms -expectedClosedPICPrototype(CogMethod *cPIC) -{ - usqInt classTag; - sqInt classTagPC; - usqInt entryPoint; - sqInt errors; - sqInt i; - sqInt methodObjPC; - usqInt object; - sqInt pc; - - errors = 0; - - /* First jump is unconditional; subsequent ones are conditional */ - pc = (((usqInt)cPIC)) + firstCPICCaseOffset; - object = literalBeforeFollowingAddress(backEnd, pc - (jumpLongByteSize(backEnd))); - if (!(asserta(object == (firstPrototypeMethodOop())))) { - errors = 1; - } - entryPoint = jumpLongTargetBeforeFollowingAddress(backEnd, pc); - if (!(asserta(entryPoint == ((cPICPrototypeCaseOffset()) + 13262352)))) { - errors += 2; - } - for (i = 1; i < MaxCPICCases; i += 1) { - - /* verify information in case is as expected. */ - pc += cPICCaseSize; - methodObjPC = (pc - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */; - object = literalBeforeFollowingAddress(backEnd, methodObjPC); - if (!(asserta(object == ((subsequentPrototypeMethodOop()) + i)))) { - errors = errors | 4; - } - classTagPC = pc - 16 /* jumpLongConditionalByteSize */; - /* begin literal32BeforeFollowingAddress: */ - classTag = literalBeforeFollowingAddress(((AbstractInstruction *) backEnd), classTagPC); - if (!(asserta(classTag == (3133021973U + i)))) { - errors = errors | 8; - } - entryPoint = jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc); - if (!(asserta(entryPoint == (((cPICPrototypeCaseOffset()) + 13262352) + (i * 16))))) { - errors = errors | 16; - } - rewriteCPICCaseAttagobjReftarget(pc, classTag ^ 0x5A5A5A5A, object ^ 0xA5A5A5A5U, entryPoint ^ 0x55AA50); - object = literalBeforeFollowingAddress(backEnd, methodObjPC); - if (!(asserta(object == (((subsequentPrototypeMethodOop()) + i) ^ 0xA5A5A5A5U)))) { - errors = errors | 32; - } - /* begin literal32BeforeFollowingAddress: */ - classTag = literalBeforeFollowingAddress(((AbstractInstruction *) backEnd), classTagPC); - if (!(asserta(classTag == ((3133021973U + i) ^ 0x5A5A5A5A)))) { - errors = errors | 64; - } - entryPoint = jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc); - if (!(asserta(entryPoint == ((((cPICPrototypeCaseOffset()) + 13262352) + (i * 16)) ^ 0x55AA50)))) { - errors = errors | 128; - } - rewriteCPICCaseAttagobjReftarget(pc, classTag ^ 0x5A5A5A5A, object ^ 0xA5A5A5A5U, entryPoint ^ 0x55AA50); - } - entryPoint = jumpLongTargetBeforeFollowingAddress(backEnd, (((usqInt)cPIC)) + cPICEndOfCodeOffset); - if (!(asserta(entryPoint == (cPICMissTrampolineFor(0))))) { - errors += 0x100; - } - return errors; -} - - -/* 224 11100000 aaaaaaaa Extend A (Ext A = Ext A prev * 256 + Ext A) */ - - /* Cogit>>#extABytecode */ -static sqInt -extABytecode(void) -{ - extA = ((((sqInt)((usqInt)(extA) << 8)))) + byte1; - return 0; -} - - -/* 225 11100001 sbbbbbbb Extend B (Ext B = Ext B prev * 256 + Ext B) */ - - /* Cogit>>#extBBytecode */ -static sqInt -extBBytecode(void) -{ - extB = ((numExtB == 0) - && (byte1 > 0x7F) - ? byte1 - 0x100 - : ((((sqInt)((usqInt)(extB) << 8)))) + byte1); - numExtB += 1; - return 0; -} - - -/* Fill in the block headers now we know the exact layout of the code. */ - - /* Cogit>>#fillInBlockHeadersAt: */ -static sqInt NoDbgRegParms -fillInBlockHeadersAt(sqInt startAddress) -{ - sqInt aCogMethodOrInteger; - CogBlockMethod *blockHeader; - BlockStart *blockStart; - sqInt i; - - if (!(needsFrame - && (blockCount > 0))) { - return null; - } - if (blockNoContextSwitchOffset == null) { - blockNoContextSwitchOffset = ((blockEntryLabel->address)) - ((blockEntryNoContextSwitch->address)); - } - else { - assert(blockNoContextSwitchOffset == (((blockEntryLabel->address)) - ((blockEntryNoContextSwitch->address)))); - } - for (i = 0; i < blockCount; i += 1) { - blockStart = blockStartAt(i); - /* begin writableBlockMethodFor: */ - aCogMethodOrInteger = (((blockStart->fakeHeader))->address); - blockHeader = ((CogBlockMethod *) ((((usqInt)aCogMethodOrInteger)) + codeToDataDelta)); - (blockHeader->homeOffset = ((((blockStart->fakeHeader))->address)) - startAddress); - (blockHeader->startpc = (blockStart->startpc)); - (blockHeader->cmType = CMBlock); - (blockHeader->cmNumArgs = (blockStart->numArgs)); - (blockHeader->cbUsesInstVars = (blockStart->hasInstVarRef)); - (blockHeader->stackCheckOffset = (((blockStart->stackCheckLabel)) == null - ? 0 - : ((((blockStart->stackCheckLabel))->address)) - ((((blockStart->fakeHeader))->address)))); - } - return 0; -} - - -/* Fill in the header for theCogMehtod method. This may be located at the - writable mapping. */ - - /* Cogit>>#fillInMethodHeader:size:selector: */ -static void NoDbgRegParms -fillInMethodHeadersizeselector(CogMethod *method, sqInt size, sqInt selector) -{ - sqInt actualMethodLocation; - CogMethod *originalMethod; - sqInt rawHeader; - - actualMethodLocation = (((usqInt)method)) - codeToDataDelta; - (method->cmType = CMMethod); - (method->objectHeader = nullHeaderForMachineCodeMethod()); - (method->blockSize = size); - (method->methodObject = methodObj); - - /* If the method has already been cogged (e.g. Newspeak accessors) then - leave the original method attached to its cog method, but get the right header. */ - rawHeader = rawHeaderOf(methodObj); - if (isCogMethodReference(rawHeader)) { - originalMethod = ((CogMethod *) rawHeader); - assert(((originalMethod->blockSize)) == size); - assert(methodHeader == ((originalMethod->methodHeader))); - addToUnpairedMethodList(method); - } - else { - rawHeaderOfput(methodObj, actualMethodLocation); - (method->nextMethodOrIRCs = theIRCs); - } - (method->methodHeader = methodHeader); - (method->selector = selector); - (method->cmNumArgs = argumentCountOfMethodHeader(methodHeader)); - (method->cmHasMovableLiteral = hasMovableLiteral); - if ((method->cmRefersToYoung = hasYoungReferent)) { - addToYoungReferrers(method); - } - (method->cmUsageCount = initialMethodUsageCount()); - /* begin cpicHasMNUCase: */ - ((((CogBlockMethod *) method))->cpicHasMNUCaseOrCMIsFullBlock) = 0; - (method->cmUsesPenultimateLit = maxLitIndex >= ((literalCountOfMethodHeader(methodHeader)) - 2)); - (method->blockEntryOffset = (blockEntryLabel != null - ? ((blockEntryLabel->address)) - actualMethodLocation - : 0)); - if (needsFrame) { - if (!((((stackCheckLabel->address)) - actualMethodLocation) <= MaxStackCheckOffset)) { - error("too much code for stack check offset"); - } - } - (method->stackCheckOffset = (needsFrame - ? ((stackCheckLabel->address)) - actualMethodLocation - : 0)); - assert((callTargetFromReturnAddress(backEnd, actualMethodLocation + missOffset)) == (methodAbortTrampolineFor((method->cmNumArgs)))); - assert(size == (roundUpLength(size))); - /* begin assertValidDualZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, actualMethodLocation + cmNoCheckEntryOffset, codeToDataDelta); -# endif - /* begin maybeEnableSingleStep */ -} - - /* Cogit>>#findBackwardBranch:IsBackwardBranch:Mcpc:Bcpc:MatchingBcpc: */ -static sqInt NoDbgRegParms -findBackwardBranchIsBackwardBranchMcpcBcpcMatchingBcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *targetBcpc) -{ - return ((((isBackwardBranchAndAnnotation & 1) != 0)) - && ((((sqInt)targetBcpc)) == bcpc) - ? ((sqInt)mcpc) - : 0); -} - - /* Cogit>>#findBlockMethodWithEntry:startBcpc: */ -static usqInt NoDbgRegParms -findBlockMethodWithEntrystartBcpc(sqInt blockEntryMcpc, sqInt startBcpc) -{ - CogBlockMethod *cogBlockMethod; - - cogBlockMethod = ((CogBlockMethod *) (blockEntryMcpc - (sizeof(CogBlockMethod)))); - if (((cogBlockMethod->startpc)) == startBcpc) { - return ((usqInt)cogBlockMethod); - } - return 0; -} - - /* Cogit>>#findMapLocationForMcpc:inMethod: */ -static usqInt NoDbgRegParms -findMapLocationForMcpcinMethod(usqInt targetMcpc, CogMethod *cogMethod) -{ - sqInt annotation; - usqInt map; - sqInt mapByte; - sqInt mcpc; - - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - if (mcpc == targetMcpc) { - return map; - } - while (((mapByte = byteAt(map))) != MapEnd) { - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - if (annotation != IsAnnotationExtension) { - mcpc += 4 /* codeGranularity */ * ((annotation == IsDisplacementX2N - ? ((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift)) - : mapByte & DisplacementMask)); - } - if (mcpc >= targetMcpc) { - assert(mcpc == targetMcpc); - if (annotation == IsDisplacementX2N) { - map -= 1; - mapByte = byteAt(map); - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - assert(annotation > IsAnnotationExtension); - } - return map; - } - map -= 1; - } - return 0; -} - - -/* Find the CMMethod or CMBlock that has zero-relative startbcpc as its first - bytecode pc. - As this is for cannot resume processing and/or conversion to machine-code - on backward - branch, it doesn't have to be fast. Enumerate block returns and map to - bytecode pcs. */ - - /* Cogit>>#findMethodForStartBcpc:inHomeMethod: */ -CogBlockMethod * -findMethodForStartBcpcinHomeMethod(sqInt startbcpc, CogMethod *cogMethod) -{ - assert(((cogMethod->cmType)) == CMMethod); - if (startbcpc == (startPCOfMethodHeader((cogMethod->methodHeader)))) { - return ((CogBlockMethod *) cogMethod); - } - assert(((cogMethod->blockEntryOffset)) != 0); - return ((CogBlockMethod *) (blockDispatchTargetsForperformarg(cogMethod, findBlockMethodWithEntrystartBcpc, startbcpc))); -} - - -/* Machine code addresses map to the following bytecode for all bytecodes - except backward branches, where they map to the backward branch itself. - This is so that loops continue, rather than terminate prematurely. */ - - /* Cogit>>#find:IsBackwardBranch:Mcpc:Bcpc:MatchingMcpc: */ -static sqInt NoDbgRegParms -findIsBackwardBranchMcpcBcpcMatchingMcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *targetMcpc) -{ - return (targetMcpc == mcpc - ? ((descriptor == null) - || (((isBackwardBranchAndAnnotation & 1) != 0)) - ? bcpc - : bcpc + ((descriptor->numBytes))) - : 0); -} - - /* Cogit>>#firstMappedPCFor: */ -static sqInt NoDbgRegParms -firstMappedPCFor(CogMethod *cogMethod) -{ - return (((usqInt)cogMethod)) + cmNoCheckEntryOffset; -} - - -/* Answer a fake value for the first method oop in the PIC prototype. - Since we use MoveUniqueCw:R: it must not be confused with a - method-relative address. */ - - /* Cogit>>#firstPrototypeMethodOop */ -static sqInt -firstPrototypeMethodOop(void) -{ - return (addressIsInCurrentCompilation(99282957) - ? 212332557 - : 99282957); -} - - /* Cogit>>#fixupAt: */ -static BytecodeFixup * NoDbgRegParms -fixupAt(sqInt fixupPC) -{ - return fixupAtIndex(fixupPC - initialPC); -} - - /* Cogit>>#followForwardedLiteralsIn: */ -void -followForwardedLiteralsIn(CogMethod *cogMethod) -{ - sqInt annotation; - sqInt hasYoungObj; - sqInt hasYoungObjPtr; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - CogMethod * writableCogMethod; - - assert((((cogMethod->cmType)) != CMMethod) - || (!(isForwarded((cogMethod->methodObject))))); - writableCogMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - hasYoungObj = isYoung((cogMethod->methodObject)); - if (shouldRemapOop((cogMethod->selector))) { - (writableCogMethod->selector = remapObj((cogMethod->selector))); - if (isYoung((cogMethod->selector))) { - hasYoungObj = 1; - } - } - hasYoungObjPtr = ((sqInt)((&hasYoungObj))); - /* begin mapFor:performUntil:arg: */ - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = remapIfObjectRefpchasYoung(annotation, (((char *) mcpc)), (((void *)hasYoungObjPtr))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - if (hasYoungObj) { - ensureInYoungReferrers(cogMethod); - } - else { - (writableCogMethod->cmRefersToYoung = 0); - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - /* Cogit>>#followForwardedMethods */ -void -followForwardedMethods(void) -{ - CogMethod * cogMethod; - sqInt freedPIC; - - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - freedPIC = 0; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - if (isForwarded((cogMethod->methodObject))) { - (cogMethod->methodObject = followForwarded((cogMethod->methodObject))); - if (isYoungObject((cogMethod->methodObject))) { - ensureInYoungReferrers(cogMethod); - } - } - } - if (((cogMethod->cmType)) == CMClosedPIC) { - if (followMethodReferencesInClosedPIC(cogMethod)) { - freedPIC = 1; - freeMethod(cogMethod); - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (freedPIC) { - unlinkSendsToFree(); - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - -/* Follow a potential object reference from a closed PIC. - This may be a method reference or null. - Answer if the followed literal is young. - 'mcpc' refers to the jump/branch instruction at the end of - each cpic case */ - - /* Cogit>>#followMaybeObjRefInClosedPICAt: */ -static sqInt NoDbgRegParms -followMaybeObjRefInClosedPICAt(sqInt mcpc) -{ - usqInt object; - sqInt subject; - - object = literalBeforeFollowingAddress(backEnd, mcpc); - if (!(couldBeObject(object))) { - return 0; - } - if (!(isForwarded(object))) { - return isYoungObject(object); - } - subject = followForwarded(object); - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - storeLiteralbeforeFollowingAddress(backEnd, subject, mcpc); - return isYoungObject(subject); -} - - -/* Remap all object references in the closed PIC. Answer if any references - are young. - Set codeModified if any modifications are made. */ - - /* Cogit>>#followMethodReferencesInClosedPIC: */ -static sqInt NoDbgRegParms -followMethodReferencesInClosedPIC(CogMethod *cPIC) -{ - sqInt i; - sqInt pc; - sqInt refersToYoung; - - - /* first we check the potential method oop load at the beginning of the CPIC */ - pc = addressOfEndOfCaseinCPIC(1, cPIC); - - /* We find the end address of the cPICNumCases'th case and can then just step forward by the case size thereafter */ - refersToYoung = followMaybeObjRefInClosedPICAt(pc - (jumpLongByteSize(backEnd))); - - /* Next we check the potential potential method oop load for each case. */ - pc = addressOfEndOfCaseinCPIC((cPIC->cPICNumCases), cPIC); - for (i = 2; i <= ((cPIC->cPICNumCases)); i += 1) { - if (followMaybeObjRefInClosedPICAt((pc - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */)) { - refersToYoung = 1; - } - pc += cPICCaseSize; - } - return refersToYoung; -} - - -/* To avoid runtime checks on literal variable and literal accesses in == and - ~~, - we follow literals in methods having movable literals in the postBecome - action. To avoid scanning every method, we annotate cogMethods with the - cmHasMovableLiteral flag. */ - - /* Cogit>>#followMovableLiteralsAndUpdateYoungReferrers */ -void -followMovableLiteralsAndUpdateYoungReferrers(void) -{ - CogMethod *cogMethod; - - assert(kosherYoungReferrers()); - codeModified = 0; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - if ((cogMethod->cmHasMovableLiteral)) { - followForwardedLiteralsIn(cogMethod); - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - pruneYoungReferrers(); - if (codeModified) { - - /* After updating oops in inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)codeBase), freeStart()); - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - /* Cogit>>#freeCogMethod: */ -void -freeCogMethod(CogMethod *cogMethod) -{ - freeMethod(cogMethod); - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - -/* Free machine-code methods whose compiled methods are unmarked - and open PICs whose selectors are not marked, and closed PICs that - refer to unmarked objects. */ - - /* Cogit>>#freeUnmarkedMachineCode */ -void -freeUnmarkedMachineCode(void) -{ - CogMethod *cogMethod; - sqInt freedMethod; - - freedMethod = 0; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) == CMMethod) - && (!(isMarked((cogMethod->methodObject))))) { - freedMethod = 1; - freeMethod(cogMethod); - } - if ((((cogMethod->cmType)) == CMOpenPIC) - && ((!(isImmediate((cogMethod->selector)))) - && (!(isMarked((cogMethod->selector)))))) { - freedMethod = 1; - freeMethod(cogMethod); - } - if ((((cogMethod->cmType)) == CMClosedPIC) - && (closedPICRefersToUnmarkedObject(cogMethod))) { - freedMethod = 1; - freeMethod(cogMethod); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (freedMethod) { - unlinkSendsToFree(); - } -} - - -/* Call ceSendMustBeBooleanTo: via the relevant trampoline. */ - - /* Cogit>>#genCallMustBeBooleanFor: */ -static AbstractInstruction * NoDbgRegParms -genCallMustBeBooleanFor(sqInt boolean) -{ - AbstractInstruction *abstractInstruction; - sqInt callTarget; - - /* begin CallRT: */ - callTarget = (boolean == (falseObject()) - ? ceSendMustBeBooleanAddFalseTrampoline - : ceSendMustBeBooleanAddTrueTrampoline); - /* begin annotateCall: */ - abstractInstruction = genoperand(Call, callTarget); - (abstractInstruction->annotation = IsRelativeCall); - return abstractInstruction; -} - - /* Cogit>>#genConditionalBranch:operand: */ -static AbstractInstruction * NoDbgRegParms -genConditionalBranchoperand(sqInt opcode, sqInt operandOne) -{ - return noteFollowingConditionalBranch(previousInstruction(), genoperand(opcode, operandOne)); -} - - -/* An enilopmart (the reverse of a trampoline) is a piece of code that makes - the system-call-like transition from the C runtime into generated machine - code. The desired arguments and entry-point are pushed on a stackPage's - stack. The enilopmart pops off the values to be loaded into registers and - then executes a return instruction to pop off the entry-point and jump to - it. - BEFORE AFTER (stacks grow down) - whatever stackPointer -> whatever - target address => reg1 = reg1val, etc - reg1val pc = target address - reg2val - stackPointer -> reg3val */ - - /* Cogit>>#genEnilopmartFor:and:and:forCall:called: */ -static void (*genEnilopmartForandandforCallcalled(sqInt regArg1, sqInt regArg2OrNone, sqInt regArg3OrNone, sqInt forCall, char *trampolineName))(void) - -{ - AbstractInstruction *anInstruction; - sqInt endAddress; - usqInt enilopmart; - sqInt quickConstant; - sqInt size; - - zeroOpcodeIndex(); - /* begin MoveCq:R: */ - quickConstant = varBaseAddress(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - genLoadStackPointers(backEnd); - if (regArg3OrNone != NoReg) { - genoperand(PopR, regArg3OrNone); - } - if (regArg2OrNone != NoReg) { - genoperand(PopR, regArg2OrNone); - } - genoperand(PopR, regArg1); - genEnilopmartReturn(forCall); - computeMaximumSizes(); - size = generateInstructionsAt(methodZoneBase); - endAddress = outputInstructionsAt(methodZoneBase); - assert((methodZoneBase + size) == endAddress); - enilopmart = methodZoneBase; - methodZoneBase = alignUptoRoutineBoundary(endAddress); - stopsFromto(backEnd, endAddress, methodZoneBase - 1); - recordGeneratedRunTimeaddress(trampolineName, enilopmart); - return ((void (*)(void)) enilopmart); -} - - -/* An enilopmart (the reverse of a trampoline) is a piece of code that makes - the system-call-like transition from the C runtime into generated machine - code. At the point the enilopmart enters machine code via a return - instruction, any argument registers have been loaded with their values and - the stack, if - for call, looks like - ret pc - stackPointer -> target address - - and if not for call, looks like - whatever - stackPointer -> target address - - If forCall and running on a CISC, ret pc must be left on the stack. If - forCall and - running on a RISC, ret pc must be popped into LinkReg. In either case, - target address must be removed from the stack and jumped/returned to. */ - - /* Cogit>>#genEnilopmartReturn: */ -static void NoDbgRegParms -genEnilopmartReturn(sqInt forCall) -{ - if (forCall) { - genoperand(PopR, RISCTempReg); - genoperand(PopR, LinkReg); - genoperand(JumpR, RISCTempReg); - } - else { - genoperand(PopR, RISCTempReg); - genoperand(JumpR, RISCTempReg); - } -} - - -/* Generate the routine that writes the current values of the C frame and - stack pointers into - variables. These are used to establish the C stack in trampolines back - into the C run-time. - This routine assumes the system's frame pointer is the same as that used - in generated code. */ - - /* Cogit>>#generateCaptureCStackPointers: */ -static void NoDbgRegParms NeverInline -generateCaptureCStackPointers(sqInt captureFramePointer) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - sqInt callerSavedReg; - sqInt fixupSize; - sqInt offset; - sqInt opcodeSize; - sqInt pushedVarBaseReg; - sqInt quickConstant; - usqInt startAddress; - - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 32; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - - /* Must happen first; value may be used in accessing any of the following addresses */ - startAddress = methodZoneBase; - callerSavedReg = 0; - pushedVarBaseReg = 0; - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { - - /* VarBaseReg is not caller-saved; must save and restore it, either by using an available caller-saved reg or push/pop. */ - - /* TempReg used below */ - callerSavedReg = availableRegisterOrNoneIn(((ABICallerSavedRegisterMask | (1U << TempReg)) - (1U << TempReg))); - if (callerSavedReg == NoReg) { - gNativePushR(VarBaseReg); - pushedVarBaseReg = 1; - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, VarBaseReg, callerSavedReg); - } - } - /* begin MoveCq:R: */ - quickConstant = varBaseAddress(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - if (captureFramePointer) { - /* begin checkLiteral:forInstruction: */ - cFramePointerAddress(); - anInstruction1 = genoperandoperand(MoveRAw, FPReg, cFramePointerAddress()); - } - if (pushedVarBaseReg) { - /* begin LoadEffectiveAddressMw:r:R: */ - offset = (pushedVarBaseReg - ? 0 /* leafCallStackPointerDelta */ + BytesPerWord - : 0 /* leafCallStackPointerDelta */); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(LoadEffectiveAddressMwrR, offset, NativeSPReg, TempReg); - /* begin checkLiteral:forInstruction: */ - cStackPointerAddress(); - anInstruction3 = genoperandoperand(MoveRAw, TempReg, cStackPointerAddress()); - } - else { - /* begin checkLiteral:forInstruction: */ - cStackPointerAddress(); - anInstruction4 = genoperandoperand(MoveRAw, NativeSPReg, cStackPointerAddress()); - } - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { - if (pushedVarBaseReg) { - gNativePopR(VarBaseReg); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, callerSavedReg, VarBaseReg); - } - } - gNativeRetN(0); - outputInstructionsForGeneratedRuntimeAt(startAddress); - flushICacheFromto(backEnd, ((usqInt)startAddress), ((usqInt)methodZoneBase)); - recordGeneratedRunTimeaddress("ceCaptureCStackPointers", startAddress); - ceCaptureCStackPointers = ((void (*)(void)) startAddress); -} - - -/* Generate the prototype ClosedPIC to determine how much space a full closed - PIC takes. - When we first allocate a closed PIC it only has one or two cases and we - want to grow it. - So we have to determine how big a full one is before hand. */ -/* stack allocate the various collections so that they - are effectively garbage collected on return. */ - - /* Cogit>>#generateClosedPICPrototype */ -static void -generateClosedPICPrototype(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - CogMethod * cPIC; - AbstractInstruction * cPICEndOfCodeLabel; - sqInt endAddress; - AbstractInstruction * endCPICCase1; - sqInt fixupSize; - sqInt h; - AbstractInstruction *jumpNext; - sqInt jumpTarget; - sqInt jumpTarget1; - sqInt jumpTarget2; - sqInt numArgs; - sqInt opcode; - sqInt opcodeSize; - sqInt wordConstant; - sqInt wordConstant1; - - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = MaxCPICCases * 9; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - (methodLabel->address = methodZoneBase); - (methodLabel->dependent = null); - /* begin compileClosedPICPrototype */ - compilePICAbort((numArgs = 0)); - - /* At the end of the entry code we need to jump to the first case code, which is actually the last chunk. - On each entension we must update this jump to move back one case. */ - jumpNext = compileCPICEntry(); - /* begin MoveUniqueCw:R: */ - wordConstant1 = firstPrototypeMethodOop(); - /* begin uniqueLiteral:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCwR, wordConstant1, SendNumArgsReg); - /* begin JumpLong: */ - jumpTarget1 = (((methodZoneBase + (youngReferrers())) / 2) - 13262352) + 13262352; - genoperand(JumpLong, jumpTarget1); - endCPICCase0 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - for (h = 1; h < MaxCPICCases; h += 1) { - if (h == (MaxCPICCases - 1)) { - jmpTarget(jumpNext, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - /* begin MoveUniqueCw:R: */ - wordConstant = (subsequentPrototypeMethodOop()) + h; - /* begin uniqueLiteral:forInstruction: */ - anInstruction = genoperandoperand(MoveCwR, wordConstant, SendNumArgsReg); - /* begin gen:literal32:operand: */ - opcode = CmpCwR; - /* begin checkLiteral32:forInstruction: */ - anInstruction1 = genoperandoperand(opcode, 3133021973U + h, TempReg); - /* begin JumpLongZero: */ - jumpTarget = ((((methodZoneBase + (youngReferrers())) / 2) - 13262352) + 13262352) + (h * 16); - genConditionalBranchoperand(JumpLongZero, ((sqInt)jumpTarget)); - if (h == 1) { - endCPICCase1 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - } - /* begin checkLiteral:forInstruction: */ - (methodLabel->address); - anInstruction3 = genoperandoperand(MoveCwR, (methodLabel->address), ClassReg); - /* begin JumpLong: */ - jumpTarget2 = cPICMissTrampolineFor(numArgs); - genoperand(JumpLong, jumpTarget2); - cPICEndOfCodeLabel = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - computeMaximumSizes(); - cPIC = ((CogMethod *) methodZoneBase); - closedPICSize = (sizeof(CogMethod)) + (generateInstructionsAt(methodZoneBase + (sizeof(CogMethod)))); - endAddress = outputInstructionsAt(methodZoneBase + (sizeof(CogMethod))); - assert((methodZoneBase + closedPICSize) == endAddress); - firstCPICCaseOffset = ((endCPICCase0->address)) - methodZoneBase; - cPICEndOfCodeOffset = ((cPICEndOfCodeLabel->address)) - methodZoneBase; - cPICCaseSize = ((endCPICCase1->address)) - ((endCPICCase0->address)); - cPICEndSize = closedPICSize - (((MaxCPICCases - 1) * cPICCaseSize) + firstCPICCaseOffset); - closedPICSize = roundUpToMethodAlignment(backEnd(), closedPICSize); - assert(((picInterpretAbort->address)) == (((methodLabel->address)) + (picInterpretAbortOffset()))); - assert((expectedClosedPICPrototype(cPIC)) == 0); - storeLiteralbeforeFollowingAddress(backEnd, 0, ((endCPICCase0->address)) - (jumpLongByteSize(backEnd))); - methodZoneBase = alignUptoRoutineBoundary(endAddress); - cPICPrototype = cPIC; -} - - -/* We handle jump sizing simply. First we make a pass that asks each - instruction to compute its maximum size. Then we make a pass that - sizes jumps based on the maxmimum sizes. Then we make a pass - that fixes up jumps. When fixing up a jump the jump is not allowed to - choose a smaller offset but must stick to the size set in the second pass. */ - - /* Cogit>>#generateCogMethod: */ -static CogMethod * NoDbgRegParms -generateCogMethod(sqInt selector) -{ - sqInt codeSize; - usqIntptr_t headerSize; - sqInt mapSize; - sqInt result; - usqInt startAddress; - sqInt totalSize; - - headerSize = sizeof(CogMethod); - (methodLabel->address = freeStart()); - computeMaximumSizes(); - concretizeAt(methodLabel, freeStart()); - codeSize = generateInstructionsAt(((methodLabel->address)) + headerSize); - mapSize = generateMapAtstart(null, ((methodLabel->address)) + cmNoCheckEntryOffset); - totalSize = roundUpToMethodAlignment(backEnd(), (headerSize + codeSize) + mapSize); - if (totalSize > MaxMethodSize) { - return ((CogMethod *) MethodTooBig); - } - startAddress = allocate(totalSize); - if (startAddress == 0) { - return ((CogMethod *) InsufficientCodeSpace); - } - assert((startAddress + cmEntryOffset) == ((entry->address))); - assert((startAddress + cmNoCheckEntryOffset) == ((noCheckEntry->address))); - result = outputInstructionsAt(startAddress + headerSize); - assert(((startAddress + headerSize) + codeSize) == result); - padIfPossibleWithStopsFromto(backEnd, result, ((startAddress + totalSize) - mapSize) - 1); - generateMapAtstart((startAddress + totalSize) - 1, startAddress + cmNoCheckEntryOffset); - fillInBlockHeadersAt(startAddress); - fillInMethodHeadersizeselector(((CogMethod *) ((((usqInt)startAddress)) + codeToDataDelta)), totalSize, selector); - flushICacheFromto(backEnd, startAddress, startAddress + totalSize); - return ((CogMethod *) startAddress); -} - - -/* Generate the method map at addressrNull (or compute it if addressOrNull is - null). Answer the length of the map in byes. Each entry in the map is in - two parts. In the - least signficant bits are a displacement of how far from the start or - previous entry, - unless it is an IsAnnotationExtension byte, in which case those bits are - the extension. - In the most signficant bits are the type of annotation at the point - reached. A null - byte ends the map. */ - - /* Cogit>>#generateMapAt:start: */ -static sqInt NoDbgRegParms -generateMapAtstart(usqInt addressOrNull, usqInt startAddress) -{ - unsigned char annotation; - sqInt delta; - sqInt i; - AbstractInstruction *instruction; - sqInt length; - usqInt location; - sqInt mapEntry; - sqInt maxDelta; - usqInt mcpc; - - length = 0; - location = startAddress; - for (i = 0; i < opcodeIndex; i += 1) { - instruction = abstractInstructionAt(i); - annotation = (instruction->annotation); - if (!(annotation == null)) { - /* begin mapEntryAddress */ - mcpc = ((instruction->address)) + ((instruction->machineCodeSize)); - while (((delta = (mcpc - location) / 4 /* codeGranularity */)) > DisplacementMask) { - maxDelta = (((((delta < MaxX2NDisplacement) ? delta : MaxX2NDisplacement)) | DisplacementMask) - DisplacementMask); - assert((((usqInt)(maxDelta)) >> AnnotationShift) <= DisplacementMask); - if (!(addressOrNull == null)) { - /* begin addToMap:instruction:byte:at:for: */ - codeByteAtput(addressOrNull - length, (((usqInt)(maxDelta)) >> AnnotationShift) + DisplacementX2N); - } - location += maxDelta * 4 /* codeGranularity */; - length += 1; - } - if (!(addressOrNull == null)) { - mapEntry = delta + (((sqInt)((usqInt)((((annotation < IsSendCall) ? annotation : IsSendCall))) << AnnotationShift))); - /* begin addToMap:instruction:byte:at:for: */ - codeByteAtput(addressOrNull - length, mapEntry); - } - location += delta * 4 /* codeGranularity */; - length += 1; - if (annotation > IsSendCall) { - - /* Add the necessary IsAnnotationExtension */ - if (!(addressOrNull == null)) { - mapEntry = (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift))) + (annotation - IsSendCall); - /* begin addToMap:instruction:byte:at:for: */ - codeByteAtput(addressOrNull - length, mapEntry); - } - length += 1; - } - } - } - if (!(addressOrNull == null)) { - /* begin addToMap:instruction:byte:at:for: */ - codeByteAtput(addressOrNull - length, MapEnd); - } - return length + 1; -} - - -/* Generate the non-send runtime support for Newspeak: push enclosing object. - The dynamic frequency is so low we merely call an interpreter routine. */ - - /* Cogit>>#generateNewspeakRuntime */ -static void -generateNewspeakRuntime(void) -{ - ceEnclosingObjectTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceEnclosingObjectAt, "ceEnclosingObjectTrampoline", 1, SendNumArgsReg, null, null, null, 0 /* emptyRegisterMask */, 1, ReceiverResultReg, 0); -} - - -/* Self send, dynamic super send, implicit receiver send, and outer send */ - - /* Cogit>>#generateNewspeakSendTrampolines */ -static void -generateNewspeakSendTrampolines(void) -{ - sqInt numArgs; - - for (numArgs = 0; numArgs < NumSendTrampolines; numArgs += 1) { - selfSendTrampolines[numArgs] = (genNSSendTrampolineFornumArgsenclosingObjectCheckcalled(ceSelfSendreceiver, numArgs, 0, trampolineNamenumArgs("ceSelfSend", numArgs))); - } - for (numArgs = 0; numArgs < NumSendTrampolines; numArgs += 1) { - dynamicSuperSendTrampolines[numArgs] = (genNSSendTrampolineFornumArgsenclosingObjectCheckcalled(ceDynamicSuperSendreceiver, numArgs, 0, trampolineNamenumArgs("ceDynamicSuperSend", numArgs))); - } - for (numArgs = 0; numArgs < NumSendTrampolines; numArgs += 1) { - implicitReceiverSendTrampolines[numArgs] = (genNSSendTrampolineFornumArgsenclosingObjectCheckcalled(ceImplicitReceiverSendreceiver, numArgs, 1, trampolineNamenumArgs("ceImplicitReceiverSend", numArgs))); - } - for (numArgs = 0; numArgs < NumSendTrampolines; numArgs += 1) { - outerSendTrampolines[numArgs] = (genNSSendTrampolineFornumArgsenclosingObjectCheckcalled(ceOuterSendreceiver, numArgs, 1, trampolineNamenumArgs("ceOuterSend", numArgs))); - } -} - - -/* Generate the prototype OpenPIC to determine how much space an open PIC - takes. - */ -/* stack allocate the various collections so that they - are effectively garbage collected on return. */ - - /* Cogit>>#generateOpenPICPrototype */ -static void -generateOpenPICPrototype(void) -{ - sqInt codeSize; - sqInt fixupSize; - sqInt mapSize; - sqInt opcodeSize; - - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 100; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - (methodLabel->address = methodZoneBase); - (methodLabel->dependent = null); - compileOpenPICnumArgs(specialSelector(0), 2 /* numRegArgs */); - computeMaximumSizes(); - concretizeAt(methodLabel, methodZoneBase); - codeSize = generateInstructionsAt(methodZoneBase + (sizeof(CogMethod))); - mapSize = generateMapAtstart(null, methodZoneBase + cmNoCheckEntryOffset); - openPICSize = (roundUpLength((sizeof(CogMethod)) + codeSize)) + (roundUpToMethodAlignment(backEnd(), mapSize)); -} - - -/* Generate the run-time entries at the base of the native code zone and - update the base. - */ - - /* Cogit>>#generateRunTimeTrampolines */ -static void -generateRunTimeTrampolines(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction2; - - ceSendMustBeBooleanAddFalseTrampoline = genMustBeBooleanTrampolineForcalled(falseObject(), "ceSendMustBeBooleanAddFalseTrampoline"); - ceSendMustBeBooleanAddTrueTrampoline = genMustBeBooleanTrampolineForcalled(trueObject(), "ceSendMustBeBooleanAddTrueTrampoline"); - /* begin genNonLocalReturnTrampoline */ - zeroOpcodeIndex(); - /* begin checkLiteral:forInstruction: */ - instructionPointerAddress(); - anInstruction2 = genoperandoperand(MoveRAw, LinkReg, instructionPointerAddress()); - ceNonLocalReturnTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNonLocalReturn, "ceNonLocalReturnTrampoline", 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 0, NoReg, 1); - /* begin genCheckForInterruptsTrampoline */ - zeroOpcodeIndex(); - /* begin checkLiteral:forInstruction: */ - instructionPointerAddress(); - anInstruction = genoperandoperand(MoveRAw, LinkReg, instructionPointerAddress()); - ceCheckForInterruptTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceCheckForInterrupt, "ceCheckForInterruptTrampoline", 0, null, null, null, null, 0 /* emptyRegisterMask */, 0, NoReg, 1); - ceFetchContextInstVarTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceContextinstVar, "ceFetchContextInstVarTrampoline", 2, ReceiverResultReg, SendNumArgsReg, null, null, 0 /* emptyRegisterMask */, 1, SendNumArgsReg, 0); - ceStoreContextInstVarTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceContextinstVarvalue, "ceStoreContextInstVarTrampoline", 3, ReceiverResultReg, SendNumArgsReg, ClassReg, null, 0 /* emptyRegisterMask */, 1, ReceiverResultReg, 0); - - /* ceInvokeInterpreter is an optimization and a work-around. Historically we used setjmp/longjmp to reenter the - interpreter at the current C stack base. The C stack base is set at start-up and on each callback enter and - callback return. The interpreter must be invoked whenever a non-machine-code method must be run. That might - be when invoking an interpreter method from one of the send linking routines (ceSend:...), or on continuing from - an evaluation primitive such as primitiveExecuteMethod. The problem here is that such primitives could have - been invoked by the interpreter or by machine code. So some form of non-local jump is required. But at least as - early as MSVC Community 2017, the Microshaft longjmp performs stack unwinding which gets hoplessly confused - (bless its little heart) by any stack switch between machine code and C stack, and raises a spurious - Stack cookie instrumentation code detected a stack-based buffer overrun - error from the bowels of gs_report.c _GSHandlerCheck. - Since the CoInterpreter maintains the base of the C stack in CFramePointer & CStackPointer, it is straight-forward - for us to simply call interpret after doing the switch to the C stack, avoiding the stack unwind issue altogether. */ - ceCannotResumeTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceCannotResume, "ceCannotResumeTrampoline", 0, null, null, null, null, 0 /* emptyRegisterMask */, 1, NoReg, 0); - - /* These two are unusual; they are reached by return instructions. */ - ceInvokeInterpret = genInvokeInterpretTrampoline(); - ceReturnToInterpreterTrampoline = genReturnToInterpreterTrampoline(); - ceBaseFrameReturnTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceBaseFrameReturn, "ceBaseFrameReturnTrampoline", 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 0, NoReg, 0); - } - - -/* Generate a routine ceCaptureCStackPointers that will capture the C stack - pointer, and, if it is in use, the C frame pointer. These are used in - trampolines to call - run-time routines in the interpreter from machine-code. */ - - /* Cogit>>#generateStackPointerCapture */ -static void -generateStackPointerCapture(void) -{ - usqInt oldMethodZoneBase; - sqInt oldTrampolineTableIndex; - - - /* For the benefit of the following assert, assume the minimum at first. */ - cFramePointerInUse = 0; - assertCStackWellAligned(); - oldMethodZoneBase = methodZoneBase; - oldTrampolineTableIndex = trampolineTableIndex; - generateCaptureCStackPointers(1); - ceCaptureCStackPointers(); - if (!((cFramePointerInUse = checkIfCFramePointerInUse()))) { - methodZoneBase = oldMethodZoneBase; - trampolineTableIndex = oldTrampolineTableIndex; - generateCaptureCStackPointers(0); - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - assertCStackWellAligned(); -} - - -/* Generate the run-time entries and exits at the base of the native code - zone and update the base. - Read the class-side method trampolines for documentation on the various - trampolines - */ - - /* Cogit>>#generateTrampolines */ -static void -generateTrampolines(void) -{ - sqInt fixupSize; - usqInt methodZoneStart; - sqInt opcodeSize; - - methodZoneStart = methodZoneBase; - (methodLabel->address = methodZoneStart); - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 80; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - setHasYoungReferent(0); - generateSendTrampolines(); - generateMissAbortTrampolines(); - generateObjectRepresentationTrampolines(); - generateRunTimeTrampolines(); - generateNewspeakRuntime(); - generateEnilopmarts(); - generateTracingTrampolines(); - recordGeneratedRunTimeaddress("methodZoneBase", methodZoneBase); -} - - /* Cogit>>#generatorForPC: */ -static BytecodeDescriptor * NoDbgRegParms -generatorForPC(sqInt pc) -{ - return generatorAt(bytecodeSetOffset + (fetchByteofObject(pc, methodObj))); -} - - -/* Generate a pair of routines that answer the frame pointer, and the stack - pointer immediately - after a leaf call, used for checking stack pointer alignment, frame - pointer usage, etc. N.B. - these are exported to the CoInterpreter et al via Cogit - class>>mustBeGlobal:. - */ - - /* Cogit>>#genGetLeafCallStackPointers */ -static void -genGetLeafCallStackPointers(void) -{ - sqInt fixupSize; - sqInt opcodeSize; - usqInt startAddress; - - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 4; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - startAddress = methodZoneBase; - genoperandoperand(MoveRR, FPReg, ABIResultReg); - genoperand(RetN, 0); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress("ceGetFP", startAddress); - ceGetFP = ((usqIntptr_t (*)(void)) startAddress); - startAddress = methodZoneBase; - zeroOpcodeIndex(); - genoperandoperand(MoveRR, NativeSPReg, ABIResultReg); - genoperand(RetN, 0); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress("ceGetSP", startAddress); - ceGetSP = ((usqIntptr_t (*)(void)) startAddress); -} - - -/* Generate the abort for a PIC. This abort performs either a call of - ceInterpretMethodFromPIC:receiver: to handle invoking an uncogged target - or a call of ceMNUFromPICMNUMethod:receiver: to handle an MNU dispatch - in a closed PIC. It distinguishes the two by testing ClassReg. If the - register is zero then this is an MNU. - - This poses a problem in 32-bit Spur, where zero is the cache tag for - immediate characters (tag pattern 2r10) because SmallIntegers have tag - patterns 2r11 - and 2r01, so anding with 1 reduces these to 0 & 1. We solve the ambiguity - by patching send sites with a 0 cache tag to open PICs instead of closed - PICs. */ - - /* Cogit>>#genInnerPICAbortTrampoline: */ -static usqInt NoDbgRegParms -genInnerPICAbortTrampoline(char *name) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *jumpMNUCase; - - /* begin CmpCq:R: */ - anInstruction = genoperandoperand(CmpCqR, 0 /* picAbortDiscriminatorValue */, ClassReg); - jumpMNUCase = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(ceInterpretMethodFromPICreceiver, 2, SendNumArgsReg, ReceiverResultReg, null, null, 0 /* emptyRegisterMask */, 0, NoReg); - jmpTarget(jumpMNUCase, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceMNUFromPICMNUMethodreceiver, name, 2, SendNumArgsReg, ReceiverResultReg, null, null, 0 /* emptyRegisterMask */, 0, NoReg, 1); -} - - -/* Switch to the C stack (do *not* save the Smalltalk stack pointers; - this is the caller's responsibility), and invoke interpret PDQ. */ - - /* Cogit>>#genInvokeInterpretTrampoline */ -static void (*genInvokeInterpretTrampoline(void))(void) - -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - sqInt quickConstant; - usqInt startAddress; - - startAddress = methodZoneBase; - zeroOpcodeIndex(); - /* begin MoveCq:R: */ - quickConstant = varBaseAddress(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - if (cFramePointerInUse) { - genLoadCStackPointers(backEnd); - } - else { - genLoadCStackPointer(backEnd); - } - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l16; - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction5 = genoperandoperand(MoveCqR, -2 - null, A0); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A0); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction11 = genoperandoperand(MoveCqR, -2 - null, A1); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A1); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction21 = genoperandoperand(MoveCqR, -2 - null, A2); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A2); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction31 = genoperandoperand(MoveCqR, -2 - null, A3); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A3); - } - l16: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin checkLiteral:forInstruction: */ - cReturnAddressAddress(); - anInstruction1 = genoperandoperand(MoveAwR, cReturnAddressAddress(), LinkReg); - /* begin checkLiteral:forInstruction: */ - ((sqInt)(((usqInt)interpret))); - anInstruction4 = genoperand(JumpFull, ((sqInt)(((usqInt)interpret)))); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress("ceInvokeInterpret", startAddress); - return ((void (*)(void)) startAddress); -} - - -/* The in-line cache for a send is implemented as a constant load into - ClassReg. We always use a 32-bit load, even in 64-bits. - - In the initial (unlinked) state the in-line cache is notionally loaded - with the selector. - But since in 64-bits an arbitrary selector oop won't fit in a 32-bit - constant load, we - instead load the cache with the selector's index, either into the literal - frame of the - current method, or into the special selector array. Negative values are - 1-relative indices into the special selector array. - - When a send is linked, the load of the selector, or selector index, is - overwritten with a - load of the receiver's class, or class tag. Hence, the 64-bit VM is - currently constrained - to use class indices as cache tags. If out-of-line literals are used, - distinct caches /must - not/ share acche locations, for if they do, send cacheing will be confused - by the sharing. - Hence we use the MoveUniqueC32:R: instruction that will not share literal - locations. */ - - /* Cogit>>#genLoadInlineCacheWithSelector: */ -static void NoDbgRegParms -genLoadInlineCacheWithSelector(sqInt selectorIndex) -{ - AbstractInstruction *anInstruction; - sqInt cacheValue; - sqInt opcode; - sqInt selector; - - assert((selectorIndex < 0 - ? (((-selectorIndex) >= 1) && ((-selectorIndex) <= (numSpecialSelectors()))) - : ((selectorIndex >= 0) && (selectorIndex <= ((literalCountOf(methodObj)) - 1))))); - selector = (selectorIndex < 0 - ? specialSelector(-1 - selectorIndex) - : getLiteral(selectorIndex)); - assert(addressCouldBeOop(selector)); - if (isNonImmediate(selector)) { - setHasMovableLiteral(1); - } - if (isYoung(selector)) { - setHasYoungReferent(1); - } - cacheValue = selector; - /* begin gen:uniqueLiteral32:operand: */ - opcode = MoveCwR; - /* begin uniqueLiteral32:forInstruction: */ - anInstruction = genoperandoperand(opcode, cacheValue, ClassReg); -} - - -/* ReceiverResultReg: method receiver - SendNumArgsReg: the NSSendCache cache */ - - /* Cogit>>#genNSSendTrampolineFor:numArgs:enclosingObjectCheck:called: */ -static usqInt NoDbgRegParms -genNSSendTrampolineFornumArgsenclosingObjectCheckcalled(void *aRoutine, sqInt numArgs, sqInt eoCheckFlag, char *aString) -{ - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *jumpItsTheReceiverStupid; - AbstractInstruction *jumpMiss; - sqInt offset; - - zeroOpcodeIndex(); - genGetInlineCacheClassTagFromintoforEntry(ReceiverResultReg, ClassReg, 0); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(MoveMwrR, NSCClassTagIndex * BytesPerWord, SendNumArgsReg, TempReg); - /* begin CmpR:R: */ - assert(!((ClassReg == SPReg))); - genoperandoperand(CmpRR, ClassReg, TempReg); - jumpMiss = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - if (eoCheckFlag) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperandoperand(MoveMwrR, NSCEnclosingObjectIndex * BytesPerWord, SendNumArgsReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, TempReg); - jumpItsTheReceiverStupid = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - if (numArgs > 2 /* numRegArgs */) { - if (numArgs >= (NumSendTrampolines - 1)) { - - /* arbitrary argument count */ - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveMwrR, NSCNumArgsIndex * BytesPerWord, SendNumArgsReg, TempReg); - genoperandoperandoperand(MoveRXwrR, ReceiverResultReg, TempReg, SPReg); - } - else { - - /* Known argument count */ - /* begin MoveR:Mw:r: */ - offset = ((0) + numArgs) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperandoperand(MoveRMwr, TempReg, offset, SPReg); - } - } - jmpTarget(jumpItsTheReceiverStupid, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperandoperand(MoveMwrR, NSCTargetIndex * BytesPerWord, SendNumArgsReg, TempReg); - genoperand(JumpR, TempReg); - jmpTarget(jumpMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genEnsureOopInRegNotForwardedscratchRegupdatingMwr(ReceiverResultReg, TempReg, FoxMFReceiver, FPReg); - genPushRegisterArgsForNumArgsscratchReg(backEnd, numArgs, TempReg); - return genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(aRoutine, aString, 2, SendNumArgsReg, ReceiverResultReg, null, null, 0 /* emptyRegisterMask */, 1, NoReg, 1); -} - - /* Cogit>>#genReturnToInterpreterTrampoline */ -static usqInt -genReturnToInterpreterTrampoline(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - usqInt startAddress; - - startAddress = methodZoneBase; - zeroOpcodeIndex(); - genoperand(PushR, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperandoperand(MoveMwrR, FoxIFSavedIP, FPReg, TempReg); - /* begin checkLiteral:forInstruction: */ - instructionPointerAddress(); - anInstruction5 = genoperandoperand(MoveRAw, TempReg, instructionPointerAddress()); - genSmalltalkToCStackSwitch(0); - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l17; - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction6 = genoperandoperand(MoveCqR, -2 - null, A0); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A0); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction11 = genoperandoperand(MoveCqR, -2 - null, A1); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A1); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction21 = genoperandoperand(MoveCqR, -2 - null, A2); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A2); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction31 = genoperandoperand(MoveCqR, -2 - null, A3); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A3); - } - l17: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin checkLiteral:forInstruction: */ - cReturnAddressAddress(); - anInstruction = genoperandoperand(MoveAwR, cReturnAddressAddress(), LinkReg); - /* begin checkLiteral:forInstruction: */ - ((sqInt)(((usqInt)interpret))); - anInstruction3 = genoperand(JumpFull, ((sqInt)(((usqInt)interpret)))); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress("ceReturnToInterpreterTrampoline", startAddress); - return startAddress; -} - - -/* If the client requires, then on an ARM-like RISC processor, the return - address needs to - be pushed to the stack so that the interpreter sees the same stack layout - as on CISC. - */ - - /* Cogit>>#genSmalltalkToCStackSwitch: */ -static sqInt NoDbgRegParms -genSmalltalkToCStackSwitch(sqInt pushLinkReg) -{ - if (pushLinkReg) { - genoperand(PushR, LinkReg); - } - genSaveStackPointers(backEnd); - if (cFramePointerInUse) { - genLoadCStackPointers(backEnd); - } - else { - genLoadCStackPointer(backEnd); - } - return 0; -} - - -/* Generate a trampoline with up to four arguments. Generate either a call or - a jump to aRoutineOrNil - as requested by callJumpBar. If generating a call and resultRegOrNone is - not NoReg pass the C result - back in resultRegOrNone. - Hack: a negative value indicates an abstract register, a non-negative - value indicates a constant. */ - - /* Cogit>>#genTrampolineFor:called:numArgs:arg:arg:arg:arg:regsToSave:pushLinkReg:resultReg:appendOpcodes: */ -static usqInt NoDbgRegParms -genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(void *aRoutine, char *trampolineName, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone, sqInt appendBoolean) -{ - usqInt startAddress; - - startAddress = methodZoneBase; - if (!appendBoolean) { - zeroOpcodeIndex(); - } - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(aRoutine, numArgs, regOrConst0, regOrConst1, regOrConst2, regOrConst3, regMask, pushLinkReg, resultRegOrNone); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress(trampolineName, startAddress); - recordRunTimeObjectReferences(); - /* begin assertValidDualZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, codeBase + cmNoCheckEntryOffset, codeToDataDelta); -# endif - return startAddress; -} - - -/* To return from a trampoline call we have to take the return address off - the stack, - iof it has been saved */ - - /* Cogit>>#genTrampolineReturn: */ -static void NoDbgRegParms -genTrampolineReturn(sqInt lnkRegWasPushed) -{ - if (lnkRegWasPushed - && (1)) { - genoperand(PopR, LinkReg); - genoperand(RetN, 0); - } - else { - genoperand(RetN, 0); - } -} - - -/* */ - - /* Cogit>>#gen: */ -static AbstractInstruction * NoDbgRegParms -gen(sqInt opcode) -{ - AbstractInstruction *abstractInstruction; - - assert(opcodeIndex < numAbstractOpcodes); - abstractInstruction = abstractInstructionAt(opcodeIndex); - opcodeIndex += 1; - (abstractInstruction->opcode = opcode); - return abstractInstruction; -} - - -/* */ -/* */ - - /* Cogit>>#gen:operand: */ -static AbstractInstruction * NoDbgRegParms -genoperand(sqInt opcode, sqInt operand) -{ - AbstractInstruction *abstractInstruction; - - assert(opcodeIndex < numAbstractOpcodes); - abstractInstruction = abstractInstructionAt(opcodeIndex); - opcodeIndex += 1; - (abstractInstruction->opcode = opcode); - ((abstractInstruction->operands))[0] = operand; - return abstractInstruction; -} - - -/* */ -/* */ -/* */ - - /* Cogit>>#gen:operand:operand: */ -static AbstractInstruction * NoDbgRegParms -genoperandoperand(sqInt opcode, sqInt operandOne, sqInt operandTwo) -{ - AbstractInstruction *abstractInstruction; - - assert(opcodeIndex < numAbstractOpcodes); - abstractInstruction = abstractInstructionAt(opcodeIndex); - opcodeIndex += 1; - (abstractInstruction->opcode = opcode); - ((abstractInstruction->operands))[0] = operandOne; - ((abstractInstruction->operands))[1] = operandTwo; - return abstractInstruction; -} - - -/* */ -/* */ -/* */ -/* */ - - /* Cogit>>#gen:operand:operand:operand: */ -static AbstractInstruction * NoDbgRegParms -genoperandoperandoperand(sqInt opcode, sqInt operandOne, sqInt operandTwo, sqInt operandThree) -{ - AbstractInstruction *abstractInstruction; - - assert(opcodeIndex < numAbstractOpcodes); - abstractInstruction = abstractInstructionAt(opcodeIndex); - opcodeIndex += 1; - (abstractInstruction->opcode = opcode); - ((abstractInstruction->operands))[0] = operandOne; - ((abstractInstruction->operands))[1] = operandTwo; - ((abstractInstruction->operands))[2] = operandThree; - return abstractInstruction; -} - - /* Cogit>>#getLiteral: */ -static sqInt NoDbgRegParms -getLiteral(sqInt litIndex) -{ - if (maxLitIndex < litIndex) { - maxLitIndex = litIndex; - } - return literalofMethod(litIndex, methodObj); -} - - /* Cogit>>#incrementUsageOfTargetIfLinkedSend:mcpc:ignored: */ -static sqInt NoDbgRegParms -incrementUsageOfTargetIfLinkedSendmcpcignored(sqInt annotation, char *mcpc, sqInt superfluity) -{ - usqInt cacheAddress; - usqInt entryPoint; - usqInt entryPoint1; - char *mcpc1; - NSSendCache *nsSendCache; - sqInt offset1; - sqInt *sendTable1; - CogMethod * targetMethod; - CogMethod *targetMethod1; - - if (annotation == IsNSSendCall) { - /* begin nsSendCacheFromReturnAddress: */ - mcpc1 = ((char *) (((sqInt)mcpc))); - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc1)); - assert(entryPoint1 < methodZoneBase); - cacheAddress = ((usqInt)(nsSendCacheAt(backEnd, mcpc1))); - assert(isInOldSpace(cacheAddress)); - nsSendCache = ((NSSendCache *) cacheAddress); - if (((nsSendCache->classTag)) != 2 /* illegalClassTag */) { - - /* send is linked */ - entryPoint = (nsSendCache->target); - targetMethod = ((CogMethod *) ((((usqInt)(entryPoint - cmNoCheckEntryOffset))) + codeToDataDelta)); - assertValidDualZoneWriteAddress(targetMethod); - if (((targetMethod->cmUsageCount)) < (CMMaxUsageCount / 2)) { - (targetMethod->cmUsageCount = ((targetMethod->cmUsageCount)) + 1); - } - } - } - if (annotation >= IsSendCall) { - assert(annotation != IsNSSendCall); - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - if (annotation == IsNSSelfSend) { - offset1 = cmEntryOffset; - sendTable1 = selfSendTrampolines; - } - else { - if (annotation == IsNSDynamicSuperSend) { - offset1 = cmEntryOffset; - sendTable1 = dynamicSuperSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (((targetMethod1->cmUsageCount)) < (CMMaxUsageCount / 2)) { - ((((CogMethod *) ((((usqInt)targetMethod1)) + codeToDataDelta)))->cmUsageCount = ((targetMethod1->cmUsageCount)) + 1); - } - } - } - return 0; -} - - -/* Answer a usage count that reflects likely long-term usage. */ - - /* Cogit>>#initialClosedPICUsageCount */ -static sqInt -initialClosedPICUsageCount(void) -{ - return CMMaxUsageCount / 2; -} - - /* Cogit>>#initializeBackend */ -static void -initializeBackend(void) -{ - (methodLabel->machineCodeSize = 0); - (methodLabel->opcode = Label); - ((methodLabel->operands))[0] = 0; - ((methodLabel->operands))[1] = 0; - assert((!((registerMaskFor(VarBaseReg)) & CallerSavedRegisterMask))); - varBaseAddress = computeGoodVarBaseAddress(); - assert((stackLimitAddress()) >= varBaseAddress); - assert((cStackPointerAddress()) >= varBaseAddress); - assert((cFramePointerAddress()) >= varBaseAddress); - assert((cReturnAddressAddress()) >= varBaseAddress); - assert((nextProfileTickAddress()) >= varBaseAddress); - } - - /* Cogit>>#initializeCodeZoneFrom:upTo: */ -void -initializeCodeZoneFromupTo(sqInt startAddress, sqInt endAddress) -{ - sqInt fixupSize; - sqInt numberOfAbstractOpcodes; - sqInt opcodeSize; - usqInt startAddress1; - - initializeBackend(); - sqMakeMemoryExecutableFromToCodeToDataDelta(startAddress, endAddress, -# if DUAL_MAPPED_CODE_ZONE - (&codeToDataDelta) -# else - null -# endif - ); - stopsFromto(backEnd, startAddress, endAddress - 1); - codeBase = (methodZoneBase = startAddress); - minValidCallAddress = (((((codeBase < (interpretAddress())) ? codeBase : (interpretAddress()))) < (primitiveFailAddress())) ? (((codeBase < (interpretAddress())) ? codeBase : (interpretAddress()))) : (primitiveFailAddress())); - /* begin manageFrom:to: */ - mzFreeStart = (baseAddress = methodZoneBase); - youngReferrers = (limitAddress = endAddress); - openPICList = null; - unpairedMethodList = null; - methodBytesFreedSinceLastCompaction = 0; - methodCount = 0; - assertValidDualZone(); - /* begin maybeGenerateCacheFlush */ - /* begin generateVMOwnerLockFunctions */ -# if COGMTVM - /* begin allocateOpcodes:bytecodes: */ - numberOfAbstractOpcodes = numLowLevelLockOpcodes(backEnd); - numAbstractOpcodes = numberOfAbstractOpcodes; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - zeroOpcodeIndex(); - startAddress1 = methodZoneBase; - generateLowLevelTryLock(backEnd, vmOwnerAddress()); - outputInstructionsForGeneratedRuntimeAt(startAddress1); - recordGeneratedRunTimeaddress("ceTryLockVMOwner", startAddress1); - ceTryLockVMOwner = ((usqIntptr_t (*)(usqIntptr_t)) startAddress1); -# endif // COGMTVM - genGetLeafCallStackPointers(); - generateStackPointerCapture(); - generateTrampolines(); - computeEntryOffsets(); - computeFullBlockEntryOffsets(); - generateClosedPICPrototype(); - alignMethodZoneBase(); - flushICacheFromto(backEnd, startAddress, ((usqInt)methodZoneBase)); - /* begin maybeFlushWritableZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - if (codeToDataDelta > 0) { - flushDCacheFromto(backEnd, startAddress, ((usqInt)methodZoneBase)); - } -# endif - /* begin manageFrom:to: */ - mzFreeStart = (baseAddress = methodZoneBase); - youngReferrers = (limitAddress = endAddress); - openPICList = null; - unpairedMethodList = null; - methodBytesFreedSinceLastCompaction = 0; - methodCount = 0; - generateOpenPICPrototype(); -} - - -/* Answer a usage count that reflects likely long-term usage. - Answer 1 for non-primitives or quick primitives (inst var accessors), - 2 for methods with interpreter primitives, and 3 for compiled primitives. */ - - /* Cogit>>#initialMethodUsageCount */ -static sqInt -initialMethodUsageCount(void) -{ - if ((primitiveIndex == 1) - || (isQuickPrimitiveIndex(primitiveIndex))) { - return 1; - } - if (!(primitiveGeneratorOrNil())) { - return 2; - } - return 3; -} - - -/* Answer a usage count that reflects likely long-term usage. */ - - /* Cogit>>#initialOpenPICUsageCount */ -static sqInt -initialOpenPICUsageCount(void) -{ - return CMMaxUsageCount - 1; -} - - /* Cogit>>#inverseBranchFor: */ -static sqInt NoDbgRegParms -inverseBranchFor(sqInt opcode) -{ - switch (opcode) { - case JumpLongZero: - return JumpLongNonZero; - - case JumpLongNonZero: - return JumpLongZero; - - case JumpZero: - return JumpNonZero; - - case JumpNonZero: - return JumpZero; - - case JumpNegative: - return JumpNonNegative; - - case JumpNonNegative: - return JumpNegative; - - case JumpOverflow: - return JumpNoOverflow; - - case JumpNoOverflow: - return JumpOverflow; - - case JumpCarry: - return JumpNoCarry; - - case JumpNoCarry: - return JumpCarry; - - case JumpLess: - return JumpGreaterOrEqual; - - case JumpGreaterOrEqual: - return JumpLess; - - case JumpGreater: - return JumpLessOrEqual; - - case JumpLessOrEqual: - return JumpGreater; - - case JumpBelow: - return JumpAboveOrEqual; - - case JumpAboveOrEqual: - return JumpBelow; - - case JumpAbove: - return JumpBelowOrEqual; - - case JumpBelowOrEqual: - return JumpAbove; - - default: - error("Case not found and no otherwise clause"); - } - error("invalid opcode for inverse"); - return 0; -} - - -/* See Cogit class>>initializeAnnotationConstants */ - - /* Cogit>>#isPCMappedAnnotation: */ -static sqInt NoDbgRegParms -isPCMappedAnnotation(sqInt annotation) -{ - return annotation >= HasBytecodePC; -} - - /* Cogit>>#isPCWithinMethodZone: */ -sqInt -isPCWithinMethodZone(void *address) -{ - return (((((usqInt)address)) >= methodZoneBase) && ((((usqInt)address)) <= (freeStart()))); -} - - -/* Answer if the instruction preceding retpc is a call instruction. */ - - /* Cogit>>#isSendReturnPC: */ -sqInt -isSendReturnPC(sqInt retpc) -{ - usqInt target; - - if (!(isCallPrecedingReturnPC(backEnd, retpc))) { - return 0; - } - target = callTargetFromReturnAddress(backEnd, retpc); - return (((target >= firstSend) && (target <= lastSend))) - || (((target >= methodZoneBase) && (target <= (freeStart())))); -} - - -/* Floating-point jumps are a little weird on some processors. Defer to - the backEnd to allow it to generate any special code it may need to. */ - - /* Cogit>>#JumpFPEqual: */ -static AbstractInstruction * NoDbgRegParms -gJumpFPEqual(void *jumpTarget) -{ - /* begin genJumpFPEqual: */ - return genoperand(JumpFPEqual, ((sqInt)jumpTarget)); -} - - -/* Floating-point jumps are a little weird on some processors. Defer to - the backEnd to allow it to generate any special code it may need to. */ - - /* Cogit>>#JumpFPGreaterOrEqual: */ -static AbstractInstruction * NoDbgRegParms -gJumpFPGreaterOrEqual(void *jumpTarget) -{ - /* begin genJumpFPGreaterOrEqual: */ - return genoperand(JumpFPGreaterOrEqual, ((sqInt)jumpTarget)); -} - - -/* Floating-point jumps are a little weird on some processors. Defer to - the backEnd to allow it to generate any special code it may need to. */ - - /* Cogit>>#JumpFPGreater: */ -static AbstractInstruction * NoDbgRegParms -gJumpFPGreater(void *jumpTarget) -{ - /* begin genJumpFPGreater: */ - return genoperand(JumpFPGreater, ((sqInt)jumpTarget)); -} - - -/* Floating-point jumps are a little weird on some processors. Defer to - the backEnd to allow it to generate any special code it may need to. */ - - /* Cogit>>#JumpFPNotEqual: */ -static AbstractInstruction * NoDbgRegParms -gJumpFPNotEqual(void *jumpTarget) -{ - /* begin genJumpFPNotEqual: */ - return genoperand(JumpFPNotEqual, ((sqInt)jumpTarget)); -} - - /* Cogit>>#LogicalShiftLeftCq:R: */ -static AbstractInstruction * NoDbgRegParms -gLogicalShiftLeftCqR(sqInt quickConstant, sqInt reg) -{ - return genoperandoperand(LogicalShiftLeftCqR, quickConstant, reg); -} - - -/* destReg := srcReg << quickConstant */ - - /* Cogit>>#LogicalShiftLeftCq:R:R: */ -static AbstractInstruction * NoDbgRegParms -gLogicalShiftLeftCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) -{ - AbstractInstruction * first; - - return genoperandoperandoperand(LogicalShiftLeftCqRR, quickConstant, srcReg, destReg); - first = genoperandoperand(MoveRR, srcReg, destReg); - genoperandoperand(LogicalShiftLeftCqR, quickConstant, destReg); - return first; -} - - -/* destReg := (unsigned)srcReg >> quickConstant */ - - /* Cogit>>#LogicalShiftRightCq:R:R: */ -static AbstractInstruction * NoDbgRegParms -gLogicalShiftRightCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) -{ - AbstractInstruction * first; - - return genoperandoperandoperand(LogicalShiftRightCqRR, quickConstant, srcReg, destReg); - first = genoperandoperand(MoveRR, srcReg, destReg); - genoperandoperand(LogicalShiftRightCqR, quickConstant, destReg); - return first; -} - - /* Cogit>>#lastOpcode */ -static AbstractInstruction * -lastOpcode(void) -{ - assert(opcodeIndex > 0); - return abstractInstructionAt(opcodeIndex - 1); -} - - /* Cogit>>#linkNSSendCache:classTag:enclosingObject:target:caller: */ -void -linkNSSendCacheclassTagenclosingObjecttargetcaller(NSSendCache *nsSendCache, sqInt classTag, sqInt enclosingObject, CogMethod *targetMethod, CogMethod *callingMethod) -{ - (nsSendCache->classTag = classTag); - (nsSendCache->enclosingObject = enclosingObject); - (nsSendCache->target = (((sqInt)targetMethod)) + cmNoCheckEntryOffset); - if (!((callingMethod->cmRefersToYoung))) { - if ((enclosingObject != 0) - && (isYoung(enclosingObject))) { - ensureInYoungReferrers(callingMethod); - } - } -} - - /* Cogit>>#linkSendAt:in:to:offset:receiver: */ -void -linkSendAtintooffsetreceiver(sqInt callSiteReturnAddress, CogMethod *sendingMethod, CogMethod *targetMethod, sqInt theEntryOffset, sqInt receiver) -{ - sqInt extent; - sqInt inlineCacheTag; - - assert((theEntryOffset == cmEntryOffset) - || (theEntryOffset == cmNoCheckEntryOffset)); - assert(((callSiteReturnAddress >= methodZoneBase) && (callSiteReturnAddress <= (freeStart())))); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - if (theEntryOffset == cmNoCheckEntryOffset) { - - /* no need to change selector cache tag */ - extent = rewriteCallAttarget(backEnd, callSiteReturnAddress, (((sqInt)targetMethod)) + cmNoCheckEntryOffset); - } - else { - inlineCacheTag = inlineCacheTagForInstance(receiver); - extent = rewriteInlineCacheAttagtarget(backEnd, callSiteReturnAddress, inlineCacheTag, (((sqInt)targetMethod)) + theEntryOffset); - } - flushICacheFromto(backEnd, (((usqInt)callSiteReturnAddress)) - extent, ((usqInt)callSiteReturnAddress)); -} - - /* Cogit>>#loadBytesAndGetDescriptor */ -static BytecodeDescriptor * -loadBytesAndGetDescriptor(void) -{ - BytecodeDescriptor *descriptor; - - byte0 = (fetchByteofObject(bytecodePC, methodObj)) + bytecodeSetOffset; - descriptor = generatorAt(byte0); - loadSubsequentBytesForDescriptorat(descriptor, bytecodePC); - return descriptor; -} - - /* Cogit>>#loadSubsequentBytesForDescriptor:at: */ -static void NoDbgRegParms -loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc) -{ - if (((descriptor->numBytes)) > 1) { - byte1 = fetchByteofObject(pc + 1, methodObj); - if (((descriptor->numBytes)) > 2) { - byte2 = fetchByteofObject(pc + 2, methodObj); - if (((descriptor->numBytes)) > 3) { - byte3 = fetchByteofObject(pc + 3, methodObj); - if (((descriptor->numBytes)) > 4) { - notYetImplemented(); - } - } - } - } -} - - /* Cogit>>#MoveCw:R: */ -static AbstractInstruction * NoDbgRegParms -gMoveCwR(sqInt wordConstant, sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkLiteral:forInstruction: */ - anInstruction = genoperandoperand(MoveCwR, wordConstant, reg); - return anInstruction; -} - - -/* Answer the address of the null byte at the end of the method map. */ - - /* Cogit>>#mapEndFor: */ -static usqInt NoDbgRegParms -mapEndFor(CogMethod *cogMethod) -{ - usqInt end; - - end = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while ((byteAt(end)) != MapEnd) { - end -= 1; - assert(end > (firstMappedPCFor(cogMethod))); - } - return end; -} - - -/* Unlinking/GC/Disassembly support */ -/* most of the time arg is a CogMethod... */ - - /* Cogit>>#mapFor:performUntil:arg: */ -static sqInt NoDbgRegParms -mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg) -{ - sqInt annotation; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - - /* begin firstMappedPCFor: */ - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = functionSymbol(annotation, (((char *) mcpc)), arg); - if (result != 0) { - return result; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - return 0; -} - - -/* Remap all object references in the closed PIC. Answer if any references - are young. - Set codeModified if any modifications are made. */ - - /* Cogit>>#mapObjectReferencesInClosedPIC: */ -static sqInt NoDbgRegParms -mapObjectReferencesInClosedPIC(CogMethod *cPIC) -{ - sqInt i; - sqInt pc; - sqInt refersToYoung; - - - /* first we check the potential method oop load at the beginning of the CPIC */ - pc = addressOfEndOfCaseinCPIC(1, cPIC); - - /* We find the end address of the cPICNumCases'th case and can then just step forward by the case size thereafter */ - refersToYoung = remapMaybeObjRefInClosedPICAt(pc - (jumpLongByteSize(backEnd))); - - /* Next we check the potential class ref in the compare instruction, and the potential method oop load for each case. */ - pc = addressOfEndOfCaseinCPIC((cPIC->cPICNumCases), cPIC); - for (i = 2; i <= ((cPIC->cPICNumCases)); i += 1) { - if (remapMaybeObjRefInClosedPICAt((pc - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */)) { - refersToYoung = 1; - } - pc += cPICCaseSize; - } - return refersToYoung; -} - - -/* Update all references to objects in the generated runtime. */ - - /* Cogit>>#mapObjectReferencesInGeneratedRuntime */ -static void -mapObjectReferencesInGeneratedRuntime(void) -{ - sqInt i; - usqInt literal; - sqInt mappedLiteral; - usqInt mcpc; - - for (i = 0; i < runtimeObjectRefIndex; i += 1) { - mcpc = objectReferencesInRuntime[i]; - literal = literalBeforeFollowingAddress(backEnd, mcpc); - mappedLiteral = remapObject(literal); - if (mappedLiteral != literal) { - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - storeLiteralbeforeFollowingAddress(backEnd, mappedLiteral, mcpc); - } - } -} - - -/* Update all references to objects in machine code for a become. - Unlike incrementalGC or fullGC a method that does not refer to young may - refer to young as a result of the become operation. Unlike incrementalGC - or fullGC the reference from a Cog method to its methodObject *must not* - change since the two are two halves of the same object. */ - - /* Cogit>>#mapObjectReferencesInMachineCodeForBecome */ -static void -mapObjectReferencesInMachineCodeForBecome(void) -{ - sqInt annotation; - CogMethod * cogMethod; - sqInt freedPIC; - sqInt hasYoungObj; - sqInt hasYoungObjPtr; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt remappedMethod; - sqInt result; - CogMethod * writableCogMethod; - - hasYoungObj = 0; - hasYoungObjPtr = ((sqInt)((&hasYoungObj))); - codeModified = (freedPIC = 0); - mapObjectReferencesInGeneratedRuntime(); - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - assert(!hasYoungObj); - if (((cogMethod->cmType)) != CMFree) { - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - writableCogMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - (writableCogMethod->selector = remapOop((cogMethod->selector))); - if (((cogMethod->cmType)) == CMClosedPIC) { - if ((isYoung((cogMethod->selector))) - || (mapObjectReferencesInClosedPIC(cogMethod))) { - freedPIC = 1; - freeMethod(cogMethod); - } - } - else { - if (isYoung((cogMethod->selector))) { - hasYoungObj = 1; - } - if (((cogMethod->cmType)) == CMMethod) { - assert(((cogMethod->objectHeader)) == (nullHeaderForMachineCodeMethod())); - remappedMethod = remapOop((cogMethod->methodObject)); - if (remappedMethod != ((cogMethod->methodObject))) { - if (methodHasCogMethod(remappedMethod)) { - error("attempt to become two cogged methods"); - } - if (!(withoutForwardingOnandwithsendToCogit((cogMethod->methodObject), remappedMethod, (cogMethod->cmUsesPenultimateLit), methodhasSameCodeAscheckPenultimate))) { - error("attempt to become cogged method into different method"); - } - if ((rawHeaderOf((cogMethod->methodObject))) == (((sqInt)cogMethod))) { - rawHeaderOfput((cogMethod->methodObject), (cogMethod->methodHeader)); - (writableCogMethod->methodHeader = rawHeaderOf(remappedMethod)); - (writableCogMethod->methodObject = remappedMethod); - rawHeaderOfput(remappedMethod, ((sqInt)cogMethod)); - } - else { - assert((noAssertMethodClassAssociationOf((cogMethod->methodObject))) == (nilObject())); - (writableCogMethod->methodHeader = rawHeaderOf(remappedMethod)); - (writableCogMethod->methodObject = remappedMethod); - } - } - if (isYoung((cogMethod->methodObject))) { - hasYoungObj = 1; - } - } - /* begin mapFor:performUntil:arg: */ - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = remapIfObjectRefpchasYoung(annotation, (((char *) mcpc)), (((CogMethod *) hasYoungObjPtr))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - if (hasYoungObj) { - ensureInYoungReferrers(cogMethod); - hasYoungObj = 0; - } - else { - (cogMethod->cmRefersToYoung = 0); - } - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - pruneYoungReferrers(); - if (freedPIC) { - unlinkSendsToFree(); - } - if (codeModified) { - - /* After updating oops in inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)codeBase), freeStart()); - } -} - - -/* Update all references to objects in machine code for a full gc. Since - the current (New)ObjectMemory GC makes everything old in a full GC - a method not referring to young will not refer to young afterwards */ - - /* Cogit>>#mapObjectReferencesInMachineCodeForFullGC */ -static void -mapObjectReferencesInMachineCodeForFullGC(void) -{ - sqInt annotation; - CogMethod * cogMethod; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - CogMethod * writableCogMethod; - - codeModified = 0; - mapObjectReferencesInGeneratedRuntime(); - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - writableCogMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - (writableCogMethod->selector = remapOop((cogMethod->selector))); - if (((cogMethod->cmType)) == CMClosedPIC) { - assert(!((cogMethod->cmRefersToYoung))); - mapObjectReferencesInClosedPIC(cogMethod); - } - else { - if (((cogMethod->cmType)) == CMMethod) { - assert(((cogMethod->objectHeader)) == (nullHeaderForMachineCodeMethod())); - (writableCogMethod->methodObject = remapOop((cogMethod->methodObject))); - } - /* begin mapFor:performUntil:arg: */ - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = remapIfObjectRefpchasYoung(annotation, (((char *) mcpc)), 0); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - pruneYoungReferrers(); - if (codeModified) { - - /* After updating oops in inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)codeBase), freeStart()); - } -} - - -/* Update all references to objects in machine code for either a Spur - scavenging gc - or a Squeak V3 incremental GC. Avoid scanning all code by using the - youngReferrers list. In a young gc a method referring to young may no - longer refer to young, but a - method not referring to young cannot and will not refer to young - afterwards. */ - - /* Cogit>>#mapObjectReferencesInMachineCodeForYoungGC */ -static void -mapObjectReferencesInMachineCodeForYoungGC(void) -{ - sqInt annotation; - CogMethod * cogMethod; - sqInt hasYoungObj; - sqInt hasYoungObjPtr; - usqInt map; - sqInt mapByte; - sqInt mcpc; - usqInt pointer; - sqInt result; - CogMethod * writableCogMethod; - sqInt zoneIsWritable; - - codeModified = (zoneIsWritable = (hasYoungObj = 0)); - hasYoungObjPtr = ((sqInt)((&hasYoungObj))); - pointer = youngReferrers(); - while (pointer < limitAddress) { - assert(!hasYoungObj); - cogMethod = ((CogMethod *) (longAt(pointer))); - if (((cogMethod->cmType)) == CMFree) { - assert(!((cogMethod->cmRefersToYoung))); - } - else { - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - if ((cogMethod->cmRefersToYoung)) { - assert((((cogMethod->cmType)) == CMMethod) - || (((cogMethod->cmType)) == CMOpenPIC)); - if (!zoneIsWritable) { - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - zoneIsWritable = 1; - } - writableCogMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - (writableCogMethod->selector = remapOop((cogMethod->selector))); - if (isYoung((cogMethod->selector))) { - hasYoungObj = 1; - } - if (((cogMethod->cmType)) == CMMethod) { - assert(((cogMethod->objectHeader)) == (nullHeaderForMachineCodeMethod())); - (writableCogMethod->methodObject = remapOop((cogMethod->methodObject))); - if (isYoung((cogMethod->methodObject))) { - hasYoungObj = 1; - } - } - /* begin mapFor:performUntil:arg: */ - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = remapIfObjectRefpchasYoung(annotation, (((char *) mcpc)), (((void *)hasYoungObjPtr))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - if (hasYoungObj) { - hasYoungObj = 0; - } - else { - (writableCogMethod->cmRefersToYoung = 0); - } - } - } - pointer += BytesPerWord; - } - pruneYoungReferrers(); - if (codeModified) { - - /* After updating oops in inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } -} - - -/* Update all references to objects in machine code. */ - - /* Cogit>>#mapObjectReferencesInMachineCode: */ -void -mapObjectReferencesInMachineCode(sqInt gcMode) -{ - switch (gcMode) { - case GCModeNewSpace: - - /* N.B. do *not* ensureWritableCodeZone for every scavenge. */ - mapObjectReferencesInMachineCodeForYoungGC(); - break; - case GCModeFull: - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - mapObjectReferencesInMachineCodeForFullGC(); - break; - case GCModeBecome: - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - mapObjectReferencesInMachineCodeForBecome(); - break; - default: - error("Case not found and no otherwise clause"); - } - if (!(asserta((freeStart()) <= (youngReferrers())))) { - error("youngReferrers list overflowed"); - } -} - - -/* Mark objects in machine-code of marked methods (or open PICs with marked - selectors). - */ - - /* Cogit>>#markAndTraceMachineCodeOfMarkedMethods */ -void -markAndTraceMachineCodeOfMarkedMethods(void) -{ - sqInt annotation; - sqInt annotation1; - CogMethod *cogMethod; - usqInt map; - usqInt map1; - sqInt mapByte; - sqInt mapByte1; - usqInt maybeIRCs; - usqInt maybeIRCs1; - sqInt mcpc; - sqInt mcpc1; - sqInt result; - sqInt result1; - - if (leakCheckFullGC()) { - asserta(allMachineCodeObjectReferencesValid()); - } - codeModified = 0; - markAndTraceObjectReferencesInGeneratedRuntime(); - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) == CMMethod) - && (isMarked((cogMethod->methodObject)))) { - /* begin markAndTraceLiteralsIn: */ - assert(((((cogMethod->cmType)) == CMMethod) - && (isMarked((cogMethod->methodObject)))) - || ((((cogMethod->cmType)) == CMOpenPIC) - && ((isImmediate((cogMethod->selector))) - || (isMarked((cogMethod->selector)))))); - markAndTraceLiteralinat((cogMethod->selector), cogMethod, (&((cogMethod->selector)))); - /* begin maybeMarkIRCsIn: */ - /* begin markIfIRC: */ - maybeIRCs = (cogMethod->nextMethodOrIRCs); - if (oopisGreaterThan(maybeIRCs, nilObject())) { - markAndTrace(maybeIRCs - BaseHeaderSize); - } - /* begin mapFor:performUntil:arg: */ - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = markLiteralspcmethod(annotation, (((char *) mcpc)), cogMethod); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - if ((((cogMethod->cmType)) == CMOpenPIC) - && ((isImmediate((cogMethod->selector))) - || (isMarked((cogMethod->selector))))) { - /* begin markAndTraceLiteralsIn: */ - assert(((((cogMethod->cmType)) == CMMethod) - && (isMarked((cogMethod->methodObject)))) - || ((((cogMethod->cmType)) == CMOpenPIC) - && ((isImmediate((cogMethod->selector))) - || (isMarked((cogMethod->selector)))))); - markAndTraceLiteralinat((cogMethod->selector), cogMethod, (&((cogMethod->selector)))); - /* begin maybeMarkIRCsIn: */ - /* begin markIfIRC: */ - maybeIRCs1 = (cogMethod->nextMethodOrIRCs); - if (oopisGreaterThan(maybeIRCs1, nilObject())) { - markAndTrace(maybeIRCs1 - BaseHeaderSize); - } - /* begin mapFor:performUntil:arg: */ - mcpc1 = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map1 = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte1 = byteAt(map1))) != MapEnd) { - if (mapByte1 >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc1 += (mapByte1 & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation1 = ((usqInt)(mapByte1)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte1 = byteAt(map1 - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation1 += mapByte1 & DisplacementMask; - map1 -= 1; - } - result1 = markLiteralspcmethod(annotation1, (((char *) mcpc1)), cogMethod); - if (result1 != 0) { - goto l4; - } - } - else { - if (mapByte1 < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc1 += (((sqInt)((usqInt)((mapByte1 - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map1 -= 1; - } - l4: /* end mapFor:performUntil:arg: */; - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (leakCheckFullGC()) { - asserta(allMachineCodeObjectReferencesValid()); - } - if (codeModified) { - - /* After updating oops in inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } -} - - -/* Mark and trace any object references in the generated run-time. */ - - /* Cogit>>#markAndTraceObjectReferencesInGeneratedRuntime */ -static void -markAndTraceObjectReferencesInGeneratedRuntime(void) -{ - sqInt i; - usqInt literal; - usqInt mcpc; - - for (i = 0; i < runtimeObjectRefIndex; i += 1) { - mcpc = objectReferencesInRuntime[i]; - literal = literalBeforeFollowingAddress(backEnd, mcpc); - markAndTraceLiteralinatpc(literal, ((CogMethod *) null), ((usqInt)mcpc)); - } -} - - -/* Mark and trace objects in the argument and free if it is appropriate. - Answer if the method has been freed. firstVisit is a hint used to avoid - scanning methods we've already seen. False positives are fine. - For a CMMethod this - frees if the bytecode method isnt marked, - marks and traces object literals and selectors, - unlinks sends to targets that should be freed. - For a CMClosedPIC this - frees if it refers to anything that should be freed or isn't marked. - For a CMOpenPIC this - frees if the selector isn't marked. */ -/* this recurses at most one level down */ - - /* Cogit>>#markAndTraceOrFreeCogMethod:firstVisit: */ -static sqInt NoDbgRegParms -markAndTraceOrFreeCogMethodfirstVisit(CogMethod *cogMethod, sqInt firstVisit) -{ - sqInt annotation; - usqInt map; - sqInt mapByte; - usqInt maybeIRCs; - sqInt mcpc; - sqInt result; - - if (((cogMethod->cmType)) == CMFree) { - return 1; - } - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - if (((cogMethod->cmType)) == CMMethod) { - if (!(isMarked((cogMethod->methodObject)))) { - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - freeMethod(cogMethod); - return 1; - } - if (firstVisit) { - /* begin markLiteralsAndUnlinkUnmarkedSendsIn: */ - assert(((cogMethod->cmType)) == CMMethod); - assert(isMarked((cogMethod->methodObject))); - markAndTraceLiteralinat((cogMethod->selector), cogMethod, (&((cogMethod->selector)))); - /* begin maybeMarkIRCsIn: */ - /* begin markIfIRC: */ - maybeIRCs = (cogMethod->nextMethodOrIRCs); - if (oopisGreaterThan(maybeIRCs, nilObject())) { - markAndTrace(maybeIRCs - BaseHeaderSize); - } - /* begin mapFor:performUntil:arg: */ - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = markLiteralsAndUnlinkIfUnmarkedSendpcmethod(annotation, (((char *) mcpc)), cogMethod); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - return 0; - } - if (((cogMethod->cmType)) == CMClosedPIC) { - if (!(closedPICRefersToUnmarkedObject(cogMethod))) { - return 0; - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - freeMethod(cogMethod); - return 1; - } - if (((cogMethod->cmType)) == CMOpenPIC) { - if (isMarked((cogMethod->selector))) { - return 0; - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - freeMethod(cogMethod); - return 1; - } - assert((((cogMethod->cmType)) == CMMethod) - || ((((cogMethod->cmType)) == CMClosedPIC) - || (((cogMethod->cmType)) == CMOpenPIC))); - return 0; -} - - -/* If entryPoint is that of some method, then mark and trace objects in it - and free if it is appropriate. - Answer if the method has been freed. */ - - /* Cogit>>#markAndTraceOrFreePICTarget:in: */ -static sqInt NoDbgRegParms -markAndTraceOrFreePICTargetin(sqInt entryPoint, CogMethod *cPIC) -{ - CogMethod *targetMethod; - - assert((entryPoint > methodZoneBase) - && (entryPoint < (freeStart()))); - if (((((usqInt)cPIC)) <= (((usqInt)entryPoint))) - && (((((usqInt)cPIC)) + ((cPIC->blockSize))) >= (((usqInt)entryPoint)))) { - return 0; - } - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - assert((((targetMethod->cmType)) == CMMethod) - || (((targetMethod->cmType)) == CMFree)); - return markAndTraceOrFreeCogMethodfirstVisit(targetMethod, (((usqInt)targetMethod)) > (((usqInt)cPIC))); -} - - -/* Mark and trace literals. Unlink sends that have unmarked cache tags or - targets. - */ - - /* Cogit>>#markLiteralsAndUnlinkIfUnmarkedSend:pc:method: */ -static sqInt NoDbgRegParms -markLiteralsAndUnlinkIfUnmarkedSendpcmethod(sqInt annotation, char *mcpc, sqInt cogMethod) -{ - usqInt cacheAddress; - usqInt cacheTag1; - sqInt cacheTagMarked; - sqInt entryPoint; - usqInt entryPoint1; - usqInt entryPoint2; - sqInt eo; - usqInt literal; - char *mcpc1; - NSSendCache *nsSendCache; - sqInt offset1; - sqInt sel; - sqInt *sendTable1; - sqInt tagCouldBeObj1; - CogMethod * targetMethod; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - literal = 0; - if (annotation == IsObjectReference) { - literal = literalBeforeFollowingAddress(backEnd, ((usqInt)mcpc)); - if (markAndTraceLiteralinatpc(literal, ((CogMethod *) cogMethod), ((usqInt)mcpc))) { - codeModified = 1; - } - } - if (annotation == IsNSSendCall) { - /* begin nsSendCacheFromReturnAddress: */ - mcpc1 = ((char *) (((sqInt)mcpc))); - entryPoint2 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc1)); - assert(entryPoint2 < methodZoneBase); - cacheAddress = ((usqInt)(nsSendCacheAt(backEnd, mcpc1))); - assert(isInOldSpace(cacheAddress)); - nsSendCache = ((NSSendCache *) cacheAddress); - entryPoint = (nsSendCache->target); - if (entryPoint != 0) { - - /* Send is linked */ - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - if (markAndTraceOrFreeCogMethodfirstVisit(targetMethod, (((usqInt)targetMethod)) > (((usqInt)mcpc)))) { - /* begin voidNSSendCache: */ - (nsSendCache->classTag = 2 /* illegalClassTag */); - (nsSendCache->enclosingObject = 0); - (nsSendCache->target = 0); - } - } - sel = (nsSendCache->selector); - if (isForwarded(sel)) { - sel = followForwarded(literal); - (nsSendCache->selector = sel); - markAndTraceUpdatedLiteralin(sel, ((CogMethod *) cogMethod)); - } - else { - markAndTrace(sel); - } - eo = (nsSendCache->enclosingObject); - if (eo != 0) { - if (isForwarded(eo)) { - eo = followForwarded(literal); - (nsSendCache->enclosingObject = eo); - markAndTraceUpdatedLiteralin(eo, ((CogMethod *) cogMethod)); - } - else { - markAndTrace(eo); - } - } - } - if (annotation >= IsSendCall) { - /* begin entryCacheTagAndCouldBeObjectAt:annotation:into: */ - cacheTag1 = inlineCacheTagAt(backEnd, ((sqInt)mcpc)); - - /* in-line cache tags are the selectors of sends if sends are unlinked, - the selectors of super sends (entry offset = cmNoCheckEntryOffset), - the selectors of open PIC sends (entry offset = cmEntryOffset, target is an Open PIC) - or in-line cache tags (classes, class indices, immediate bit patterns, etc). - Note that selectors can be immediate so there is no guarantee that they - are markable/remappable objects. */ - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - tagCouldBeObj1 = entryPointTagIsSelector(entryPoint1); - cacheTagMarked = tagCouldBeObj1 - && (1); - if (entryPoint1 > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - if (annotation == IsNSSelfSend) { - offset1 = cmEntryOffset; - sendTable1 = selfSendTrampolines; - } - else { - if (annotation == IsNSDynamicSuperSend) { - offset1 = cmEntryOffset; - sendTable1 = dynamicSuperSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint1 - offset1)); - if ((!cacheTagMarked) - || (markAndTraceOrFreeCogMethodfirstVisit(targetMethod1, (((usqInt)targetMethod1)) > (((usqInt)mcpc))))) { - - /* Either the cacheTag is unmarked (e.g. new class) or the target - has been freed (because it is unmarked), so unlink the send. */ - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - markAndTraceLiteralinat((targetMethod1->selector), targetMethod1, (&((targetMethod1->selector)))); - } - } - else { - - /* cacheTag is selector */ - if (markAndTraceCacheTagLiteralinatpc(cacheTag1, ((CogMethod *) cogMethod), ((usqInt)mcpc))) { - codeModified = 1; - } - } - } - return 0; -} - - -/* Mark and trace literals. - Additionally in Newspeak, void push implicits that have unmarked classes. */ - - /* Cogit>>#markLiterals:pc:method: */ -static sqInt NoDbgRegParms -markLiteralspcmethod(sqInt annotation, char *mcpc, CogMethod *cogMethod) -{ - usqInt cacheAddress; - usqInt cacheTag1; - usqInt entryPoint1; - usqInt entryPoint2; - sqInt eo; - usqInt literal; - char *mcpc1; - NSSendCache *nsSendCache; - sqInt sel; - sqInt tagCouldBeObj1; - - literal = 0; - if (annotation == IsObjectReference) { - literal = literalBeforeFollowingAddress(backEnd, ((usqInt)mcpc)); - if (markAndTraceLiteralinatpc(literal, cogMethod, ((usqInt)mcpc))) { - codeModified = 1; - } - } - if (annotation == IsNSSendCall) { - /* begin nsSendCacheFromReturnAddress: */ - mcpc1 = ((char *) (((sqInt)mcpc))); - entryPoint2 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc1)); - assert(entryPoint2 < methodZoneBase); - cacheAddress = ((usqInt)(nsSendCacheAt(backEnd, mcpc1))); - assert(isInOldSpace(cacheAddress)); - nsSendCache = ((NSSendCache *) cacheAddress); - sel = (nsSendCache->selector); - if (isForwarded(sel)) { - sel = followForwarded(literal); - (nsSendCache->selector = sel); - markAndTraceUpdatedLiteralin(sel, ((CogMethod *) cogMethod)); - } - else { - markAndTrace(sel); - } - eo = (nsSendCache->enclosingObject); - if (eo != 0) { - if (isForwarded(eo)) { - eo = followForwarded(literal); - (nsSendCache->enclosingObject = eo); - markAndTraceUpdatedLiteralin(eo, ((CogMethod *) cogMethod)); - } - else { - markAndTrace(eo); - } - } - } - if (annotation >= IsSendCall) { - /* begin entryCacheTagAndCouldBeObjectAt:annotation:into: */ - cacheTag1 = inlineCacheTagAt(backEnd, ((sqInt)mcpc)); - - /* in-line cache tags are the selectors of sends if sends are unlinked, - the selectors of super sends (entry offset = cmNoCheckEntryOffset), - the selectors of open PIC sends (entry offset = cmEntryOffset, target is an Open PIC) - or in-line cache tags (classes, class indices, immediate bit patterns, etc). - Note that selectors can be immediate so there is no guarantee that they - are markable/remappable objects. */ - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - tagCouldBeObj1 = entryPointTagIsSelector(entryPoint1); - if (tagCouldBeObj1 - && (markAndTraceCacheTagLiteralinatpc(cacheTag1, cogMethod, ((usqInt)mcpc)))) { - - /* cacheTag is selector */ - codeModified = 1; - } - } - return 0; -} - - /* Cogit>>#markMethodAndReferents: */ -void -markMethodAndReferents(CogBlockMethod *aCogMethod) -{ - sqInt annotation; - CogMethod * cogMethod; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - CogMethod * writableMethod; - - assert((((aCogMethod->cmType)) == CMMethod) - || (((aCogMethod->cmType)) == CMBlock)); - cogMethod = (((aCogMethod->cmType)) == CMMethod - ? ((CogMethod *) aCogMethod) - : cmHomeMethod(aCogMethod)); - writableMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - (writableMethod->cmUsageCount = CMMaxUsageCount); - /* begin mapFor:performUntil:arg: */ - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = incrementUsageOfTargetIfLinkedSendmcpcignored(annotation, (((char *) mcpc)), 0); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; -} - - /* Cogit>>#maxCogMethodAddress */ -usqInt -maxCogMethodAddress(void) -{ - return ((usqInt)(limitZony())); -} - - -/* If this is the Newspeak VM and the objectRepresentation supports pinning - then allocate space for the implicit receiver caches on the heap. */ - - /* Cogit>>#maybeAllocAndInitIRCs */ -static sqInt -maybeAllocAndInitIRCs(void) -{ - sqInt objOop; - - indexOfIRC = (theIRCs = 0); - if (numIRCs > 0) { - assert((noAssertMethodClassAssociationOf(methodObj)) != (nilObject())); - /* begin allocateNPinnedSlots: */ - objOop = allocatePinnedSlots(numIRCs * NumOopsPerNSC); - theIRCs = (objOop == null - ? 0 - : objOop + BaseHeaderSize); - return theIRCs != 0; - } - return 1; -} - - -/* Check that the header fields are consistent with the type. - Answer 0 if it is ok, otherwise answer a code for the error. */ - - /* Cogit>>#maybeFreeCogMethodDoesntLookKosher: */ -static sqInt NoDbgRegParms -maybeFreeCogMethodDoesntLookKosher(CogMethod *cogMethod) -{ - sqInt result; - - result = cogMethodDoesntLookKosher(cogMethod); - return (result == 2 - ? 0 - : result); -} - - /* Cogit>>#mclassIsSmallInteger */ -static sqInt -mclassIsSmallInteger(void) -{ - return (receiverTags & 1); -} - - -/* Answer the absolute machine code pc matching the zero-relative - bytecode pc of a backward branch in cogMethod, given the start - of the bytecodes for cogMethod's block or method object. */ - - /* Cogit>>#mcPCForBackwardBranch:startBcpc:in: */ -usqInt -mcPCForBackwardBranchstartBcpcin(sqInt bcpc, sqInt startbcpc, CogBlockMethod *cogMethod) -{ - sqInt aMethodHeader; - sqInt aMethodHeader1; - sqInt aMethodObj; - sqInt annotation; - sqInt bcpc1; - sqInt bsOffset; - sqInt byte; - BytecodeDescriptor *descriptor; - sqInt distance; - sqInt endbcpc; - CogMethod *homeMethod; - sqInt isBackwardBranch; - sqInt isInBlock; - sqInt latestContinuation; - usqInt map; - sqInt mapByte; - usqInt mcpc; - sqInt nExts; - sqInt nextBcpc; - sqInt result; - sqInt targetPC; - - latestContinuation = 0; - /* begin mapFor:bcpc:performUntil:arg: */ - assert(((cogMethod->stackCheckOffset)) > 0); - - /* The stack check maps to the start of the first bytecode, - the first bytecode being effectively after frame build. */ - mcpc = (((usqInt)cogMethod)) + ((cogMethod->stackCheckOffset)); - result = (((((0 + (((int)((usqInt)(HasBytecodePC) << 1)))) & 1) != 0)) - && ((((sqInt)(((void *)bcpc)))) == startbcpc) - ? ((sqInt)(((char *) mcpc))) - : 0); - if (result != 0) { - return result; - } - - /* In both CMMethod and CMBlock cases find the start of the map and - skip forward to the bytecode pc map entry for the stack check. */ - bcpc1 = startbcpc; - if (((cogMethod->cmType)) == CMMethod) { - /* begin cmIsFullBlock */ - isInBlock = 0; - homeMethod = ((CogMethod *) cogMethod); - assert(startbcpc == (startPCOfMethodHeader((homeMethod->methodHeader)))); - map = ((((usqInt)homeMethod)) + ((homeMethod->blockSize))) - 1; - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert((annotation == IsAbsPCReference) - || ((annotation == IsObjectReference) - || ((annotation == IsRelativeCall) - || (annotation == IsDisplacementX2N)))); - latestContinuation = startbcpc; - aMethodObj = (homeMethod->methodObject); - endbcpc = (numBytesOf(aMethodObj)) - 1; - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader) - ? 0x100 - : 0) -# else - 0 -# endif - ; - bcpc1 += deltaToSkipPrimAndErrorStoreInheader(aMethodObj, (homeMethod->methodHeader)); - } - else { - isInBlock = 1; - assert(bcpc1 == ((cogMethod->startpc))); - homeMethod = cmHomeMethod(cogMethod); - map = findMapLocationForMcpcinMethod((((usqInt)cogMethod)) + (sizeof(CogBlockMethod)), homeMethod); - assert(map != 0); - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert(((((usqInt)(annotation)) >> AnnotationShift) == HasBytecodePC) - || ((((usqInt)(annotation)) >> AnnotationShift) == IsDisplacementX2N)); - while (((annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift)) != HasBytecodePC) { - map -= 1; - } - - /* skip fiducial; i.e. the map entry for the pc immediately following the method header. */ - map -= 1; - aMethodObj = (homeMethod->methodObject); - bcpc1 = startbcpc - ( -#if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet((homeMethod->methodHeader)) - ? AltBlockCreationBytecodeSize - : BlockCreationBytecodeSize) -#else // MULTIPLEBYTECODESETS - BlockCreationBytecodeSize -#endif - ); - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader1 = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader1) - ? 0x100 - : 0) -# else - 0 -# endif - ; - byte = (fetchByteofObject(bcpc1, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - endbcpc = (bcpc1 + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc1, -1, aMethodObj)) - : 0)); - bcpc1 = startbcpc; - } - nExts = 0; - while ((((usqInt)((byteAt(map)))) >> AnnotationShift) != HasBytecodePC) { - map -= 1; - } - map -= 1; - while (((mapByte = byteAt(map))) != MapEnd) { - - /* defensive; we exit on bcpc */ - if (mapByte >= FirstAnnotation) { - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if (annotation >= HasBytecodePC) { - if ((annotation == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - while (1) { - byte = (fetchByteofObject(bcpc1, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - if (isInBlock) { - if (bcpc1 >= endbcpc) { - return 0; - } - } - else { - if (((descriptor->isReturn)) - && (bcpc1 >= latestContinuation)) { - return 0; - } - if ((isBranch(descriptor)) - || ((descriptor->isBlockCreation))) { - /* begin latestContinuationPCFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, bcpc1, nExts, aMethodObj); - targetPC = (bcpc1 + ((descriptor->numBytes))) + (((distance < 0) ? 0 : distance)); - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - /* latestContinuation = */ latestContinuation; - } - nextBcpc = (bcpc1 + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc1, nExts, aMethodObj)) - : 0)); - if (((descriptor->isMapped)) - || (isInBlock - && ((descriptor->isMappedInBlock)))) break; - bcpc1 = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - isBackwardBranch = (isBranch(descriptor)) - && ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, bcpc1, nExts, aMethodObj)) < 0)); - result = findBackwardBranchIsBackwardBranchMcpcBcpcMatchingBcpc(descriptor, ((isBackwardBranch - ? (((sqInt)((usqInt)(annotation) << 1))) + 1 - : ((sqInt)((usqInt)(annotation) << 1)))), (((char *) mcpc)), ((isBackwardBranch - ? bcpc1 - (2 * nExts) - : bcpc1)), (((void *)bcpc))); - if (result != 0) { - return result; - } - bcpc1 = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - } - else { - assert(((((usqInt)(mapByte)) >> AnnotationShift) == IsDisplacementX2N) - || ((((usqInt)(mapByte)) >> AnnotationShift) == IsAnnotationExtension)); - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - return 0; -} - - /* Cogit>>#methodNumArgs */ -static sqInt -methodNumArgs(void) -{ - return methodOrBlockNumArgs; -} - - -/* For the purposes of become: see if the two methods are similar, i.e. can - be safely becommed. - This is pretty strict. All literals and bytecodes must be identical. Only - trailer bytes and header - flags can differ. */ - - /* Cogit>>#method:hasSameCodeAs:checkPenultimate: */ -static sqInt NoDbgRegParms -methodhasSameCodeAscheckPenultimate(sqInt methodA, sqInt methodB, sqInt comparePenultimateLiteral) -{ - sqInt bi; - sqInt endPCA; - sqInt headerA; - sqInt headerB; - sqInt li; - sqInt numLitsA; - - headerA = methodHeaderOf(methodA); - headerB = methodHeaderOf(methodB); - numLitsA = literalCountOfMethodHeader(headerA); - endPCA = endPCOf(methodA); - if (((argumentCountOfMethodHeader(headerA)) != (argumentCountOfMethodHeader(headerB))) - || (((temporaryCountOfMethodHeader(headerA)) != (temporaryCountOfMethodHeader(headerB))) - || (((primitiveIndexOfMethodheader(methodA, headerA)) != (primitiveIndexOfMethodheader(methodB, headerB))) - || ((numLitsA != (literalCountOfMethodHeader(headerB))) - || (endPCA > (numBytesOf(methodB))))))) { - return 0; - } - for (li = 1; li < numLitsA; li += 1) { - if ((fetchPointerofObject(li, methodA)) != (fetchPointerofObject(li, methodB))) { - if ((li < (numLitsA - 1)) - || (comparePenultimateLiteral)) { - return 0; - } - } - } - for (bi = (startPCOfMethod(methodA)); bi <= endPCA; bi += 1) { - if ((fetchByteofObject(bi, methodA)) != (fetchByteofObject(bi, methodB))) { - return 0; - } - } - return 1; -} - - /* Cogit>>#mnuOffset */ -sqInt -mnuOffset(void) -{ - return missOffset; -} - - /* Cogit>>#NativePopR: */ -static AbstractInstruction * NoDbgRegParms -gNativePopR(sqInt reg) -{ - return genoperand(PopR, reg); -} - - /* Cogit>>#NativePushR: */ -static AbstractInstruction * NoDbgRegParms -gNativePushR(sqInt reg) -{ - return genoperand(PushR, reg); -} - - /* Cogit>>#NativeRetN: */ -static AbstractInstruction * NoDbgRegParms -gNativeRetN(sqInt offset) -{ - return genoperand(RetN, offset); -} - - /* Cogit>>#needsFrameIfImmutability: */ -static sqInt NoDbgRegParms -needsFrameIfImmutability(sqInt stackDelta) -{ - return IMMUTABILITY; -} - - /* Cogit>>#needsFrameIfInBlock: */ -static sqInt NoDbgRegParms -needsFrameIfInBlock(sqInt stackDelta) -{ - return inBlock > 0; -} - - /* Cogit>>#needsFrameNever: */ -static sqInt NoDbgRegParms -needsFrameNever(sqInt stackDelta) -{ - return 0; -} - - /* Cogit>>#noAssertMethodClassAssociationOf: */ -static sqInt NoDbgRegParms -noAssertMethodClassAssociationOf(sqInt methodPointer) -{ - return literalofMethod((literalCountOfMethodHeader(noAssertHeaderOf(methodPointer))) - 1, methodPointer); -} - - -/* Check that no method is maximally marked. A maximal mark is an indication - the method has been scanned to increase the usage count of its referent - methods. */ - - /* Cogit>>#noCogMethodsMaximallyMarked */ -static sqInt -noCogMethodsMaximallyMarked(void) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) != CMFree) - && (((cogMethod->cmUsageCount)) == CMMaxUsageCount)) { - return 0; - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return 1; -} - - -/* Answer if all targets in the PIC are in-use methods. */ - - /* Cogit>>#noTargetsFreeInClosedPIC: */ -static sqInt NoDbgRegParms -noTargetsFreeInClosedPIC(CogMethod *cPIC) -{ - return !(cPICHasFreedTargets(cPIC)); -} - - /* Cogit>>#OrCq:R:R: */ -static AbstractInstruction * NoDbgRegParms -gOrCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction * first; - - /* begin gen:quickConstant:operand:operand: */ - anInstruction = genoperandoperandoperand(OrCqRR, quickConstant, srcReg, destReg); - return anInstruction; - if (srcReg == destReg) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(OrCqR, quickConstant, destReg); - return anInstruction1; - } - first = genoperandoperand(MoveRR, srcReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(OrCqR, quickConstant, destReg); - return first; -} - - -/* Store the generated machine code, answering the last address */ - - /* Cogit>>#outputInstructionsAt: */ -static sqInt NoDbgRegParms -outputInstructionsAt(sqInt startAddress) -{ - sqInt absoluteAddress; - AbstractInstruction * abstractInstruction; - sqInt i; - sqInt j; - - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - absoluteAddress = startAddress; - for (i = 0; i < opcodeIndex; i += 1) { - maybeBreakGeneratingInstructionWithIndex(i); - abstractInstruction = abstractInstructionAt(i); - assert(((abstractInstruction->address)) == absoluteAddress); - /* begin outputMachineCodeAt: */ - for (j = 0; j < ((abstractInstruction->machineCodeSize)); j += 4) { - longAtput(absoluteAddress + j, ((abstractInstruction->machineCode))[j / 4]); - } - absoluteAddress += (abstractInstruction->machineCodeSize); - } - return absoluteAddress; -} - - -/* Output instructions generated for one of the generated run-time routines, - a trampoline, etc - */ - - /* Cogit>>#outputInstructionsForGeneratedRuntimeAt: */ -static sqInt NoDbgRegParms -outputInstructionsForGeneratedRuntimeAt(sqInt startAddress) -{ - sqInt endAddress; - sqInt size; - - computeMaximumSizes(); - (methodLabel->address = startAddress); - size = generateInstructionsAt(startAddress); - endAddress = outputInstructionsAt(startAddress); - assert((startAddress + size) == endAddress); - methodZoneBase = alignUptoRoutineBoundary(endAddress); - stopsFromto(backEnd, endAddress, methodZoneBase - 1); - return startAddress; -} - - /* Cogit>>#PushCw: */ -static AbstractInstruction * NoDbgRegParms -gPushCw(sqInt wordConstant) -{ - AbstractInstruction *anInstruction; - - /* begin checkLiteral:forInstruction: */ - anInstruction = genoperand(PushCw, wordConstant); - return anInstruction; -} - - -/* Code entry closed PIC full or miss to an instance of a young class or to a - young target method. - Attempt to patch the send site to an open PIC. Answer if the attempt - succeeded; in fact it will - only return if the attempt failed. - The stack looks like: - receiver - args - sp=> sender return address */ - - /* Cogit>>#patchToOpenPICFor:numArgs:receiver: */ -sqInt -patchToOpenPICFornumArgsreceiver(sqInt selector, sqInt numArgs, sqInt receiver) -{ - sqInt extent; - CogMethod *oPIC; - sqInt outerReturn; - - - /* See if an Open PIC is already available. */ - outerReturn = stackTop(); - oPIC = openPICWithSelector(selector); - if (!oPIC) { - - /* otherwise attempt to create an Open PIC. */ - oPIC = cogOpenPICSelectornumArgs(selector, numArgs); - if ((((((sqInt)oPIC)) >= MaxNegativeErrorCode) && ((((sqInt)oPIC)) <= -1))) { - - /* For some reason the PIC couldn't be generated, most likely a lack of code memory. */ - if ((((sqInt)oPIC)) == InsufficientCodeSpace) { - callForCogCompiledCodeCompaction(); - } - return 0; - } - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - extent = rewriteInlineCacheAttagtarget(backEnd, outerReturn, inlineCacheValueForSelectorin(backEnd, selector, mframeHomeMethodExport()), (((sqInt)oPIC)) + cmEntryOffset); - flushICacheFromto(backEnd, (((usqInt)outerReturn)) - extent, ((usqInt)outerReturn)); - flushICacheFromto(backEnd, ((usqInt)oPIC), (((usqInt)oPIC)) + openPICSize); - executeCogMethodfromLinkedSendWithReceiver(oPIC, receiver); - return 1; -} - - -/* This value is used to decide between MNU processing - or interpretation in the closed PIC aborts. */ - - /* Cogit>>#picAbortDiscriminatorValue */ -static sqInt -picAbortDiscriminatorValue(void) -{ - return 0; -} - - -/* Answer the start of the abort sequence for invoking the interpreter in a - closed PIC. - */ - - /* Cogit>>#picInterpretAbortOffset */ -static sqInt -picInterpretAbortOffset(void) -{ - return (interpretOffset()) - (8 /* pushLinkRegisterByteSize */ + (callInstructionByteSize(backEnd))); -} - - /* Cogit>>#previousInstruction */ -static AbstractInstruction * -previousInstruction(void) -{ - assert(opcodeIndex > 0); - return abstractInstructionAt(opcodeIndex - 1); -} - - /* Cogit>>#printCogMethodFor: */ -void -printCogMethodFor(void *address) -{ - CogMethod * cogMethod; - - cogMethod = methodFor(address); - if (cogMethod == null) { - if ((codeEntryFor(address)) == null) { - print("not a method"); - cr(); - } - else { - print("trampoline "); - print(codeEntryNameFor(address)); - cr(); - } - } - else { - printCogMethod(cogMethod); - } -} - - /* Cogit>>#printTrampolineTable */ -void -printTrampolineTable(void) -{ - sqInt i; - - for (i = 0; i < trampolineTableIndex; i += 2) { - printHex(((sqInt)(trampolineAddresses[i + 1]))); - print(": "); - print(((char *) (trampolineAddresses[i]))); - cr(); - } -} - - /* Cogit>>#processorHasDivQuoRemAndMClassIsSmallInteger */ -static sqInt -processorHasDivQuoRemAndMClassIsSmallInteger(void) -{ - return mclassIsSmallInteger(); -} - - /* Cogit>>#processorHasMultiplyAndMClassIsSmallInteger */ -static sqInt -processorHasMultiplyAndMClassIsSmallInteger(void) -{ - return 0; -} - - /* Cogit>>#recordGeneratedRunTime:address: */ -static void NoDbgRegParms -recordGeneratedRunTimeaddress(char *aString, sqInt address) -{ - assert((trampolineTableIndex + 2) <= (NumTrampolines * 2)); - trampolineAddresses[trampolineTableIndex] = aString; - trampolineAddresses[trampolineTableIndex + 1] = (((char *) address)); - - /* self printTrampolineTable */ - trampolineTableIndex += 2; -} - - -/* This one for C support code. */ - - /* Cogit>>#recordPrimTraceFunc */ -sqInt -recordPrimTraceFunc(void) -{ - return recordPrimTrace(); -} - - /* Cogit>>#recordRunTimeObjectReferences */ -static void -recordRunTimeObjectReferences(void) -{ - sqInt i; - AbstractInstruction *instruction; - - for (i = 0; i < opcodeIndex; i += 1) { - instruction = abstractInstructionAt(i); - if (((instruction->annotation)) == IsObjectReference) { - assert(runtimeObjectRefIndex < NumObjRefsInRuntime); - assert(!hasYoungReferent); - if (hasYoungReferent) { - error("attempt to generate run-time routine containing young object reference. Cannot initialize Cogit run-time."); - } - objectReferencesInRuntime[runtimeObjectRefIndex] = (((usqInt)(((instruction->address)) + ((instruction->machineCodeSize))))); - runtimeObjectRefIndex += 1; - } - } -} - - /* Cogit>>#registerMaskFor: */ -static sqInt NoDbgRegParms -registerMaskFor(sqInt reg) -{ - return 1U << reg; -} - - /* Cogit>>#registerMaskFor:and:and: */ -static sqInt NoDbgRegParms -registerMaskForandand(sqInt reg1, sqInt reg2, sqInt reg3) -{ - return ((1U << reg1) | (1U << reg2)) | (1U << reg3); -} - - /* Cogit>>#relocateCallsAndSelfReferencesInMethod: */ -static void NoDbgRegParms -relocateCallsAndSelfReferencesInMethod(CogMethod *cogMethod) -{ - sqInt annotation; - sqInt callDelta; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqLong refDelta; - sqInt result; - - refDelta = (cogMethod->objectHeader); - callDelta = 0; - assert((((cogMethod->cmType)) == CMMethod) - || (((cogMethod->cmType)) == CMOpenPIC)); - assert((callTargetFromReturnAddress(backEnd, (((sqInt)cogMethod)) + missOffset)) == ((((cogMethod->cmType)) == CMMethod - ? methodAbortTrampolineFor((cogMethod->cmNumArgs)) - : picAbortTrampolineFor((cogMethod->cmNumArgs))))); - relocateCallBeforeReturnPCby(backEnd, (((sqInt)cogMethod)) + missOffset, -callDelta); - /* begin mapFor:performUntil:arg: */ - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = relocateIfCallOrMethodReferencemcpcdelta(annotation, (((char *) mcpc)), (((void *)refDelta))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; -} - - /* Cogit>>#relocateCallsInClosedPIC: */ -static void NoDbgRegParms -relocateCallsInClosedPIC(CogMethod *cPIC) -{ - sqInt callDelta; - usqInt entryPoint; - sqInt i; - sqInt pc; - sqLong refDelta; - CogMethod *targetMethod; - - refDelta = (cPIC->objectHeader); - callDelta = 0; - assert((callTargetFromReturnAddress(backEnd, (((sqInt)cPIC)) + missOffset)) == (picAbortTrampolineFor((cPIC->cmNumArgs)))); - relocateCallBeforeReturnPCby(backEnd, (((sqInt)cPIC)) + missOffset, -callDelta); - pc = (((sqInt)cPIC)) + firstCPICCaseOffset; - for (i = 1; i <= ((cPIC->cPICNumCases)); i += 1) { - pc = addressOfEndOfCaseinCPIC(i, cPIC); - entryPoint = (i == 1 - ? jumpLongTargetBeforeFollowingAddress(backEnd, pc) - : jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc)); - if (((((usqInt)cPIC)) <= (((usqInt)entryPoint))) - && (((((usqInt)cPIC)) + ((cPIC->blockSize))) >= (((usqInt)entryPoint)))) { - - /* Interpret/MNU */ - if (i == 1) { - relocateJumpLongBeforeFollowingAddressby(backEnd, pc, refDelta); - } - else { - relocateJumpLongConditionalBeforeFollowingAddressby(backEnd, pc, refDelta); - } - } - else { - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - assert(((targetMethod->cmType)) == CMMethod); - if (i == 1) { - relocateJumpLongBeforeFollowingAddressby(backEnd, pc, -(callDelta - ((targetMethod->objectHeader)))); - } - else { - relocateJumpLongConditionalBeforeFollowingAddressby(backEnd, pc, -(callDelta - ((targetMethod->objectHeader)))); - } - } - } - assert(((cPIC->cPICNumCases)) > 0); - relocateMethodReferenceBeforeAddressby(backEnd, (addressOfEndOfCaseinCPIC(2, cPIC)) + 8 /* loadLiteralByteSize */, refDelta); - relocateJumpLongBeforeFollowingAddressby(backEnd, (((sqInt)cPIC)) + cPICEndOfCodeOffset, -callDelta); -} - - -/* To placate the C static type system... */ - - /* Cogit>>#relocateIfCallOrMethodReference:mcpc:delta: */ -static sqInt NoDbgRegParms -relocateIfCallOrMethodReferencemcpcdelta(sqInt annotation, char *mcpc, CogMethod *refDeltaArg) -{ - usqInt cacheAddress; - sqInt callDelta; - usqInt entryPoint; - usqInt entryPoint1; - char *mcpc1; - NSSendCache *nsSendCache; - sqInt offset1; - sqInt refDelta; - sqInt *sendTable1; - CogMethod *targetMethod; - sqInt unlinkedRoutine; - - refDelta = ((sqInt) refDeltaArg); - callDelta = 0; - if (annotation == IsNSSendCall) { - - /* Retrieve the send cache before relocating the stub call. Fetching the send - cache asserts the stub call points below all the cogged methods, but - until this method is actually moved, the adjusted stub call may appear to - point to somewhere in the method zone. */ - /* begin nsSendCacheFromReturnAddress: */ - mcpc1 = ((char *) (((sqInt)mcpc))); - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc1)); - assert(entryPoint1 < methodZoneBase); - cacheAddress = ((usqInt)(nsSendCacheAt(backEnd, mcpc1))); - assert(isInOldSpace(cacheAddress)); - nsSendCache = ((NSSendCache *) cacheAddress); - relocateCallBeforeReturnPCby(backEnd, ((sqInt)mcpc), -callDelta); - if (((nsSendCache->target)) != 0) { - - /* Send is linked */ - entryPoint = (nsSendCache->target); - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - if (((targetMethod->cmType)) == CMMethod) { - - /* send target not freed; just relocate. The cache has an absolute - target, so only adjust by the target method's displacement. */ - (nsSendCache->target = entryPoint + ((targetMethod->objectHeader))); - } - else { - - /* send target was freed, unlink */ - /* begin voidNSSendCache: */ - (nsSendCache->classTag = 2 /* illegalClassTag */); - (nsSendCache->enclosingObject = 0); - (nsSendCache->target = 0); - } - } - return 0; - } - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint <= methodZoneBase) { - - /* send is not linked; just relocate */ - relocateCallBeforeReturnPCby(backEnd, ((sqInt)mcpc), -callDelta); - return 0; - } - /* begin offsetAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - if (annotation == IsNSSelfSend) { - offset1 = cmEntryOffset; - sendTable1 = selfSendTrampolines; - } - else { - if (annotation == IsNSDynamicSuperSend) { - offset1 = cmEntryOffset; - sendTable1 = dynamicSuperSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - } - } - targetMethod = ((CogMethod *) (entryPoint - offset1)); - if (((targetMethod->cmType)) != CMFree) { - - /* send target not freed; just relocate. */ - relocateCallBeforeReturnPCby(backEnd, ((sqInt)mcpc), -(callDelta - ((targetMethod->objectHeader)))); - return 0; - } - unlinkedRoutine = sendTable1[((((targetMethod->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod->cmNumArgs)) : (NumSendTrampolines - 1))]; - unlinkedRoutine -= callDelta; - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod->selector), enumeratingCogMethod), unlinkedRoutine); - return 0; - } - if (annotation == IsRelativeCall) { - relocateCallBeforeReturnPCby(backEnd, ((sqInt)mcpc), -callDelta); - return 0; - } - if (annotation == IsAbsPCReference) { - relocateMethodReferenceBeforeAddressby(backEnd, ((sqInt)mcpc), refDelta); - } - return 0; -} - - -/* to placate the C static type system... */ - - /* Cogit>>#remapIfObjectRef:pc:hasYoung: */ -static sqInt NoDbgRegParms -remapIfObjectRefpchasYoung(sqInt annotation, char *mcpc, CogMethod *hasYoungPtr) -{ - usqInt cacheAddress; - usqInt cacheTag1; - usqInt entryPoint1; - usqInt entryPoint2; - usqInt literal; - sqInt mappedCacheTag; - sqInt mappedLiteral; - sqInt mappedOop; - NSSendCache *nsSendCache; - sqInt offset1; - sqInt oop; - sqInt *sendTable1; - sqInt tagCouldBeObj1; - CogMethod *targetMethod1; - - if (annotation == IsObjectReference) { - literal = literalBeforeFollowingAddress(backEnd, ((usqInt)mcpc)); - if (couldBeObject(literal)) { - mappedLiteral = remapObject(literal); - if (literal != mappedLiteral) { - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - storeLiteralbeforeFollowingAddress(backEnd, mappedLiteral, ((usqInt)mcpc)); - } - if ((hasYoungPtr != 0) - && (isYoung(mappedLiteral))) { - (*((sqInt *) hasYoungPtr) = 1); - } - } - } - if (annotation == IsNSSendCall) { - /* begin nsSendCacheFromReturnAddress: */ - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - assert(entryPoint1 < methodZoneBase); - cacheAddress = ((usqInt)(nsSendCacheAt(backEnd, mcpc))); - assert(isInOldSpace(cacheAddress)); - nsSendCache = ((NSSendCache *) cacheAddress); - oop = (nsSendCache->selector); - mappedOop = remapObject(oop); - if (oop != mappedOop) { - (nsSendCache->selector = mappedOop); - if ((hasYoungPtr != 0) - && (isYoung(mappedOop))) { - (*((sqInt *) hasYoungPtr) = 1); - } - } - oop = (nsSendCache->enclosingObject); - if (oop != 0) { - mappedOop = remapObject(oop); - if (oop != mappedOop) { - (nsSendCache->enclosingObject = mappedOop); - if ((hasYoungPtr != 0) - && (isYoung(mappedOop))) { - (*((sqInt *) hasYoungPtr) = 1); - } - } - } - return 0; - } - if (annotation >= IsSendCall) { - /* begin entryCacheTagAndCouldBeObjectAt:annotation:into: */ - cacheTag1 = inlineCacheTagAt(backEnd, ((sqInt)mcpc)); - - /* in-line cache tags are the selectors of sends if sends are unlinked, - the selectors of super sends (entry offset = cmNoCheckEntryOffset), - the selectors of open PIC sends (entry offset = cmEntryOffset, target is an Open PIC) - or in-line cache tags (classes, class indices, immediate bit patterns, etc). - Note that selectors can be immediate so there is no guarantee that they - are markable/remappable objects. */ - entryPoint2 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - tagCouldBeObj1 = entryPointTagIsSelector(entryPoint2); - if (tagCouldBeObj1 - && (couldBeObject(cacheTag1))) { - mappedCacheTag = remapObject(cacheTag1); - if (cacheTag1 != mappedCacheTag) { - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheTagat(backEnd, mappedCacheTag, ((usqInt)mcpc)); - } - if ((hasYoungPtr != 0) - && (isYoung(mappedCacheTag))) { - (*((sqInt *) hasYoungPtr) = 1); - } - } - if (hasYoungPtr != 0) { - - /* Since the unlinking routines may rewrite the cacheTag to the send's selector, and - since they don't have the cogMethod to hand and can't add it to youngReferrers, - the method must remain in youngReferrers if the targetMethod's selector is young. */ - if (entryPoint2 > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - if (annotation == IsNSSelfSend) { - offset1 = cmEntryOffset; - sendTable1 = selfSendTrampolines; - } - else { - if (annotation == IsNSDynamicSuperSend) { - offset1 = cmEntryOffset; - sendTable1 = dynamicSuperSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint2 - offset1)); - if (isYoung((targetMethod1->selector))) { - (*((sqInt *) hasYoungPtr) = 1); - } - } - } - } - return 0; -} - - -/* Remap a potential object reference from a closed PIC. - This may be an object reference, an inline cache tag or null. - Answer if the updated literal is young. - mcpc is the address of the next instruction following either - the load of the method literal or the compare of the class tag. */ - - /* Cogit>>#remapMaybeObjRefInClosedPICAt: */ -static sqInt NoDbgRegParms -remapMaybeObjRefInClosedPICAt(sqInt mcpc) -{ - usqInt object; - sqInt subject; - - object = literalBeforeFollowingAddress(backEnd, mcpc); - if (!(couldBeObject(object))) { - return 0; - } - subject = remapOop(object); - if (object != subject) { - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - storeLiteralbeforeFollowingAddress(backEnd, subject, mcpc); - } - return isYoungObject(subject); -} - - -/* Rewrite the three values involved in a CPIC case. Used by the initialize & - extend CPICs. - c.f. expectedClosedPICPrototype: */ -/* write the obj ref/operand via the second ldr */ - - /* Cogit>>#rewriteCPICCaseAt:tag:objRef:target: */ -static void NoDbgRegParms -rewriteCPICCaseAttagobjReftarget(sqInt followingAddress, sqInt newTag, sqInt newObjRef, sqInt newTarget) -{ - sqInt classTagPC; - sqInt methodObjPC; - - methodObjPC = (followingAddress - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */; - storeLiteralbeforeFollowingAddress(backEnd, newObjRef, methodObjPC); - - /* rewite the tag via the first ldr */ - classTagPC = followingAddress - 16 /* jumpLongConditionalByteSize */; - /* begin storeLiteral32:beforeFollowingAddress: */ - storeLiteralbeforeFollowingAddress(((AbstractInstruction *) backEnd), newTag, classTagPC); - rewriteConditionalJumpLongAttarget(backEnd, followingAddress, newTarget); -} - - -/* destReg := fromReg - subReg */ - - /* Cogit>>#SubR:R:R: */ -static AbstractInstruction * NoDbgRegParms -gSubRRR(sqInt subReg, sqInt fromReg, sqInt destReg) -{ - AbstractInstruction * first; - - return genoperandoperandoperand(SubRRR, subReg, fromReg, destReg); - assert(subReg != destReg); - first = genoperandoperand(MoveRR, fromReg, destReg); - genoperandoperand(SubRR, subReg, destReg); - return first; -} - - -/* Answer the number of clean blocks found in the literal frame */ - - /* Cogit>>#scanForCleanBlocks */ -static sqInt -scanForCleanBlocks(void) -{ - sqInt i; - sqInt iLimiT; - sqInt lit; - sqInt numCleanBlocks; - sqInt startPCOrNil; - - numCleanBlocks = 0; - for (i = 1, iLimiT = (literalCountOf(methodObj)); i <= iLimiT; i += 1) { - lit = fetchPointerofObject(i, methodObj); - startPCOrNil = startPCOrNilOfLiteralin(lit, methodObj); - if (!(startPCOrNil == null)) { - numCleanBlocks += 1; - } - } - return numCleanBlocks; -} - - /* Cogit>>#setBreakMethod: */ -void -setBreakMethod(sqInt anObj) -{ - breakMethod = anObj; -} - - -/* If a method is compiled to machine code via a block entry it won't have a - selector. A subsequent send can find the method and hence fill in the - selector. - */ -/* self disassembleMethod: cogMethod */ - - /* Cogit>>#setSelectorOf:to: */ -void -setSelectorOfto(CogMethod *cogMethod, sqInt aSelectorOop) -{ - compilationBreakpointisMNUCase(aSelectorOop, 0); - assert(((cogMethod->cmType)) == CMMethod); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - ((((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)))->selector = aSelectorOop); - if (isYoung(aSelectorOop)) { - ensureInYoungReferrers(cogMethod); - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - /* Cogit>>#spanForCleanBlockStartingAt: */ -static sqInt NoDbgRegParms -spanForCleanBlockStartingAt(sqInt startPC) -{ - BytecodeDescriptor *descriptor; - sqInt end; - sqInt pc; - - pc = startPC; - end = numBytesOf(methodObj); - while (pc <= end) { - /* begin generatorForPC: */ - descriptor = generatorAt(bytecodeSetOffset + (fetchByteofObject(pc, methodObj))); - pc += (descriptor->numBytes); - if ((descriptor->isReturn)) { - return pc - startPC; - } - } - error("couldn't locate end of clean block"); - return 0; -} - - /* Cogit>>#stackCheckOffsetOfBlockAt:isMcpc: */ -static usqInt NoDbgRegParms -stackCheckOffsetOfBlockAtisMcpc(sqInt blockEntryMcpc, sqInt mcpc) -{ - CogBlockMethod *cogBlockMethod; - - cogBlockMethod = ((CogBlockMethod *) (blockEntryMcpc - (sizeof(CogBlockMethod)))); - if (((((sqInt)cogBlockMethod)) + ((cogBlockMethod->stackCheckOffset))) == mcpc) { - return ((usqInt)cogBlockMethod); - } - return 0; -} - - -/* Answer a fake value for the method oop in other than the first case in the - PIC prototype. - Since we use MoveUniqueCw:R: it must not be confused with a - method-relative address. - */ - - /* Cogit>>#subsequentPrototypeMethodOop */ -static sqInt -subsequentPrototypeMethodOop(void) -{ - return (addressIsInCurrentCompilation(0xBADA550) - ? 0xDEADEAD - : 0xBADA550); -} - - /* Cogit>>#traceLinkedSendOffset */ -sqInt -traceLinkedSendOffset(void) -{ - return (cmNoCheckEntryOffset + (callFullInstructionByteSize(backEnd))) + (8 /* pushLinkRegisterByteSize */); -} - - -/* Encode true and false and 0 to N such that they can't be confused for - register numbers (including NoReg) - and can be tested for by isTrampolineArgConstant: and decoded by - trampolineArgValue: - */ - - /* Cogit>>#trampolineArgConstant: */ -static sqInt NoDbgRegParms -trampolineArgConstant(sqInt booleanOrInteger) -{ - assert(booleanOrInteger >= 0); - return -2 - booleanOrInteger; -} - - /* Cogit>>#trampolineName:numArgs: */ -static char * NoDbgRegParms -trampolineNamenumArgs(char *routinePrefix, sqInt numArgs) -{ - char *theString; - - /* begin trampolineName:numArgs:limit: */ - theString = malloc((strlen(routinePrefix)) + 6); - sprintf(theString, "%s%cArgs", routinePrefix, (numArgs <= (NumSendTrampolines - 2) - ? '0' + numArgs - : 'N')); - return theString; -} - - -/* Malloc a string with the contents for the trampoline table */ - - /* Cogit>>#trampolineName:numArgs:limit: */ -static char * NoDbgRegParms -trampolineNamenumArgslimit(char *routinePrefix, int numArgs, sqInt argsLimit) -{ - char *theString; - - theString = malloc((strlen(routinePrefix)) + 6); - sprintf(theString, "%s%cArgs", routinePrefix, (numArgs <= argsLimit - ? '0' + numArgs - : 'N')); - return theString; -} - - /* Cogit>>#trampolineName:numRegArgs: */ -static char * NoDbgRegParms -trampolineNamenumRegArgs(char *routinePrefix, sqInt numArgs) -{ - sqInt argsLimit; - char *theString; - - /* begin trampolineName:numArgs:limit: */ - argsLimit = 2 /* numRegArgs */; - theString = malloc((strlen(routinePrefix)) + 6); - sprintf(theString, "%s%cArgs", routinePrefix, (numArgs <= argsLimit - ? '0' + numArgs - : 'N')); - return theString; -} - - /* Cogit>>#unknownBytecode */ -static sqInt -unknownBytecode(void) -{ - return EncounteredUnknownBytecode; -} - - -/* Unlink all sends in cog methods. */ - - /* Cogit>>#unlinkAllSends */ -void -unlinkAllSends(void) -{ - sqInt annotation; - CogMethod *cogMethod; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - - if (!methodZoneBase) { - return; - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - cogMethod = ((CogMethod *) methodZoneBase); - voidOpenPICList(); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - /* begin mapFor:performUntil:arg: */ - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfLinkedSendpcignored(annotation, (((char *) mcpc)), 0); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - else { - if (((cogMethod->cmType)) != CMFree) { - freeMethod(cogMethod); - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); -} - - -/* To placate the C static type system... */ - - /* Cogit>>#unlinkIfFreeOrLinkedSend:pc:of: */ -static sqInt NoDbgRegParms -unlinkIfFreeOrLinkedSendpcof(sqInt annotation, char *mcpc, CogMethod *theSelector) -{ - usqInt cacheAddress; - usqInt entryPoint; - usqInt entryPoint1; - char *mcpc1; - NSSendCache *nsSendCache; - sqInt offset1; - sqInt *sendTable1; - CogMethod * targetMethod; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - if (annotation == IsNSSendCall) { - /* begin nsSendCacheFromReturnAddress: */ - mcpc1 = ((char *) (((sqInt)mcpc))); - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc1)); - assert(entryPoint1 < methodZoneBase); - cacheAddress = ((usqInt)(nsSendCacheAt(backEnd, mcpc1))); - assert(isInOldSpace(cacheAddress)); - nsSendCache = ((NSSendCache *) cacheAddress); - if (((entryPoint = (nsSendCache->target))) != 0) { - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - if ((((targetMethod->cmType)) == CMFree) - || (((nsSendCache->selector)) == (((sqInt) theSelector)))) { - /* begin voidNSSendCache: */ - (nsSendCache->classTag = 2 /* illegalClassTag */); - (nsSendCache->enclosingObject = 0); - (nsSendCache->target = 0); - } - } - return 0; - } - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - if (annotation == IsNSSelfSend) { - offset1 = cmEntryOffset; - sendTable1 = selfSendTrampolines; - } - else { - if (annotation == IsNSDynamicSuperSend) { - offset1 = cmEntryOffset; - sendTable1 = dynamicSuperSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if ((((targetMethod1->cmType)) == CMFree) - || (((targetMethod1->selector)) == (((sqInt) theSelector)))) { - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - } - return 0; -} - - /* Cogit>>#unlinkIfInvalidClassSend:pc:ignored: */ -static sqInt NoDbgRegParms -unlinkIfInvalidClassSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity) -{ - usqInt cacheAddress; - usqInt entryPoint; - usqInt entryPoint1; - char *mcpc1; - NSSendCache *nsSendCache; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - if (annotation == IsNSSendCall) { - /* begin nsSendCacheFromReturnAddress: */ - mcpc1 = ((char *) (((sqInt)mcpc))); - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc1)); - assert(entryPoint1 < methodZoneBase); - cacheAddress = ((usqInt)(nsSendCacheAt(backEnd, mcpc1))); - assert(isInOldSpace(cacheAddress)); - nsSendCache = ((NSSendCache *) cacheAddress); - if ((((nsSendCache->classTag)) != 2 /* illegalClassTag */) - && (isForwardedClassIndex((nsSendCache->classTag)))) { - /* begin voidNSSendCache: */ - (nsSendCache->classTag = 2 /* illegalClassTag */); - (nsSendCache->enclosingObject = 0); - (nsSendCache->target = 0); - } - } - return 0; - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send, but maybe a super send or linked to an OpenPIC, in which case the cache tag will be a selector.... */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - if (annotation == IsNSSelfSend) { - offset1 = cmEntryOffset; - sendTable1 = selfSendTrampolines; - } - else { - if (annotation == IsNSDynamicSuperSend) { - offset1 = cmEntryOffset; - sendTable1 = dynamicSuperSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (!(((annotation == IsSuperSend) - || (((annotation >= IsDirectedSuperSend) && (annotation <= IsDirectedSuperBindingSend)))) - || (((targetMethod1->cmType)) == CMOpenPIC))) { - if (!(isValidClassTag(inlineCacheTagAt(backEnd, ((sqInt)mcpc))))) { - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - } - } - return 0; -} - - /* Cogit>>#unlinkIfLinkedSendToFree:pc:ignored: */ -static sqInt NoDbgRegParms -unlinkIfLinkedSendToFreepcignored(sqInt annotation, char *mcpc, sqInt superfluity) -{ - usqInt cacheAddress; - usqInt entryPoint; - usqInt entryPoint1; - char *mcpc1; - NSSendCache *nsSendCache; - CogMethod *nsTargetMethod; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - if (annotation == IsNSSendCall) { - /* begin nsSendCacheFromReturnAddress: */ - mcpc1 = ((char *) (((sqInt)mcpc))); - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc1)); - assert(entryPoint1 < methodZoneBase); - cacheAddress = ((usqInt)(nsSendCacheAt(backEnd, mcpc1))); - assert(isInOldSpace(cacheAddress)); - nsSendCache = ((NSSendCache *) cacheAddress); - if (((entryPoint = (nsSendCache->target))) != 0) { - - /* It's a linked send. */ - nsTargetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - if (((nsTargetMethod->cmType)) == CMFree) { - /* begin voidNSSendCache: */ - (nsSendCache->classTag = 2 /* illegalClassTag */); - (nsSendCache->enclosingObject = 0); - (nsSendCache->target = 0); - } - } - return 0; - } - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - if (annotation == IsNSSelfSend) { - offset1 = cmEntryOffset; - sendTable1 = selfSendTrampolines; - } - else { - if (annotation == IsNSDynamicSuperSend) { - offset1 = cmEntryOffset; - sendTable1 = dynamicSuperSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (((targetMethod1->cmType)) == CMFree) { - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - } - return 0; -} - - -/* To placate the C static type system... */ - - /* Cogit>>#unlinkIfLinkedSend:pc:if: */ -static sqInt NoDbgRegParms -unlinkIfLinkedSendpcif(sqInt annotation, char *mcpc, CogMethod *criterionArg) -{ - usqInt cacheAddress; - sqInt (*criterion)(CogMethod *); - usqInt entryPoint; - usqInt entryPoint1; - char *mcpc1; - NSSendCache *nsSendCache; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - criterion = ((void *)criterionArg); - if (annotation == IsNSSendCall) { - /* begin nsSendCacheFromReturnAddress: */ - mcpc1 = ((char *) (((sqInt)mcpc))); - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc1)); - assert(entryPoint1 < methodZoneBase); - cacheAddress = ((usqInt)(nsSendCacheAt(backEnd, mcpc1))); - assert(isInOldSpace(cacheAddress)); - nsSendCache = ((NSSendCache *) cacheAddress); - if ((((entryPoint = (nsSendCache->target))) != 0) - && (criterion((((CogMethod *) (entryPoint - cmNoCheckEntryOffset)))))) { - /* begin voidNSSendCache: */ - (nsSendCache->classTag = 2 /* illegalClassTag */); - (nsSendCache->enclosingObject = 0); - (nsSendCache->target = 0); - } - return 0; - } - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - if (annotation == IsNSSelfSend) { - offset1 = cmEntryOffset; - sendTable1 = selfSendTrampolines; - } - else { - if (annotation == IsNSDynamicSuperSend) { - offset1 = cmEntryOffset; - sendTable1 = dynamicSuperSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (criterion(targetMethod1)) { - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - } - return 0; -} - - /* Cogit>>#unlinkIfLinkedSend:pc:ignored: */ -static sqInt NoDbgRegParms -unlinkIfLinkedSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity) -{ - usqInt cacheAddress; - usqInt entryPoint; - usqInt entryPoint1; - char *mcpc1; - NSSendCache *nsSendCache; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - if (annotation == IsNSSendCall) { - /* begin nsSendCacheFromReturnAddress: */ - mcpc1 = ((char *) (((sqInt)mcpc))); - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc1)); - assert(entryPoint1 < methodZoneBase); - cacheAddress = ((usqInt)(nsSendCacheAt(backEnd, mcpc1))); - assert(isInOldSpace(cacheAddress)); - nsSendCache = ((NSSendCache *) cacheAddress); - if (((nsSendCache->classTag)) != 2 /* illegalClassTag */) { - - /* Send is linked */ - /* begin voidNSSendCache: */ - (nsSendCache->classTag = 2 /* illegalClassTag */); - (nsSendCache->enclosingObject = 0); - (nsSendCache->target = 0); - } - return 0; - } - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - if (annotation == IsNSSelfSend) { - offset1 = cmEntryOffset; - sendTable1 = selfSendTrampolines; - } - else { - if (annotation == IsNSDynamicSuperSend) { - offset1 = cmEntryOffset; - sendTable1 = dynamicSuperSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - return 0; -} - - /* Cogit>>#unlinkIfLinkedSend:pc:to: */ -static sqInt NoDbgRegParms -unlinkIfLinkedSendpcto(sqInt annotation, char *mcpc, sqInt theCogMethod) -{ - usqInt cacheAddress; - usqInt entryPoint; - usqInt entryPoint1; - char *mcpc1; - NSSendCache *nsSendCache; - sqInt offset1; - sqInt *sendTable1; - sqInt targetMethod; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - if (annotation == IsNSSendCall) { - /* begin nsSendCacheFromReturnAddress: */ - mcpc1 = ((char *) (((sqInt)mcpc))); - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc1)); - assert(entryPoint1 < methodZoneBase); - cacheAddress = ((usqInt)(nsSendCacheAt(backEnd, mcpc1))); - assert(isInOldSpace(cacheAddress)); - nsSendCache = ((NSSendCache *) cacheAddress); - if (((entryPoint = (nsSendCache->target))) != 0) { - targetMethod = entryPoint - cmNoCheckEntryOffset; - if (targetMethod == theCogMethod) { - /* begin voidNSSendCache: */ - (nsSendCache->classTag = 2 /* illegalClassTag */); - (nsSendCache->enclosingObject = 0); - (nsSendCache->target = 0); - } - } - return 0; - } - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - if (annotation == IsNSSelfSend) { - offset1 = cmEntryOffset; - sendTable1 = selfSendTrampolines; - } - else { - if (annotation == IsNSDynamicSuperSend) { - offset1 = cmEntryOffset; - sendTable1 = dynamicSuperSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if ((((sqInt)targetMethod1)) == theCogMethod) { - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - } - return 0; -} - - -/* Unlink all sends in cog methods whose class tag is that of a forwarded - class. - */ - - /* Cogit>>#unlinkSendsLinkedForInvalidClasses */ -void -unlinkSendsLinkedForInvalidClasses(void) -{ - sqInt annotation; - CogMethod *cogMethod; - sqInt freedPIC; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - - if (!methodZoneBase) { - return; - } - cogMethod = ((CogMethod *) methodZoneBase); - codeModified = (freedPIC = 0); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - /* begin mapFor:performUntil:arg: */ - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfInvalidClassSendpcignored(annotation, (((char *) mcpc)), 0); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - else { - if ((((cogMethod->cmType)) == CMClosedPIC) - && (cPICHasForwardedClass(cogMethod))) { - freeMethod(cogMethod); - freedPIC = 1; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (freedPIC) { - unlinkSendsToFree(); - } - else { - if (codeModified) { - - /* After possibly updating inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } - } -} - - -/* Unlink all sends in cog methods. Free all Closed PICs with the selector, - or with an MNU case if isMNUSelector. First check if any method actually - has the selector; if not there can't be any linked send to it. This - routine (including descendents) is performance critical. It contributes - perhaps 30% of entire execution time in Compiler recompileAll. */ - - /* Cogit>>#unlinkSendsOf:isMNUSelector: */ -void -unlinkSendsOfisMNUSelector(sqInt selector, sqInt isMNUSelector) -{ - sqInt annotation; - CogMethod *cogMethod; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt mustScanAndUnlink; - sqInt result; - - if (!methodZoneBase) { - return; - } - cogMethod = ((CogMethod *) methodZoneBase); - mustScanAndUnlink = 0; - if (isMNUSelector) { - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - if ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock)) { - assert(((cogMethod->cmType)) == CMClosedPIC); - freeMethod(cogMethod); - mustScanAndUnlink = 1; - } - else { - if (((cogMethod->selector)) == selector) { - mustScanAndUnlink = 1; - if (((cogMethod->cmType)) == CMClosedPIC) { - freeMethod(cogMethod); - } - } - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - } - else { - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) != CMFree) - && (((cogMethod->selector)) == selector)) { - mustScanAndUnlink = 1; - if (((cogMethod->cmType)) == CMClosedPIC) { - freeMethod(cogMethod); - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - } - if (!mustScanAndUnlink) { - return; - } - codeModified = 0; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - /* begin mapFor:performUntil:arg: */ - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfFreeOrLinkedSendpcof(annotation, (((char *) mcpc)), (((CogMethod *) selector))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (codeModified) { - - /* After possibly updating inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - -/* Unlink all sends in cog methods to free methods and/or pics. */ - - /* Cogit>>#unlinkSendsToFree */ -void -unlinkSendsToFree(void) -{ - sqInt annotation; - CogMethod *cogMethod; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - - if (!methodZoneBase) { - return; - } - codeModified = 0; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - /* begin mapFor:performUntil:arg: */ - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfLinkedSendToFreepcignored(annotation, (((char *) mcpc)), 0); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - else { - if (((cogMethod->cmType)) == CMClosedPIC) { - assert(noTargetsFreeInClosedPIC(cogMethod)); - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (codeModified) { - - /* After possibly updating inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } -} - - -/* Unlink all sends in cog methods to methods with a machine code - primitive, and free machine code primitive methods if freeIfTrue. - To avoid having to scan PICs, free any and all PICs */ - - /* Cogit>>#unlinkSendsToMethodsSuchThat:AndFreeIf: */ -void -unlinkSendsToMethodsSuchThatAndFreeIf(sqInt (*criterion)(CogMethod *), sqInt freeIfTrue) -{ - sqInt annotation; - CogMethod *cogMethod; - sqInt freedSomething; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - - if (!methodZoneBase) { - return; - } - codeModified = (freedSomething = 0); - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - if (freeIfTrue - && (criterion(cogMethod))) { - freeMethod(cogMethod); - freedSomething = 1; - } - else { - /* begin mapFor:performUntil:arg: */ - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfLinkedSendpcif(annotation, (((char *) mcpc)), (((CogMethod *) criterion))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - } - else { - if (((cogMethod->cmType)) == CMClosedPIC) { - freeMethod(cogMethod); - freedSomething = 1; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (freedSomething) { - unlinkSendsToFree(); - } - else { - if (codeModified) { - - /* After possibly updating inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } - } -} - - -/* Unlink all sends in cog methods to a particular target method. - If targetMethodObject isn't actually a method (perhaps being - used via invokeAsMethod) then there's nothing to do. */ - - /* Cogit>>#unlinkSendsTo:andFreeIf: */ -void -unlinkSendsToandFreeIf(sqInt targetMethodObject, sqInt freeIfTrue) -{ - sqInt annotation; - CogMethod *cogMethod; - sqInt freedPIC; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - CogMethod *targetMethod; - - if (!((isOopCompiledMethod(targetMethodObject)) - && (methodHasCogMethod(targetMethodObject)))) { - return; - } - targetMethod = cogMethodOf(targetMethodObject); - if (!methodZoneBase) { - return; - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - codeModified = (freedPIC = 0); - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - /* begin mapFor:performUntil:arg: */ - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfLinkedSendpcto(annotation, (((char *) mcpc)), targetMethod); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - else { - if ((((cogMethod->cmType)) == CMClosedPIC) - && (cPICHasTarget(cogMethod, targetMethod))) { - freeMethod(cogMethod); - freedPIC = 1; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (freeIfTrue) { - freeMethod(targetMethod); - } - if (freedPIC) { - unlinkSendsToFree(); - } - else { - if (codeModified) { - - /* After possibly updating inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - /* Cogit>>#voidCogCompiledCode */ -void -voidCogCompiledCode(void) -{ - CogMethod *cogMethod; - - /* begin clearCogCompiledCode */ - unpairedMethodList = null; - cogMethod = ((CogMethod *) baseAddress); - while ((((usqInt)cogMethod)) < mzFreeStart) { - if (((cogMethod->cmType)) == CMMethod) { - freeMethod(cogMethod); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - /* begin manageFrom:to: */ - mzFreeStart = (/* baseAddress = */ baseAddress); - youngReferrers = (/* limitAddress = */ limitAddress); - openPICList = null; - unpairedMethodList = null; - methodBytesFreedSinceLastCompaction = 0; - methodCount = 0; -} - - -/* Access for the object representations when they need to prepend code to - trampolines. - */ -/* Eliminate stale dependent info. */ - - /* Cogit>>#zeroOpcodeIndex */ -static void -zeroOpcodeIndex(void) -{ - sqInt i; - - for (i = 0; i < opcodeIndex; i += 1) { - ((abstractOpcodes[i]).dependent = null); - } - zeroOpcodeIndexForNewOpcodes(); -} - - -/* Access for the object representations when they need to prepend code to - trampolines. - */ - - /* Cogit>>#zeroOpcodeIndexForNewOpcodes */ -static void -zeroOpcodeIndexForNewOpcodes(void) -{ - opcodeIndex = 0; -} - - /* CogMethod>>#counters */ -static sqInt NoDbgRegParms -counters(CogMethod * self_in_counters) -{ - return 0; -} - - /* CogMethodZone>>#addToOpenPICList: */ -static void NoDbgRegParms -addToOpenPICList(CogMethod *anOpenPIC) -{ - assert(((anOpenPIC->cmType)) == CMOpenPIC); - assert((openPICList == null) - || (((openPICList->cmType)) == CMOpenPIC)); - assertValidDualZoneWriteAddress(anOpenPIC); - (anOpenPIC->nextOpenPIC = ((usqInt)openPICList)); - openPICList = ((CogMethod *) ((((usqInt)anOpenPIC)) - (getCodeToDataDelta()))); -} - - /* CogMethodZone>>#addToUnpairedMethodList: */ -static void NoDbgRegParms -addToUnpairedMethodList(CogMethod *aCogMethod) -{ - assert(((aCogMethod->cmType)) == CMMethod); - assert((noAssertMethodClassAssociationOf((aCogMethod->methodObject))) == (nilObject())); - assert((unpairedMethodList == null) - || ((((((CogMethod *) unpairedMethodList))->cmType)) == CMMethod)); - assertValidDualZoneWriteAddress(aCogMethod); - (aCogMethod->nextMethodOrIRCs = unpairedMethodList); - unpairedMethodList = (((usqInt)aCogMethod)) - (getCodeToDataDelta()); -} - - /* CogMethodZone>>#addToYoungReferrers: */ -static void NoDbgRegParms -addToYoungReferrers(CogMethod *cogMethod) -{ - assertValidDualZoneWriteAddress(cogMethod); - assert((occurrencesInYoungReferrers(cogMethod)) == 0); - assert((cogMethod->cmRefersToYoung)); - assert((youngReferrers <= limitAddress) - && (youngReferrers >= (limitAddress - (methodCount * BytesPerWord)))); - if (!(asserta((limitAddress - (methodCount * BytesPerWord)) >= mzFreeStart))) { - error("no room on youngReferrers list"); - } - youngReferrers -= BytesPerWord; - codeLongAtput(youngReferrers, (((usqInt)cogMethod)) - (getCodeToDataDelta())); -} - - /* CogMethodZone>>#allocate: */ -static usqInt NoDbgRegParms -allocate(sqInt numBytes) -{ - usqInt allocation; - sqInt roundedBytes; - - roundedBytes = (numBytes + 7) & -8; - if ((mzFreeStart + roundedBytes) >= (limitAddress - (methodCount * BytesPerWord))) { - return 0; - } - allocation = mzFreeStart; - mzFreeStart += roundedBytes; - methodCount += 1; - return allocation; -} - - -/* Answer the method containing mcpc for the purposes of code zone - compaction, where mcpc is actually the value of instructionPointer at the - time of a compaction. */ - - /* CogMethodZone>>#cogMethodContaining: */ -CogMethod * -cogMethodContaining(usqInt mcpc) -{ - CogMethod * cogMethod; - CogMethod * prevMethod; - - if (mcpc > limitAddress) { - return null; - } - if (mcpc < baseAddress) { - /* begin assertMcpcIsPrimReturn: */ - assert((mcpc == cePrimReturnEnterCogCode) - || (mcpc == cePrimReturnEnterCogCodeProfiling)); - return null; - } - assert(mcpc < (freeStart())); - cogMethod = ((CogMethod *) baseAddress); - while ((((usqInt)cogMethod)) < mcpc) { - prevMethod = cogMethod; - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - assert((prevMethod != null) - && ((mcpc == ((((usqInt)prevMethod)) + ((prevMethod->stackCheckOffset)))) - || ((mcpcisAtStackCheckOfBlockMethodIn(mcpc, prevMethod)) - || (((primitiveIndexOfMethodheader((prevMethod->methodObject), (prevMethod->methodHeader))) > 0) - || ((isCallPrecedingReturnPC(backEnd(), mcpc)) - && ((callTargetFromReturnAddress(backEnd(), mcpc)) == (ceCheckForInterruptTrampoline()))))))); - return prevMethod; -} - - /* CogMethodZone>>#compactCompiledCode */ -static void -compactCompiledCode(void) -{ - unsigned short bytes; - CogMethod *dest; - sqLong objectHeaderValue; - CogMethod *source; - CogMethod * writableVersion; - - compactionInProgress = 1; - methodCount = 0; - objectHeaderValue = nullHeaderForMachineCodeMethod(); - source = ((CogMethod *) baseAddress); - voidOpenPICList(); - voidUnpairedMethodList(); - while ((source < (limitZony())) - && (((source->cmType)) != CMFree)) { - assert((cogMethodDoesntLookKosher(source)) == 0); - /* begin writableMethodFor: */ - writableVersion = ((CogMethod *) ((((usqInt)source)) + codeToDataDelta)); - (writableVersion->objectHeader = objectHeaderValue); - if (((source->cmUsageCount)) > 0) { - (writableVersion->cmUsageCount = ((source->cmUsageCount)) / 2); - } - /* begin maybeLinkOnUnpairedMethodList: */ - if ((((source->cmType)) == CMMethod) - && ((((sqInt)(rawHeaderOf((source->methodObject))))) != (((sqInt)source)))) { - ((((CogMethod *) ((((usqInt)source)) + codeToDataDelta)))->nextMethodOrIRCs = unpairedMethodList); - unpairedMethodList = ((usqInt)source); - } - /* begin clearSavedPICUsageCount: */ - if (((source->cmType)) == CMOpenPIC) { - addToOpenPICList(writableVersion); - } - methodCount += 1; - source = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)source)) + ((source->blockSize))))); - } - if (source >= (limitZony())) { - haltmsg("no free methods; cannot compact."); - return; - } - dest = source; - while (source < (limitZony())) { - assert((maybeFreeCogMethodDoesntLookKosher(source)) == 0); - bytes = (source->blockSize); - if (((source->cmType)) != CMFree) { - methodCount += 1; - codeMemmove(dest, source, bytes); - /* begin maybeFlushWritableZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - if (codeToDataDelta > 0) { - flushDCacheFromto(backEnd, ((usqInt)dest), (((usqInt)dest)) + bytes); - } -# endif - ((writableVersion = ((CogMethod *) ((((usqInt)dest)) + codeToDataDelta)))->objectHeader = objectHeaderValue); - if (((dest->cmType)) == CMMethod) { - - /* For non-Newspeak there should be a one-to-one mapping between bytecoded and - cog methods. For Newspeak not necessarily, but only for anonymous accessors. */ - /* Only update the original method's header if it is referring to this CogMethod. */ - if ((((sqInt)(rawHeaderOf((dest->methodObject))))) == (((sqInt)source))) { - rawHeaderOfput((dest->methodObject), ((sqInt)dest)); - } - else { - assert((noAssertMethodClassAssociationOf((dest->methodObject))) == (nilObject())); - /* begin linkOnUnpairedMethodList: */ - (dest->nextMethodOrIRCs = unpairedMethodList); - unpairedMethodList = ((usqInt)dest); - } - } - else { - /* begin clearSavedPICUsageCount: */ - if (((dest->cmType)) == CMOpenPIC) { - addToOpenPICList(writableVersion); - } - } - if (((dest->cmUsageCount)) > 0) { - (writableVersion->cmUsageCount = ((dest->cmUsageCount)) / 2); - } - /* begin maybeFlushWritableZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - if (codeToDataDelta > 0) { - flushDCacheFromto(backEnd, ((usqInt)dest), ((usqInt)(dest + 1))); - } -# endif - dest = ((CogMethod *) ((((usqInt)dest)) + bytes)); - } - source = ((CogMethod *) ((((usqInt)source)) + bytes)); - } - mzFreeStart = ((usqInt)dest); - methodBytesFreedSinceLastCompaction = 0; - compactionInProgress = 0; -} - - /* CogMethodZone>>#ensureInYoungReferrers: */ -static void NoDbgRegParms -ensureInYoungReferrers(CogMethod *cogMethod) -{ - CogMethod * writableMethod; - - assertValidDualZoneReadAddress(cogMethod); - if (!((cogMethod->cmRefersToYoung))) { - assert((occurrencesInYoungReferrers(cogMethod)) == 0); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - ((writableMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)))->cmRefersToYoung = 1); - addToYoungReferrers(writableMethod); - } -} - - -/* Newspeak uses a set of methods to implement accessors, a setter and a - getter for - each inst var offset (e.g. 0 to 255). These accessors are installed under - the relevant - selectors in different method dictionaries as required. These methods - effectively have multiple selectors. The current inline cache design - stores the selector of a - linked send in the header of the target method. So this requires a - one-to-many mapping of bytecoded method to cog method, with the bytecoded - method referring - directly to only one cog method, which will have a specific selector, not - necessarily the right one. It is therefore worth-while searching for a cog - method on this bytecoded - method that has the right selector. To speed up the search we maintain all - such unpaired - methods on the unpairedMethodList, which is linked through - nextMethodOrIRCs. */ - - /* CogMethodZone>>#findPreviouslyCompiledVersionOf:with: */ -static CogMethod * NoDbgRegParms -findPreviouslyCompiledVersionOfwith(sqInt aMethodObj, sqInt aSelectorOop) -{ - CogMethod *cogMethod; - - if ((methodHasCogMethod(aMethodObj)) - && ((methodClassAssociationOf(aMethodObj)) == (nilObject()))) { - cogMethod = ((CogMethod *) unpairedMethodList); - while (cogMethod != null) { - assert(((cogMethod->cmType)) == CMMethod); - if ((((cogMethod->selector)) == aSelectorOop) - && (((cogMethod->methodObject)) == aMethodObj)) { - return cogMethod; - } - cogMethod = ((CogMethod *) ((cogMethod->nextMethodOrIRCs))); - } - } - return null; -} - - /* CogMethodZone>>#followForwardedLiteralsInOpenPICList */ -static void -followForwardedLiteralsInOpenPICList(void) -{ - CogMethod *openPIC; - - openPIC = openPICList; - while (openPIC != null) { - followForwardedLiteralsIn(openPIC); - openPIC = ((CogMethod *) ((openPIC->nextOpenPIC))); - } - pruneYoungReferrers(); -} - - /* CogMethodZone>>#freeMethod: */ -static void NoDbgRegParms -freeMethod(CogMethod *cogMethod) -{ - usqInt maybeIRCs; - CogMethod * writableMethod; - - assert(((cogMethod->cmType)) != CMFree); - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - if (((cogMethod->cmType)) == CMMethod) { - - /* For non-Newspeak there should be a one-to-one mapping between bytecoded and - cog methods. For Newspeak not necessarily, but only for anonymous accessors. */ - /* Only reset the original method's header if it is referring to this CogMethod. */ - if ((((sqInt)(rawHeaderOf((cogMethod->methodObject))))) == (((sqInt)cogMethod))) { - rawHeaderOfput((cogMethod->methodObject), (cogMethod->methodHeader)); - if (((cogMethod->nextMethodOrIRCs)) > limitAddress) { - /* begin freeIRCs: */ - maybeIRCs = (cogMethod->nextMethodOrIRCs); - if (oopisGreaterThan(maybeIRCs, nilObject())) { - freeObject(maybeIRCs - BaseHeaderSize); - } - } - } - else { - assert((noAssertMethodClassAssociationOf((cogMethod->methodObject))) == (nilObject())); - removeFromUnpairedMethodList(cogMethod); - } - } - if (((cogMethod->cmType)) == CMOpenPIC) { - removeFromOpenPICList(cogMethod); - } - /* begin writableMethodFor: */ - writableMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - (writableMethod->cmRefersToYoung = 0); - (writableMethod->cmType = CMFree); - methodBytesFreedSinceLastCompaction += (cogMethod->blockSize); -} - - -/* Free methods, preferring older methods for compaction, up to some - fraction, currently a quarter. - */ - - /* CogMethodZone>>#freeOlderMethodsForCompaction */ -static void -freeOlderMethodsForCompaction(void) -{ - sqInt amountToFree; - CogMethod *cogMethod; - sqInt freeableUsage; - sqInt freedSoFar; - sqInt initialFreeSpace; - sqInt zoneSize; - - zoneSize = limitAddress - baseAddress; - initialFreeSpace = (limitAddress - mzFreeStart) + methodBytesFreedSinceLastCompaction; - freedSoFar = initialFreeSpace; - - /* 4 needs to be e.g. a start-up parameter */ - amountToFree = zoneSize / 4; - freeableUsage = 0; - do { - cogMethod = ((CogMethod *) baseAddress); - while (((((usqInt)cogMethod)) < mzFreeStart) - && (freedSoFar < amountToFree)) { - if ((((cogMethod->cmType)) != CMFree) - && (((cogMethod->cmUsageCount)) <= freeableUsage)) { - freeMethod(cogMethod); - freedSoFar += (cogMethod->blockSize); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - } while((freedSoFar < amountToFree) - && (((freeableUsage += 1)) < CMMaxUsageCount)); -} - - -/* Answer that all entries in youngReferrers are in-use and have the - cmRefersToYoung flag set. - Used to check that the youngreferrers pruning routines work correctly. */ - - /* CogMethodZone>>#kosherYoungReferrers */ -sqInt -kosherYoungReferrers(void) -{ - CogMethod * cogMethod; - usqInt pointer; - CogMethod * prevMethod; - - if ((youngReferrers > limitAddress) - || (youngReferrers < mzFreeStart)) { - return 0; - } - pointer = youngReferrers; - while (pointer < limitAddress) { - cogMethod = ((CogMethod *) (longAt(pointer))); - if (((cogMethod->cmType)) != CMFree) { - if (!((cogMethod->cmRefersToYoung))) { - return 0; - } - if ((occurrencesInYoungReferrers(cogMethod)) != 1) { - return 0; - } - } - pointer += BytesPerWord; - } - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - prevMethod = cogMethod; - if (((cogMethod->cmType)) != CMFree) { - if ((occurrencesInYoungReferrers(cogMethod)) != (((cogMethod->cmRefersToYoung) - ? 1 - : 0))) { - return 0; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - if (cogMethod == prevMethod) { - return 0; - } - } - return 1; -} - - -/* For assert checking... */ - - /* CogMethodZone>>#mcpc:isAtStackCheckOfBlockMethodIn: */ -static sqInt NoDbgRegParms -mcpcisAtStackCheckOfBlockMethodIn(sqInt mcpc, CogMethod *cogMethod) -{ - if (((cogMethod->blockEntryOffset)) == 0) { - return 0; - } - return (blockDispatchTargetsForperformarg(cogMethod, stackCheckOffsetOfBlockAtisMcpc, mcpc)) != 0; -} - - /* CogMethodZone>>#methodFor: */ -CogMethod * -methodFor(void *address) -{ - CogMethod * cogMethod; - CogMethod * nextMethod; - - cogMethod = ((CogMethod *) baseAddress); - while ((cogMethod < (limitZony())) - && ((((usqInt)cogMethod)) <= (((usqInt)address)))) { - /* begin methodAfter: */ - nextMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - if (nextMethod == cogMethod) { - return null; - } - if (((((usqInt)address)) >= (((usqInt)cogMethod))) - && ((((usqInt)address)) < (((usqInt)nextMethod)))) { - return cogMethod; - } - cogMethod = nextMethod; - } - return null; -} - - /* CogMethodZone>>#methodsCompiledToMachineCodeInto: */ -sqInt -methodsCompiledToMachineCodeInto(sqInt arrayObj) -{ - CogMethod *cogMethod; - sqInt methodIndex; - - methodIndex = 0; - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - storePointerUncheckedofObjectwithValue(methodIndex, arrayObj, (cogMethod->methodObject)); - methodIndex += 1; - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return methodIndex; -} - - /* CogMethodZone>>#numMethods */ -sqInt -numMethods(void) -{ - return methodCount; -} - - /* CogMethodZone>>#numMethodsOfType: */ -sqInt -numMethodsOfType(sqInt cogMethodType) -{ - CogMethod *cogMethod; - sqInt n; - - n = 0; - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == cogMethodType) { - n += 1; - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return n; -} - - /* CogMethodZone>>#occurrencesInYoungReferrers: */ -static sqInt NoDbgRegParms -occurrencesInYoungReferrers(CogMethod *cogMethod) -{ - sqInt count; - usqInt pointer; - - assert(youngReferrers <= limitAddress); - count = 0; - pointer = youngReferrers; - while (pointer < limitAddress) { - if ((((sqInt)cogMethod)) == (longAt(pointer))) { - count += 1; - } - pointer += BytesPerWord; - } - return count; -} - - /* CogMethodZone>>#openPICWithSelector: */ -static CogMethod * NoDbgRegParms -openPICWithSelector(sqInt aSelector) -{ - CogMethod *openPIC; - - openPIC = openPICList; - do { - if ((openPIC == null) - || (((openPIC->selector)) == aSelector)) { - return openPIC; - } - openPIC = ((CogMethod *) ((openPIC->nextOpenPIC))); - } while(1); - return 0; -} - - -/* Some methods have been freed. Compute how much each survivor needs to - move during the ensuing compaction and record it in the objectHeader - field. - For Sista, where we want PICs to last so they can be observed, we need to - keep PICs unless - they are definitely unused. So we need to identify unused PICs. So in - planCompact, zero the - usage counts of all PICs, saving the actual usage count in - blockEntryOffset. Then in - relocateMethodsPreCompaction (actually in - relocateIfCallOrMethodReference:mcpc:delta:) restore the usage counts of - used PICs. Finally in compactCompiledCode, clear the blockEntryOffset - of the unused PICs; they will then have a zero count and be reclaimed in - the next code compaction. */ - - /* CogMethodZone>>#planCompaction */ -static void -planCompaction(void) -{ - CogMethod *cogMethod; - sqInt delta; - - delta = 0; - cogMethod = ((CogMethod *) baseAddress); - while ((((usqInt)cogMethod)) < mzFreeStart) { - if (((cogMethod->cmType)) == CMFree) { - delta -= (cogMethod->blockSize); - } - else { - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - ((((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)))->objectHeader = delta); - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* CogMethodZone>>#printCogMethods */ -void -printCogMethods(void) -{ - CogMethod *cogMethod; - sqInt nc; - sqInt nf; - sqInt nm; - sqInt no; - sqInt nu; - - /* begin printCogMethodsSummarizing: */ - nm = (nc = (no = (nf = (nu = 0)))); - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - printCogMethod(cogMethod); - switch ((cogMethod->cmType)) { - case CMFree: - nf += 1; - break; - case CMMethod: - nm += 1; - break; - case CMClosedPIC: - nc += 1; - break; - case CMOpenPIC: - no += 1; - break; - default: - nu += 1; - - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - print("CMMethod "); - printNum(nm); - print(" CMClosedPIC "); - printNum(nc); - print(" CMOpenPIC "); - printNum(no); - print(" CMFree "); - printNum(nf); - if (nu > 0) { - print(" UNKNOWN "); - printNum(nu); - } - print(" total "); - printNum((((nm + nc) + no) + nf) + nu); - cr(); -} - - /* CogMethodZone>>#printCogMethodsOfType: */ -void -printCogMethodsOfType(sqInt cmType) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == cmType) { - printCogMethod(cogMethod); - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* CogMethodZone>>#printCogMethodsWithMethod: */ -void -printCogMethodsWithMethod(sqInt methodOop) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) != CMFree) - && (((cogMethod->methodObject)) == methodOop)) { - printCogMethod(cogMethod); - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* CogMethodZone>>#printCogMethodsWithPrimitive: */ -void -printCogMethodsWithPrimitive(sqInt primIdx) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) == CMMethod) - && (primIdx == (primitiveIndexOfMethodheader((cogMethod->methodObject), (cogMethod->methodHeader))))) { - printCogMethod(cogMethod); - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* CogMethodZone>>#printCogMethodsWithSelector: */ -void -printCogMethodsWithSelector(sqInt selectorOop) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) != CMFree) - && (((cogMethod->selector)) == selectorOop)) { - printCogMethod(cogMethod); - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* CogMethodZone>>#printCogYoungReferrers */ -void -printCogYoungReferrers(void) -{ - CogMethod *cogMethod; - usqInt pointer; - - pointer = youngReferrers; - while (pointer < limitAddress) { - cogMethod = ((CogMethod *) (longAt(pointer))); - if (!((cogMethod->cmRefersToYoung))) { - print("*"); - } - if (((cogMethod->cmType)) == CMFree) { - print("!"); - } - if (!(((cogMethod->cmRefersToYoung)) - && (((cogMethod->cmType)) != CMFree))) { - print(" "); - } - printCogMethod(cogMethod); - pointer += BytesPerWord; - } -} - - /* CogMethodZone>>#printOpenPICList */ -sqInt -printOpenPICList(void) -{ - sqInt n; - CogMethod *openPIC; - - /* begin printOpenPICListSummarizing: */ - n = 0; - openPIC = openPICList; - while (!(openPIC == null)) { - n += 1; - printCogMethod(openPIC); - openPIC = ((CogMethod *) ((openPIC->nextOpenPIC))); - } - return n; -} - - /* CogMethodZone>>#pruneYoungReferrers */ -sqInt -pruneYoungReferrers(void) -{ - usqInt dest; - usqInt next; - usqInt source; - - assert(youngReferrers <= limitAddress); - if (youngReferrers == limitAddress) { - return null; - } - dest = limitAddress; - while (1) { - next = dest - BytesPerWord; - if (!((next >= youngReferrers) - && (((((CogMethod *) (longAt(next))))->cmRefersToYoung)))) break; - dest = next; - } - assert(dest >= youngReferrers); - source = dest - BytesPerWord; - while (source >= youngReferrers) { - if (((((CogMethod *) (longAt(source))))->cmRefersToYoung)) { - assert(source < (dest - BytesPerWord)); - if (!(next == null)) { - - /* convenient first-time flag */ - next = null; - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - } - codeLongAtput((dest -= BytesPerWord), longAt(source)); - } - source -= BytesPerWord; - } - youngReferrers = dest; - assert(kosherYoungReferrers()); - return 0; -} - - /* CogMethodZone>>#relocateAndPruneYoungReferrers */ -static sqInt -relocateAndPruneYoungReferrers(void) -{ - CogMethod *cogMethod; - usqInt dest; - usqInt next; - usqInt source; - - assert(youngReferrers <= limitAddress); - if (youngReferrers == limitAddress) { - return null; - } - dest = limitAddress; - while (1) { - next = dest - BytesPerWord; - if (!((next >= youngReferrers) - && (((((cogMethod = ((CogMethod *) (longAt(next))))->cmType)) != CMFree) - && ((cogMethod->cmRefersToYoung))))) break; - if (((cogMethod->objectHeader)) != 0) { - codeLongAtput(next, (((sqInt)cogMethod)) + ((cogMethod->objectHeader))); - } - dest = next; - } - assert(dest >= youngReferrers); - source = dest - BytesPerWord; - while (source >= youngReferrers) { - cogMethod = ((CogMethod *) (longAt(source))); - if ((((cogMethod->cmType)) != CMFree) - && ((cogMethod->cmRefersToYoung))) { - assert(source < (dest - BytesPerWord)); - if (((cogMethod->objectHeader)) != 0) { - cogMethod = ((CogMethod *) ((((sqInt)cogMethod)) + (((sqInt)((cogMethod->objectHeader)))))); - } - codeLongAtput((dest -= BytesPerWord), ((sqInt)cogMethod)); - } - source -= BytesPerWord; - } - youngReferrers = dest; - return 0; -} - - -/* All surviving methods have had the amount they are going to relocate by - stored in their objectHeader fields. Relocate all relative calls so that - after the compaction of both the method containing each call and the call - target the calls invoke the same target. */ - - /* CogMethodZone>>#relocateMethodsPreCompaction */ -static sqInt -relocateMethodsPreCompaction(void) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) baseAddress); - while ((((usqInt)cogMethod)) < mzFreeStart) { - if (((cogMethod->cmType)) != CMFree) { - if (((cogMethod->cmType)) == CMClosedPIC) { - relocateCallsInClosedPIC(cogMethod); - } - else { - relocateCallsAndSelfReferencesInMethod(cogMethod); - } - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - relocateAndPruneYoungReferrers(); - return 1; -} - - /* CogMethodZone>>#removeFromOpenPICList: */ -static sqInt NoDbgRegParms -removeFromOpenPICList(CogMethod *anOpenPIC) -{ - CogMethod *prevPIC; - - assert(((anOpenPIC->cmType)) == CMOpenPIC); - if (!openPICList) { - return null; - } - assert((((openPICList->cmType)) == CMOpenPIC) - && ((((openPICList->nextOpenPIC)) == null) - || ((((((CogMethod *) ((openPICList->nextOpenPIC))))->cmType)) == CMOpenPIC))); - if (anOpenPIC == openPICList) { - - /* N.B. Use self rather than coInterpreter to avoid attempting to cast nil. - Conversion to CogMethod done in the nextOpenPIC accessor. */ - openPICList = ((CogMethod *) ((anOpenPIC->nextOpenPIC))); - return null; - } - prevPIC = openPICList; - do { - assert((prevPIC != null) - && (((prevPIC->cmType)) == CMOpenPIC)); - if (((prevPIC->nextOpenPIC)) == (((usqInt)anOpenPIC))) { - ((((CogMethod *) ((((usqInt)prevPIC)) + codeToDataDelta)))->nextOpenPIC = (anOpenPIC->nextOpenPIC)); - return null; - } - prevPIC = ((CogMethod *) ((prevPIC->nextOpenPIC))); - } while(1); - return 0; -} - - /* CogMethodZone>>#removeFromUnpairedMethodList: */ -static sqInt NoDbgRegParms -removeFromUnpairedMethodList(CogMethod *aCogMethod) -{ - CogMethod *prevMethod; - - assert(((aCogMethod->cmType)) == CMMethod); - if ((((usqInt)aCogMethod)) == unpairedMethodList) { - unpairedMethodList = (aCogMethod->nextMethodOrIRCs); - return null; - } - prevMethod = ((CogMethod *) unpairedMethodList); - while (prevMethod != null) { - assert((prevMethod != null) - && (((prevMethod->cmType)) == CMMethod)); - if (((prevMethod->nextMethodOrIRCs)) == (((usqInt)aCogMethod))) { - (prevMethod->nextMethodOrIRCs = (aCogMethod->nextMethodOrIRCs)); - return null; - } - prevMethod = ((CogMethod *) ((prevMethod->nextMethodOrIRCs))); - } - return 0; -} - - -/* Determine the default alignment for the start of a CogMethod, which in - turn determines the size of the mask used to distinguish the checked and - unchecked entry-points, used to distinguish normal and super sends on - method unlinking. - This is passed onto the backEnd to allow processors with coarse - instructions (ARM) to increase the alignment if required. */ - - /* CogMethodZone>>#roundUpLength: */ -static sqInt NoDbgRegParms -roundUpLength(sqInt numBytes) -{ - return roundUpToMethodAlignment(backEnd(), numBytes); -} - - /* CogMethodZone>>#voidOpenPICList */ -static void -voidOpenPICList(void) -{ - openPICList = null; -} - - /* CogMethodZone>>#voidUnpairedMethodList */ -static void -voidUnpairedMethodList(void) -{ - unpairedMethodList = null; -} - - /* CogMethodZone>>#voidYoungReferrersPostTenureAll */ -static void -voidYoungReferrersPostTenureAll(void) -{ - CogMethod *cogMethod; - usqInt pointer; - - assert(youngReferrers <= limitAddress); - pointer = youngReferrers; - while (pointer < limitAddress) { - cogMethod = ((CogMethod *) (longAt(pointer))); - if (((cogMethod->cmType)) != CMFree) { - (cogMethod->cmRefersToYoung = 0); - } - pointer += BytesPerWord; - } - youngReferrers = limitAddress; -} - - -/* useful for VM debugging; use export: so it will be accessible on win32 */ - - /* CogMethodZone>>#whereIsMaybeCodeThing: */ -EXPORT(char *) -whereIsMaybeCodeThing(sqInt anOop) -{ - if (oopisGreaterThanOrEqualToandLessThan(anOop, codeBase, limitAddress)) { - if (oopisLessThan(anOop, minCogMethodAddress())) { - return " is in generated runtime"; - } - if (oopisLessThan(anOop, mzFreeStart)) { - return " is in generated methods"; - } - if (oopisLessThan(anOop, youngReferrers)) { - return " is in code zone"; - } - return " is in young referrers"; - } - return null; -} - - /* CogMIPSELCompiler>>#addiuR:R:C: */ -static sqInt NoDbgRegParms -addiuRRC(AbstractInstruction * self_in_addiuRRC, sqInt destReg, sqInt srcReg, sqInt imm) -{ - return itypersrtsignedImmediate(self_in_addiuRRC, ADDIU, srcReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#adduR:R:R: */ -static sqInt NoDbgRegParms -adduRRR(AbstractInstruction * self_in_adduRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_adduRRR, SPECIAL, leftReg, rightReg, destReg, 0, ADDU); -} - - /* CogMIPSELCompiler>>#andiR:R:C: */ -static sqInt NoDbgRegParms -andiRRC(AbstractInstruction * self_in_andiRRC, sqInt destReg, sqInt srcReg, sqInt imm) -{ - return itypersrteitherImmediate(self_in_andiRRC, ANDI, srcReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#andR:R:R: */ -static sqInt NoDbgRegParms -andRRR(AbstractInstruction * self_in_andRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_andRRR, SPECIAL, leftReg, rightReg, destReg, 0, AND); -} - - /* CogMIPSELCompiler>>#beqR:R:offset: */ -static sqInt NoDbgRegParms -beqRRoffset(AbstractInstruction * self_in_beqRRoffset, sqInt leftReg, sqInt rightReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_beqRRoffset, BEQ, leftReg, rightReg, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#bgezR:offset: */ -static sqInt NoDbgRegParms -bgezRoffset(AbstractInstruction * self_in_bgezRoffset, sqInt cmpReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_bgezRoffset, REGIMM, cmpReg, BGEZ, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#bgtzR:offset: */ -static sqInt NoDbgRegParms -bgtzRoffset(AbstractInstruction * self_in_bgtzRoffset, sqInt cmpReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_bgtzRoffset, BGTZ, cmpReg, 0, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#blezR:offset: */ -static sqInt NoDbgRegParms -blezRoffset(AbstractInstruction * self_in_blezRoffset, sqInt cmpReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_blezRoffset, BLEZ, cmpReg, 0, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#bltzR:offset: */ -static sqInt NoDbgRegParms -bltzRoffset(AbstractInstruction * self_in_bltzRoffset, sqInt cmpReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_bltzRoffset, REGIMM, cmpReg, BLTZ, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#bneR:R:offset: */ -static sqInt NoDbgRegParms -bneRRoffset(AbstractInstruction * self_in_bneRRoffset, sqInt leftReg, sqInt rightReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_bneRRoffset, BNE, leftReg, rightReg, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#callInstructionByteSize */ -static sqInt NoDbgRegParms -callInstructionByteSize(AbstractInstruction * self_in_callInstructionByteSize) -{ - flag("todo"); - return 16; -} - - -/* csra - 16: lui t9, high - csra - 12: ori t9, low - csra - 8: jalr t9 - csra - 4: nop (delay slot) */ - - /* CogMIPSELCompiler>>#callTargetFromReturnAddress: */ -static usqInt NoDbgRegParms -callTargetFromReturnAddress(AbstractInstruction * self_in_callTargetFromReturnAddress, sqInt callSiteReturnAddress) -{ - assert((opcodeAtAddress(self_in_callTargetFromReturnAddress, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_callTargetFromReturnAddress, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_callTargetFromReturnAddress, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_callTargetFromReturnAddress, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_callTargetFromReturnAddress))); - return literalAtAddress(self_in_callTargetFromReturnAddress, callSiteReturnAddress - 12); -} - - -/* NOTE: the right reg (rt) MUST equal dest reg (rd) or behavior is undefined */ - - /* CogMIPSELCompiler>>#clzR:R:R: */ -static sqInt NoDbgRegParms -clzRRR(AbstractInstruction * self_in_clzRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_clzRRR, SPECIAL, leftReg, rightReg, destReg, 0, 32); -} - - /* CogMIPSELCompiler>>#cmpC32RTempByteSize */ -static sqInt NoDbgRegParms -cmpC32RTempByteSize(AbstractInstruction * self_in_cmpC32RTempByteSize) -{ - return 8; -} - - -/* Each MIPS instruction has 4 bytes. Many abstract opcodes need more than - one instruction. Instructions that refer to constants and/or literals - depend on literals - being stored in-line or out-of-line. - - N.B. The ^N forms are to get around the bytecode compiler's long branch - limits which are exceeded when each case jumps around the otherwise. */ - - /* CogMIPSELCompiler>>#computeMaximumSize */ -static sqInt NoDbgRegParms -computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize) -{ - switch ((self_in_computeMaximumSize->opcode)) { - case BrEqualRR: - case BrNotEqualRR: - case JumpR: - case Jump: - case JumpZero: - case JumpNonZero: - case JumpNegative: - case JumpNonNegative: - case JumpOverflow: - case JumpNoOverflow: - case JumpCarry: - case JumpNoCarry: - case JumpLess: - case JumpGreaterOrEqual: - case JumpGreater: - case JumpLessOrEqual: - case JumpBelow: - case JumpAboveOrEqual: - case JumpAbove: - case JumpBelowOrEqual: - case JumpFPEqual: - case JumpFPNotEqual: - case JumpFPLess: - case JumpFPGreaterOrEqual: - case JumpFPGreater: - case JumpFPLessOrEqual: - case JumpFPOrdered: - case JumpFPUnordered: - case RetN: - case MoveCwR: - case MoveXbrRR: - case MoveRXbrR: - case PopR: - case PushR: - case ConvertRRd: - return 8; - - case BrUnsignedLessRR: - case BrUnsignedLessEqualRR: - case BrUnsignedGreaterRR: - case BrUnsignedGreaterEqualRR: - case BrSignedLessRR: - case BrSignedLessEqualRR: - case BrSignedGreaterRR: - case BrSignedGreaterEqualRR: - case XorCqR: - case AddCwR: - case AndCwR: - case OrCwR: - case SubCwR: - case XorCwR: - case MoveXwrRR: - case MoveRXwrR: - case PrefetchAw: - return 12; - - case BrLongEqualRR: - case BrLongNotEqualRR: - case PushCw: - case PushCq: - return 16; - - case MulRR: - case DivRR: - case MoveLowR: - case MoveHighR: - case Literal: - case Fill32: - case Nop: - case Stop: - case AddRR: - case AndRR: - case OrRR: - case XorRR: - case SubRR: - case NegateR: - case AddRRR: - case SubRRR: - case LogicalShiftLeftCqR: - case LogicalShiftRightCqR: - case ArithmeticShiftRightCqR: - case LogicalShiftLeftRR: - case LogicalShiftRightRR: - case ArithmeticShiftRightRR: - case AddRdRd: - case CmpRdRd: - case SubRdRd: - case MulRdRd: - case DivRdRd: - case SqrtRd: - case ClzRR: - case MoveRR: - case MoveRdRd: - case MoveRMwr: - case MoveMbrR: - case MoveRMbr: - case MoveM16rR: - case MoveRM16r: - return 4; - - case Label: - return 0; - - case AlignmentNops: - return (((self_in_computeMaximumSize->operands))[0]) - 4; - - case Call: - case CallFull: - case JumpFull: - case JumpLong: - case JumpLongZero: - case JumpLongNonZero: - return 16; - - case AddCqR: - case OrCqR: - case OrCqRR: - case SubCqR: - case TstCqR: - case LoadEffectiveAddressMwrR: - return (isShortOffset(self_in_computeMaximumSize, ((self_in_computeMaximumSize->operands))[0]) - ? 4 - : 12); - - case AndCqR: - case AndCqRR: - return ((((((self_in_computeMaximumSize->operands))[0]) >= 0) && ((((self_in_computeMaximumSize->operands))[0]) <= 0xFFFF)) - ? 4 - : 12); - - case CmpCqR: - case CmpCwR: - case AddCheckOverflowCqR: - case SubCheckOverflowCqR: - return 28; - - case CmpRR: - case AddCheckOverflowRR: - case SubCheckOverflowRR: - case MulCheckOverflowRR: - return 20; - - case MoveCqR: - return (isShortOffset(self_in_computeMaximumSize, ((self_in_computeMaximumSize->operands))[0]) - ? 4 - : 8); - - case MoveAwR: - case MoveAbR: - return (((((self_in_computeMaximumSize->operands))[0]) != null) - && ((((varBaseAddress()) - (0x8000)) < (((self_in_computeMaximumSize->operands))[0])) - && ((((self_in_computeMaximumSize->operands))[0]) < ((varBaseAddress()) + (0x8000)))) - ? 4 - : 12); - - case MoveRAw: - case MoveRAb: - return (((((self_in_computeMaximumSize->operands))[1]) != null) - && ((((varBaseAddress()) - (0x8000)) < (((self_in_computeMaximumSize->operands))[1])) - && ((((self_in_computeMaximumSize->operands))[1]) < ((varBaseAddress()) + (0x8000)))) - ? 4 - : 12); - - case MoveRdM64r: - case MoveM64rRd: - return 12; - - case MoveMwrR: - return (isShortOffset(self_in_computeMaximumSize, ((self_in_computeMaximumSize->operands))[0]) - ? 4 - : 16); - - default: - error("Case not found and no otherwise clause"); - } - return 0; -} - - /* CogMIPSELCompiler>>#concretizeAddCheckOverflowCqR */ -static sqInt NoDbgRegParms -concretizeAddCheckOverflowCqR(AbstractInstruction * self_in_concretizeAddCheckOverflowCqR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - sqInt aWord4; - sqInt aWord5; - sqInt aWord6; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeAddCheckOverflowCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAddCheckOverflowCqR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeAddCheckOverflowCqR, AT, high16BitsOf(self_in_concretizeAddCheckOverflowCqR, rightImm)); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeAddCheckOverflowCqR, AT, AT, low16BitsOf(self_in_concretizeAddCheckOverflowCqR, rightImm)); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = adduRRR(self_in_concretizeAddCheckOverflowCqR, OverflowTemp1, leftReg, ZR); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = adduRRR(self_in_concretizeAddCheckOverflowCqR, destReg, leftReg, AT); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[12 / 4] = aWord3; - /* begin machineCodeAt:put: */ - aWord4 = xorRRR(self_in_concretizeAddCheckOverflowCqR, OverflowTemp2, destReg, AT); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[16 / 4] = aWord4; - /* begin machineCodeAt:put: */ - aWord5 = xorRRR(self_in_concretizeAddCheckOverflowCqR, OverflowTemp1, destReg, OverflowTemp1); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[20 / 4] = aWord5; - /* begin machineCodeAt:put: */ - aWord6 = andRRR(self_in_concretizeAddCheckOverflowCqR, Overflow, OverflowTemp1, OverflowTemp2); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[24 / 4] = aWord6; - return 28; -} - - /* CogMIPSELCompiler>>#concretizeAddCheckOverflowRR */ -static sqInt NoDbgRegParms -concretizeAddCheckOverflowRR(AbstractInstruction * self_in_concretizeAddCheckOverflowRR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - sqInt aWord4; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeAddCheckOverflowRR->operands))[0]; - - /* Save original LHS */ - destReg = (leftReg = ((self_in_concretizeAddCheckOverflowRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeAddCheckOverflowRR, OverflowTemp1, leftReg, ZR); - ((self_in_concretizeAddCheckOverflowRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = adduRRR(self_in_concretizeAddCheckOverflowRR, destReg, leftReg, rightReg); - ((self_in_concretizeAddCheckOverflowRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = xorRRR(self_in_concretizeAddCheckOverflowRR, OverflowTemp2, destReg, rightReg); - ((self_in_concretizeAddCheckOverflowRR->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = xorRRR(self_in_concretizeAddCheckOverflowRR, OverflowTemp1, destReg, OverflowTemp1); - ((self_in_concretizeAddCheckOverflowRR->machineCode))[12 / 4] = aWord3; - /* begin machineCodeAt:put: */ - aWord4 = andRRR(self_in_concretizeAddCheckOverflowRR, Overflow, OverflowTemp1, OverflowTemp2); - ((self_in_concretizeAddCheckOverflowRR->machineCode))[16 / 4] = aWord4; - return 20; -} - - /* CogMIPSELCompiler>>#concretizeAddCqR */ -static sqInt NoDbgRegParms -concretizeAddCqR(AbstractInstruction * self_in_concretizeAddCqR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeAddCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAddCqR->operands))[1]); - if (!(isShortOffset(self_in_concretizeAddCqR, rightImm))) { - return concretizeAddCwR(self_in_concretizeAddCqR); - } - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizeAddCqR, destReg, leftReg, rightImm); - ((self_in_concretizeAddCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeAddCwR */ -static sqInt NoDbgRegParms -concretizeAddCwR(AbstractInstruction * self_in_concretizeAddCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeAddCwR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAddCwR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeAddCwR, AT, high16BitsOf(self_in_concretizeAddCwR, rightImm)); - ((self_in_concretizeAddCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeAddCwR, AT, AT, low16BitsOf(self_in_concretizeAddCwR, rightImm)); - ((self_in_concretizeAddCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = adduRRR(self_in_concretizeAddCwR, destReg, leftReg, AT); - ((self_in_concretizeAddCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeAddRRDest: */ -static sqInt NoDbgRegParms -concretizeAddRRDest(AbstractInstruction * self_in_concretizeAddRRDest, sqInt destReg) -{ - sqInt aWord; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeAddRRDest->operands))[0]; - leftReg = ((self_in_concretizeAddRRDest->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeAddRRDest, destReg, leftReg, rightReg); - ((self_in_concretizeAddRRDest->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeAlignmentNops */ -static usqInt NoDbgRegParms -concretizeAlignmentNops(AbstractInstruction * self_in_concretizeAlignmentNops) -{ - sqInt p; - - assert((((self_in_concretizeAlignmentNops->machineCodeSize)) % 4) == 0); - for (p = 0; p < ((self_in_concretizeAlignmentNops->machineCodeSize)); p += 4) { - /* begin machineCodeAt:put: */ - ((self_in_concretizeAlignmentNops->machineCode))[p / 4] = 0 /* nop */; - } - return (self_in_concretizeAlignmentNops->machineCodeSize); -} - - /* CogMIPSELCompiler>>#concretizeAndCqR */ -static sqInt NoDbgRegParms -concretizeAndCqR(AbstractInstruction * self_in_concretizeAndCqR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeAndCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAndCqR->operands))[1]); - if (!(isShortOffset(self_in_concretizeAndCqR, rightImm))) { - return concretizeAndCwR(self_in_concretizeAndCqR); - } - /* begin machineCodeAt:put: */ - aWord = andiRRC(self_in_concretizeAndCqR, destReg, leftReg, rightImm); - ((self_in_concretizeAndCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeAndCqRDest: */ -static sqInt NoDbgRegParms -concretizeAndCqRDest(AbstractInstruction * self_in_concretizeAndCqRDest, sqInt destReg) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt srcReg; - usqInt value; - - value = ((self_in_concretizeAndCqRDest->operands))[0]; - srcReg = ((self_in_concretizeAndCqRDest->operands))[1]; - if (((value >= 0) && (value <= 0xFFFF))) { - /* begin machineCodeAt:put: */ - aWord = andiRRC(self_in_concretizeAndCqRDest, destReg, srcReg, value); - ((self_in_concretizeAndCqRDest->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeAndCqRDest, AT, high16BitsOf(self_in_concretizeAndCqRDest, value)); - ((self_in_concretizeAndCqRDest->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeAndCqRDest, AT, AT, low16BitsOf(self_in_concretizeAndCqRDest, value)); - ((self_in_concretizeAndCqRDest->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = andRRR(self_in_concretizeAndCqRDest, destReg, srcReg, AT); - ((self_in_concretizeAndCqRDest->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeAndCwR */ -static sqInt NoDbgRegParms -concretizeAndCwR(AbstractInstruction * self_in_concretizeAndCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeAndCwR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAndCwR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeAndCwR, AT, high16BitsOf(self_in_concretizeAndCwR, rightImm)); - ((self_in_concretizeAndCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeAndCwR, AT, AT, low16BitsOf(self_in_concretizeAndCwR, rightImm)); - ((self_in_concretizeAndCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = andRRR(self_in_concretizeAndCwR, destReg, leftReg, AT); - ((self_in_concretizeAndCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeAndRR */ -static sqInt NoDbgRegParms -concretizeAndRR(AbstractInstruction * self_in_concretizeAndRR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeAndRR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAndRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = andRRR(self_in_concretizeAndRR, destReg, leftReg, rightReg); - ((self_in_concretizeAndRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeArithmeticShiftRightCqR */ -static sqInt NoDbgRegParms -concretizeArithmeticShiftRightCqR(AbstractInstruction * self_in_concretizeArithmeticShiftRightCqR) -{ - sqInt aWord; - sqInt distance; - usqInt reg; - - distance = (((((self_in_concretizeArithmeticShiftRightCqR->operands))[0]) < 0x1F) ? (((self_in_concretizeArithmeticShiftRightCqR->operands))[0]) : 0x1F); - reg = ((self_in_concretizeArithmeticShiftRightCqR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = sraRRC(self_in_concretizeArithmeticShiftRightCqR, reg, reg, distance); - ((self_in_concretizeArithmeticShiftRightCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeArithmeticShiftRightRR */ -static sqInt NoDbgRegParms -concretizeArithmeticShiftRightRR(AbstractInstruction * self_in_concretizeArithmeticShiftRightRR) -{ - sqInt aWord; - usqInt destReg; - usqInt distReg; - - distReg = ((self_in_concretizeArithmeticShiftRightRR->operands))[0]; - destReg = ((self_in_concretizeArithmeticShiftRightRR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = sravRRR(self_in_concretizeArithmeticShiftRightRR, destReg, destReg, distReg); - ((self_in_concretizeArithmeticShiftRightRR->machineCode))[0 / 4] = aWord; - return 4; -} - - -/* Generate concrete machine code for the instruction at actualAddress, - setting machineCodeSize, and answer the following address. */ -/* Generate concrete machine code for the instruction at actualAddress, - setting machineCodeSize, and answer the following address. */ - - /* CogMIPSELCompiler>>#concretizeAt: */ -static sqInt NoDbgRegParms -concretizeAt(AbstractInstruction * self_in_concretizeAt, sqInt actualAddress) -{ - assert((actualAddress % 4) == 0); - (self_in_concretizeAt->address) = actualAddress; - (self_in_concretizeAt->machineCodeSize) = dispatchConcretize(self_in_concretizeAt); - assert((((self_in_concretizeAt->maxSize)) == null) - || (((self_in_concretizeAt->maxSize)) >= ((self_in_concretizeAt->machineCodeSize)))); - return actualAddress + ((self_in_concretizeAt->machineCodeSize)); -} - - /* CogMIPSELCompiler>>#concretizeBrEqualRR */ -static sqInt NoDbgRegParms -concretizeBrEqualRR(AbstractInstruction * self_in_concretizeBrEqualRR) -{ - sqInt aWord; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrEqualRR->address)) + 4))); - leftReg = ((self_in_concretizeBrEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrEqualRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = beqRRoffset(self_in_concretizeBrEqualRR, leftReg, rightReg, offset); - ((self_in_concretizeBrEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrEqualRR->machineCode))[4 / 4] = 0 /* nop */; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeBrLongEqualRR */ -static sqInt NoDbgRegParms -concretizeBrLongEqualRR(AbstractInstruction * self_in_concretizeBrLongEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - usqInt jumpTargetAddr; - AbstractInstruction *jumpTargetInstruction; - usqInt leftReg; - usqInt rightReg; - - /* begin longJumpTargetAddress */ - jumpTarget = ((AbstractInstruction *) (((self_in_concretizeBrLongEqualRR->operands))[0])); - if ((addressIsInInstructions(jumpTarget)) - || (jumpTarget == (methodLabel()))) { - jumpTarget = ((AbstractInstruction *) ((jumpTarget->address))); - } - assert(jumpTarget != 0); - jumpTargetInstruction = jumpTarget; - flag("todo"); - jumpTargetAddr = (((usqInt)jumpTargetInstruction)) & 0xFFFFFFF; - leftReg = ((self_in_concretizeBrLongEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrLongEqualRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = bneRRoffset(self_in_concretizeBrLongEqualRR, leftReg, rightReg, 12); - ((self_in_concretizeBrLongEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrLongEqualRR->machineCode))[4 / 4] = 0 /* nop */; - /* begin machineCodeAt:put: */ - aWord1 = jA(self_in_concretizeBrLongEqualRR, jumpTargetAddr); - ((self_in_concretizeBrLongEqualRR->machineCode))[8 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrLongEqualRR->machineCode))[12 / 4] = 0 /* nop */; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeBrLongNotEqualRR */ -static sqInt NoDbgRegParms -concretizeBrLongNotEqualRR(AbstractInstruction * self_in_concretizeBrLongNotEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - usqInt jumpTargetAddr; - AbstractInstruction *jumpTargetInstruction; - usqInt leftReg; - usqInt rightReg; - - /* begin longJumpTargetAddress */ - jumpTarget = ((AbstractInstruction *) (((self_in_concretizeBrLongNotEqualRR->operands))[0])); - if ((addressIsInInstructions(jumpTarget)) - || (jumpTarget == (methodLabel()))) { - jumpTarget = ((AbstractInstruction *) ((jumpTarget->address))); - } - assert(jumpTarget != 0); - jumpTargetInstruction = jumpTarget; - flag("todo"); - jumpTargetAddr = (((usqInt)jumpTargetInstruction)) & 0xFFFFFFF; - leftReg = ((self_in_concretizeBrLongNotEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrLongNotEqualRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = beqRRoffset(self_in_concretizeBrLongNotEqualRR, leftReg, rightReg, 12); - ((self_in_concretizeBrLongNotEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrLongNotEqualRR->machineCode))[4 / 4] = 0 /* nop */; - /* begin machineCodeAt:put: */ - aWord1 = jA(self_in_concretizeBrLongNotEqualRR, jumpTargetAddr); - ((self_in_concretizeBrLongNotEqualRR->machineCode))[8 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrLongNotEqualRR->machineCode))[12 / 4] = 0 /* nop */; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeBrNotEqualRR */ -static sqInt NoDbgRegParms -concretizeBrNotEqualRR(AbstractInstruction * self_in_concretizeBrNotEqualRR) -{ - sqInt aWord; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrNotEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrNotEqualRR->address)) + 4))); - leftReg = ((self_in_concretizeBrNotEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrNotEqualRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = bneRRoffset(self_in_concretizeBrNotEqualRR, leftReg, rightReg, offset); - ((self_in_concretizeBrNotEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrNotEqualRR->machineCode))[4 / 4] = 0 /* nop */; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeBrSignedGreaterEqualRR */ -static sqInt NoDbgRegParms -concretizeBrSignedGreaterEqualRR(AbstractInstruction * self_in_concretizeBrSignedGreaterEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrSignedGreaterEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrSignedGreaterEqualRR->address)) + 8))); - leftReg = ((self_in_concretizeBrSignedGreaterEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrSignedGreaterEqualRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltRRR(self_in_concretizeBrSignedGreaterEqualRR, BranchTemp, leftReg, rightReg); - ((self_in_concretizeBrSignedGreaterEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = beqRRoffset(self_in_concretizeBrSignedGreaterEqualRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrSignedGreaterEqualRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrSignedGreaterEqualRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrSignedGreaterRR */ -static sqInt NoDbgRegParms -concretizeBrSignedGreaterRR(AbstractInstruction * self_in_concretizeBrSignedGreaterRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrSignedGreaterRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrSignedGreaterRR->address)) + 8))); - leftReg = ((self_in_concretizeBrSignedGreaterRR->operands))[1]; - rightReg = ((self_in_concretizeBrSignedGreaterRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltRRR(self_in_concretizeBrSignedGreaterRR, BranchTemp, rightReg, leftReg); - ((self_in_concretizeBrSignedGreaterRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = bneRRoffset(self_in_concretizeBrSignedGreaterRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrSignedGreaterRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrSignedGreaterRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrSignedLessEqualRR */ -static sqInt NoDbgRegParms -concretizeBrSignedLessEqualRR(AbstractInstruction * self_in_concretizeBrSignedLessEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrSignedLessEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrSignedLessEqualRR->address)) + 8))); - leftReg = ((self_in_concretizeBrSignedLessEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrSignedLessEqualRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltRRR(self_in_concretizeBrSignedLessEqualRR, BranchTemp, rightReg, leftReg); - ((self_in_concretizeBrSignedLessEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = beqRRoffset(self_in_concretizeBrSignedLessEqualRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrSignedLessEqualRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrSignedLessEqualRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrSignedLessRR */ -static sqInt NoDbgRegParms -concretizeBrSignedLessRR(AbstractInstruction * self_in_concretizeBrSignedLessRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrSignedLessRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrSignedLessRR->address)) + 8))); - leftReg = ((self_in_concretizeBrSignedLessRR->operands))[1]; - rightReg = ((self_in_concretizeBrSignedLessRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltRRR(self_in_concretizeBrSignedLessRR, BranchTemp, leftReg, rightReg); - ((self_in_concretizeBrSignedLessRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = bneRRoffset(self_in_concretizeBrSignedLessRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrSignedLessRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrSignedLessRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrUnsignedGreaterEqualRR */ -static sqInt NoDbgRegParms -concretizeBrUnsignedGreaterEqualRR(AbstractInstruction * self_in_concretizeBrUnsignedGreaterEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrUnsignedGreaterEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrUnsignedGreaterEqualRR->address)) + 8))); - leftReg = ((self_in_concretizeBrUnsignedGreaterEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrUnsignedGreaterEqualRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltuRRR(self_in_concretizeBrUnsignedGreaterEqualRR, BranchTemp, leftReg, rightReg); - ((self_in_concretizeBrUnsignedGreaterEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = beqRRoffset(self_in_concretizeBrUnsignedGreaterEqualRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrUnsignedGreaterEqualRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrUnsignedGreaterEqualRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrUnsignedGreaterRR */ -static sqInt NoDbgRegParms -concretizeBrUnsignedGreaterRR(AbstractInstruction * self_in_concretizeBrUnsignedGreaterRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrUnsignedGreaterRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrUnsignedGreaterRR->address)) + 8))); - leftReg = ((self_in_concretizeBrUnsignedGreaterRR->operands))[1]; - rightReg = ((self_in_concretizeBrUnsignedGreaterRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltuRRR(self_in_concretizeBrUnsignedGreaterRR, BranchTemp, rightReg, leftReg); - ((self_in_concretizeBrUnsignedGreaterRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = bneRRoffset(self_in_concretizeBrUnsignedGreaterRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrUnsignedGreaterRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrUnsignedGreaterRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrUnsignedLessEqualRR */ -static sqInt NoDbgRegParms -concretizeBrUnsignedLessEqualRR(AbstractInstruction * self_in_concretizeBrUnsignedLessEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrUnsignedLessEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrUnsignedLessEqualRR->address)) + 8))); - leftReg = ((self_in_concretizeBrUnsignedLessEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrUnsignedLessEqualRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltuRRR(self_in_concretizeBrUnsignedLessEqualRR, BranchTemp, rightReg, leftReg); - ((self_in_concretizeBrUnsignedLessEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = beqRRoffset(self_in_concretizeBrUnsignedLessEqualRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrUnsignedLessEqualRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrUnsignedLessEqualRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrUnsignedLessRR */ -static sqInt NoDbgRegParms -concretizeBrUnsignedLessRR(AbstractInstruction * self_in_concretizeBrUnsignedLessRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrUnsignedLessRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrUnsignedLessRR->address)) + 8))); - leftReg = ((self_in_concretizeBrUnsignedLessRR->operands))[1]; - rightReg = ((self_in_concretizeBrUnsignedLessRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltuRRR(self_in_concretizeBrUnsignedLessRR, BranchTemp, leftReg, rightReg); - ((self_in_concretizeBrUnsignedLessRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = bneRRoffset(self_in_concretizeBrUnsignedLessRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrUnsignedLessRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrUnsignedLessRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - -/* Call is used only for calls within code-space, See CallFull for general - anywhere in address space calling - */ -/* Relative branches in MIPS have a displacement of +/- 131kB (signed 18 - bits), which is too small to cover - the method zone. */ - - /* CogMIPSELCompiler>>#concretizeCall */ -static sqInt NoDbgRegParms -concretizeCall(AbstractInstruction * self_in_concretizeCall) -{ - return concretizeCallFull(self_in_concretizeCall); -} - - /* CogMIPSELCompiler>>#concretizeCallFull */ -static sqInt NoDbgRegParms -concretizeCallFull(AbstractInstruction * self_in_concretizeCallFull) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - AbstractInstruction *jumpTarget; - usqInt jumpTargetAddr; - AbstractInstruction *jumpTargetInstruction; - - /* begin longJumpTargetAddress */ - jumpTarget = ((AbstractInstruction *) (((self_in_concretizeCallFull->operands))[0])); - if ((addressIsInInstructions(jumpTarget)) - || (jumpTarget == (methodLabel()))) { - jumpTarget = ((AbstractInstruction *) ((jumpTarget->address))); - } - assert(jumpTarget != 0); - jumpTargetInstruction = jumpTarget; - jumpTargetAddr = ((usqInt)jumpTargetInstruction); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeCallFull, TargetReg, high16BitsOf(self_in_concretizeCallFull, jumpTargetAddr)); - ((self_in_concretizeCallFull->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeCallFull, TargetReg, TargetReg, low16BitsOf(self_in_concretizeCallFull, jumpTargetAddr)); - ((self_in_concretizeCallFull->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = jalR(self_in_concretizeCallFull, TargetReg); - ((self_in_concretizeCallFull->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - ((self_in_concretizeCallFull->machineCode))[12 / 4] = 0 /* nop */; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeClzRR */ -static sqInt NoDbgRegParms -concretizeClzRR(AbstractInstruction * self_in_concretizeClzRR) -{ - sqInt aWord; - usqInt destReg; - usqInt maskReg; - usqInt rightReg; - - maskReg = ((self_in_concretizeClzRR->operands))[0]; - destReg = (rightReg = ((self_in_concretizeClzRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = clzRRR(self_in_concretizeClzRR, destReg, maskReg, rightReg); - ((self_in_concretizeClzRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeCmpCqR */ -static sqInt NoDbgRegParms -concretizeCmpCqR(AbstractInstruction * self_in_concretizeCmpCqR) -{ - return concretizeCmpCwR(self_in_concretizeCmpCqR); -} - - /* CogMIPSELCompiler>>#concretizeCmpCwR */ -static sqInt NoDbgRegParms -concretizeCmpCwR(AbstractInstruction * self_in_concretizeCmpCwR) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeCmpRR */ -static sqInt NoDbgRegParms -concretizeCmpRR(AbstractInstruction * self_in_concretizeCmpRR) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeDivRR */ -static sqInt NoDbgRegParms -concretizeDivRR(AbstractInstruction * self_in_concretizeDivRR) -{ - sqInt aWord; - usqInt dividendReg; - usqInt divisorReg; - - dividendReg = ((self_in_concretizeDivRR->operands))[0]; - divisorReg = ((self_in_concretizeDivRR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = divRR(self_in_concretizeDivRR, dividendReg, divisorReg); - ((self_in_concretizeDivRR->machineCode))[0 / 4] = aWord; - return 4; -} - - -/* fill with operand 0 according to the processor's endianness. - You might think this is bogus and we should fill with stop instrurctions - instead, but this is used to leave room for a CMBlock header before the - code for a block; - the gaps get filled in by fillInBlockHeadersAt: after code has been - generated. */ - - /* CogMIPSELCompiler>>#concretizeFill32 */ -static sqInt NoDbgRegParms -concretizeFill32(AbstractInstruction * self_in_concretizeFill32) -{ - sqInt aWord; - - /* begin machineCodeAt:put: */ - aWord = ((self_in_concretizeFill32->operands))[0]; - ((self_in_concretizeFill32->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeJump */ -static sqInt NoDbgRegParms -concretizeJump(AbstractInstruction * self_in_concretizeJump) -{ - sqInt aWord; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - sqInt offset; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeJump->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeJump->address)) + 4))); - flag("BranchRange"); - /* begin machineCodeAt:put: */ - aWord = beqRRoffset(self_in_concretizeJump, ZR, ZR, offset); - ((self_in_concretizeJump->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeJump->machineCode))[4 / 4] = 0 /* nop */; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeJumpFull */ -static sqInt NoDbgRegParms -concretizeJumpFull(AbstractInstruction * self_in_concretizeJumpFull) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - AbstractInstruction *jumpTarget; - usqInt jumpTargetAddr; - AbstractInstruction *jumpTargetInstruction; - - /* begin longJumpTargetAddress */ - jumpTarget = ((AbstractInstruction *) (((self_in_concretizeJumpFull->operands))[0])); - if ((addressIsInInstructions(jumpTarget)) - || (jumpTarget == (methodLabel()))) { - jumpTarget = ((AbstractInstruction *) ((jumpTarget->address))); - } - assert(jumpTarget != 0); - jumpTargetInstruction = jumpTarget; - jumpTargetAddr = ((usqInt)jumpTargetInstruction); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeJumpFull, TargetReg, high16BitsOf(self_in_concretizeJumpFull, jumpTargetAddr)); - ((self_in_concretizeJumpFull->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeJumpFull, TargetReg, TargetReg, low16BitsOf(self_in_concretizeJumpFull, jumpTargetAddr)); - ((self_in_concretizeJumpFull->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = jR(self_in_concretizeJumpFull, TargetReg); - ((self_in_concretizeJumpFull->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - ((self_in_concretizeJumpFull->machineCode))[12 / 4] = 0 /* nop */; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeJumpLong */ -static sqInt NoDbgRegParms -concretizeJumpLong(AbstractInstruction * self_in_concretizeJumpLong) -{ - return concretizeJumpFull(self_in_concretizeJumpLong); -} - - /* CogMIPSELCompiler>>#concretizeJumpLongNonZero */ -static sqInt NoDbgRegParms -concretizeJumpLongNonZero(AbstractInstruction * self_in_concretizeJumpLongNonZero) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpLongZero */ -static sqInt NoDbgRegParms -concretizeJumpLongZero(AbstractInstruction * self_in_concretizeJumpLongZero) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpNonZero */ -static sqInt NoDbgRegParms -concretizeJumpNonZero(AbstractInstruction * self_in_concretizeJumpNonZero) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpNoOverflow */ -static sqInt NoDbgRegParms -concretizeJumpNoOverflow(AbstractInstruction * self_in_concretizeJumpNoOverflow) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpOverflow */ -static sqInt NoDbgRegParms -concretizeJumpOverflow(AbstractInstruction * self_in_concretizeJumpOverflow) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpR */ -static sqInt NoDbgRegParms -concretizeJumpR(AbstractInstruction * self_in_concretizeJumpR) -{ - sqInt aWord; - usqInt reg; - - flag("OABI"); - reg = ((self_in_concretizeJumpR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = jR(self_in_concretizeJumpR, reg); - ((self_in_concretizeJumpR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeJumpR->machineCode))[4 / 4] = 0 /* nop */; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeJumpSignedGreaterEqual */ -static sqInt NoDbgRegParms -concretizeJumpSignedGreaterEqual(AbstractInstruction * self_in_concretizeJumpSignedGreaterEqual) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpSignedGreaterThan */ -static sqInt NoDbgRegParms -concretizeJumpSignedGreaterThan(AbstractInstruction * self_in_concretizeJumpSignedGreaterThan) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpSignedLessEqual */ -static sqInt NoDbgRegParms -concretizeJumpSignedLessEqual(AbstractInstruction * self_in_concretizeJumpSignedLessEqual) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpSignedLessThan */ -static sqInt NoDbgRegParms -concretizeJumpSignedLessThan(AbstractInstruction * self_in_concretizeJumpSignedLessThan) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpUnsignedGreaterEqual */ -static sqInt NoDbgRegParms -concretizeJumpUnsignedGreaterEqual(AbstractInstruction * self_in_concretizeJumpUnsignedGreaterEqual) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpUnsignedGreaterThan */ -static sqInt NoDbgRegParms -concretizeJumpUnsignedGreaterThan(AbstractInstruction * self_in_concretizeJumpUnsignedGreaterThan) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpUnsignedLessEqual */ -static sqInt NoDbgRegParms -concretizeJumpUnsignedLessEqual(AbstractInstruction * self_in_concretizeJumpUnsignedLessEqual) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpUnsignedLessThan */ -static sqInt NoDbgRegParms -concretizeJumpUnsignedLessThan(AbstractInstruction * self_in_concretizeJumpUnsignedLessThan) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpZero */ -static sqInt NoDbgRegParms -concretizeJumpZero(AbstractInstruction * self_in_concretizeJumpZero) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeLoadEffectiveAddressMwrR */ -static sqInt NoDbgRegParms -concretizeLoadEffectiveAddressMwrR(AbstractInstruction * self_in_concretizeLoadEffectiveAddressMwrR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt baseReg; - usqInt destReg; - sqInt offset; - - offset = ((self_in_concretizeLoadEffectiveAddressMwrR->operands))[0]; - baseReg = ((self_in_concretizeLoadEffectiveAddressMwrR->operands))[1]; - destReg = ((self_in_concretizeLoadEffectiveAddressMwrR->operands))[2]; - if (isShortOffset(self_in_concretizeLoadEffectiveAddressMwrR, offset)) { - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizeLoadEffectiveAddressMwrR, destReg, baseReg, offset); - ((self_in_concretizeLoadEffectiveAddressMwrR->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeLoadEffectiveAddressMwrR, AT, high16BitsOf(self_in_concretizeLoadEffectiveAddressMwrR, offset)); - ((self_in_concretizeLoadEffectiveAddressMwrR->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeLoadEffectiveAddressMwrR, AT, AT, low16BitsOf(self_in_concretizeLoadEffectiveAddressMwrR, offset)); - ((self_in_concretizeLoadEffectiveAddressMwrR->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = adduRRR(self_in_concretizeLoadEffectiveAddressMwrR, destReg, baseReg, AT); - ((self_in_concretizeLoadEffectiveAddressMwrR->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeLogicalShiftLeftCqR */ -static sqInt NoDbgRegParms -concretizeLogicalShiftLeftCqR(AbstractInstruction * self_in_concretizeLogicalShiftLeftCqR) -{ - sqInt aWord; - sqInt distance; - usqInt reg; - - distance = (((((self_in_concretizeLogicalShiftLeftCqR->operands))[0]) < 0x1F) ? (((self_in_concretizeLogicalShiftLeftCqR->operands))[0]) : 0x1F); - reg = ((self_in_concretizeLogicalShiftLeftCqR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = sllRRC(self_in_concretizeLogicalShiftLeftCqR, reg, reg, distance); - ((self_in_concretizeLogicalShiftLeftCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeLogicalShiftLeftRR */ -static sqInt NoDbgRegParms -concretizeLogicalShiftLeftRR(AbstractInstruction * self_in_concretizeLogicalShiftLeftRR) -{ - sqInt aWord; - usqInt destReg; - usqInt distReg; - - distReg = ((self_in_concretizeLogicalShiftLeftRR->operands))[0]; - destReg = ((self_in_concretizeLogicalShiftLeftRR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = sllvRRR(self_in_concretizeLogicalShiftLeftRR, destReg, destReg, distReg); - ((self_in_concretizeLogicalShiftLeftRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeLogicalShiftRightCqR */ -static sqInt NoDbgRegParms -concretizeLogicalShiftRightCqR(AbstractInstruction * self_in_concretizeLogicalShiftRightCqR) -{ - sqInt aWord; - sqInt distance; - usqInt reg; - - distance = (((((self_in_concretizeLogicalShiftRightCqR->operands))[0]) < 0x1F) ? (((self_in_concretizeLogicalShiftRightCqR->operands))[0]) : 0x1F); - reg = ((self_in_concretizeLogicalShiftRightCqR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = srlRRC(self_in_concretizeLogicalShiftRightCqR, reg, reg, distance); - ((self_in_concretizeLogicalShiftRightCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeLogicalShiftRightRR */ -static sqInt NoDbgRegParms -concretizeLogicalShiftRightRR(AbstractInstruction * self_in_concretizeLogicalShiftRightRR) -{ - sqInt aWord; - usqInt destReg; - usqInt distReg; - - distReg = ((self_in_concretizeLogicalShiftRightRR->operands))[0]; - destReg = ((self_in_concretizeLogicalShiftRightRR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = srlvRRR(self_in_concretizeLogicalShiftRightRR, destReg, destReg, distReg); - ((self_in_concretizeLogicalShiftRightRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveAbR */ -static sqInt NoDbgRegParms -concretizeMoveAbR(AbstractInstruction * self_in_concretizeMoveAbR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt destReg; - usqInt srcAddr; - - srcAddr = ((self_in_concretizeMoveAbR->operands))[0]; - destReg = ((self_in_concretizeMoveAbR->operands))[1]; - if ((srcAddr != null) - && ((((varBaseAddress()) - (0x8000)) < srcAddr) - && (srcAddr < ((varBaseAddress()) + (0x8000))))) { - /* begin machineCodeAt:put: */ - aWord = lwRbaseoffset(self_in_concretizeMoveAbR, destReg, ConcreteVarBaseReg, srcAddr - (varBaseAddress())); - ((self_in_concretizeMoveAbR->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeMoveAbR, AT, high16BitsOf(self_in_concretizeMoveAbR, srcAddr)); - ((self_in_concretizeMoveAbR->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeMoveAbR, AT, AT, low16BitsOf(self_in_concretizeMoveAbR, srcAddr)); - ((self_in_concretizeMoveAbR->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = lbuRbaseoffset(self_in_concretizeMoveAbR, destReg, AT, 0); - ((self_in_concretizeMoveAbR->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMoveAwR */ -static sqInt NoDbgRegParms -concretizeMoveAwR(AbstractInstruction * self_in_concretizeMoveAwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt destReg; - usqInt srcAddr; - - srcAddr = ((self_in_concretizeMoveAwR->operands))[0]; - destReg = ((self_in_concretizeMoveAwR->operands))[1]; - if ((srcAddr != null) - && ((((varBaseAddress()) - (0x8000)) < srcAddr) - && (srcAddr < ((varBaseAddress()) + (0x8000))))) { - /* begin machineCodeAt:put: */ - aWord = lwRbaseoffset(self_in_concretizeMoveAwR, destReg, ConcreteVarBaseReg, srcAddr - (varBaseAddress())); - ((self_in_concretizeMoveAwR->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeMoveAwR, AT, high16BitsOf(self_in_concretizeMoveAwR, srcAddr)); - ((self_in_concretizeMoveAwR->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeMoveAwR, AT, AT, low16BitsOf(self_in_concretizeMoveAwR, srcAddr)); - ((self_in_concretizeMoveAwR->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = lwRbaseoffset(self_in_concretizeMoveAwR, destReg, AT, 0); - ((self_in_concretizeMoveAwR->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMoveCqR */ -static sqInt NoDbgRegParms -concretizeMoveCqR(AbstractInstruction * self_in_concretizeMoveCqR) -{ - sqInt aWord; - usqInt reg; - sqInt word; - - word = ((self_in_concretizeMoveCqR->operands))[0]; - reg = ((self_in_concretizeMoveCqR->operands))[1]; - if (!(isShortOffset(self_in_concretizeMoveCqR, word))) { - return concretizeMoveCwR(self_in_concretizeMoveCqR); - } - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizeMoveCqR, reg, ZR, word); - ((self_in_concretizeMoveCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveCwR */ -static sqInt NoDbgRegParms -concretizeMoveCwR(AbstractInstruction * self_in_concretizeMoveCwR) -{ - sqInt aWord; - sqInt aWord1; - usqInt reg; - sqInt word; - - word = ((self_in_concretizeMoveCwR->operands))[0]; - reg = ((self_in_concretizeMoveCwR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeMoveCwR, reg, high16BitsOf(self_in_concretizeMoveCwR, word)); - ((self_in_concretizeMoveCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeMoveCwR, reg, reg, low16BitsOf(self_in_concretizeMoveCwR, word)); - ((self_in_concretizeMoveCwR->machineCode))[4 / 4] = aWord1; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeMoveHighR */ -static sqInt NoDbgRegParms -concretizeMoveHighR(AbstractInstruction * self_in_concretizeMoveHighR) -{ - sqInt aWord; - usqInt destReg; - - destReg = ((self_in_concretizeMoveHighR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = mfhiR(self_in_concretizeMoveHighR, destReg); - ((self_in_concretizeMoveHighR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveLowR */ -static sqInt NoDbgRegParms -concretizeMoveLowR(AbstractInstruction * self_in_concretizeMoveLowR) -{ - sqInt aWord; - usqInt destReg; - - destReg = ((self_in_concretizeMoveLowR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = mfloR(self_in_concretizeMoveLowR, destReg); - ((self_in_concretizeMoveLowR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveM16rR */ -static sqInt NoDbgRegParms -concretizeMoveM16rR(AbstractInstruction * self_in_concretizeMoveM16rR) -{ - sqInt aWord; - usqInt destReg; - sqInt offset; - usqInt srcReg; - - offset = ((self_in_concretizeMoveM16rR->operands))[0]; - srcReg = ((self_in_concretizeMoveM16rR->operands))[1]; - destReg = ((self_in_concretizeMoveM16rR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = lhuRbaseoffset(self_in_concretizeMoveM16rR, destReg, srcReg, offset); - ((self_in_concretizeMoveM16rR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveMbrR */ -static sqInt NoDbgRegParms -concretizeMoveMbrR(AbstractInstruction * self_in_concretizeMoveMbrR) -{ - sqInt aWord; - usqInt destReg; - sqInt offset; - usqInt srcReg; - - offset = ((self_in_concretizeMoveMbrR->operands))[0]; - srcReg = ((self_in_concretizeMoveMbrR->operands))[1]; - destReg = ((self_in_concretizeMoveMbrR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = lbuRbaseoffset(self_in_concretizeMoveMbrR, destReg, srcReg, offset); - ((self_in_concretizeMoveMbrR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveMwrR */ -static sqInt NoDbgRegParms -concretizeMoveMwrR(AbstractInstruction * self_in_concretizeMoveMwrR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - sqInt aWord4; - usqInt baseReg; - usqInt destReg; - sqInt offset; - - offset = ((self_in_concretizeMoveMwrR->operands))[0]; - baseReg = ((self_in_concretizeMoveMwrR->operands))[1]; - destReg = ((self_in_concretizeMoveMwrR->operands))[2]; - if (isShortOffset(self_in_concretizeMoveMwrR, offset)) { - /* begin machineCodeAt:put: */ - aWord = lwRbaseoffset(self_in_concretizeMoveMwrR, destReg, baseReg, offset); - ((self_in_concretizeMoveMwrR->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeMoveMwrR, AT, high16BitsOf(self_in_concretizeMoveMwrR, offset)); - ((self_in_concretizeMoveMwrR->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeMoveMwrR, AT, AT, low16BitsOf(self_in_concretizeMoveMwrR, offset)); - ((self_in_concretizeMoveMwrR->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = adduRRR(self_in_concretizeMoveMwrR, AT, baseReg, AT); - ((self_in_concretizeMoveMwrR->machineCode))[8 / 4] = aWord3; - /* begin machineCodeAt:put: */ - aWord4 = lwRbaseoffset(self_in_concretizeMoveMwrR, destReg, AT, 0); - ((self_in_concretizeMoveMwrR->machineCode))[12 / 4] = aWord4; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeMoveRAb */ -static sqInt NoDbgRegParms -concretizeMoveRAb(AbstractInstruction * self_in_concretizeMoveRAb) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt destAddr; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRAb->operands))[0]; - destAddr = ((self_in_concretizeMoveRAb->operands))[1]; - if ((destAddr != null) - && ((((varBaseAddress()) - (0x8000)) < destAddr) - && (destAddr < ((varBaseAddress()) + (0x8000))))) { - /* begin machineCodeAt:put: */ - aWord = swRbaseoffset(self_in_concretizeMoveRAb, srcReg, ConcreteVarBaseReg, destAddr - (varBaseAddress())); - ((self_in_concretizeMoveRAb->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeMoveRAb, AT, high16BitsOf(self_in_concretizeMoveRAb, destAddr)); - ((self_in_concretizeMoveRAb->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeMoveRAb, AT, AT, low16BitsOf(self_in_concretizeMoveRAb, destAddr)); - ((self_in_concretizeMoveRAb->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = sbRbaseoffset(self_in_concretizeMoveRAb, srcReg, AT, 0); - ((self_in_concretizeMoveRAb->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMoveRAw */ -static sqInt NoDbgRegParms -concretizeMoveRAw(AbstractInstruction * self_in_concretizeMoveRAw) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt destAddr; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRAw->operands))[0]; - destAddr = ((self_in_concretizeMoveRAw->operands))[1]; - if ((destAddr != null) - && ((((varBaseAddress()) - (0x8000)) < destAddr) - && (destAddr < ((varBaseAddress()) + (0x8000))))) { - /* begin machineCodeAt:put: */ - aWord = swRbaseoffset(self_in_concretizeMoveRAw, srcReg, ConcreteVarBaseReg, destAddr - (varBaseAddress())); - ((self_in_concretizeMoveRAw->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeMoveRAw, AT, high16BitsOf(self_in_concretizeMoveRAw, destAddr)); - ((self_in_concretizeMoveRAw->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeMoveRAw, AT, AT, low16BitsOf(self_in_concretizeMoveRAw, destAddr)); - ((self_in_concretizeMoveRAw->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = swRbaseoffset(self_in_concretizeMoveRAw, srcReg, AT, 0); - ((self_in_concretizeMoveRAw->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMoveRM16r */ -static sqInt NoDbgRegParms -concretizeMoveRM16r(AbstractInstruction * self_in_concretizeMoveRM16r) -{ - sqInt aWord; - usqInt destReg; - sqInt offset; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRM16r->operands))[0]; - offset = ((self_in_concretizeMoveRM16r->operands))[1]; - destReg = ((self_in_concretizeMoveRM16r->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = shRbaseoffset(self_in_concretizeMoveRM16r, srcReg, destReg, offset); - ((self_in_concretizeMoveRM16r->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveRMbr */ -static sqInt NoDbgRegParms -concretizeMoveRMbr(AbstractInstruction * self_in_concretizeMoveRMbr) -{ - sqInt aWord; - usqInt destReg; - sqInt offset; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRMbr->operands))[0]; - offset = ((self_in_concretizeMoveRMbr->operands))[1]; - destReg = ((self_in_concretizeMoveRMbr->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = sbRbaseoffset(self_in_concretizeMoveRMbr, srcReg, destReg, offset); - ((self_in_concretizeMoveRMbr->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveRMwr */ -static sqInt NoDbgRegParms -concretizeMoveRMwr(AbstractInstruction * self_in_concretizeMoveRMwr) -{ - sqInt aWord; - usqInt baseReg; - sqInt offset; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRMwr->operands))[0]; - offset = ((self_in_concretizeMoveRMwr->operands))[1]; - baseReg = ((self_in_concretizeMoveRMwr->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = swRbaseoffset(self_in_concretizeMoveRMwr, srcReg, baseReg, offset); - ((self_in_concretizeMoveRMwr->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveRR */ -static sqInt NoDbgRegParms -concretizeMoveRR(AbstractInstruction * self_in_concretizeMoveRR) -{ - sqInt aWord; - usqInt destReg; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRR->operands))[0]; - destReg = ((self_in_concretizeMoveRR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeMoveRR, destReg, srcReg, ZR); - ((self_in_concretizeMoveRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveRXbrR */ -static sqInt NoDbgRegParms -concretizeMoveRXbrR(AbstractInstruction * self_in_concretizeMoveRXbrR) -{ - sqInt aWord; - sqInt aWord1; - usqInt baseReg; - usqInt indexReg; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRXbrR->operands))[0]; - indexReg = ((self_in_concretizeMoveRXbrR->operands))[1]; - baseReg = ((self_in_concretizeMoveRXbrR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeMoveRXbrR, AT, baseReg, indexReg); - ((self_in_concretizeMoveRXbrR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = sbRbaseoffset(self_in_concretizeMoveRXbrR, srcReg, AT, 0); - ((self_in_concretizeMoveRXbrR->machineCode))[4 / 4] = aWord1; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeMoveRXwrR */ -static sqInt NoDbgRegParms -concretizeMoveRXwrR(AbstractInstruction * self_in_concretizeMoveRXwrR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt baseReg; - usqInt indexReg; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRXwrR->operands))[0]; - indexReg = ((self_in_concretizeMoveRXwrR->operands))[1]; - baseReg = ((self_in_concretizeMoveRXwrR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = sllRRC(self_in_concretizeMoveRXwrR, AT, indexReg, 2); - ((self_in_concretizeMoveRXwrR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = adduRRR(self_in_concretizeMoveRXwrR, AT, baseReg, AT); - ((self_in_concretizeMoveRXwrR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = swRbaseoffset(self_in_concretizeMoveRXwrR, srcReg, AT, 0); - ((self_in_concretizeMoveRXwrR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMoveXbrRR */ -static sqInt NoDbgRegParms -concretizeMoveXbrRR(AbstractInstruction * self_in_concretizeMoveXbrRR) -{ - sqInt aWord; - sqInt aWord1; - usqInt baseReg; - usqInt destReg; - usqInt indexReg; - - - /* index is number of *bytes* */ - indexReg = ((self_in_concretizeMoveXbrRR->operands))[0]; - baseReg = ((self_in_concretizeMoveXbrRR->operands))[1]; - destReg = ((self_in_concretizeMoveXbrRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeMoveXbrRR, AT, baseReg, indexReg); - ((self_in_concretizeMoveXbrRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = lbuRbaseoffset(self_in_concretizeMoveXbrRR, destReg, AT, 0); - ((self_in_concretizeMoveXbrRR->machineCode))[4 / 4] = aWord1; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeMoveXwrRR */ -static sqInt NoDbgRegParms -concretizeMoveXwrRR(AbstractInstruction * self_in_concretizeMoveXwrRR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt baseReg; - usqInt destReg; - usqInt indexReg; - - indexReg = ((self_in_concretizeMoveXwrRR->operands))[0]; - baseReg = ((self_in_concretizeMoveXwrRR->operands))[1]; - destReg = ((self_in_concretizeMoveXwrRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = sllRRC(self_in_concretizeMoveXwrRR, AT, indexReg, 2); - ((self_in_concretizeMoveXwrRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = adduRRR(self_in_concretizeMoveXwrRR, AT, baseReg, AT); - ((self_in_concretizeMoveXwrRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = lwRbaseoffset(self_in_concretizeMoveXwrRR, destReg, AT, 0); - ((self_in_concretizeMoveXwrRR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMulCheckOverflowRR */ -static sqInt NoDbgRegParms -concretizeMulCheckOverflowRR(AbstractInstruction * self_in_concretizeMulCheckOverflowRR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeMulCheckOverflowRR->operands))[0]; - - /* Overflow occured if the sign bit of the low part is different from the high part. */ - destReg = (leftReg = ((self_in_concretizeMulCheckOverflowRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = multRR(self_in_concretizeMulCheckOverflowRR, leftReg, rightReg); - ((self_in_concretizeMulCheckOverflowRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = mfloR(self_in_concretizeMulCheckOverflowRR, destReg); - ((self_in_concretizeMulCheckOverflowRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = sraRRC(self_in_concretizeMulCheckOverflowRR, OverflowTemp1, destReg, 0x1F); - ((self_in_concretizeMulCheckOverflowRR->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = mfhiR(self_in_concretizeMulCheckOverflowRR, OverflowTemp2); - ((self_in_concretizeMulCheckOverflowRR->machineCode))[12 / 4] = aWord3; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeNegateR */ -static sqInt NoDbgRegParms -concretizeNegateR(AbstractInstruction * self_in_concretizeNegateR) -{ - sqInt aWord; - usqInt reg; - - reg = ((self_in_concretizeNegateR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = subuRRR(self_in_concretizeNegateR, reg, ZR, reg); - ((self_in_concretizeNegateR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeNop */ -static sqInt NoDbgRegParms -concretizeNop(AbstractInstruction * self_in_concretizeNop) -{ - /* begin machineCodeAt:put: */ - ((self_in_concretizeNop->machineCode))[0 / 4] = 0 /* nop */; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeOrCqR */ -static sqInt NoDbgRegParms -concretizeOrCqR(AbstractInstruction * self_in_concretizeOrCqR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeOrCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeOrCqR->operands))[1]); - if (!(((rightImm >= 0) && (rightImm <= 0xFFFF)))) { - return concretizeOrCwR(self_in_concretizeOrCqR); - } - /* begin machineCodeAt:put: */ - aWord = oriRRC(self_in_concretizeOrCqR, destReg, leftReg, rightImm); - ((self_in_concretizeOrCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeOrCqRR */ -static sqInt NoDbgRegParms -concretizeOrCqRR(AbstractInstruction * self_in_concretizeOrCqRR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt dstReg; - usqInt srcReg; - usqInt value; - - value = ((self_in_concretizeOrCqRR->operands))[0]; - srcReg = ((self_in_concretizeOrCqRR->operands))[1]; - dstReg = ((self_in_concretizeOrCqRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeOrCqRR, AT, high16BitsOf(self_in_concretizeOrCqRR, value)); - ((self_in_concretizeOrCqRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeOrCqRR, AT, AT, low16BitsOf(self_in_concretizeOrCqRR, value)); - ((self_in_concretizeOrCqRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = orRRR(self_in_concretizeOrCqRR, dstReg, srcReg, AT); - ((self_in_concretizeOrCqRR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeOrCwR */ -static sqInt NoDbgRegParms -concretizeOrCwR(AbstractInstruction * self_in_concretizeOrCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeOrCwR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeOrCwR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeOrCwR, AT, high16BitsOf(self_in_concretizeOrCwR, rightImm)); - ((self_in_concretizeOrCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeOrCwR, AT, AT, low16BitsOf(self_in_concretizeOrCwR, rightImm)); - ((self_in_concretizeOrCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = orRRR(self_in_concretizeOrCwR, destReg, leftReg, AT); - ((self_in_concretizeOrCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeOrRR */ -static sqInt NoDbgRegParms -concretizeOrRR(AbstractInstruction * self_in_concretizeOrRR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeOrRR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeOrRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = orRRR(self_in_concretizeOrRR, destReg, leftReg, rightReg); - ((self_in_concretizeOrRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizePopR */ -static sqInt NoDbgRegParms -concretizePopR(AbstractInstruction * self_in_concretizePopR) -{ - sqInt aWord; - sqInt aWord1; - usqInt destReg; - - destReg = ((self_in_concretizePopR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = lwRbaseoffset(self_in_concretizePopR, destReg, SP, 0); - ((self_in_concretizePopR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = addiuRRC(self_in_concretizePopR, SP, SP, 4); - ((self_in_concretizePopR->machineCode))[4 / 4] = aWord1; - return 8; -} - - /* CogMIPSELCompiler>>#concretizePrefetchAw */ -static sqInt NoDbgRegParms -concretizePrefetchAw(AbstractInstruction * self_in_concretizePrefetchAw) -{ - usqInt addressOperand; - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - - addressOperand = ((self_in_concretizePrefetchAw->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizePrefetchAw, AT, high16BitsOf(self_in_concretizePrefetchAw, addressOperand)); - ((self_in_concretizePrefetchAw->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizePrefetchAw, AT, AT, low16BitsOf(self_in_concretizePrefetchAw, addressOperand)); - ((self_in_concretizePrefetchAw->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = prefRoffsethint(self_in_concretizePrefetchAw, AT, 0, HintLoad); - ((self_in_concretizePrefetchAw->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizePushCq */ -static sqInt NoDbgRegParms -concretizePushCq(AbstractInstruction * self_in_concretizePushCq) -{ - return concretizePushCw(self_in_concretizePushCq); -} - - /* CogMIPSELCompiler>>#concretizePushCw */ -static sqInt NoDbgRegParms -concretizePushCw(AbstractInstruction * self_in_concretizePushCw) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt value; - - value = ((self_in_concretizePushCw->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizePushCw, AT, high16BitsOf(self_in_concretizePushCw, value)); - ((self_in_concretizePushCw->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizePushCw, AT, AT, low16BitsOf(self_in_concretizePushCw, value)); - ((self_in_concretizePushCw->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = addiuRRC(self_in_concretizePushCw, SP, SP, -4); - ((self_in_concretizePushCw->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = swRbaseoffset(self_in_concretizePushCw, AT, SP, 0); - ((self_in_concretizePushCw->machineCode))[12 / 4] = aWord3; - return 16; -} - - /* CogMIPSELCompiler>>#concretizePushR */ -static sqInt NoDbgRegParms -concretizePushR(AbstractInstruction * self_in_concretizePushR) -{ - sqInt aWord; - sqInt aWord1; - usqInt srcReg; - - srcReg = ((self_in_concretizePushR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizePushR, SP, SP, -4); - ((self_in_concretizePushR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = swRbaseoffset(self_in_concretizePushR, srcReg, SP, 0); - ((self_in_concretizePushR->machineCode))[4 / 4] = aWord1; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeRetN */ -static sqInt NoDbgRegParms -concretizeRetN(AbstractInstruction * self_in_concretizeRetN) -{ - sqInt aWord; - sqInt aWord1; - sqInt offset; - - offset = ((self_in_concretizeRetN->operands))[0]; - /* begin machineCodeAt:put: */ - aWord1 = jR(self_in_concretizeRetN, RA); - ((self_in_concretizeRetN->machineCode))[0 / 4] = aWord1; - if (offset == 0) { - /* begin machineCodeAt:put: */ - ((self_in_concretizeRetN->machineCode))[4 / 4] = 0 /* nop */; - } - else { - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizeRetN, SP, SP, offset); - ((self_in_concretizeRetN->machineCode))[4 / 4] = aWord; - } - return 8; -} - - /* CogMIPSELCompiler>>#concretizeStop */ -static sqInt NoDbgRegParms -concretizeStop(AbstractInstruction * self_in_concretizeStop) -{ - sqInt aWord; - - /* begin machineCodeAt:put: */ - aWord = stop(self_in_concretizeStop); - ((self_in_concretizeStop->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeSubCheckOverflowCqR */ -static sqInt NoDbgRegParms -concretizeSubCheckOverflowCqR(AbstractInstruction * self_in_concretizeSubCheckOverflowCqR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - sqInt aWord4; - sqInt aWord5; - sqInt aWord6; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeSubCheckOverflowCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeSubCheckOverflowCqR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeSubCheckOverflowCqR, AT, high16BitsOf(self_in_concretizeSubCheckOverflowCqR, rightImm)); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeSubCheckOverflowCqR, AT, AT, low16BitsOf(self_in_concretizeSubCheckOverflowCqR, rightImm)); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = adduRRR(self_in_concretizeSubCheckOverflowCqR, OverflowTemp1, leftReg, ZR); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = subuRRR(self_in_concretizeSubCheckOverflowCqR, destReg, leftReg, AT); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[12 / 4] = aWord3; - /* begin machineCodeAt:put: */ - aWord4 = xorRRR(self_in_concretizeSubCheckOverflowCqR, OverflowTemp2, destReg, AT); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[16 / 4] = aWord4; - /* begin machineCodeAt:put: */ - aWord5 = xorRRR(self_in_concretizeSubCheckOverflowCqR, OverflowTemp1, destReg, OverflowTemp1); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[20 / 4] = aWord5; - /* begin machineCodeAt:put: */ - aWord6 = andRRR(self_in_concretizeSubCheckOverflowCqR, Overflow, OverflowTemp1, OverflowTemp2); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[24 / 4] = aWord6; - return 28; -} - - /* CogMIPSELCompiler>>#concretizeSubCheckOverflowRR */ -static sqInt NoDbgRegParms -concretizeSubCheckOverflowRR(AbstractInstruction * self_in_concretizeSubCheckOverflowRR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - sqInt aWord4; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeSubCheckOverflowRR->operands))[0]; - - /* Save original LHS */ - destReg = (leftReg = ((self_in_concretizeSubCheckOverflowRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeSubCheckOverflowRR, OverflowTemp1, leftReg, ZR); - ((self_in_concretizeSubCheckOverflowRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = subuRRR(self_in_concretizeSubCheckOverflowRR, destReg, leftReg, rightReg); - ((self_in_concretizeSubCheckOverflowRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = xorRRR(self_in_concretizeSubCheckOverflowRR, OverflowTemp2, destReg, rightReg); - ((self_in_concretizeSubCheckOverflowRR->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = xorRRR(self_in_concretizeSubCheckOverflowRR, OverflowTemp1, destReg, OverflowTemp1); - ((self_in_concretizeSubCheckOverflowRR->machineCode))[12 / 4] = aWord3; - /* begin machineCodeAt:put: */ - aWord4 = andRRR(self_in_concretizeSubCheckOverflowRR, Overflow, OverflowTemp1, OverflowTemp2); - ((self_in_concretizeSubCheckOverflowRR->machineCode))[16 / 4] = aWord4; - return 20; -} - - /* CogMIPSELCompiler>>#concretizeSubCqR */ -static sqInt NoDbgRegParms -concretizeSubCqR(AbstractInstruction * self_in_concretizeSubCqR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeSubCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeSubCqR->operands))[1]); - if (!(isShortOffset(self_in_concretizeSubCqR, -rightImm))) { - return concretizeSubCwR(self_in_concretizeSubCqR); - } - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizeSubCqR, destReg, leftReg, -rightImm); - ((self_in_concretizeSubCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeSubCwR */ -static sqInt NoDbgRegParms -concretizeSubCwR(AbstractInstruction * self_in_concretizeSubCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeSubCwR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeSubCwR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeSubCwR, AT, high16BitsOf(self_in_concretizeSubCwR, rightImm)); - ((self_in_concretizeSubCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeSubCwR, AT, AT, low16BitsOf(self_in_concretizeSubCwR, rightImm)); - ((self_in_concretizeSubCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = subuRRR(self_in_concretizeSubCwR, destReg, leftReg, AT); - ((self_in_concretizeSubCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeSubRRDest: */ -static sqInt NoDbgRegParms -concretizeSubRRDest(AbstractInstruction * self_in_concretizeSubRRDest, sqInt destReg) -{ - sqInt aWord; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeSubRRDest->operands))[0]; - leftReg = ((self_in_concretizeSubRRDest->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = subuRRR(self_in_concretizeSubRRDest, destReg, leftReg, rightReg); - ((self_in_concretizeSubRRDest->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeTstCqR */ -static sqInt NoDbgRegParms -concretizeTstCqR(AbstractInstruction * self_in_concretizeTstCqR) -{ - sqInt aWord; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeTstCqR->operands))[0]; - leftReg = ((self_in_concretizeTstCqR->operands))[1]; - if (!(isShortOffset(self_in_concretizeTstCqR, rightImm))) { - return concretizeTstCwR(self_in_concretizeTstCqR); - } - /* begin machineCodeAt:put: */ - aWord = andiRRC(self_in_concretizeTstCqR, Cmp, leftReg, rightImm); - ((self_in_concretizeTstCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeTstCwR */ -static sqInt NoDbgRegParms -concretizeTstCwR(AbstractInstruction * self_in_concretizeTstCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeTstCwR->operands))[0]; - leftReg = ((self_in_concretizeTstCwR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeTstCwR, AT, high16BitsOf(self_in_concretizeTstCwR, rightImm)); - ((self_in_concretizeTstCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeTstCwR, AT, AT, low16BitsOf(self_in_concretizeTstCwR, rightImm)); - ((self_in_concretizeTstCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = andRRR(self_in_concretizeTstCwR, Cmp, leftReg, AT); - ((self_in_concretizeTstCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeUnimplemented */ -static sqInt NoDbgRegParms -concretizeUnimplemented(AbstractInstruction * self_in_concretizeUnimplemented) -{ - error("Unimplemented RTL instruction"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeXorCwR */ -static sqInt NoDbgRegParms -concretizeXorCwR(AbstractInstruction * self_in_concretizeXorCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeXorCwR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeXorCwR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeXorCwR, AT, high16BitsOf(self_in_concretizeXorCwR, rightImm)); - ((self_in_concretizeXorCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeXorCwR, AT, AT, low16BitsOf(self_in_concretizeXorCwR, rightImm)); - ((self_in_concretizeXorCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = xorRRR(self_in_concretizeXorCwR, destReg, leftReg, AT); - ((self_in_concretizeXorCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeXorRR */ -static sqInt NoDbgRegParms -concretizeXorRR(AbstractInstruction * self_in_concretizeXorRR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeXorRR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeXorRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = xorRRR(self_in_concretizeXorRR, destReg, leftReg, rightReg); - ((self_in_concretizeXorRR->machineCode))[0 / 4] = aWord; - return 4; -} - - -/* Attempt to generate concrete machine code for the instruction at address. - This is the inner dispatch of concretizeAt: actualAddress which exists - only to get around the branch size limits in the SqueakV3 (blue book - derived) bytecode set. */ - - /* CogMIPSELCompiler>>#dispatchConcretize */ -static sqInt NoDbgRegParms -dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) -{ - AbstractInstruction *dependentChain; - - switch ((self_in_dispatchConcretize->opcode)) { - case BrEqualRR: - return concretizeBrEqualRR(self_in_dispatchConcretize); - - case BrNotEqualRR: - return concretizeBrNotEqualRR(self_in_dispatchConcretize); - - case BrUnsignedLessRR: - return concretizeBrUnsignedLessRR(self_in_dispatchConcretize); - - case BrUnsignedLessEqualRR: - return concretizeBrUnsignedLessEqualRR(self_in_dispatchConcretize); - - case BrUnsignedGreaterRR: - return concretizeBrUnsignedGreaterRR(self_in_dispatchConcretize); - - case BrUnsignedGreaterEqualRR: - return concretizeBrUnsignedGreaterEqualRR(self_in_dispatchConcretize); - - case BrSignedLessRR: - return concretizeBrSignedLessRR(self_in_dispatchConcretize); - - case BrSignedLessEqualRR: - return concretizeBrSignedLessEqualRR(self_in_dispatchConcretize); - - case BrSignedGreaterRR: - return concretizeBrSignedGreaterRR(self_in_dispatchConcretize); - - case BrSignedGreaterEqualRR: - return concretizeBrSignedGreaterEqualRR(self_in_dispatchConcretize); - - case BrLongEqualRR: - return concretizeBrLongEqualRR(self_in_dispatchConcretize); - - case BrLongNotEqualRR: - return concretizeBrLongNotEqualRR(self_in_dispatchConcretize); - - case MulRR: - case JumpNegative: - case JumpNonNegative: - case JumpCarry: - case JumpNoCarry: - case JumpFPEqual: - case JumpFPNotEqual: - case JumpFPLess: - case JumpFPGreaterOrEqual: - case JumpFPGreater: - case JumpFPLessOrEqual: - case JumpFPOrdered: - case JumpFPUnordered: - case XorCqR: - case AddRdRd: - case CmpRdRd: - case DivRdRd: - case MulRdRd: - case SubRdRd: - case SqrtRd: - case MoveRMbr: - case MoveM64rRd: - case MoveRdM64r: - case ConvertRRd: - return concretizeUnimplemented(self_in_dispatchConcretize); - - case DivRR: - return concretizeDivRR(self_in_dispatchConcretize); - - case MoveLowR: - return concretizeMoveLowR(self_in_dispatchConcretize); - - case MoveHighR: - return concretizeMoveHighR(self_in_dispatchConcretize); - - case Label: - /* begin concretizeLabel */ - dependentChain = (self_in_dispatchConcretize->dependent); - while (!(dependentChain == null)) { - /* begin updateLabel: */ - assert((((dependentChain->opcode)) == MoveCwR) - || (((dependentChain->opcode)) == PushCw)); - ((dependentChain->operands))[0] = (((self_in_dispatchConcretize->address)) + (((self_in_dispatchConcretize->operands))[1])); - dependentChain = (dependentChain->dependent); - } - return 0; - - case AlignmentNops: - return concretizeAlignmentNops(self_in_dispatchConcretize); - - case Fill32: - return concretizeFill32(self_in_dispatchConcretize); - - case Nop: - return concretizeNop(self_in_dispatchConcretize); - - case Call: - return concretizeCall(self_in_dispatchConcretize); - - case CallFull: - return concretizeCallFull(self_in_dispatchConcretize); - - case JumpR: - return concretizeJumpR(self_in_dispatchConcretize); - - case JumpFull: - return concretizeJumpFull(self_in_dispatchConcretize); - - case JumpLong: - return concretizeJumpLong(self_in_dispatchConcretize); - - case JumpLongZero: - return concretizeJumpLongZero(self_in_dispatchConcretize); - - case JumpLongNonZero: - return concretizeJumpLongNonZero(self_in_dispatchConcretize); - - case Jump: - return concretizeJump(self_in_dispatchConcretize); - - case JumpZero: - return concretizeJumpZero(self_in_dispatchConcretize); - - case JumpNonZero: - return concretizeJumpNonZero(self_in_dispatchConcretize); - - case JumpOverflow: - return concretizeJumpOverflow(self_in_dispatchConcretize); - - case JumpNoOverflow: - return concretizeJumpNoOverflow(self_in_dispatchConcretize); - - case JumpLess: - return concretizeJumpSignedLessThan(self_in_dispatchConcretize); - - case JumpGreaterOrEqual: - return concretizeJumpSignedGreaterEqual(self_in_dispatchConcretize); - - case JumpGreater: - return concretizeJumpSignedGreaterThan(self_in_dispatchConcretize); - - case JumpLessOrEqual: - return concretizeJumpSignedLessEqual(self_in_dispatchConcretize); - - case JumpBelow: - return concretizeJumpUnsignedLessThan(self_in_dispatchConcretize); - - case JumpAboveOrEqual: - return concretizeJumpUnsignedGreaterEqual(self_in_dispatchConcretize); - - case JumpAbove: - return concretizeJumpUnsignedGreaterThan(self_in_dispatchConcretize); - - case JumpBelowOrEqual: - return concretizeJumpUnsignedLessEqual(self_in_dispatchConcretize); - - case RetN: - return concretizeRetN(self_in_dispatchConcretize); - - case Stop: - return concretizeStop(self_in_dispatchConcretize); - - case AddCqR: - return concretizeAddCqR(self_in_dispatchConcretize); - - case AndCqR: - return concretizeAndCqRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]); - - case AndCqRR: - return concretizeAndCqRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[2]); - - case OrCqRR: - return concretizeOrCqRR(self_in_dispatchConcretize); - - case CmpCqR: - return concretizeCmpCqR(self_in_dispatchConcretize); - - case OrCqR: - return concretizeOrCqR(self_in_dispatchConcretize); - - case SubCqR: - return concretizeSubCqR(self_in_dispatchConcretize); - - case TstCqR: - return concretizeTstCqR(self_in_dispatchConcretize); - - case AddCwR: - return concretizeAddCwR(self_in_dispatchConcretize); - - case AndCwR: - return concretizeAndCwR(self_in_dispatchConcretize); - - case CmpCwR: - return concretizeCmpCwR(self_in_dispatchConcretize); - - case OrCwR: - return concretizeOrCwR(self_in_dispatchConcretize); - - case SubCwR: - return concretizeSubCwR(self_in_dispatchConcretize); - - case XorCwR: - return concretizeXorCwR(self_in_dispatchConcretize); - - case AddRR: - return concretizeAddRRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]); - - case AndRR: - return concretizeAndRR(self_in_dispatchConcretize); - - case CmpRR: - return concretizeCmpRR(self_in_dispatchConcretize); - - case OrRR: - return concretizeOrRR(self_in_dispatchConcretize); - - case SubRR: - return concretizeSubRRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]); - - case XorRR: - return concretizeXorRR(self_in_dispatchConcretize); - - case AddRRR: - return concretizeAddRRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[2]); - - case SubRRR: - return concretizeSubRRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[2]); - - case NegateR: - return concretizeNegateR(self_in_dispatchConcretize); - - case LoadEffectiveAddressMwrR: - return concretizeLoadEffectiveAddressMwrR(self_in_dispatchConcretize); - - case ArithmeticShiftRightCqR: - return concretizeArithmeticShiftRightCqR(self_in_dispatchConcretize); - - case LogicalShiftRightCqR: - return concretizeLogicalShiftRightCqR(self_in_dispatchConcretize); - - case LogicalShiftLeftCqR: - return concretizeLogicalShiftLeftCqR(self_in_dispatchConcretize); - - case ArithmeticShiftRightRR: - return concretizeArithmeticShiftRightRR(self_in_dispatchConcretize); - - case LogicalShiftLeftRR: - return concretizeLogicalShiftLeftRR(self_in_dispatchConcretize); - - case LogicalShiftRightRR: - return concretizeLogicalShiftRightRR(self_in_dispatchConcretize); - - case ClzRR: - return concretizeClzRR(self_in_dispatchConcretize); - - case MoveCqR: - return concretizeMoveCqR(self_in_dispatchConcretize); - - case MoveCwR: - return concretizeMoveCwR(self_in_dispatchConcretize); - - case MoveRR: - return concretizeMoveRR(self_in_dispatchConcretize); - - case MoveAwR: - return concretizeMoveAwR(self_in_dispatchConcretize); - - case MoveRAw: - return concretizeMoveRAw(self_in_dispatchConcretize); - - case MoveAbR: - return concretizeMoveAbR(self_in_dispatchConcretize); - - case MoveRAb: - return concretizeMoveRAb(self_in_dispatchConcretize); - - case MoveMbrR: - return concretizeMoveMbrR(self_in_dispatchConcretize); - - case MoveM16rR: - return concretizeMoveM16rR(self_in_dispatchConcretize); - - case MoveRM16r: - return concretizeMoveRM16r(self_in_dispatchConcretize); - - case MoveMwrR: - return concretizeMoveMwrR(self_in_dispatchConcretize); - - case MoveXbrRR: - return concretizeMoveXbrRR(self_in_dispatchConcretize); - - case MoveRXbrR: - return concretizeMoveRXbrR(self_in_dispatchConcretize); - - case MoveXwrRR: - return concretizeMoveXwrRR(self_in_dispatchConcretize); - - case MoveRXwrR: - return concretizeMoveRXwrR(self_in_dispatchConcretize); - - case MoveRMwr: - return concretizeMoveRMwr(self_in_dispatchConcretize); - - case PopR: - return concretizePopR(self_in_dispatchConcretize); - - case PushR: - return concretizePushR(self_in_dispatchConcretize); - - case PushCq: - return concretizePushCq(self_in_dispatchConcretize); - - case PushCw: - return concretizePushCw(self_in_dispatchConcretize); - - case PrefetchAw: - return concretizePrefetchAw(self_in_dispatchConcretize); - - case AddCheckOverflowCqR: - return concretizeAddCheckOverflowCqR(self_in_dispatchConcretize); - - case AddCheckOverflowRR: - return concretizeAddCheckOverflowRR(self_in_dispatchConcretize); - - case SubCheckOverflowCqR: - return concretizeSubCheckOverflowCqR(self_in_dispatchConcretize); - - case SubCheckOverflowRR: - return concretizeSubCheckOverflowRR(self_in_dispatchConcretize); - - case MulCheckOverflowRR: - return concretizeMulCheckOverflowRR(self_in_dispatchConcretize); - - default: - error("Case not found and no otherwise clause"); - } - return 0; -} - - /* CogMIPSELCompiler>>#divR:R: */ -static sqInt NoDbgRegParms -divRR(AbstractInstruction * self_in_divRR, sqInt dividendReg, sqInt divisorReg) -{ - flag("todo"); - return rtypersrtrdsafunct(self_in_divRR, SPECIAL, dividendReg, divisorReg, 0, 0, DIV); -} - - -/* Answer if CallFull and/or JumpFull are relative and hence need relocating - on method - compation. If so, they are annotated with IsRelativeCall in methods and - relocated in - relocateIfCallOrMethodReference:mcpc:delta: */ - - /* CogMIPSELCompiler>>#fullCallsAreRelative */ -static sqInt NoDbgRegParms -fullCallsAreRelative(AbstractInstruction * self_in_fullCallsAreRelative) -{ - return 0; -} - - /* CogMIPSELCompiler>>#functionAtAddress: */ -static sqInt NoDbgRegParms -functionAtAddress(AbstractInstruction * self_in_functionAtAddress, sqInt mcpc) -{ - return (longAt(mcpc)) & 0x3F; -} - - /* CogMIPSELCompiler>>#genDivR:R:Quo:Rem: */ -static sqInt NoDbgRegParms -genDivRRQuoRem(AbstractInstruction * self_in_genDivRRQuoRem, sqInt abstractRegDivisor, sqInt abstractRegDividend, sqInt abstractRegQuotient, sqInt abstractRegRemainder) -{ - genoperandoperand(DivRR, abstractRegDividend, abstractRegDivisor); - genoperand(MoveLowR, abstractRegQuotient); - genoperand(MoveHighR, abstractRegRemainder); - return 0; -} - - /* CogMIPSELCompiler>>#genMulR:R: */ -static AbstractInstruction * NoDbgRegParms -genMulRR(AbstractInstruction * self_in_genMulRR, sqInt regSource, sqInt regDest) -{ - return genoperandoperand(MulRR, regSource, regDest); -} - - -/* Ensure that the register args are pushed before the outer and - inner retpcs at an entry miss for arity <= self numRegArgs. The - outer retpc is that of a call at a send site. The inner is the call - from a method or PIC abort/miss to the trampoline. */ -/* Putting the receiver and args above the return address means the - CoInterpreter has a single machine-code frame format which saves - us a lot of work. */ -/* Iff there are register args convert - sp -> outerRetpc (send site retpc) - linkReg = innerRetpc (PIC abort/miss retpc) - to - base -> receiver - (arg0) - (arg1) - sp -> outerRetpc (send site retpc) - sp -> linkReg/innerRetpc (PIC abort/miss retpc) */ - - /* CogMIPSELCompiler>>#genPushRegisterArgsForAbortMissNumArgs: */ -static void NoDbgRegParms -genPushRegisterArgsForAbortMissNumArgs(AbstractInstruction * self_in_genPushRegisterArgsForAbortMissNumArgs, sqInt numArgs) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - flag("inefficient"); - if (numArgs <= 2 /* numRegArgs */) { - assert((numRegArgs()) <= 2); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, SPReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveRMwr, ReceiverResultReg, 0, SPReg); - if (numArgs > 0) { - /* begin PushR: */ - genoperand(PushR, Arg0Reg); - if (numArgs > 1) { - /* begin PushR: */ - genoperand(PushR, Arg1Reg); - } - } - /* begin PushR: */ - genoperand(PushR, TempReg); - } - /* begin PushR: */ - genoperand(PushR, LinkReg); -} - - -/* Ensure that the register args are pushed before the retpc for arity <= - self numRegArgs. - */ -/* This is easy on a RISC like ARM because the return address is in the link - register. Putting - the receiver and args above the return address means the CoInterpreter has - a single - machine-code frame format which saves us a lot of work - NOTA BENE: we do NOT push the return address here, which means it must be - dealt with later. */ - - /* CogMIPSELCompiler>>#genPushRegisterArgsForNumArgs:scratchReg: */ -static void NoDbgRegParms -genPushRegisterArgsForNumArgsscratchReg(AbstractInstruction * self_in_genPushRegisterArgsForNumArgsscratchReg, sqInt numArgs, sqInt ignored) -{ - flag("inefficient"); - if (numArgs <= 2 /* numRegArgs */) { - assert((numRegArgs()) <= 2); - /* begin PushR: */ - genoperand(PushR, ReceiverResultReg); - if (numArgs > 0) { - /* begin PushR: */ - genoperand(PushR, Arg0Reg); - if (numArgs > 1) { - /* begin PushR: */ - genoperand(PushR, Arg1Reg); - } - } - } -} - - -/* This is a no-op on MIPS since the ABI passes up to 4 args in registers and - trampolines currently observe that limit. - */ - - /* CogMIPSELCompiler>>#genRemoveNArgsFromStack: */ -static sqInt NoDbgRegParms -genRemoveNArgsFromStack(AbstractInstruction * self_in_genRemoveNArgsFromStack, sqInt n) -{ - assert(n <= 4); - return 0; -} - - -/* Restore the registers in regMask as saved by genSaveRegs:. - We don't need to do anything because all of the abstract registers are - allocated to C preserved registers. But for the future... */ - - /* CogMIPSELCompiler>>#genRestoreRegs: */ -static sqInt NoDbgRegParms -genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask) -{ - sqInt reg; - - assert(regMask == 0); - assert(!((((regMask & (registerMaskForandand(SP, FP, RA))) != 0)))); - for (reg = R0; reg <= R28; reg += 1) { - if (((regMask & (1U << reg)) != 0)) { - /* begin PopR: */ - genoperand(PopR, reg); - } - } - return 0; -} - - -/* Save the registers in regMask for a call into the C run-time from a - trampoline. We don't need to do anything because all of the abstract - registers are - allocated to C preserved registers. But for the future... */ - - /* CogMIPSELCompiler>>#genSaveRegs: */ -static sqInt NoDbgRegParms -genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask) -{ - sqInt reg; - - assert(regMask == 0); - assert(!((((regMask & (registerMaskForandand(SP, FP, RA))) != 0)))); - for (reg = R28; reg >= R0; reg += -1) { - if (((regMask & (1U << reg)) != 0)) { - /* begin PushR: */ - genoperand(PushR, reg); - } - } - return 0; -} - - /* CogMIPSELCompiler>>#genSubstituteReturnAddress: */ -static AbstractInstruction * NoDbgRegParms -genSubstituteReturnAddress(AbstractInstruction * self_in_genSubstituteReturnAddress, sqInt retpc) -{ - AbstractInstruction *anInstruction; - - /* begin checkLiteral:forInstruction: */ - anInstruction = genoperandoperand(MoveCwR, retpc, RA); - return anInstruction; -} - - /* CogMIPSELCompiler>>#high16BitsOf: */ -static usqInt NoDbgRegParms -high16BitsOf(AbstractInstruction * self_in_high16BitsOf, usqInt word) -{ - return (word) >> 16; -} - - -/* Answer the inline cache tag for the return address of a send. */ -/* MoveCwR ClassReg selectorIndex/expectedClass - Call: unlinked send stub/expectedTarget - Push ReceiverResult <-- callSiteReturnAddress */ -/* lui s3, selector/tagHigh - ori s3, s3, selector/tagLow - lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jalr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#inlineCacheTagAt: */ -static usqInt NoDbgRegParms -inlineCacheTagAt(AbstractInstruction * self_in_inlineCacheTagAt, usqInt callSiteReturnAddress) -{ - assert((opcodeAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 24)) == LUI); - assert((opcodeAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 20)) == ORI); - assert((opcodeAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_inlineCacheTagAt))); - return literalAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 20); -} - - -/* Answer the instruction size at pc. */ - - /* CogMIPSELCompiler>>#instructionSizeAt: */ -static sqInt NoDbgRegParms -instructionSizeAt(AbstractInstruction * self_in_instructionSizeAt, sqInt pc) -{ - return 4; -} - - -/* Assuming mcpc is a send return pc answer if the instruction before it is a - call (not a CallFull). - */ -/* cogit disassembleFrom: mcpc - 8 to: mcpc. */ - - /* CogMIPSELCompiler>>#isCallPrecedingReturnPC: */ -static sqInt NoDbgRegParms -isCallPrecedingReturnPC(AbstractInstruction * self_in_isCallPrecedingReturnPC, sqInt mcpc) -{ - if ((opcodeAtAddress(self_in_isCallPrecedingReturnPC, mcpc - 8)) == JAL) { - return 1; - } - if (((opcodeAtAddress(self_in_isCallPrecedingReturnPC, mcpc - 8)) == SPECIAL) - && ((functionAtAddress(self_in_isCallPrecedingReturnPC, mcpc - 8)) == JALR)) { - return 1; - } - return 0; -} - - /* CogMIPSELCompiler>>#isJump */ -static sqInt NoDbgRegParms -isJump(AbstractInstruction * self_in_isJump) -{ - return (((((self_in_isJump->opcode)) >= FirstJump) && (((self_in_isJump->opcode)) <= LastJump))) - || (((((self_in_isJump->opcode)) >= BrEqualRR) && (((self_in_isJump->opcode)) <= BrLongNotEqualRR))); -} - - -/* cogit disassembleFrom: pc to: pc + 4. */ - - /* CogMIPSELCompiler>>#isJumpAt: */ -static sqInt NoDbgRegParms -isJumpAt(AbstractInstruction * self_in_isJumpAt, sqInt pc) -{ - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == J) { - return 1; - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == SPECIAL) { - if ((functionAtAddress(self_in_isJumpAt, pc)) == JR) { - return 1; - } - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == BEQ) { - return 1; - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == BNE) { - return 1; - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == BLEZ) { - return 1; - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == BGTZ) { - return 1; - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == REGIMM) { - if ((rtAtAddress(self_in_isJumpAt, pc)) == BLTZ) { - return 1; - } - if ((rtAtAddress(self_in_isJumpAt, pc)) == BGEZ) { - return 1; - } - } - return 0; -} - - -/* Answer if the receiver is a pc-dependent instruction. */ - - /* CogMIPSELCompiler>>#isPCDependent */ -static sqInt NoDbgRegParms -isPCDependent(AbstractInstruction * self_in_isPCDependent) -{ - return (isJump(self_in_isPCDependent)) - || (((self_in_isPCDependent->opcode)) == AlignmentNops); -} - - /* CogMIPSELCompiler>>#isShortOffset: */ -static sqInt NoDbgRegParms -isShortOffset(AbstractInstruction * self_in_isShortOffset, sqInt offset) -{ - return ((offset >= -32768) && (offset <= 0x7FFF)); -} - - /* CogMIPSELCompiler>>#itype:rs:rt:eitherImmediate: */ -static sqInt NoDbgRegParms -itypersrteitherImmediate(AbstractInstruction * self_in_itypersrteitherImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate) -{ - assert(((op >= 0) && (op <= 0x3F))); - assert(((rs >= 0) && (rs <= 0x1F))); - assert(((rt >= 0) && (rt <= 0x1F))); - return (((((sqInt)((usqInt)(op) << 26))) | (((sqInt)((usqInt)(rs) << 21)))) | (((sqInt)((usqInt)(rt) << 16)))) | (immediate & 0xFFFF); -} - - /* CogMIPSELCompiler>>#itype:rs:rt:signedImmediate: */ -static sqInt NoDbgRegParms -itypersrtsignedImmediate(AbstractInstruction * self_in_itypersrtsignedImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate) -{ - assert(((op >= 0) && (op <= 0x3F))); - assert(((rs >= 0) && (rs <= 0x1F))); - assert(((rt >= 0) && (rt <= 0x1F))); - assert(isShortOffset(self_in_itypersrtsignedImmediate, immediate)); - return (((((sqInt)((usqInt)(op) << 26))) | (((sqInt)((usqInt)(rs) << 21)))) | (((sqInt)((usqInt)(rt) << 16)))) | (immediate & 0xFFFF); -} - - /* CogMIPSELCompiler>>#itype:rs:rt:unsignedImmediate: */ -static sqInt NoDbgRegParms -itypersrtunsignedImmediate(AbstractInstruction * self_in_itypersrtunsignedImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate) -{ - assert(((op >= 0) && (op <= 0x3F))); - assert(((rs >= 0) && (rs <= 0x1F))); - assert(((rt >= 0) && (rt <= 0x1F))); - assert(((immediate >= 0) && (immediate <= 0xFFFF))); - return (((((sqInt)((usqInt)(op) << 26))) | (((sqInt)((usqInt)(rs) << 21)))) | (((sqInt)((usqInt)(rt) << 16)))) | immediate; -} - - /* CogMIPSELCompiler>>#jA: */ -static sqInt NoDbgRegParms -jA(AbstractInstruction * self_in_jA, sqInt target) -{ - assert((target & 3) == 0); - return jtypetarget(self_in_jA, J, ((usqInt)((target & 0xFFFFFFF))) >> 2); -} - - /* CogMIPSELCompiler>>#jalA: */ -static sqInt NoDbgRegParms -jalA(AbstractInstruction * self_in_jalA, sqInt target) -{ - assert((target & 3) == 0); - return jtypetarget(self_in_jalA, JAL, ((usqInt)((target & 0xFFFFFFF))) >> 2); -} - - /* CogMIPSELCompiler>>#jalR: */ -static sqInt NoDbgRegParms -jalR(AbstractInstruction * self_in_jalR, sqInt targetReg) -{ - return rtypersrtrdsafunct(self_in_jalR, SPECIAL, targetReg, 0, RA, 0, JALR); -} - - /* CogMIPSELCompiler>>#jR: */ -static sqInt NoDbgRegParms -jR(AbstractInstruction * self_in_jR, sqInt targetReg) -{ - return rtypersrtrdsafunct(self_in_jR, SPECIAL, targetReg, 0, 0, 0, JR); -} - - /* CogMIPSELCompiler>>#jtype:target: */ -static sqInt NoDbgRegParms -jtypetarget(AbstractInstruction * self_in_jtypetarget, sqInt op, sqInt target) -{ - assert(((op >= 0) && (op <= 0x3F))); - assert(((target >= 0) && (target <= 0x7FFFFFF))); - return (((sqInt)((usqInt)(op) << 26))) | target; -} - - /* CogMIPSELCompiler>>#jumpLongByteSize */ -static sqInt NoDbgRegParms -jumpLongByteSize(AbstractInstruction * self_in_jumpLongByteSize) -{ - flag("bogus"); - return 16; -} - - /* CogMIPSELCompiler>>#jumpLongConditionalByteSize */ -static sqInt NoDbgRegParms -jumpLongConditionalByteSize(AbstractInstruction * self_in_jumpLongConditionalByteSize) -{ - return 16; -} - - -/* mcpc - 16: beq/ne Cmp, ZR, +12 - mcpc - 12: nop (delay slot) - mcpc - 8: j psuedo-address - mcpc - 4: nop (delay slot) */ - - /* CogMIPSELCompiler>>#jumpLongConditionalTargetBeforeFollowingAddress: */ -static usqInt NoDbgRegParms -jumpLongConditionalTargetBeforeFollowingAddress(AbstractInstruction * self_in_jumpLongConditionalTargetBeforeFollowingAddress, sqInt mcpc) -{ - assert(((opcodeAtAddress(self_in_jumpLongConditionalTargetBeforeFollowingAddress, mcpc - 16)) == BEQ) - || ((opcodeAtAddress(self_in_jumpLongConditionalTargetBeforeFollowingAddress, mcpc - 16)) == BNE)); - assert((longAt(mcpc - 12)) == (nop(self_in_jumpLongConditionalTargetBeforeFollowingAddress))); - assert((opcodeAtAddress(self_in_jumpLongConditionalTargetBeforeFollowingAddress, mcpc - 8)) == J); - assert((longAt(mcpc - 4)) == (nop(self_in_jumpLongConditionalTargetBeforeFollowingAddress))); - return targetFromJTypeAtAddress(self_in_jumpLongConditionalTargetBeforeFollowingAddress, mcpc - 8); -} - - -/* Answer the target address for the long jump immediately preceding mcpc */ - - /* CogMIPSELCompiler>>#jumpLongTargetBeforeFollowingAddress: */ -static usqInt NoDbgRegParms -jumpLongTargetBeforeFollowingAddress(AbstractInstruction * self_in_jumpLongTargetBeforeFollowingAddress, sqInt mcpc) -{ - assert((longAt(mcpc - 4)) == (nop(self_in_jumpLongTargetBeforeFollowingAddress))); - assert((opcodeAtAddress(self_in_jumpLongTargetBeforeFollowingAddress, mcpc - 8)) == SPECIAL); - assert((functionAtAddress(self_in_jumpLongTargetBeforeFollowingAddress, mcpc - 8)) == JR); - return literalAtAddress(self_in_jumpLongTargetBeforeFollowingAddress, mcpc - 12); -} - - /* CogMIPSELCompiler>>#jumpShortByteSize */ -static sqInt NoDbgRegParms -jumpShortByteSize(AbstractInstruction * self_in_jumpShortByteSize) -{ - return 8; -} - - -/* cogit disassembleFrom: pc to: pc + 4. */ - - /* CogMIPSELCompiler>>#jumpTargetPCAt: */ -static usqInt NoDbgRegParms -jumpTargetPCAt(AbstractInstruction * self_in_jumpTargetPCAt, sqInt pc) -{ - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == J) { - return targetFromJTypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == BEQ) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == BNE) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == BLEZ) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == BGTZ) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == REGIMM) { - if ((rtAtAddress(self_in_jumpTargetPCAt, pc)) == BLTZ) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((rtAtAddress(self_in_jumpTargetPCAt, pc)) == BGEZ) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - } - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#lbR:base:offset: */ -static sqInt NoDbgRegParms -lbRbaseoffset(AbstractInstruction * self_in_lbRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_lbRbaseoffset, LB, baseReg, destReg, offset); -} - - /* CogMIPSELCompiler>>#lbuR:base:offset: */ -static sqInt NoDbgRegParms -lbuRbaseoffset(AbstractInstruction * self_in_lbuRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_lbuRbaseoffset, LBU, baseReg, destReg, offset); -} - - /* CogMIPSELCompiler>>#lhR:base:offset: */ -static sqInt NoDbgRegParms -lhRbaseoffset(AbstractInstruction * self_in_lhRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_lhRbaseoffset, LH, baseReg, destReg, offset); -} - - /* CogMIPSELCompiler>>#lhuR:base:offset: */ -static sqInt NoDbgRegParms -lhuRbaseoffset(AbstractInstruction * self_in_lhuRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_lhuRbaseoffset, LHU, baseReg, destReg, offset); -} - - /* CogMIPSELCompiler>>#literalAtAddress: */ -static usqInt NoDbgRegParms -literalAtAddress(AbstractInstruction * self_in_literalAtAddress, sqInt mcpc) -{ - usqInt high; - usqInt low; - - assert((opcodeAtAddress(self_in_literalAtAddress, mcpc)) == ORI); - assert((opcodeAtAddress(self_in_literalAtAddress, mcpc - 4)) == LUI); - low = (longAt(mcpc)) & 0xFFFF; - high = (longAt(mcpc - 4)) & 0xFFFF; - return (high << 16) | low; -} - - /* CogMIPSELCompiler>>#literalAtAddress:put: */ -static sqInt NoDbgRegParms -literalAtAddressput(AbstractInstruction * self_in_literalAtAddressput, sqInt mcpc, sqInt newLiteral) -{ - usqInt newLower; - usqInt newUpper; - usqInt oldLower; - usqInt oldUpper; - - assert((opcodeAtAddress(self_in_literalAtAddressput, mcpc - 4)) == LUI); - assert((opcodeAtAddress(self_in_literalAtAddressput, mcpc)) == ORI); - oldUpper = longAt(mcpc - 4); - newUpper = (oldUpper & 0xFFFF0000U) | (high16BitsOf(self_in_literalAtAddressput, newLiteral)); - longAtput(mcpc - 4, newUpper); - oldLower = longAt(mcpc); - newLower = (oldLower & 0xFFFF0000U) | (low16BitsOf(self_in_literalAtAddressput, newLiteral)); - longAtput(mcpc, newLower); - assert((opcodeAtAddress(self_in_literalAtAddressput, mcpc - 4)) == LUI); - assert((opcodeAtAddress(self_in_literalAtAddressput, mcpc)) == ORI); - assert((literalAtAddress(self_in_literalAtAddressput, mcpc)) == newLiteral); - return newLiteral; -} - - -/* Answer the literal embedded in the instruction immediately preceding - followingAddress. This is used in the MoveCwR, PushCw and CmpCwR cases. */ -/* Cmp/MoveCwR - pc-8 lui rx, uper - pc-4 ori rx, rx, lower */ - - /* CogMIPSELCompiler>>#literalBeforeFollowingAddress: */ -static usqInt NoDbgRegParms -literalBeforeFollowingAddress(AbstractInstruction * self_in_literalBeforeFollowingAddress, sqInt followingAddress) -{ - if ((opcodeAtAddress(self_in_literalBeforeFollowingAddress, followingAddress - 4)) == ORI) { - return literalAtAddress(self_in_literalBeforeFollowingAddress, followingAddress - 4); - } - if (((opcodeAtAddress(self_in_literalBeforeFollowingAddress, followingAddress - 4)) == SW) - && ((opcodeAtAddress(self_in_literalBeforeFollowingAddress, followingAddress - 8)) == ADDIU)) { - return literalAtAddress(self_in_literalBeforeFollowingAddress, followingAddress - 12); - } - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#loadLiteralByteSize */ -static sqInt NoDbgRegParms -loadLiteralByteSize(AbstractInstruction * self_in_loadLiteralByteSize) -{ - return 8; -} - - -/* Answer the byte size of a MoveCwR opcode's corresponding machine code - when the argument is a PIC. This is for the self-reference at the end of a - closed PIC. */ - - /* CogMIPSELCompiler>>#loadPICLiteralByteSize */ -static sqInt NoDbgRegParms -loadPICLiteralByteSize(AbstractInstruction * self_in_loadPICLiteralByteSize) -{ - /* begin loadLiteralByteSize */ - return 8; -} - - /* CogMIPSELCompiler>>#low16BitsOf: */ -static usqInt NoDbgRegParms -low16BitsOf(AbstractInstruction * self_in_low16BitsOf, usqInt word) -{ - return word & 0xFFFF; -} - - /* CogMIPSELCompiler>>#luiR:C: */ -static sqInt NoDbgRegParms -luiRC(AbstractInstruction * self_in_luiRC, sqInt destReg, sqInt imm) -{ - return itypersrteitherImmediate(self_in_luiRC, LUI, 0, destReg, imm); -} - - /* CogMIPSELCompiler>>#lwR:base:offset: */ -static sqInt NoDbgRegParms -lwRbaseoffset(AbstractInstruction * self_in_lwRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_lwRbaseoffset, LW, baseReg, destReg, offset); -} - - /* CogMIPSELCompiler>>#machineCodeBytes */ -static sqInt NoDbgRegParms -machineCodeBytes(AbstractInstruction * self_in_machineCodeBytes) -{ - return 28; -} - - -/* Answer the maximum number of words of machine code generated for any - abstract instruction. - e.g. AddCheckOverflowCqR */ - - /* CogMIPSELCompiler>>#machineCodeWords */ -static sqInt NoDbgRegParms -machineCodeWords(AbstractInstruction * self_in_machineCodeWords) -{ - return 7; -} - - /* CogMIPSELCompiler>>#mfhiR: */ -static sqInt NoDbgRegParms -mfhiR(AbstractInstruction * self_in_mfhiR, sqInt destReg) -{ - flag("todo"); - return rtypersrtrdsafunct(self_in_mfhiR, SPECIAL, 0, 0, destReg, 0, MFHI); -} - - /* CogMIPSELCompiler>>#mfloR: */ -static sqInt NoDbgRegParms -mfloR(AbstractInstruction * self_in_mfloR, sqInt destReg) -{ - flag("todo"); - return rtypersrtrdsafunct(self_in_mfloR, SPECIAL, 0, 0, destReg, 0, MFLO); -} - - /* CogMIPSELCompiler>>#mipsbreak: */ -static sqInt NoDbgRegParms -mipsbreak(AbstractInstruction * self_in_mipsbreak, sqInt code) -{ - assert(((code >= 0) && (code <= 0xFFFFF))); - return (((sqInt)((usqInt)(code) << 6))) | BREAK; -} - - /* CogMIPSELCompiler>>#multR:R: */ -static sqInt NoDbgRegParms -multRR(AbstractInstruction * self_in_multRR, sqInt leftReg, sqInt rightReg) -{ - flag("todo"); - return rtypersrtrdsafunct(self_in_multRR, SPECIAL, leftReg, rightReg, 0, 0, MULT); -} - - /* CogMIPSELCompiler>>#nop */ -static sqInt NoDbgRegParms -nop(AbstractInstruction * self_in_nop) -{ - return 0; -} - - -/* Support for processors without condition codes, such as the MIPS. - Answer the branch opcode. Modify the receiver and the branch to - implement a suitable conditional branch that doesn't depend on - condition codes being set by the receiver. */ - - /* CogMIPSELCompiler>>#noteFollowingConditionalBranch: */ -static AbstractInstruction * NoDbgRegParms -noteFollowingConditionalBranch(AbstractInstruction * self_in_noteFollowingConditionalBranch, AbstractInstruction *branch) -{ - usqInt newBranchLeft; - sqInt newBranchOpcode; - usqInt newBranchRight; - - if ((((branch->opcode)) == JumpOverflow) - || (((branch->opcode)) == JumpNoOverflow)) { - return noteFollowingOverflowBranch(self_in_noteFollowingConditionalBranch, branch); - } - switch ((branch->opcode)) { - case JumpZero: - newBranchOpcode = BrEqualRR; - break; - - case JumpNonZero: - newBranchOpcode = BrNotEqualRR; - break; - - case JumpBelow: - newBranchOpcode = BrUnsignedLessRR; - break; - - case JumpBelowOrEqual: - newBranchOpcode = BrUnsignedLessEqualRR; - break; - - case JumpAbove: - newBranchOpcode = BrUnsignedGreaterRR; - break; - - case JumpAboveOrEqual: - newBranchOpcode = BrUnsignedGreaterEqualRR; - break; - - case JumpLess: - case JumpNegative: - newBranchOpcode = BrSignedLessRR; - break; - - case JumpLessOrEqual: - newBranchOpcode = BrSignedLessEqualRR; - break; - - case JumpGreater: - newBranchOpcode = BrSignedGreaterRR; - break; - - case JumpGreaterOrEqual: - newBranchOpcode = BrSignedGreaterEqualRR; - break; - - case JumpLongZero: - newBranchOpcode = BrLongEqualRR; - break; - - case JumpLongNonZero: - newBranchOpcode = BrLongNotEqualRR; - break; - - default: - /* begin unreachable */ - error("UNREACHABLE"); - newBranchOpcode = 0;; - } - switch ((self_in_noteFollowingConditionalBranch->opcode)) { - case BrEqualRR: - case BrUnsignedLessRR: - - /* I.e., two jumps after a compare. */ - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[1]; - newBranchRight = ((self_in_noteFollowingConditionalBranch->operands))[2]; - break; - case CmpRR: - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[1]; - newBranchRight = ((self_in_noteFollowingConditionalBranch->operands))[0]; - (self_in_noteFollowingConditionalBranch->opcode) = Label; - break; - case CmpCqR: - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[1]; - newBranchRight = AT; - (self_in_noteFollowingConditionalBranch->opcode) = MoveCqR; - ((self_in_noteFollowingConditionalBranch->operands))[1] = AT; - break; - case CmpCwR: - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[1]; - newBranchRight = AT; - (self_in_noteFollowingConditionalBranch->opcode) = MoveCwR; - ((self_in_noteFollowingConditionalBranch->operands))[1] = AT; - break; - case TstCqR: - newBranchLeft = Cmp; - newBranchRight = ZR; - break; - case AndCqR: - case OrRR: - case XorRR: - case SubCwR: - case SubCqR: - case ArithmeticShiftRightCqR: - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[1]; - newBranchRight = ZR; - break; - case AndCqRR: - case OrCqRR: - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[2]; - newBranchRight = ZR; - break; - case ClzRR: - - /* we test if the destination register is zero */ - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[0]; - newBranchRight = ZR; - break; - default: - /* begin unreachable */ - error("UNREACHABLE"); - - } - /* begin rewriteOpcode:with:with: */ - (branch->opcode) = newBranchOpcode; - ((branch->operands))[1] = newBranchLeft; - ((branch->operands))[2] = newBranchRight; - return branch; -} - - -/* Support for processors without condition codes, such as the MIPS. - Answer the branch opcode. Modify the receiver and the branch to - implement a suitable conditional branch that doesn't depend on - condition codes being set by the receiver. */ - - /* CogMIPSELCompiler>>#noteFollowingOverflowBranch: */ -static AbstractInstruction * NoDbgRegParms -noteFollowingOverflowBranch(AbstractInstruction * self_in_noteFollowingOverflowBranch, AbstractInstruction *branch) -{ - sqInt newBranchOpcode; - - if (((self_in_noteFollowingOverflowBranch->opcode)) == MulRR) { - (self_in_noteFollowingOverflowBranch->opcode) = MulCheckOverflowRR; - switch ((branch->opcode)) { - case JumpOverflow: - newBranchOpcode = BrNotEqualRR; - break; - - case JumpNoOverflow: - newBranchOpcode = BrEqualRR; - break; - - default: - /* begin unreachable */ - error("UNREACHABLE"); - newBranchOpcode = 0;; - } - /* begin rewriteOpcode:with:with: */ - (branch->opcode) = newBranchOpcode; - ((branch->operands))[1] = OverflowTemp1; - ((branch->operands))[2] = OverflowTemp2; - return branch; - } - switch ((self_in_noteFollowingOverflowBranch->opcode)) { - case AddCqR: - (self_in_noteFollowingOverflowBranch->opcode) = AddCheckOverflowCqR; - break; - - case AddRR: - (self_in_noteFollowingOverflowBranch->opcode) = AddCheckOverflowRR; - break; - - case SubCqR: - (self_in_noteFollowingOverflowBranch->opcode) = SubCheckOverflowCqR; - break; - - case SubRR: - (self_in_noteFollowingOverflowBranch->opcode) = SubCheckOverflowRR; - break; - - default: - /* begin unreachable */ - error("UNREACHABLE"); - (self_in_noteFollowingOverflowBranch->opcode) = 0;; - } - switch ((branch->opcode)) { - case JumpOverflow: - newBranchOpcode = BrSignedLessRR; - break; - - case JumpNoOverflow: - newBranchOpcode = BrSignedGreaterEqualRR; - break; - - default: - /* begin unreachable */ - error("UNREACHABLE"); - newBranchOpcode = 0;; - } - /* begin rewriteOpcode:with:with: */ - (branch->opcode) = newBranchOpcode; - ((branch->operands))[1] = Overflow; - ((branch->operands))[2] = ZR; - return branch; -} - - -/* Answer the NSSendCache for the return address of a Newspeak - self, super, outer, or implicit receiver send. */ -/* ra - 24 lui s4, cacheHigh - ra - 20 ori s4, s4, cacheLow - ra - 16 lui t9, stubHigh - ra - 12 ori t9, t9, stubLow - ra - 8 jalr t9 - ra - 4 nop (delay slot) */ - - /* CogMIPSELCompiler>>#nsSendCacheAt: */ -static usqInt NoDbgRegParms -nsSendCacheAt(AbstractInstruction * self_in_nsSendCacheAt, sqInt callSiteReturnAddress) -{ - assert((opcodeAtAddress(self_in_nsSendCacheAt, callSiteReturnAddress - 24)) == LUI); - assert((opcodeAtAddress(self_in_nsSendCacheAt, callSiteReturnAddress - 20)) == ORI); - assert((opcodeAtAddress(self_in_nsSendCacheAt, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_nsSendCacheAt, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_nsSendCacheAt, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_nsSendCacheAt, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_nsSendCacheAt))); - return literalAtAddress(self_in_nsSendCacheAt, callSiteReturnAddress - 20); -} - - /* CogMIPSELCompiler>>#numIntRegArgs */ -static sqInt NoDbgRegParms -numIntRegArgs(AbstractInstruction * self_in_numIntRegArgs) -{ - flag("OABI"); - return 4; -} - - /* CogMIPSELCompiler>>#opcodeAtAddress: */ -static sqInt NoDbgRegParms -opcodeAtAddress(AbstractInstruction * self_in_opcodeAtAddress, sqInt mcpc) -{ - return ((usqInt)((longAt(mcpc)))) >> 26; -} - - /* CogMIPSELCompiler>>#oriR:R:C: */ -static sqInt NoDbgRegParms -oriRRC(AbstractInstruction * self_in_oriRRC, sqInt destReg, sqInt srcReg, sqInt imm) -{ - return itypersrteitherImmediate(self_in_oriRRC, ORI, srcReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#orR:R:R: */ -static sqInt NoDbgRegParms -orRRR(AbstractInstruction * self_in_orRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_orRRR, SPECIAL, leftReg, rightReg, destReg, 0, OR); -} - - /* CogMIPSELCompiler>>#padIfPossibleWithStopsFrom:to: */ -static void NoDbgRegParms -padIfPossibleWithStopsFromto(AbstractInstruction * self_in_padIfPossibleWithStopsFromto, sqInt startAddr, sqInt endAddr) -{ - sqInt addr; - - for (addr = startAddr; addr < endAddr; addr += 4) { - longAtput(addr, stop(self_in_padIfPossibleWithStopsFromto)); - } -} - - /* CogMIPSELCompiler>>#prefR:offset:hint: */ -static sqInt NoDbgRegParms -prefRoffsethint(AbstractInstruction * self_in_prefRoffsethint, sqInt baseReg, sqInt offset, sqInt hint) -{ - flag("todo"); - assert((hint == HintLoad) - || (hint == HintStore)); - return itypersrtsignedImmediate(self_in_prefRoffsethint, PREF, baseReg, hint, offset); -} - - /* CogMIPSELCompiler>>#pushLinkRegisterByteSize */ -static sqInt NoDbgRegParms -pushLinkRegisterByteSize(AbstractInstruction * self_in_pushLinkRegisterByteSize) -{ - return 8; -} - - /* CogMIPSELCompiler>>#relocateCallBeforeReturnPC:by: */ -static AbstractInstruction * NoDbgRegParms -relocateCallBeforeReturnPCby(AbstractInstruction * self_in_relocateCallBeforeReturnPCby, sqInt retpc, sqInt delta) -{ - usqInt target; - - assert((delta % 4) == 0); - if (delta == 0) { - return self_in_relocateCallBeforeReturnPCby; - } - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 16)) == LUI); - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 12)) == ORI); - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 8)) == SPECIAL); - assert((functionAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 8)) == JALR); - assert((longAt(retpc - 4)) == (nop(self_in_relocateCallBeforeReturnPCby))); - target = literalAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 12); - target += delta; - literalAtAddressput(self_in_relocateCallBeforeReturnPCby, retpc - 12, target); - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 16)) == LUI); - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 12)) == ORI); - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 8)) == SPECIAL); - assert((functionAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 8)) == JALR); - assert((longAt(retpc - 4)) == (nop(self_in_relocateCallBeforeReturnPCby))); - return 0; -} - - -/* lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jr t9 - nop (delay slot) - ... <-- pc */ - - /* CogMIPSELCompiler>>#relocateJumpLongBeforeFollowingAddress:by: */ -static AbstractInstruction * NoDbgRegParms -relocateJumpLongBeforeFollowingAddressby(AbstractInstruction * self_in_relocateJumpLongBeforeFollowingAddressby, sqInt pc, sqInt delta) -{ - usqInt newTarget; - usqInt oldTarget; - - assert((delta % 4) == 0); - if (delta == 0) { - return self_in_relocateJumpLongBeforeFollowingAddressby; - } - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 16)) == LUI); - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 12)) == ORI); - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 8)) == SPECIAL); - assert((functionAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 8)) == JR); - assert((longAt(pc - 4)) == (nop(self_in_relocateJumpLongBeforeFollowingAddressby))); - oldTarget = literalAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 12); - newTarget = oldTarget + delta; - literalAtAddressput(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 12, newTarget); - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 16)) == LUI); - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 12)) == ORI); - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 8)) == SPECIAL); - assert((functionAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 8)) == JR); - assert((longAt(pc - 4)) == (nop(self_in_relocateJumpLongBeforeFollowingAddressby))); - return 0; -} - - -/* lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jalr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#relocateJumpLongConditionalBeforeFollowingAddress:by: */ -static void NoDbgRegParms -relocateJumpLongConditionalBeforeFollowingAddressby(AbstractInstruction * self_in_relocateJumpLongConditionalBeforeFollowingAddressby, sqInt pc, sqInt delta) -{ - assert((opcodeAtAddress(self_in_relocateJumpLongConditionalBeforeFollowingAddressby, pc - 16)) == BNE); - assert((longAt(pc - 12)) == (nop(self_in_relocateJumpLongConditionalBeforeFollowingAddressby))); - assert((opcodeAtAddress(self_in_relocateJumpLongConditionalBeforeFollowingAddressby, pc - 8)) == J); - assert((longAt(pc - 4)) == (nop(self_in_relocateJumpLongConditionalBeforeFollowingAddressby))); - rewriteJTypeAtAddressdelta(self_in_relocateJumpLongConditionalBeforeFollowingAddressby, pc - 8, delta); - assert((opcodeAtAddress(self_in_relocateJumpLongConditionalBeforeFollowingAddressby, pc - 16)) == BNE); - assert((longAt(pc - 12)) == (nop(self_in_relocateJumpLongConditionalBeforeFollowingAddressby))); - assert((opcodeAtAddress(self_in_relocateJumpLongConditionalBeforeFollowingAddressby, pc - 8)) == J); - assert((longAt(pc - 4)) == (nop(self_in_relocateJumpLongConditionalBeforeFollowingAddressby))); -} - - -/* cogit disassembleFrom: pc - 16 to: pc + 16 a StackToRegisterMappingCogit. */ - - /* CogMIPSELCompiler>>#relocateMethodReferenceBeforeAddress:by: */ -static AbstractInstruction * NoDbgRegParms -relocateMethodReferenceBeforeAddressby(AbstractInstruction * self_in_relocateMethodReferenceBeforeAddressby, sqInt pc, sqInt delta) -{ - usqInt newValue; - usqInt oldValue; - - if (((opcodeAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 8)) == ADDIU) - && ((opcodeAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 4)) == SW)) { - - /* PushCw */ - oldValue = literalAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 12); - newValue = oldValue + delta; - literalAtAddressput(self_in_relocateMethodReferenceBeforeAddressby, pc - 12, newValue); - assert((literalAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 12)) == newValue); - return self_in_relocateMethodReferenceBeforeAddressby; - } - oldValue = literalAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 4); - newValue = oldValue + delta; - literalAtAddressput(self_in_relocateMethodReferenceBeforeAddressby, pc - 4, newValue); - assert((literalAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 4)) == newValue); - return 0; -} - - -/* Rewrite a call instruction to call a different target. This variant is - used to link PICs - in ceSendMiss et al,. - Answer the extent of the code change which is used to compute the range of - the icache to flush. */ -/* lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jalr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#rewriteCallAt:target: */ -static sqInt NoDbgRegParms -rewriteCallAttarget(AbstractInstruction * self_in_rewriteCallAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress) -{ - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteCallAttarget))); - literalAtAddressput(self_in_rewriteCallAttarget, callSiteReturnAddress - 12, callTargetAddress); - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteCallAttarget))); - return 20; -} - - -/* Rewrite a jump instruction to call a different target. This variant is - used to reset the - jumps in the prototype CPIC to suit each use,. - Answer the extent of the code change which is used to compute the range of - the icache to flush. */ - - /* CogMIPSELCompiler>>#rewriteConditionalJumpLongAt:target: */ -static void NoDbgRegParms -rewriteConditionalJumpLongAttarget(AbstractInstruction * self_in_rewriteConditionalJumpLongAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress) -{ - assert((opcodeAtAddress(self_in_rewriteConditionalJumpLongAttarget, callSiteReturnAddress - 8)) == J); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteConditionalJumpLongAttarget))); - rewriteJTypeAtAddresstarget(self_in_rewriteConditionalJumpLongAttarget, callSiteReturnAddress - 8, callTargetAddress); - assert((opcodeAtAddress(self_in_rewriteConditionalJumpLongAttarget, callSiteReturnAddress - 8)) == J); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteConditionalJumpLongAttarget))); -} - - -/* Rewrite a jump instruction to call a different target. This variant is - used to reset the - jumps in the prototype CPIC to suit each use,. - Answer the extent of the code change which is used to compute the range of - the icache to flush. */ -/* self CmpR: ClassReg R: TempReg. - ^self JumpNonZero: 0 */ -/* bne s5, s3, +156 ; =BE7C - nop (delay slot) - .... <-- addressFollowingJump */ - - /* CogMIPSELCompiler>>#rewriteCPICJumpAt:target: */ -static void NoDbgRegParms -rewriteCPICJumpAttarget(AbstractInstruction * self_in_rewriteCPICJumpAttarget, usqInt addressFollowingJump, usqInt jumpTargetAddr) -{ - assert((opcodeAtAddress(self_in_rewriteCPICJumpAttarget, addressFollowingJump - 8)) == BNE); - assert((longAt(addressFollowingJump - 4)) == (nop(self_in_rewriteCPICJumpAttarget))); - rewriteITypeBranchAtAddresstarget(self_in_rewriteCPICJumpAttarget, addressFollowingJump - 8, jumpTargetAddr); - assert((opcodeAtAddress(self_in_rewriteCPICJumpAttarget, addressFollowingJump - 8)) == BNE); - assert((longAt(addressFollowingJump - 4)) == (nop(self_in_rewriteCPICJumpAttarget))); -} - - -/* Rewrite an inline cache to call a different target for a new tag. This - variant is used - to link unlinked sends in ceSend:to:numArgs: et al. Answer the extent of - the code - change which is used to compute the range of the icache to flush. */ -/* MoveCwR ClassReg selectorIndex/expectedClass - Call: unlinked send stub/expectedTarget - Push ReceiverResult <-- callSiteReturnAddress */ -/* lui s3, selector/tagHigh - ori s3, s3, selector/tagLow - lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jalr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#rewriteInlineCacheAt:tag:target: */ -static sqInt NoDbgRegParms -rewriteInlineCacheAttagtarget(AbstractInstruction * self_in_rewriteInlineCacheAttagtarget, usqInt callSiteReturnAddress, sqInt cacheTag, usqInt callTargetAddress) -{ - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 24)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 20)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteInlineCacheAttagtarget))); - literalAtAddressput(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 20, cacheTag); - literalAtAddressput(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 12, callTargetAddress); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 24)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 20)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteInlineCacheAttagtarget))); - return 24; -} - - -/* Rewrite an inline cache with a new tag. This variant is used - by the garbage collector. */ -/* MoveCwR ClassReg selectorIndex/expectedClass - Call: unlinked send stub/expectedTarget - Push ReceiverResult <-- callSiteReturnAddress */ -/* lui s3, selector/tagHigh - ori s3, s3, selector/tagLow - lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jalr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#rewriteInlineCacheTag:at: */ -static void NoDbgRegParms -rewriteInlineCacheTagat(AbstractInstruction * self_in_rewriteInlineCacheTagat, sqInt cacheTag, usqInt callSiteReturnAddress) -{ - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 24)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 20)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteInlineCacheTagat))); - literalAtAddressput(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 20, cacheTag); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 24)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 20)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteInlineCacheTagat))); -} - - /* CogMIPSELCompiler>>#rewriteITypeBranchAtAddress:target: */ -static void NoDbgRegParms -rewriteITypeBranchAtAddresstarget(AbstractInstruction * self_in_rewriteITypeBranchAtAddresstarget, sqInt mcpc, sqInt newTarget) -{ - sqInt newDisplacement; - unsigned int newInstruction; - sqInt oldInstruction; - - - /* Displacement is relative to delay slot. */ - newDisplacement = newTarget - (mcpc + 4); - - /* Displacement is in words. */ - newDisplacement = (newDisplacement) >> 2; - newDisplacement = newDisplacement & 0xFFFF; - oldInstruction = longAt(mcpc); - newInstruction = (oldInstruction & 0xFFFF0000U) | newDisplacement; - longAtput(mcpc, newInstruction); -} - - /* CogMIPSELCompiler>>#rewriteJTypeAtAddress:delta: */ -static void NoDbgRegParms -rewriteJTypeAtAddressdelta(AbstractInstruction * self_in_rewriteJTypeAtAddressdelta, sqInt mcpc, sqInt delta) -{ - usqInt newTarget; - usqInt oldTarget; - - oldTarget = targetFromJTypeAtAddress(self_in_rewriteJTypeAtAddressdelta, mcpc); - newTarget = oldTarget + delta; - rewriteJTypeAtAddresstarget(self_in_rewriteJTypeAtAddressdelta, mcpc, newTarget); -} - - /* CogMIPSELCompiler>>#rewriteJTypeAtAddress:target: */ -static void NoDbgRegParms -rewriteJTypeAtAddresstarget(AbstractInstruction * self_in_rewriteJTypeAtAddresstarget, sqInt mcpc, sqInt newTarget) -{ - sqInt regionMask; - - assert((opcodeAtAddress(self_in_rewriteJTypeAtAddresstarget, mcpc)) == J); - - /* mcpc + 4: relative to delay slot not j */ - regionMask = 0xF0000000U; - assert(((mcpc + 4) & regionMask) == (newTarget & regionMask)); - longAtput(mcpc, jA(self_in_rewriteJTypeAtAddresstarget, newTarget)); -} - - -/* Rewrite a jump instruction to call a different target. This variant is - used to reset the - jumps in the prototype CPIC to suit each use,. - Answer the extent of the code change which is used to compute the range of - the icache to flush. */ -/* lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#rewriteJumpLongAt:target: */ -static sqInt NoDbgRegParms -rewriteJumpLongAttarget(AbstractInstruction * self_in_rewriteJumpLongAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress) -{ - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 8)) == JR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteJumpLongAttarget))); - literalAtAddressput(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 12, callTargetAddress); - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 8)) == JR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteJumpLongAttarget))); - return 20; -} - - /* CogMIPSELCompiler>>#rtAtAddress: */ -static sqInt NoDbgRegParms -rtAtAddress(AbstractInstruction * self_in_rtAtAddress, sqInt mcpc) -{ - return (((usqInt)((longAt(mcpc)))) >> 16) & 0x1F; -} - - /* CogMIPSELCompiler>>#rtype:rs:rt:rd:sa:funct: */ -static sqInt NoDbgRegParms -rtypersrtrdsafunct(AbstractInstruction * self_in_rtypersrtrdsafunct, sqInt op, sqInt rs, sqInt rt, sqInt rd, sqInt sa, sqInt funct) -{ - assert(((op >= 0) && (op <= 0x3F))); - assert(((rs >= 0) && (rs <= 0x1F))); - assert(((rt >= 0) && (rt <= 0x1F))); - assert(((rd >= 0) && (rd <= 0x1F))); - assert(((sa >= 0) && (sa <= 0x1F))); - assert(((funct >= 0) && (funct <= 0x3F))); - return (((((((sqInt)((usqInt)(op) << 26))) | (((sqInt)((usqInt)(rs) << 21)))) | (((sqInt)((usqInt)(rt) << 16)))) | (((sqInt)((usqInt)(rd) << 11)))) | (((sqInt)((usqInt)(sa) << 6)))) | funct; -} - - /* CogMIPSELCompiler>>#sbR:base:offset: */ -static sqInt NoDbgRegParms -sbRbaseoffset(AbstractInstruction * self_in_sbRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_sbRbaseoffset, SB, baseReg, srcReg, offset); -} - - -/* Not really, but we can merge this in noteFollowingConditionalBranch:. */ - - /* CogMIPSELCompiler>>#setsConditionCodesFor: */ -static sqInt NoDbgRegParms -setsConditionCodesFor(AbstractInstruction * self_in_setsConditionCodesFor, sqInt aConditionalJumpOpcode) -{ - if (((self_in_setsConditionCodesFor->opcode)) == XorRR) { - return 1; - } - if (((self_in_setsConditionCodesFor->opcode)) == ArithmeticShiftRightCqR) { - return 1; - } - if ((((self_in_setsConditionCodesFor->opcode)) == ClzRR) - && (aConditionalJumpOpcode == JumpZero)) { - return 1; - } - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#shR:base:offset: */ -static sqInt NoDbgRegParms -shRbaseoffset(AbstractInstruction * self_in_shRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_shRbaseoffset, SH, baseReg, srcReg, offset); -} - - -/* Size a jump and set its address. The target may be another instruction - or an absolute address. On entry the address inst var holds our virtual - address. On exit address is set to eventualAbsoluteAddress, which is - where this instruction will be output. The span of a jump to a following - instruction is therefore between that instruction's address and this - instruction's address ((which are both still their virtual addresses), but - the span of a jump to a preceding instruction or to an absolute address is - between that instruction's address (which by now is its eventual absolute - address) or absolute address and eventualAbsoluteAddress. - - ARM is simple; the 26-bit call/jump range means no short jumps. This - routine only has to determine the targets of jumps, not determine sizes. */ - - /* CogMIPSELCompiler>>#sizePCDependentInstructionAt: */ -static usqInt NoDbgRegParms -sizePCDependentInstructionAt(AbstractInstruction * self_in_sizePCDependentInstructionAt, sqInt eventualAbsoluteAddress) -{ - usqInt alignment; - - if (((self_in_sizePCDependentInstructionAt->opcode)) == AlignmentNops) { - (self_in_sizePCDependentInstructionAt->address) = eventualAbsoluteAddress; - alignment = ((self_in_sizePCDependentInstructionAt->operands))[0]; - return ((self_in_sizePCDependentInstructionAt->machineCodeSize) = ((eventualAbsoluteAddress + (alignment - 1)) & (-alignment)) - eventualAbsoluteAddress); - } - assert((isJump(self_in_sizePCDependentInstructionAt)) - || ((((self_in_sizePCDependentInstructionAt->opcode)) == Call) - || (((self_in_sizePCDependentInstructionAt->opcode)) == CallFull))); - if (isJump(self_in_sizePCDependentInstructionAt)) { - resolveJumpTarget(self_in_sizePCDependentInstructionAt); - } - (self_in_sizePCDependentInstructionAt->address) = eventualAbsoluteAddress; - return ((self_in_sizePCDependentInstructionAt->machineCodeSize) = (self_in_sizePCDependentInstructionAt->maxSize)); -} - - /* CogMIPSELCompiler>>#sllR:R:C: */ -static sqInt NoDbgRegParms -sllRRC(AbstractInstruction * self_in_sllRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount) -{ - return rtypersrtrdsafunct(self_in_sllRRC, SPECIAL, 0, sourceReg, destReg, shiftAmount, SLL); -} - - /* CogMIPSELCompiler>>#sllvR:R:R: */ -static sqInt NoDbgRegParms -sllvRRR(AbstractInstruction * self_in_sllvRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_sllvRRR, SPECIAL, rightReg, leftReg, destReg, 0, SLLV); -} - - /* CogMIPSELCompiler>>#sltiR:R:C: */ -static sqInt NoDbgRegParms -sltiRRC(AbstractInstruction * self_in_sltiRRC, sqInt destReg, sqInt leftReg, sqInt imm) -{ - return itypersrtsignedImmediate(self_in_sltiRRC, SLTI, leftReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#sltiuR:R:C: */ -static sqInt NoDbgRegParms -sltiuRRC(AbstractInstruction * self_in_sltiuRRC, sqInt destReg, sqInt leftReg, sqInt imm) -{ - return itypersrtsignedImmediate(self_in_sltiuRRC, SLTIU, leftReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#sltR:R:R: */ -static sqInt NoDbgRegParms -sltRRR(AbstractInstruction * self_in_sltRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_sltRRR, SPECIAL, leftReg, rightReg, destReg, 0, SLT); -} - - /* CogMIPSELCompiler>>#sltuR:R:R: */ -static sqInt NoDbgRegParms -sltuRRR(AbstractInstruction * self_in_sltuRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_sltuRRR, SPECIAL, leftReg, rightReg, destReg, 0, SLTU); -} - - /* CogMIPSELCompiler>>#sraR:R:C: */ -static sqInt NoDbgRegParms -sraRRC(AbstractInstruction * self_in_sraRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount) -{ - return rtypersrtrdsafunct(self_in_sraRRC, SPECIAL, 0, sourceReg, destReg, shiftAmount, SRA); -} - - /* CogMIPSELCompiler>>#sravR:R:R: */ -static sqInt NoDbgRegParms -sravRRR(AbstractInstruction * self_in_sravRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_sravRRR, SPECIAL, rightReg, leftReg, destReg, 0, SRAV); -} - - /* CogMIPSELCompiler>>#srlR:R:C: */ -static sqInt NoDbgRegParms -srlRRC(AbstractInstruction * self_in_srlRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount) -{ - return rtypersrtrdsafunct(self_in_srlRRC, SPECIAL, 0, sourceReg, destReg, shiftAmount, SRL); -} - - /* CogMIPSELCompiler>>#srlvR:R:R: */ -static sqInt NoDbgRegParms -srlvRRR(AbstractInstruction * self_in_srlvRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_srlvRRR, SPECIAL, rightReg, leftReg, destReg, 0, SRLV); -} - - /* CogMIPSELCompiler>>#stop */ -static sqInt NoDbgRegParms -stop(AbstractInstruction * self_in_stop) -{ - return mipsbreak(self_in_stop, 0); -} - - /* CogMIPSELCompiler>>#stopsFrom:to: */ -static void NoDbgRegParms -stopsFromto(AbstractInstruction * self_in_stopsFromto, sqInt startAddr, sqInt endAddr) -{ - sqInt addr; - - assert((((endAddr - startAddr) + 1) % 4) == 0); - for (addr = startAddr; addr <= endAddr; addr += 4) { - codeLongAtput(addr, stop(self_in_stopsFromto)); - } -} - - -/* Rewrite the long constant loaded by a MoveCwR or PushCw before the given - address - */ - - /* CogMIPSELCompiler>>#storeLiteral:beforeFollowingAddress: */ -static sqInt NoDbgRegParms -storeLiteralbeforeFollowingAddress(AbstractInstruction * self_in_storeLiteralbeforeFollowingAddress, sqInt literal, sqInt followingAddress) -{ - flag("bogus"); - if ((opcodeAtAddress(self_in_storeLiteralbeforeFollowingAddress, followingAddress - 4)) == ORI) { - return literalAtAddressput(self_in_storeLiteralbeforeFollowingAddress, followingAddress - 4, literal); - } - if (((opcodeAtAddress(self_in_storeLiteralbeforeFollowingAddress, followingAddress - 4)) == SW) - && ((opcodeAtAddress(self_in_storeLiteralbeforeFollowingAddress, followingAddress - 8)) == ADDIU)) { - return literalAtAddressput(self_in_storeLiteralbeforeFollowingAddress, followingAddress - 12, literal); - } - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#subuR:R:R: */ -static sqInt NoDbgRegParms -subuRRR(AbstractInstruction * self_in_subuRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_subuRRR, SPECIAL, leftReg, rightReg, destReg, 0, SUBU); -} - - /* CogMIPSELCompiler>>#swR:base:offset: */ -static sqInt NoDbgRegParms -swRbaseoffset(AbstractInstruction * self_in_swRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_swRbaseoffset, SW, baseReg, srcReg, offset); -} - - /* CogMIPSELCompiler>>#targetFromITypeAtAddress: */ -static usqInt NoDbgRegParms -targetFromITypeAtAddress(AbstractInstruction * self_in_targetFromITypeAtAddress, usqInt mcpc) -{ - usqInt offset; - - offset = (longAt(mcpc)) & 0xFFFF; - offset = offset << 2; - return (mcpc + offset) + OneInstruction; -} - - /* CogMIPSELCompiler>>#targetFromJTypeAtAddress: */ -static usqInt NoDbgRegParms -targetFromJTypeAtAddress(AbstractInstruction * self_in_targetFromJTypeAtAddress, usqInt mcpc) -{ - sqInt targetLow; - - - /* mcpc + 4: relative to delay slot not j */ - targetLow = (longAt(mcpc)) & 0x3FFFFFF; - return ((mcpc + 4) & 0xF0000000U) + (((sqInt)((usqInt)(targetLow) << 2))); -} - - /* CogMIPSELCompiler>>#xoriR:R:C: */ -static sqInt NoDbgRegParms -xoriRRC(AbstractInstruction * self_in_xoriRRC, sqInt destReg, sqInt srcReg, sqInt imm) -{ - return itypersrteitherImmediate(self_in_xoriRRC, XORI, srcReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#xorR:R:R: */ -static sqInt NoDbgRegParms -xorRRR(AbstractInstruction * self_in_xorRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_xorRRR, SPECIAL, leftReg, rightReg, destReg, 0, XOR); -} - - -/* Answer if Call and JumpLong are relative and hence need to take the - caller's relocation delta into account during code compaction, rather than - just the - callee's delta. */ - - /* CogMIPSELCompiler>>#zoneCallsAreRelative */ -static sqInt NoDbgRegParms -zoneCallsAreRelative(AbstractInstruction * self_in_zoneCallsAreRelative) -{ - return 0; -} - - /* CogObjectRepresentation>>#checkValidObjectReference: */ -static sqInt NoDbgRegParms -checkValidObjectReference(sqInt anOop) -{ - return (!(isImmediate(anOop))) - && ((heapMapAtWord(pointerForOop(anOop))) != 0); -} - - /* CogObjectRepresentation>>#genCmpClassFloatCompactIndexR: */ -static AbstractInstruction * NoDbgRegParms -genCmpClassFloatCompactIndexR(sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, ClassFloatCompactIndex, reg); - return anInstruction; -} - - /* CogObjectRepresentation>>#genCmpClassMethodContextCompactIndexR: */ -static AbstractInstruction * NoDbgRegParms -genCmpClassMethodContextCompactIndexR(sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, reg); - return anInstruction; -} - - -/* Get the method header (first word) of a CompiledMethod into headerReg. - Deal with the method possibly being cogged. */ - - /* CogObjectRepresentation>>#genGetMethodHeaderOf:into:scratch: */ -static sqInt NoDbgRegParms -genGetMethodHeaderOfintoscratch(sqInt methodReg, sqInt headerReg, sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *jumpNotCogged; - sqInt offset; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, BaseHeaderSize, methodReg, headerReg); - jumpNotCogged = genJumpSmallInteger(headerReg); - /* begin MoveMw:r:R: */ - offset = offsetof(CogMethod, methodHeader); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, offset, headerReg, headerReg); - jmpTarget(jumpNotCogged, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - /* CogObjectRepresentation>>#genLoadSlot:sourceReg:destReg: */ -static sqInt NoDbgRegParms -genLoadSlotsourceRegdestReg(sqInt index, sqInt sourceReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, (index * BytesPerWord) + BaseHeaderSize, sourceReg, destReg); - return 0; -} - - /* CogObjectRepresentation>>#genPrimitiveAdd */ -static sqInt -genPrimitiveAdd(void) -{ - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpOvfl; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genRemoveSmallIntegerTagsInScratchReg(ClassReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, ReceiverResultReg, ClassReg); - /* begin JumpOverflow: */ - jumpOvfl = genConditionalBranchoperand(JumpOverflow, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpOvfl, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveBitAnd */ -static sqInt -genPrimitiveBitAnd(void) -{ - AbstractInstruction *jumpNotSI; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - /* begin AndR:R: */ - genoperandoperand(AndRR, Arg0Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveBitOr */ -static sqInt -genPrimitiveBitOr(void) -{ - AbstractInstruction *jumpNotSI; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - /* begin OrR:R: */ - genoperandoperand(OrRR, Arg0Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - -/* rTemp := rArg0 - rClass := tTemp - rTemp := rTemp & 1 - jz nonInt - rClass >>= 1 - cmp 0,rClass - jge neg - cmp 31,rClass // numSmallIntegerBits, jge for sign - jge tooBig - rTemp := rReceiver - rTemp <<= rClass - rTemp >>= rClass (arithmetic) - cmp rTemp,rReceiver - jnz ovfl - rReceiver := rReceiver - 1 - rReceiver := rReceiver <<= rClass - rReceiver := rReceiver + 1 - ret - neg: - rClass := 0 - rClass - cmp 31,rClass // numSmallIntegerBits - jge inRange - rClass := 31 - inRange - rReceiver := rReceiver >>= rClass. - rReceiver := rReceiver | smallIntegerTags. - ret - ovfl - tooBig - nonInt: - fail - */ - - /* CogObjectRepresentation>>#genPrimitiveBitShift */ -static sqInt -genPrimitiveBitShift(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *jumpInRange; - AbstractInstruction *jumpNegative; - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpOvfl; - AbstractInstruction *jumpTooBig; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genConvertSmallIntegerToIntegerInReg(ClassReg); - if (!(setsConditionCodesFor(lastOpcode(), JumpNegative))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, ClassReg); - } - /* begin JumpNegative: */ - jumpNegative = genConditionalBranchoperand(JumpNegative, ((sqInt)0)); - /* begin CmpCq:R: */ - anInstruction1 = genoperandoperand(CmpCqR, 0x1F /* numSmallIntegerBits */, ClassReg); - /* begin JumpGreaterOrEqual: */ - jumpTooBig = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - /* begin LogicalShiftLeftR:R: */ - genoperandoperand(LogicalShiftLeftRR, ClassReg, TempReg); - /* begin ArithmeticShiftRightR:R: */ - genoperandoperand(ArithmeticShiftRightRR, ClassReg, TempReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, ReceiverResultReg); - /* begin JumpNonZero: */ - jumpOvfl = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genRemoveSmallIntegerTagsInScratchReg(ReceiverResultReg); - /* begin LogicalShiftLeftR:R: */ - genoperandoperand(LogicalShiftLeftRR, ClassReg, ReceiverResultReg); - genAddSmallIntegerTagsTo(ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNegative, genoperand(NegateR, ClassReg)); - /* begin CmpCq:R: */ - anInstruction2 = genoperandoperand(CmpCqR, 0x1F /* numSmallIntegerBits */, ClassReg); - /* begin JumpLessOrEqual: */ - jumpInRange = genConditionalBranchoperand(JumpLessOrEqual, ((sqInt)0)); - /* begin MoveCq:R: */ - anInstruction3 = genoperandoperand(MoveCqR, 0x1F /* numSmallIntegerBits */, ClassReg); - jmpTarget(jumpInRange, genoperandoperand(ArithmeticShiftRightRR, ClassReg, ReceiverResultReg)); - genClearAndSetSmallIntegerTagsIn(ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotSI, jmpTarget(jumpTooBig, jmpTarget(jumpOvfl, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveBitXor */ -static sqInt -genPrimitiveBitXor(void) -{ - AbstractInstruction *jumpNotSI; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genRemoveSmallIntegerTagsInScratchReg(Arg0Reg); - /* begin XorR:R: */ - genoperandoperand(XorRR, Arg0Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveClass */ -static sqInt -genPrimitiveClass(void) -{ - sqInt reg; - - reg = ReceiverResultReg; - if (methodOrBlockNumArgs > 0) { - if (methodOrBlockNumArgs > 1) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - reg = Arg0Reg; - assert(0 < (numRegArgs())); - } - if ((genGetClassObjectOfintoscratchRegmayBeAForwarder(reg, ReceiverResultReg, TempReg, reg != ReceiverResultReg)) == BadRegisterSet) { - genGetClassObjectOfintoscratchRegmayBeAForwarder(reg, ClassReg, TempReg, reg != ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, ReceiverResultReg); - } - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - return UnfailingPrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveDiv */ -static sqInt -genPrimitiveDiv(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *convert; - AbstractInstruction *jumpExact; - AbstractInstruction *jumpIsSI; - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpSameSign; - AbstractInstruction *jumpZero; - - if (!(processorHasDivQuoRemAndMClassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, Arg1Reg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genShiftAwaySmallIntegerTagsInScratchReg(ClassReg); - if (!(setsConditionCodesFor(lastOpcode(), JumpZero))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, ClassReg); - } - /* begin JumpZero: */ - jumpZero = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - genShiftAwaySmallIntegerTagsInScratchReg(TempReg); - gDivRRQuoRem(ClassReg, TempReg, TempReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(CmpCqR, 0, ClassReg); - /* begin JumpZero: */ - jumpExact = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin XorR:R: */ - genoperandoperand(XorRR, ClassReg, Arg1Reg); - if (!(setsConditionCodesFor(lastOpcode(), JumpZero))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, Arg1Reg); - } - /* begin JumpGreaterOrEqual: */ - jumpSameSign = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(SubCqR, 1, TempReg); - jmpTarget(jumpSameSign, (convert = genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - genConvertIntegerInRegtoSmallIntegerInReg(TempReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpExact, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - jumpIsSI = genJumpIsSmallIntegerValuescratch(TempReg, Arg1Reg); - jmpTarget(jumpIsSI, convert); - jmpTarget(jumpZero, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveDivide */ -static sqInt -genPrimitiveDivide(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *jumpInexact; - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpOverflow; - AbstractInstruction *jumpZero; - - if (!(processorHasDivQuoRemAndMClassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genShiftAwaySmallIntegerTagsInScratchReg(ClassReg); - /* begin JumpZero: */ - jumpZero = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - genShiftAwaySmallIntegerTagsInScratchReg(TempReg); - gDivRRQuoRem(ClassReg, TempReg, TempReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, ClassReg); - /* begin JumpNonZero: */ - jumpInexact = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - jumpOverflow = genJumpNotSmallIntegerValuescratch(TempReg, Arg1Reg); - genConvertIntegerInRegtoSmallIntegerInReg(TempReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpOverflow, jmpTarget(jumpInexact, jmpTarget(jumpZero, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveEqual */ -static sqInt -genPrimitiveEqual(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpZero, gJumpFPEqual, 0) - : genSmallIntegerComparison(JumpZero)); -} - - /* CogObjectRepresentation>>#genPrimitiveGreaterOrEqual */ -static sqInt -genPrimitiveGreaterOrEqual(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpGreaterOrEqual, gJumpFPGreaterOrEqual, 0) - : genSmallIntegerComparison(JumpGreaterOrEqual)); -} - - /* CogObjectRepresentation>>#genPrimitiveGreaterThan */ -static sqInt -genPrimitiveGreaterThan(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpGreater, gJumpFPGreater, 0) - : genSmallIntegerComparison(JumpGreater)); -} - - -/* Implementation notes: there are two reasons to use TempReg - -1) if primitive fails, ReceiverResultReg must remain unchanged (we - CompletePrimitive) -2) CLZ/BSR only work on 64bits for registers R0-R7 on - Intel X64. But Win64 uses R9 - Normally, this should be backEnd dependent, but for now we have a single - 64bits target... - */ - - /* CogObjectRepresentation>>#genPrimitiveHighBit */ -static sqInt -genPrimitiveHighBit(void) -{ - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *jumpNegativeReceiver; - AbstractInstruction *jumpNegativeReceiver2; - - - /* remove excess tag bits from the receiver oop */ - - /* and use the abstract cogit facility for case of single tag-bit */ - /* begin genHighBitIn:ofSmallIntegerOopWithSingleTagBit: */ - /* begin genHighBitClzIn:ofSmallIntegerOopWithSingleTagBit: */ - genoperandoperand(ClzRR, ReceiverResultReg, TempReg); - if (!(setsConditionCodesFor(lastOpcode(), JumpZero))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(CmpCqR, 0, TempReg); - } - - /* Note the nice bit trick below: - highBit_1based_of_small_int_value = (BytesPerWord * 8) - leadingZeroCout_of_oop - 1 toAccountForTagBit. - This is like 2 complements (- reg - 1) on (BytesPerWord * 8) log2 bits, or exactly a bit invert operation... */ - jumpNegativeReceiver2 = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkLiteral:forInstruction: */ - anInstruction3 = genoperandoperand(XorCwR, (BytesPerWord * 8) - 1, TempReg); - jumpNegativeReceiver = jumpNegativeReceiver2; - goto l4; - l4: /* end genHighBitIn:ofSmallIntegerOopWithSingleTagBit: */; - if (jumpNegativeReceiver == 0) { - return UnimplementedPrimitive; - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - genConvertIntegerToSmallIntegerInReg(ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNegativeReceiver, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveIdentical */ -static sqInt -genPrimitiveIdentical(void) -{ - return genPrimitiveIdenticalOrNotIf(0); -} - - /* CogObjectRepresentation>>#genPrimitiveLessOrEqual */ -static sqInt -genPrimitiveLessOrEqual(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpLessOrEqual, gJumpFPGreaterOrEqual, 1) - : genSmallIntegerComparison(JumpLessOrEqual)); -} - - /* CogObjectRepresentation>>#genPrimitiveLessThan */ -static sqInt -genPrimitiveLessThan(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpLess, gJumpFPGreater, 1) - : genSmallIntegerComparison(JumpLess)); -} - - /* CogObjectRepresentation>>#genPrimitiveMod */ -static sqInt -genPrimitiveMod(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *jumpExact; - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpSameSign; - AbstractInstruction *jumpZero; - - if (!(processorHasDivQuoRemAndMClassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genRemoveSmallIntegerTagsInScratchReg(ClassReg); - /* begin JumpZero: */ - jumpZero = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, Arg1Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - genRemoveSmallIntegerTagsInScratchReg(TempReg); - gDivRRQuoRem(ClassReg, TempReg, TempReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, ClassReg); - /* begin JumpZero: */ - jumpExact = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin XorR:R: */ - genoperandoperand(XorRR, ClassReg, Arg1Reg); - if (!(setsConditionCodesFor(lastOpcode(), JumpZero))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, Arg1Reg); - } - /* begin JumpGreaterOrEqual: */ - jumpSameSign = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin XorR:R: */ - genoperandoperand(XorRR, ClassReg, Arg1Reg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg1Reg, ClassReg); - jmpTarget(jumpSameSign, jmpTarget(jumpExact, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - genSetSmallIntegerTagsIn(ClassReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpZero, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveMultiply */ -static sqInt -genPrimitiveMultiply(void) -{ - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpOvfl; - - if (!(processorHasMultiplyAndMClassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, Arg1Reg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genShiftAwaySmallIntegerTagsInScratchReg(ClassReg); - genRemoveSmallIntegerTagsInScratchReg(Arg1Reg); - /* begin MulOverflowR:R: */ - genMulRR(backEnd, Arg1Reg, ClassReg); - /* begin JumpOverflow: */ - jumpOvfl = genConditionalBranchoperand(JumpOverflow, ((sqInt)0)); - genSetSmallIntegerTagsIn(ClassReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpOvfl, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - -/* subclasses override if they can */ - - /* CogObjectRepresentation>>#genPrimitiveNewMethod */ -static sqInt -genPrimitiveNewMethod(void) -{ - return UnimplementedPrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveNotEqual */ -static sqInt -genPrimitiveNotEqual(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpNonZero, gJumpFPNotEqual, 0) - : genSmallIntegerComparison(JumpNonZero)); -} - - /* CogObjectRepresentation>>#genPrimitiveNotIdentical */ -static sqInt -genPrimitiveNotIdentical(void) -{ - return genPrimitiveIdenticalOrNotIf(1); -} - - /* CogObjectRepresentation>>#genPrimitiveQuo */ -static sqInt -genPrimitiveQuo(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *convert; - AbstractInstruction *jumpExact; - AbstractInstruction *jumpIsSI; - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpZero; - - if (!(processorHasDivQuoRemAndMClassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genShiftAwaySmallIntegerTagsInScratchReg(ClassReg); - if (!(setsConditionCodesFor(lastOpcode(), JumpZero))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, ClassReg); - } - /* begin JumpZero: */ - jumpZero = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - genShiftAwaySmallIntegerTagsInScratchReg(TempReg); - gDivRRQuoRem(ClassReg, TempReg, TempReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, ClassReg); - /* begin JumpZero: */ - jumpExact = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin Label */ - convert = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - genConvertIntegerInRegtoSmallIntegerInReg(TempReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpExact, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - jumpIsSI = genJumpIsSmallIntegerValuescratch(TempReg, Arg1Reg); - jmpTarget(jumpIsSI, convert); - jmpTarget(jumpZero, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveSubtract */ -static sqInt -genPrimitiveSubtract(void) -{ - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpOvfl; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, Arg0Reg, TempReg); - /* begin JumpOverflow: */ - jumpOvfl = genConditionalBranchoperand(JumpOverflow, ((sqInt)0)); - genAddSmallIntegerTagsTo(TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpOvfl, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genSmallIntegerComparison: */ -static sqInt NoDbgRegParms -genSmallIntegerComparison(sqInt jumpOpcode) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt constant; - AbstractInstruction *jumpFail; - AbstractInstruction *jumpTrue; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpFail = genJumpNotSmallInteger(Arg0Reg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, ReceiverResultReg); - jumpTrue = genConditionalBranchoperand(jumpOpcode, 0); - /* begin genMoveConstant:R: */ - constant = falseObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpTrue, (shouldAnnotateObjectReference(trueObject()) - ? annotateobjRef(checkLiteralforInstruction(trueObject(), genoperandoperand(MoveCwR, trueObject(), ReceiverResultReg)), trueObject()) - : (/* begin checkQuickConstant:forInstruction: */ - trueObject(), - (anInstruction1 = genoperandoperand(MoveCqR, trueObject(), ReceiverResultReg)), - anInstruction1))); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpFail, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - -/* Stack looks like - return address */ - - /* CogObjectRepresentation>>#genSmallIntegerComparison:orDoubleComparison:invert: */ -static sqInt NoDbgRegParms -genSmallIntegerComparisonorDoubleComparisoninvert(sqInt jumpOpcode, AbstractInstruction * NoDbgRegParms (*jumpFPOpcodeGenerator)(void *), sqInt invertComparison) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt constant; - AbstractInstruction *jumpCond; - AbstractInstruction * jumpFail; - AbstractInstruction * jumpNonInt; - sqInt r; - - jumpNonInt = ((AbstractInstruction *) 0); - r = genSmallIntegerComparison(jumpOpcode); - if (r < 0) { - return r; - } -# if defined(DPFPReg0) - - /* Fall through on non-SmallInteger argument. Argument may be a Float : let us check or fail */ - jumpNonInt = genJumpImmediate(Arg0Reg); - genGetCompactClassIndexNonImmOfinto(Arg0Reg, SendNumArgsReg); - genCmpClassFloatCompactIndexR(SendNumArgsReg); - /* begin JumpNonZero: */ - jumpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genConvertSmallIntegerToIntegerInReg(ReceiverResultReg); - /* begin ConvertR:Rd: */ - genoperandoperand(ConvertRRd, ReceiverResultReg, DPFPReg0); - genGetDoubleValueOfinto(Arg0Reg, DPFPReg1); - if (invertComparison) { - - /* May need to invert for NaNs */ - /* begin CmpRd:Rd: */ - genoperandoperand(CmpRdRd, DPFPReg0, DPFPReg1); - } - else { - /* begin CmpRd:Rd: */ - genoperandoperand(CmpRdRd, DPFPReg1, DPFPReg0); - } - - /* FP jumps are a little weird */ - jumpCond = jumpFPOpcodeGenerator(0); - /* begin genMoveConstant:R: */ - constant = falseObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpCond, (shouldAnnotateObjectReference(trueObject()) - ? annotateobjRef(checkLiteralforInstruction(trueObject(), genoperandoperand(MoveCwR, trueObject(), ReceiverResultReg)), trueObject()) - : (/* begin checkQuickConstant:forInstruction: */ - trueObject(), - (anInstruction1 = genoperandoperand(MoveCqR, trueObject(), ReceiverResultReg)), - anInstruction1))); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNonInt, jmpTarget(jumpFail, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); -# endif // defined(DPFPReg0) - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#isUnannotatableConstant: */ -static sqInt NoDbgRegParms -isUnannotatableConstant(CogSimStackEntry *simStackEntry) -{ - return (((simStackEntry->type)) == SSConstant) - && ((isImmediate((simStackEntry->constant))) - || (!(shouldAnnotateObjectReference((simStackEntry->constant))))); -} - - -/* Character gets mapped to zero. See inlineCacheTagForInstance:. */ - - /* CogObjectRepresentationFor32BitSpur>>#classForInlineCacheTag: */ -static sqInt NoDbgRegParms -classForInlineCacheTag(sqInt inlineCacheTag) -{ - return classOrNilAtIndex((inlineCacheTag == 0 - ? characterTag() - : inlineCacheTag)); -} - - /* CogObjectRepresentationFor32BitSpur>>#genAddSmallIntegerTagsTo: */ -static sqInt NoDbgRegParms -genAddSmallIntegerTagsTo(sqInt aRegister) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, 1, aRegister); - return 0; -} - - -/* Set the SmallInteger tag bits when the tag bits may be filled with - garbage. - */ - - /* CogObjectRepresentationFor32BitSpur>>#genClearAndSetSmallIntegerTagsIn: */ -static sqInt NoDbgRegParms -genClearAndSetSmallIntegerTagsIn(sqInt scratchReg) -{ - return genSetSmallIntegerTagsIn(scratchReg); -} - - -/* Convert the Character in reg to a SmallInteger, assuming - the Character's value is a valid character. */ -/* self assume: objectMemory smallIntegerTag = 1 */ - - /* CogObjectRepresentationFor32BitSpur>>#genConvertCharacterToSmallIntegerInReg: */ -static void NoDbgRegParms -genConvertCharacterToSmallIntegerInReg(sqInt reg) -{ - assert(((numCharacterBits()) + 1) == (numSmallIntegerBits())); - /* begin LogicalShiftRightCq:R: */ - genoperandoperand(LogicalShiftRightCqR, 1, reg); -} - - /* CogObjectRepresentationFor32BitSpur>>#genConvertIntegerInReg:toSmallIntegerInReg: */ -static sqInt NoDbgRegParms -genConvertIntegerInRegtoSmallIntegerInReg(sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - - gLogicalShiftLeftCqRR(1, srcReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, 1, destReg); - return 0; -} - - /* CogObjectRepresentationFor32BitSpur>>#genConvertIntegerToSmallIntegerInReg: */ -static sqInt NoDbgRegParms -genConvertIntegerToSmallIntegerInReg(sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, 1, reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, 1, reg); - return 0; -} - - -/* Convert the SmallInteger in reg to a Character, assuming - the SmallInteger's value is a valid character. */ -/* self assume: objectMemory smallIntegerTag = 1 */ - - /* CogObjectRepresentationFor32BitSpur>>#genConvertSmallIntegerToCharacterInReg: */ -static void NoDbgRegParms -genConvertSmallIntegerToCharacterInReg(sqInt reg) -{ - assert(((numCharacterBits()) + 1) == (numSmallIntegerBits())); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, 1, reg); -} - - /* CogObjectRepresentationFor32BitSpur>>#genConvertSmallIntegerToIntegerInReg: */ -static sqInt NoDbgRegParms -genConvertSmallIntegerToIntegerInReg(sqInt reg) -{ - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, 1, reg); - return 0; -} - - -/* Fetch the instance's identity hash into destReg, encoded as a - SmallInteger. - */ -/* Get header word in scratchReg */ - - /* CogObjectRepresentationFor32BitSpur>>#genGetHashFieldNonImmOf:asSmallIntegerInto: */ -static sqInt NoDbgRegParms -genGetHashFieldNonImmOfasSmallIntegerInto(sqInt instReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 4, instReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - identityHashHalfWordMask(); - anInstruction1 = genoperandoperand(AndCqR, identityHashHalfWordMask(), destReg); - genConvertIntegerToSmallIntegerInReg(destReg); - return 0; -} - - -/* Fetch the instance's identity hash into destReg, unencoded. */ - - /* CogObjectRepresentationFor32BitSpur>>#genGetHashFieldNonImmOf:into: */ -static sqInt NoDbgRegParms -genGetHashFieldNonImmOfinto(sqInt instReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 4, instReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - identityHashHalfWordMask(); - anInstruction1 = genoperandoperand(AndCqR, identityHashHalfWordMask(), destReg); - return 0; -} - - -/* Extract the inline cache tag for the object in sourceReg into destReg. The - inline cache tag for a given object is the value loaded in inline caches - to distinguish - objects of different classes. In Spur this is either the tags for - immediates, (with - 1 & 3 collapsed to 1 for SmallIntegers, and 2 collapsed to 0 for - Characters), or - the receiver's classIndex. - If forEntry is true answer the entry label at which control is to enter - (cmEntryOffset). If forEntry is false, control enters at the start. - If forEntry is true, generate something like this: - Limm: - andl $0x1, rDest - j Lcmp - Lentry: - movl rSource, rDest - andl $0x3, rDest - jnz Limm - movl 0(%edx), rDest - andl $0x3fffff, rDest - Lcmp: - If forEntry is false, generate something like the following. - At least on a 2.2GHz Intel Core i7 the following is slightly faster than - the above, - 136m sends/sec vs 130m sends/sec for nfib in tinyBenchmarks - Lentry: - movl rSource, rDest - andl $0x3, rDest - jz LnotImm - andl $1, rDest - j Lcmp - LnotImm: - movl 0(%edx), rDest - andl $0x3fffff, rDest - Lcmp: - But we expect most SmallInteger arithmetic to be performed in-line and so - prefer the - version that is faster for non-immediates (because it branches for - immediates only). */ - - /* CogObjectRepresentationFor32BitSpur>>#genGetInlineCacheClassTagFrom:into:forEntry: */ -static AbstractInstruction * NoDbgRegParms -genGetInlineCacheClassTagFromintoforEntry(sqInt sourceReg, sqInt destReg, sqInt forEntry) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *entryLabel; - AbstractInstruction *immLabel; - AbstractInstruction *jumpCompare; - AbstractInstruction *jumpNotImm; - - if (forEntry) { - /* begin AlignmentNops: */ - genoperand(AlignmentNops, BytesPerWord); - /* begin Label */ - immLabel = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, 1, destReg); - /* begin Jump: */ - jumpCompare = genoperand(Jump, ((sqInt)0)); - /* begin AlignmentNops: */ - genoperand(AlignmentNops, BytesPerWord); - /* begin Label */ - entryLabel = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - gAndCqRR(tagMask(), sourceReg, destReg); - /* begin JumpNonZero: */ - genConditionalBranchoperand(JumpNonZero, ((sqInt)immLabel)); - flag("endianness"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, 0, sourceReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - classIndexMask(); - anInstruction2 = genoperandoperand(AndCqR, classIndexMask(), destReg); - jmpTarget(jumpCompare, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - else { - /* begin Label */ - entryLabel = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - gAndCqRR(tagMask(), sourceReg, destReg); - /* begin JumpZero: */ - jumpNotImm = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(AndCqR, 1, destReg); - /* begin Jump: */ - jumpCompare = genoperand(Jump, ((sqInt)0)); - flag("endianness"); - jmpTarget(jumpNotImm, checkQuickConstantforInstruction(0, genoperandoperandoperand(MoveMwrR, 0, sourceReg, destReg))); - jmpTarget(jumpCompare, checkQuickConstantforInstruction(classIndexMask(), genoperandoperand(AndCqR, classIndexMask(), destReg))); - } - return entryLabel; -} - - /* CogObjectRepresentationFor32BitSpur>>#genGetOverflowSlotsOf:into: */ -static sqInt NoDbgRegParms -genGetOverflowSlotsOfinto(sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - -BaseHeaderSize; - anInstruction = genoperandoperandoperand(MoveMwrR, -BaseHeaderSize, srcReg, destReg); - return 0; -} - - -/* Generate a test for aRegister containing an integer value in the - SmallInteger range, and a jump if so, answering the jump. - c.f. Spur32BitMemoryManager>>isIntegerValue: */ - - /* CogObjectRepresentationFor32BitSpur>>#genJumpIsSmallIntegerValue:scratch: */ -static AbstractInstruction * NoDbgRegParms -genJumpIsSmallIntegerValuescratch(sqInt aRegister, sqInt scratchReg) -{ - return (gLogicalShiftLeftCqRR(1, aRegister, scratchReg), - /* begin XorR:R: */ - genoperandoperand(XorRR, aRegister, scratchReg), - /* begin JumpGreaterOrEqual: */ - genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0))); -} - - /* CogObjectRepresentationFor32BitSpur>>#genJumpNotSmallIntegerInScratchReg: */ -static AbstractInstruction * NoDbgRegParms -genJumpNotSmallIntegerInScratchReg(sqInt aRegister) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, 1, aRegister); - /* begin JumpZero: */ - return genConditionalBranchoperand(JumpZero, ((sqInt)0)); -} - - -/* Generate a test for aRegister containing an integer value outside the - SmallInteger range, and a jump if so, answering the jump. - c.f. Spur32BitMemoryManager>>isIntegerValue: */ - - /* CogObjectRepresentationFor32BitSpur>>#genJumpNotSmallIntegerValue:scratch: */ -static AbstractInstruction * NoDbgRegParms -genJumpNotSmallIntegerValuescratch(sqInt aRegister, sqInt scratchReg) -{ - return (gArithmeticShiftRightCqRR(1, aRegister, scratchReg), - /* begin XorR:R: */ - genoperandoperand(XorRR, aRegister, scratchReg), - /* begin JumpLess: */ - genConditionalBranchoperand(JumpLess, ((sqInt)0))); -} - - /* CogObjectRepresentationFor32BitSpur>>#genJumpNotSmallInteger: */ -static AbstractInstruction * NoDbgRegParms -genJumpNotSmallInteger(sqInt aRegister) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(TstCqR, 1, aRegister); - /* begin JumpZero: */ - return genConditionalBranchoperand(JumpZero, ((sqInt)0)); -} - - /* CogObjectRepresentationFor32BitSpur>>#genJumpSmallInteger: */ -static AbstractInstruction * NoDbgRegParms -genJumpSmallInteger(sqInt aRegister) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(TstCqR, 1, aRegister); - /* begin JumpNonZero: */ - return genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -} - - -/* c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: - fixedFieldsOf:format:length: - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveAtPut */ -static sqInt -genPrimitiveAtPut(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt formatReg; - AbstractInstruction *jumpArrayOutOfBounds; - AbstractInstruction *jumpBadIndex; - AbstractInstruction *jumpBytesOutOfBounds; - AbstractInstruction *jumpBytesOutOfRange; - AbstractInstruction * jumpFixedFieldsOutOfBounds; - AbstractInstruction *jumpHasFixedFields; - AbstractInstruction *jumpImmediate; - AbstractInstruction * jumpImmutable; - AbstractInstruction *jumpIsBytes; - AbstractInstruction * jumpIsCompiledMethod; - AbstractInstruction *jumpIsContext; - AbstractInstruction *jumpIsShorts; - AbstractInstruction * jumpNonSmallIntegerValue; - AbstractInstruction *jumpNotIndexableBits; - AbstractInstruction *jumpNotIndexablePointers; - AbstractInstruction * jumpNotPointers; - AbstractInstruction *jumpShortsOutOfBounds; - AbstractInstruction *jumpShortsOutOfRange; - AbstractInstruction *jumpWordsOutOfBounds; - AbstractInstruction *jumpWordsOutOfRange; - AbstractInstruction *methodInBounds; - sqInt nSlotsOrBytesReg; - - jumpImmutable = ((AbstractInstruction *) 0); - nSlotsOrBytesReg = ClassReg; - /* begin genLoadArgAtDepth:into: */ - assert(1 < (numRegArgs())); - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - jumpImmediate = genJumpImmediate(ReceiverResultReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpBadIndex = genJumpNotSmallInteger(Arg0Reg); - genConvertSmallIntegerToIntegerInReg(Arg0Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(SubCqR, 1, Arg0Reg); -# if IMMUTABILITY - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), TempReg); - /* begin genJumpBaseHeaderImmutable: */ - immutableBitMask(); - anInstruction17 = genoperandoperand(TstCqR, immutableBitMask(), TempReg); - /* begin JumpNonZero: */ - jumpImmutable = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -# else // IMMUTABILITY - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), NoReg); -# endif // IMMUTABILITY - genGetNumSlotsOfinto(ReceiverResultReg, nSlotsOrBytesReg); - /* begin checkQuickConstant:forInstruction: */ - weakArrayFormat(); - anInstruction2 = genoperandoperand(CmpCqR, weakArrayFormat(), formatReg); - /* begin JumpAbove: */ - jumpNotPointers = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - genStoreCheckReceiverRegvalueRegscratchReginFrame(ReceiverResultReg, Arg1Reg, TempReg, 0); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction3 = genoperandoperand(CmpCqR, arrayFormat(), formatReg); - /* begin JumpBelow: */ - jumpNotIndexablePointers = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin JumpNonZero: */ - jumpHasFixedFields = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpArrayOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddCq:R: */ - anInstruction4 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg0Reg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, Arg1Reg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpHasFixedFields, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genGetClassIndexOfNonImminto(ReceiverResultReg, formatReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, formatReg); - /* begin JumpZero: */ - jumpIsContext = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin PushR: */ - genoperand(PushR, nSlotsOrBytesReg); - genGetClassObjectOfClassIndexintoscratchReg(formatReg, nSlotsOrBytesReg, TempReg); - genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, nSlotsOrBytesReg, formatReg); - /* begin PopR: */ - genoperand(PopR, nSlotsOrBytesReg); - genConvertSmallIntegerToIntegerInReg(formatReg); - /* begin checkQuickConstant:forInstruction: */ - fixedFieldsOfClassFormatMask(); - anInstruction6 = genoperandoperand(AndCqR, fixedFieldsOfClassFormatMask(), formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, nSlotsOrBytesReg); - /* begin AddCq:R: */ - anInstruction7 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), formatReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpFixedFieldsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddR:R: */ - genoperandoperand(AddRR, formatReg, Arg0Reg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, Arg1Reg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotPointers, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNonSmallIntegerValue = genJumpNotSmallInteger(Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction8 = genoperandoperand(CmpCqR, firstByteFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsBytes = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstShortFormat(); - anInstruction9 = genoperandoperand(CmpCqR, firstShortFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsShorts = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction10 = genoperandoperand(CmpCqR, firstLongFormat(), formatReg); - /* begin JumpBelow: */ - jumpNotIndexableBits = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpWordsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - if (!(setsConditionCodesFor(lastOpcode(), JumpLess))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, TempReg); - } - /* begin JumpLess: */ - jumpWordsOutOfRange = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin AddCq:R: */ - anInstruction11 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg0Reg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, TempReg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsBytes, checkQuickConstantforInstruction((((usqInt)0xFF << 1) | 1), genoperandoperand(CmpCqR, (((usqInt)0xFF << 1) | 1), Arg1Reg))); - /* begin JumpAbove: */ - jumpBytesOutOfRange = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), nSlotsOrBytesReg); - gAndCqRR(BytesPerWord - 1, formatReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, nSlotsOrBytesReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpBytesOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction12 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsCompiledMethod = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - methodInBounds = genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperand(AddCqR, BaseHeaderSize, Arg0Reg); - /* begin MoveR:Xbr:R: */ - genoperandoperandoperand(MoveRXbrR, TempReg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsShorts, checkQuickConstantforInstruction((((usqInt)0xFFFF << 1) | 1), genoperandoperand(CmpCqR, (((usqInt)0xFFFF << 1) | 1), Arg1Reg))); - /* begin JumpAbove: */ - jumpShortsOutOfRange = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (shiftForWord()) - 1, nSlotsOrBytesReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(AndCqR, (BytesPerWord / 2) - 1, formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, nSlotsOrBytesReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpShortsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperandoperand(MoveRM16r, TempReg, BaseHeaderSize, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsCompiledMethod, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - getLiteralCountOfplusOneinBytesintoscratch(ReceiverResultReg, 1, 1, nSlotsOrBytesReg, TempReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelow: */ - genConditionalBranchoperand(JumpBelow, ((sqInt)methodInBounds)); - jmpTarget(jumpIsContext, jmpTarget(jumpNotIndexableBits, jmpTarget(jumpBytesOutOfRange, jmpTarget(jumpWordsOutOfRange, jmpTarget(jumpShortsOutOfRange, jmpTarget(jumpIsCompiledMethod, jmpTarget(jumpArrayOutOfBounds, jmpTarget(jumpBytesOutOfBounds, jmpTarget(jumpShortsOutOfBounds, jmpTarget(jumpWordsOutOfBounds, jmpTarget(jumpNotIndexablePointers, jmpTarget(jumpNonSmallIntegerValue, jmpTarget(jumpFixedFieldsOutOfBounds, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))))))))))))); -# if IMMUTABILITY - jmpTarget(jumpImmutable, ((AbstractInstruction *) (((jumpIsContext->operands))[0]))); -# endif - /* begin checkQuickConstant:forInstruction: */ - anInstruction16 = genoperandoperand(AddCqR, 1, Arg0Reg); - genConvertIntegerToSmallIntegerInReg(Arg0Reg); - jmpTarget(jumpBadIndex, jmpTarget(jumpImmediate, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return 0; -} - - -/* Generate the code for primitives 61 & 165, at:put:/basicAt:put: & - integerAt:put:. If signedVersion is true - then generate signed accesses to the bits classes (a la 164 & 165). If - signedVersion is false, - generate unsigned accesses (a la 60, 61, 63 & 64). */ -/* c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: - fixedFieldsOf:format:length: - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveAtPutSigned: */ -static sqInt NoDbgRegParms -genPrimitiveAtPutSigned(sqInt signedVersion) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt formatReg; - AbstractInstruction * jumpArrayOutOfBounds; - AbstractInstruction * jumpBadIndex; - AbstractInstruction * jumpBytesOutOfBounds; - AbstractInstruction * jumpBytesOutOfRange; - AbstractInstruction * jumpFixedFieldsOutOfBounds; - AbstractInstruction * jumpHasFixedFields; - AbstractInstruction * jumpImmediate; - AbstractInstruction * jumpImmutable; - AbstractInstruction * jumpIsBytes; - AbstractInstruction * jumpIsCompiledMethod; - AbstractInstruction * jumpIsContext; - AbstractInstruction * jumpIsShorts; - AbstractInstruction * jumpNonSmallIntegerValue; - AbstractInstruction * jumpNotIndexableBits; - AbstractInstruction * jumpNotIndexablePointers; - AbstractInstruction * jumpNotPointers; - AbstractInstruction * jumpShortsOutOfBounds; - AbstractInstruction * jumpShortsOutOfRange; - AbstractInstruction * jumpWordsOutOfBounds; - AbstractInstruction * jumpWordsOutOfRange; - AbstractInstruction * methodInBounds; - sqInt nSlotsOrBytesReg; - - jumpImmutable = ((AbstractInstruction *) 0); - jumpWordsOutOfRange = ((AbstractInstruction *) 0); - nSlotsOrBytesReg = ClassReg; - /* begin genLoadArgAtDepth:into: */ - assert(1 < (numRegArgs())); - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - jumpImmediate = genJumpImmediate(ReceiverResultReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpBadIndex = genJumpNotSmallInteger(Arg0Reg); - genConvertSmallIntegerToIntegerInReg(Arg0Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(SubCqR, 1, Arg0Reg); -# if IMMUTABILITY - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), TempReg); - /* begin genJumpBaseHeaderImmutable: */ - immutableBitMask(); - anInstruction21 = genoperandoperand(TstCqR, immutableBitMask(), TempReg); - /* begin JumpNonZero: */ - jumpImmutable = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -# else // IMMUTABILITY - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), NoReg); -# endif // IMMUTABILITY - genGetNumSlotsOfinto(ReceiverResultReg, nSlotsOrBytesReg); - /* begin checkQuickConstant:forInstruction: */ - weakArrayFormat(); - anInstruction6 = genoperandoperand(CmpCqR, weakArrayFormat(), formatReg); - /* begin JumpAbove: */ - jumpNotPointers = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - genStoreCheckReceiverRegvalueRegscratchReginFrame(ReceiverResultReg, Arg1Reg, TempReg, 0); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction7 = genoperandoperand(CmpCqR, arrayFormat(), formatReg); - /* begin JumpBelow: */ - jumpNotIndexablePointers = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin JumpNonZero: */ - jumpHasFixedFields = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpArrayOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddCq:R: */ - anInstruction8 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg0Reg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, Arg1Reg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpHasFixedFields, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genGetClassIndexOfNonImminto(ReceiverResultReg, formatReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, formatReg); - /* begin JumpZero: */ - jumpIsContext = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin PushR: */ - genoperand(PushR, nSlotsOrBytesReg); - genGetClassObjectOfClassIndexintoscratchReg(formatReg, nSlotsOrBytesReg, TempReg); - genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, nSlotsOrBytesReg, formatReg); - /* begin PopR: */ - genoperand(PopR, nSlotsOrBytesReg); - genConvertSmallIntegerToIntegerInReg(formatReg); - /* begin checkQuickConstant:forInstruction: */ - fixedFieldsOfClassFormatMask(); - anInstruction10 = genoperandoperand(AndCqR, fixedFieldsOfClassFormatMask(), formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, nSlotsOrBytesReg); - /* begin AddCq:R: */ - anInstruction11 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), formatReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpFixedFieldsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddR:R: */ - genoperandoperand(AddRR, formatReg, Arg0Reg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, Arg1Reg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotPointers, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNonSmallIntegerValue = genJumpNotSmallInteger(Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction12 = genoperandoperand(CmpCqR, firstByteFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsBytes = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstShortFormat(); - anInstruction13 = genoperandoperand(CmpCqR, firstShortFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsShorts = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction14 = genoperandoperand(CmpCqR, firstLongFormat(), formatReg); - /* begin JumpBelow: */ - jumpNotIndexableBits = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpWordsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - if (!signedVersion) { - if (!(setsConditionCodesFor(lastOpcode(), JumpLess))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, TempReg); - } - /* begin JumpLess: */ - jumpWordsOutOfRange = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - } - /* begin AddCq:R: */ - anInstruction15 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg0Reg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, TempReg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - if (signedVersion) { - jmpTarget(jumpIsBytes, gArithmeticShiftRightCqRR(8, Arg1Reg, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AddCqR, 1, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(CmpCqR, 1, TempReg); - } - else { - jmpTarget(jumpIsBytes, checkQuickConstantforInstruction((((usqInt)0xFF << 1) | 1), genoperandoperand(CmpCqR, (((usqInt)0xFF << 1) | 1), Arg1Reg))); - } - /* begin JumpAbove: */ - jumpBytesOutOfRange = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), nSlotsOrBytesReg); - gAndCqRR(BytesPerWord - 1, formatReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, nSlotsOrBytesReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpBytesOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction16 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsCompiledMethod = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - methodInBounds = genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperand(AddCqR, BaseHeaderSize, Arg0Reg); - /* begin MoveR:Xbr:R: */ - genoperandoperandoperand(MoveRXbrR, TempReg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - if (signedVersion) { - jmpTarget(jumpIsShorts, gArithmeticShiftRightCqRR(16, Arg1Reg, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(AddCqR, 1, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, 1, TempReg); - } - else { - jmpTarget(jumpIsShorts, checkQuickConstantforInstruction((((usqInt)0xFFFF << 1) | 1), genoperandoperand(CmpCqR, (((usqInt)0xFFFF << 1) | 1), Arg1Reg))); - } - /* begin JumpAbove: */ - jumpShortsOutOfRange = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (shiftForWord()) - 1, nSlotsOrBytesReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction18 = genoperandoperand(AndCqR, (BytesPerWord / 2) - 1, formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, nSlotsOrBytesReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpShortsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperandoperand(MoveRM16r, TempReg, BaseHeaderSize, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsCompiledMethod, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - getLiteralCountOfplusOneinBytesintoscratch(ReceiverResultReg, 1, 1, nSlotsOrBytesReg, TempReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelow: */ - genConditionalBranchoperand(JumpBelow, ((sqInt)methodInBounds)); - jmpTarget(jumpIsContext, jmpTarget(jumpNotIndexableBits, jmpTarget(jumpBytesOutOfRange, jmpTarget(jumpShortsOutOfRange, jmpTarget(jumpIsCompiledMethod, jmpTarget(jumpArrayOutOfBounds, jmpTarget(jumpBytesOutOfBounds, jmpTarget(jumpShortsOutOfBounds, jmpTarget(jumpWordsOutOfBounds, jmpTarget(jumpNotIndexablePointers, jmpTarget(jumpNonSmallIntegerValue, jmpTarget(jumpFixedFieldsOutOfBounds, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))))))))))); - if (!signedVersion) { - jmpTarget(jumpWordsOutOfRange, ((AbstractInstruction *) (((jumpIsContext->operands))[0]))); - } -# if IMMUTABILITY - jmpTarget(jumpImmutable, ((AbstractInstruction *) (((jumpIsContext->operands))[0]))); -# endif - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperand(AddCqR, 1, Arg0Reg); - genConvertIntegerToSmallIntegerInReg(Arg0Reg); - jmpTarget(jumpBadIndex, jmpTarget(jumpImmediate, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return 0; -} - - -/* Generate the code for primitives 60 & 164, at:/basicAt: & integerAt:. If - signedVersion is true - then generate signed accesses to the bits classes (a la 164 & 165). If - signedVersion is false, - generate unsigned accesses (a la 60, 61, 63 & 64). */ -/* c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: - fixedFieldsOf:format:length: - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveAtSigned: */ -static sqInt NoDbgRegParms -genPrimitiveAtSigned(sqInt signedVersion) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - AbstractInstruction * convertToIntAndReturn; - AbstractInstruction * first; - AbstractInstruction * first1; - sqInt formatReg; - AbstractInstruction * jumpArrayOutOfBounds; - AbstractInstruction * jumpBadIndex; - AbstractInstruction * jumpBytesOutOfBounds; - AbstractInstruction * jumpFixedFieldsOutOfBounds; - AbstractInstruction * jumpHasFixedFields; - AbstractInstruction * jumpImmediate; - AbstractInstruction * jumpIsArray; - AbstractInstruction * jumpIsBytes; - AbstractInstruction * jumpIsContext; - AbstractInstruction * jumpIsMethod; - AbstractInstruction * jumpIsShorts; - AbstractInstruction * jumpIsWords; - AbstractInstruction * jumpNotIndexable; - AbstractInstruction * jumpShortsOutOfBounds; - AbstractInstruction * jumpWordsOutOfBounds; - AbstractInstruction * jumpWordTooBig; - AbstractInstruction * methodInBounds; - sqInt nSlotsOrBytesReg; - - nSlotsOrBytesReg = ClassReg; - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - jumpImmediate = genJumpImmediate(ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, Arg1Reg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpBadIndex = genJumpNotSmallInteger(Arg0Reg); - genConvertSmallIntegerToIntegerInReg(Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, 1, Arg1Reg); - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), TempReg); - genGetNumSlotsOfinto(ReceiverResultReg, nSlotsOrBytesReg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction1 = genoperandoperand(CmpCqR, firstByteFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsBytes = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction2 = genoperandoperand(CmpCqR, arrayFormat(), formatReg); - /* begin JumpZero: */ - jumpIsArray = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin JumpBelow: */ - jumpNotIndexable = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - weakArrayFormat(); - anInstruction3 = genoperandoperand(CmpCqR, weakArrayFormat(), formatReg); - /* begin JumpBelowOrEqual: */ - jumpHasFixedFields = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstShortFormat(); - anInstruction4 = genoperandoperand(CmpCqR, firstShortFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsShorts = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction5 = genoperandoperand(CmpCqR, firstLongFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsWords = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - jmpTarget(jumpNotIndexable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin Jump: */ - jumpNotIndexable = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpIsArray, (assert(!((Arg1Reg == SPReg))), - genoperandoperand(CmpRR, Arg1Reg, nSlotsOrBytesReg))); - /* begin JumpBelowOrEqual: */ - jumpArrayOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddCq:R: */ - anInstruction6 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg1Reg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, Arg1Reg, ReceiverResultReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsBytes, genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), nSlotsOrBytesReg)); - gAndCqRR(BytesPerWord - 1, formatReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, nSlotsOrBytesReg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpBytesOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction7 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsMethod = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(AddCqR, BaseHeaderSize, Arg1Reg); - methodInBounds = anInstruction8; - if (signedVersion) { - /* begin MoveXbr:R:R: */ - genoperandoperandoperand(MoveXbrRR, Arg1Reg, ReceiverResultReg, ReceiverResultReg); - } - else { - - /* formatReg already contains a value <= 16r1f, so no need to zero it */ - /* begin MoveXbr:R:R: */ - genoperandoperandoperand(MoveXbrRR, Arg1Reg, ReceiverResultReg, formatReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, formatReg, ReceiverResultReg); - } - if (signedVersion) { - /* begin SignExtend8R:R: */ - /* begin LogicalShiftLeftCq:R: */ - first = genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 8, ReceiverResultReg); - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, (BytesPerWord * 8) - 8, ReceiverResultReg); - goto l8; - l8: /* end SignExtend8R:R: */; - } - /* begin Label */ - convertToIntAndReturn = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - genConvertIntegerToSmallIntegerInReg(ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsShorts, gLogicalShiftLeftCqR((shiftForWord()) - 1, nSlotsOrBytesReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(AndCqR, 1, formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, nSlotsOrBytesReg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpShortsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg1Reg, ReceiverResultReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg1Reg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveM16rR, BaseHeaderSize, ReceiverResultReg, ReceiverResultReg); - if (signedVersion) { - /* begin SignExtend16R:R: */ - /* begin LogicalShiftLeftCq:R: */ - first1 = genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 16, ReceiverResultReg); - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, (BytesPerWord * 8) - 16, ReceiverResultReg); - goto l13; - l13: /* end SignExtend16R:R: */; - } - /* begin Jump: */ - genoperand(Jump, ((sqInt)convertToIntAndReturn)); - jmpTarget(jumpIsWords, (assert(!((Arg1Reg == SPReg))), - genoperandoperand(CmpRR, Arg1Reg, nSlotsOrBytesReg))); - /* begin JumpBelowOrEqual: */ - jumpWordsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddCq:R: */ - anInstruction11 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg1Reg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, Arg1Reg, ReceiverResultReg, TempReg); - jumpWordTooBig = jumpNotSmallIntegerUnsignedValueInRegister(TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)convertToIntAndReturn)); - jmpTarget(jumpHasFixedFields, checkQuickConstantforInstruction(classIndexMask(), genoperandoperand(AndCqR, classIndexMask(), TempReg))); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, formatReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, TempReg); - /* begin JumpZero: */ - jumpIsContext = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin PushR: */ - genoperand(PushR, nSlotsOrBytesReg); - genGetClassObjectOfClassIndexintoscratchReg(formatReg, nSlotsOrBytesReg, TempReg); - genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, nSlotsOrBytesReg, formatReg); - /* begin PopR: */ - genoperand(PopR, nSlotsOrBytesReg); - genConvertSmallIntegerToIntegerInReg(formatReg); - /* begin checkQuickConstant:forInstruction: */ - fixedFieldsOfClassFormatMask(); - anInstruction13 = genoperandoperand(AndCqR, fixedFieldsOfClassFormatMask(), formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, nSlotsOrBytesReg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpFixedFieldsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddR:R: */ - genoperandoperand(AddRR, formatReg, Arg1Reg); - /* begin AddCq:R: */ - anInstruction14 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg1Reg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, Arg1Reg, ReceiverResultReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsMethod, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - getLiteralCountOfplusOneinBytesintoscratch(ReceiverResultReg, 1, 1, nSlotsOrBytesReg, TempReg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, nSlotsOrBytesReg); - /* begin JumpBelow: */ - genConditionalBranchoperand(JumpBelow, ((sqInt)methodInBounds)); - jmpTarget(jumpWordTooBig, jmpTarget(jumpFixedFieldsOutOfBounds, jmpTarget(jumpArrayOutOfBounds, jmpTarget(jumpBytesOutOfBounds, jmpTarget(jumpShortsOutOfBounds, jmpTarget(jumpWordsOutOfBounds, jmpTarget(jumpNotIndexable, jmpTarget(jumpIsContext, jmpTarget(jumpBadIndex, jmpTarget(jumpImmediate, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))))))))); - return 0; -} - - -/* Arguably we should fail for immediates, but so far no one has complained, - so... - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveIdentityHash */ -static sqInt -genPrimitiveIdentityHash(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction * inst; - AbstractInstruction *jumpImm; - AbstractInstruction *jumpNotSet; - AbstractInstruction *jumpSI; - AbstractInstruction * ret; - - jumpImm = genJumpImmediate(ReceiverResultReg); - genGetHashFieldNonImmOfasSmallIntegerInto(ReceiverResultReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, ConstZero, TempReg); - /* begin JumpZero: */ - jumpNotSet = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - ret = genoperand(RetN, 0); - } - else { - /* begin RetN: */ - ret = genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpImm, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - jumpSI = genJumpSmallInteger(ReceiverResultReg); - jmpTarget(jumpSI, ret); - genConvertCharacterToSmallIntegerInReg(ReceiverResultReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)ret)); - jmpTarget(jumpNotSet, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (!(primitiveIndex == 75)) { - return 0; - } - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceNewHashTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin PopR: */ - genoperand(PopR, LinkReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - return UnfailingPrimitive; -} - - -/* :Assume the receiuver is never a SmallInteger. One would use ^self for - that. - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveImmediateAsInteger */ -static sqInt -genPrimitiveImmediateAsInteger(void) -{ - genConvertCharacterToSmallIntegerInReg(ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - return UnfailingPrimitive; -} - - -/* Implement 1-arg (instantiateFixedClass:) primitiveNew for convenient - cases: - the class argument has a hash - - the class argument is fixed size (excluding ephemerons to save - instructions & miniscule time) - - single word header/num slots < numSlotsMask - - the result fits in eden (actually below scavengeThreshold) - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveMirrorNew */ -static sqInt -genPrimitiveMirrorNew(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt byteSizeReg; - AbstractInstruction *fillLoop; - sqInt fillReg; - sqInt halfHeaderReg; - sqInt instSpecReg; - AbstractInstruction *jumpBadFormat; - AbstractInstruction *jumpHasSlots; - AbstractInstruction *jumpImmediate; - AbstractInstruction *jumpNoSpace; - AbstractInstruction *jumpNotFixedPointers; - AbstractInstruction *jumpTooBig; - AbstractInstruction *jumpTooSmall; - AbstractInstruction *jumpUnhashed; - AbstractInstruction *jumpVariableOrEphemeron; - sqInt quickConstant; - sqInt quickConstant1; - AbstractInstruction *skip; - - assert((methodNumArgs()) == 1); - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - - /* inst spec will hold class's instance specification, then byte size and finally end of new object. */ - halfHeaderReg = (fillReg = SendNumArgsReg); - - /* get freeStart as early as possible so as not to wait later... */ - instSpecReg = (byteSizeReg = ClassReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction = genoperandoperand(MoveAwR, freeStartAddress(), Arg1Reg); - - /* Is the class arg pointers with at least 3 fields? */ - jumpImmediate = genJumpImmediate(Arg0Reg); - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(Arg0Reg, TempReg, NoReg); - /* begin checkQuickConstant:forInstruction: */ - nonIndexablePointerFormat(); - anInstruction1 = genoperandoperand(CmpCqR, nonIndexablePointerFormat(), TempReg); - /* begin JumpNonZero: */ - jumpNotFixedPointers = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genGetRawSlotSizeOfNonImminto(Arg0Reg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(CmpCqR, InstanceSpecificationIndex + 1, TempReg); - /* begin JumpLess: */ - jumpTooSmall = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - genGetHashFieldNonImmOfinto(Arg0Reg, halfHeaderReg); - /* begin JumpZero: */ - jumpUnhashed = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, Arg0Reg, instSpecReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpBadFormat = genJumpNotSmallInteger(instSpecReg); - genConvertSmallIntegerToIntegerInReg(instSpecReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instSpecReg, TempReg); - /* begin LogicalShiftRightCq:R: */ - quickConstant = fixedFieldsFieldWidth(); - genoperandoperand(LogicalShiftRightCqR, quickConstant, TempReg); - /* begin checkQuickConstant:forInstruction: */ - formatMask(); - anInstruction3 = genoperandoperand(AndCqR, formatMask(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - fixedFieldsOfClassFormatMask(); - anInstruction4 = genoperandoperand(AndCqR, fixedFieldsOfClassFormatMask(), instSpecReg); - /* begin checkQuickConstant:forInstruction: */ - nonIndexablePointerFormat(); - anInstruction5 = genoperandoperand(CmpCqR, nonIndexablePointerFormat(), TempReg); - /* begin JumpAbove: */ - jumpVariableOrEphemeron = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - numSlotsMask(); - anInstruction6 = genoperandoperand(CmpCqR, numSlotsMask(), instSpecReg); - /* begin JumpAboveOrEqual: */ - jumpTooBig = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - quickConstant1 = formatShift(); - genoperandoperand(LogicalShiftLeftCqR, quickConstant1, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, halfHeaderReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveRMwr, halfHeaderReg, 0, Arg1Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instSpecReg, halfHeaderReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(CmpCqR, 0, byteSizeReg); - /* begin JumpNonZero: */ - jumpHasSlots = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(MoveCqR, BaseHeaderSize * 2, byteSizeReg); - /* begin Jump: */ - skip = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpHasSlots, genoperandoperand(MoveRR, byteSizeReg, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperand(AndCqR, 1, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, byteSizeReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperand(AddCqR, BaseHeaderSize / BytesPerWord, byteSizeReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), byteSizeReg); - jmpTarget(skip, genoperandoperand(LogicalShiftLeftCqR, numSlotsHalfShift(), halfHeaderReg)); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg1Reg, byteSizeReg); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction12 = genoperandoperand(CmpCqR, getScavengeThreshold(), byteSizeReg); - /* begin JumpAboveOrEqual: */ - jumpNoSpace = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction13 = genoperandoperand(MoveRAw, byteSizeReg, freeStartAddress()); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperandoperand(MoveRMwr, halfHeaderReg, 4, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperandoperand(LoadEffectiveAddressMwrR, BaseHeaderSize, ReceiverResultReg, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - nilObject(); - anInstruction16 = genoperandoperand(MoveCqR, nilObject(), fillReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperandoperand(MoveRMwr, fillReg, 0, Arg1Reg); - fillLoop = anInstruction17; - /* begin checkQuickConstant:forInstruction: */ - anInstruction18 = genoperandoperandoperand(MoveRMwr, fillReg, 4, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperand(AddCqR, 8, Arg1Reg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, byteSizeReg); - /* begin JumpAbove: */ - genConditionalBranchoperand(JumpAbove, ((sqInt)fillLoop)); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotFixedPointers, jmpTarget(jumpBadFormat, jmpTarget(jumpTooSmall, jmpTarget(jumpImmediate, jmpTarget(jumpUnhashed, jmpTarget(jumpVariableOrEphemeron, jmpTarget(jumpTooBig, jmpTarget(jumpNoSpace, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))))))); - return 0; -} - - -/* Implement instantiateVariableClass:withSize: for convenient cases: - - the class argument has a hash - - the class argument is variable and not compiled method - - single word header/num slots < numSlotsMask - - the result fits in eden - See superclass method for dynamic frequencies of formats. - For the moment we implement only arrayFormat, firstByteFormat & - firstLongFormat - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveMirrorNewWithArg */ -static sqInt -genPrimitiveMirrorNewWithArg(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction22; - AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction24; - AbstractInstruction *anInstruction25; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt byteSizeReg; - AbstractInstruction *fillLoop; - sqInt fillReg; - sqInt halfHeaderReg; - sqInt instSpecReg; - AbstractInstruction *jumpArrayFormat; - AbstractInstruction *jumpArrayTooBig; - AbstractInstruction *jumpByteFormat; - AbstractInstruction *jumpBytePrepDone; - AbstractInstruction *jumpByteTooBig; - AbstractInstruction *jumpFailCuzFixed; - AbstractInstruction *jumpHasSlots; - AbstractInstruction *jumpImmediate; - AbstractInstruction *jumpLongPrepDone; - AbstractInstruction *jumpLongTooBig; - AbstractInstruction *jumpNElementsNonInt; - AbstractInstruction *jumpNoSpace; - AbstractInstruction *jumpNotFixedPointers; - AbstractInstruction *jumpTooSmall; - AbstractInstruction *jumpUnhashed; - sqInt maxSlots; - sqInt quickConstant; - sqInt quickConstant1; - sqInt quickConstant2; - AbstractInstruction *skip; - - assert((methodNumArgs()) == 2); - /* begin genLoadArgAtDepth:into: */ - assert(1 < (numRegArgs())); - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - - /* inst spec will hold class's instance specification and then byte size and finally numSlots half of header */ - halfHeaderReg = (fillReg = SendNumArgsReg); - - /* The max slots we'll allocate here are those for a single header */ - instSpecReg = (byteSizeReg = ClassReg); - - /* check size and fail if not a +ve integer */ - maxSlots = (numSlotsMask()) - 1; - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNElementsNonInt = genJumpNotSmallInteger(Arg1Reg); - jumpImmediate = genJumpImmediate(Arg0Reg); - genGetRawSlotSizeOfNonImminto(Arg0Reg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, InstanceSpecificationIndex + 1, TempReg); - /* begin JumpLess: */ - jumpTooSmall = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(Arg0Reg, TempReg, NoReg); - /* begin checkQuickConstant:forInstruction: */ - nonIndexablePointerFormat(); - anInstruction1 = genoperandoperand(CmpCqR, nonIndexablePointerFormat(), TempReg); - /* begin JumpNonZero: */ - jumpNotFixedPointers = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genGetHashFieldNonImmOfinto(Arg0Reg, halfHeaderReg); - /* begin JumpZero: */ - jumpUnhashed = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin PushR: */ - genoperand(PushR, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, Arg0Reg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction2 = genoperandoperand(MoveAwR, freeStartAddress(), Arg1Reg); - genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, ReceiverResultReg, instSpecReg); - /* begin LogicalShiftRightCq:R: */ - quickConstant = (fixedFieldsFieldWidth()) + 1 /* numSmallIntegerTagBits */; - genoperandoperand(LogicalShiftRightCqR, quickConstant, instSpecReg); - /* begin checkQuickConstant:forInstruction: */ - formatMask(); - anInstruction3 = genoperandoperand(AndCqR, formatMask(), instSpecReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instSpecReg, TempReg); - /* begin LogicalShiftLeftCq:R: */ - quickConstant1 = formatShift(); - genoperandoperand(LogicalShiftLeftCqR, quickConstant1, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, halfHeaderReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction4 = genoperandoperand(CmpCqR, arrayFormat(), instSpecReg); - /* begin JumpZero: */ - jumpArrayFormat = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction5 = genoperandoperand(CmpCqR, firstByteFormat(), instSpecReg); - /* begin JumpZero: */ - jumpByteFormat = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction6 = genoperandoperand(CmpCqR, firstLongFormat(), instSpecReg); - /* begin JumpNonZero: */ - jumpFailCuzFixed = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)maxSlots << 1) | 1); - anInstruction7 = genoperandoperand(CmpCqR, (((usqInt)maxSlots << 1) | 1), Arg0Reg); - /* begin JumpAbove: */ - jumpLongTooBig = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, instSpecReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperand(PushCq, 0); - /* begin Jump: */ - jumpLongPrepDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpByteFormat, checkQuickConstantforInstruction((((usqInt)(maxSlots * BytesPerWord) << 1) | 1), genoperandoperand(CmpCqR, (((usqInt)(maxSlots * BytesPerWord) << 1) | 1), Arg0Reg))); - /* begin JumpAbove: */ - jumpByteTooBig = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, instSpecReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(MoveCqR, BytesPerWord, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, instSpecReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperand(AndCqR, BytesPerWord - 1, TempReg); - /* begin LogicalShiftLeftCq:R: */ - quickConstant2 = formatShift(); - genoperandoperand(LogicalShiftLeftCqR, quickConstant2, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, halfHeaderReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperand(AddCqR, BytesPerWord - 1, instSpecReg); - /* begin LogicalShiftRightCq:R: */ - genoperandoperand(LogicalShiftRightCqR, shiftForWord(), instSpecReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperand(PushCq, 0); - /* begin Jump: */ - jumpBytePrepDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpArrayFormat, checkQuickConstantforInstruction((((usqInt)maxSlots << 1) | 1), genoperandoperand(CmpCqR, (((usqInt)maxSlots << 1) | 1), Arg0Reg))); - /* begin JumpAbove: */ - jumpArrayTooBig = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, instSpecReg); - /* begin checkLiteral:forInstruction: */ - nilObject(); - anInstruction13 = genoperand(PushCw, nilObject()); - jmpTarget(jumpBytePrepDone, jmpTarget(jumpLongPrepDone, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperandoperand(MoveRMwr, halfHeaderReg, 0, Arg1Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instSpecReg, halfHeaderReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperand(CmpCqR, 0, byteSizeReg); - /* begin JumpNonZero: */ - jumpHasSlots = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction16 = genoperandoperand(MoveCqR, BaseHeaderSize * 2, byteSizeReg); - /* begin Jump: */ - skip = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpHasSlots, genoperandoperand(MoveRR, byteSizeReg, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperand(AndCqR, 1, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, byteSizeReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction18 = genoperandoperand(AddCqR, BaseHeaderSize / BytesPerWord, byteSizeReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), byteSizeReg); - jmpTarget(skip, genoperandoperand(LogicalShiftLeftCqR, numSlotsHalfShift(), halfHeaderReg)); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg1Reg, byteSizeReg); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction19 = genoperandoperand(CmpCqR, getScavengeThreshold(), byteSizeReg); - /* begin JumpAboveOrEqual: */ - jumpNoSpace = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction20 = genoperandoperand(MoveRAw, byteSizeReg, freeStartAddress()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperandoperand(MoveRMwr, halfHeaderReg, 4, ReceiverResultReg); - /* begin PopR: */ - genoperand(PopR, fillReg); - /* begin PopR: */ - genoperand(PopR, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperandoperand(LoadEffectiveAddressMwrR, BaseHeaderSize, ReceiverResultReg, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction23 = genoperandoperandoperand(MoveRMwr, fillReg, 0, Arg1Reg); - fillLoop = anInstruction23; - /* begin checkQuickConstant:forInstruction: */ - anInstruction24 = genoperandoperandoperand(MoveRMwr, fillReg, 4, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction25 = genoperandoperand(AddCqR, 8, Arg1Reg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, byteSizeReg); - /* begin JumpAbove: */ - genConditionalBranchoperand(JumpAbove, ((sqInt)fillLoop)); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNoSpace, genoperand(PopR, TempReg)); - jmpTarget(jumpFailCuzFixed, jmpTarget(jumpArrayTooBig, jmpTarget(jumpByteTooBig, jmpTarget(jumpLongTooBig, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, Arg1Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, Arg0Reg); - /* begin PopR: */ - genoperand(PopR, ReceiverResultReg); - jmpTarget(jumpUnhashed, jmpTarget(jumpImmediate, jmpTarget(jumpNotFixedPointers, jmpTarget(jumpTooSmall, jmpTarget(jumpNElementsNonInt, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))))); - return 0; -} - - -/* Implement primitiveNew for convenient cases: - - the receiver has a hash - - the receiver is fixed size (excluding ephemerons to save instructions & - miniscule time) - - single word header/num slots < numSlotsMask - - the result fits in eden (actually below scavengeThreshold) - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveNew */ -static sqInt -genPrimitiveNew(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt byteSizeReg; - AbstractInstruction *fillLoop; - sqInt fillReg; - sqInt halfHeaderReg; - sqInt instSpecReg; - AbstractInstruction *jumpHasSlots; - AbstractInstruction *jumpNoSpace; - AbstractInstruction *jumpTooBig; - AbstractInstruction *jumpUnhashed; - AbstractInstruction *jumpVariableOrEphemeron; - sqInt quickConstant; - sqInt quickConstant1; - AbstractInstruction *skip; - - if (methodOrBlockNumArgs == 1) { - return genPrimitiveMirrorNew(); - } - if (methodOrBlockNumArgs != 0) { - return UnimplementedPrimitive; - } - - /* inst spec will hold class's instance specification, then byte size and finally end of new object. */ - halfHeaderReg = (fillReg = SendNumArgsReg); - - /* get freeStart as early as possible so as not to wait later... */ - instSpecReg = (byteSizeReg = ClassReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction = genoperandoperand(MoveAwR, freeStartAddress(), Arg1Reg); - genGetHashFieldNonImmOfinto(ReceiverResultReg, halfHeaderReg); - /* begin JumpZero: */ - jumpUnhashed = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, ReceiverResultReg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, instSpecReg); - /* begin LogicalShiftRightCq:R: */ - quickConstant = fixedFieldsFieldWidth(); - genoperandoperand(LogicalShiftRightCqR, quickConstant, TempReg); - /* begin checkQuickConstant:forInstruction: */ - formatMask(); - anInstruction1 = genoperandoperand(AndCqR, formatMask(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - fixedFieldsOfClassFormatMask(); - anInstruction2 = genoperandoperand(AndCqR, fixedFieldsOfClassFormatMask(), instSpecReg); - /* begin checkQuickConstant:forInstruction: */ - nonIndexablePointerFormat(); - anInstruction3 = genoperandoperand(CmpCqR, nonIndexablePointerFormat(), TempReg); - /* begin JumpAbove: */ - jumpVariableOrEphemeron = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - numSlotsMask(); - anInstruction4 = genoperandoperand(CmpCqR, numSlotsMask(), instSpecReg); - /* begin JumpAboveOrEqual: */ - jumpTooBig = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - quickConstant1 = formatShift(); - genoperandoperand(LogicalShiftLeftCqR, quickConstant1, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, halfHeaderReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(MoveRMwr, halfHeaderReg, 0, Arg1Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instSpecReg, halfHeaderReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(CmpCqR, 0, byteSizeReg); - /* begin JumpNonZero: */ - jumpHasSlots = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(MoveCqR, BaseHeaderSize * 2, byteSizeReg); - /* begin Jump: */ - skip = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpHasSlots, genoperandoperand(MoveRR, byteSizeReg, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(AndCqR, 1, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, byteSizeReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(AddCqR, BaseHeaderSize / BytesPerWord, byteSizeReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), byteSizeReg); - jmpTarget(skip, genoperandoperand(LogicalShiftLeftCqR, numSlotsHalfShift(), halfHeaderReg)); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg1Reg, byteSizeReg); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction10 = genoperandoperand(CmpCqR, getScavengeThreshold(), byteSizeReg); - /* begin JumpAboveOrEqual: */ - jumpNoSpace = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction11 = genoperandoperand(MoveRAw, byteSizeReg, freeStartAddress()); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveRMwr, halfHeaderReg, 4, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperandoperand(LoadEffectiveAddressMwrR, BaseHeaderSize, ReceiverResultReg, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - nilObject(); - anInstruction14 = genoperandoperand(MoveCqR, nilObject(), fillReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperandoperand(MoveRMwr, fillReg, 0, Arg1Reg); - fillLoop = anInstruction15; - /* begin checkQuickConstant:forInstruction: */ - anInstruction16 = genoperandoperandoperand(MoveRMwr, fillReg, 4, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperand(AddCqR, 8, Arg1Reg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, byteSizeReg); - /* begin JumpAbove: */ - genConditionalBranchoperand(JumpAbove, ((sqInt)fillLoop)); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpUnhashed, jmpTarget(jumpVariableOrEphemeron, jmpTarget(jumpTooBig, jmpTarget(jumpNoSpace, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))); - return 0; -} - - -/* Implement primitiveNewWithArg for convenient cases: - - the receiver has a hash - - the receiver is variable and not compiled method - - single word header/num slots < numSlotsMask - - the result fits in eden - See superclass method for dynamic frequencies of formats. - For the moment we implement only arrayFormat, firstByteFormat & - firstLongFormat - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveNewWithArg */ -static sqInt -genPrimitiveNewWithArg(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction22; - AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt byteSizeReg; - AbstractInstruction *fillLoop; - sqInt fillReg; - sqInt halfHeaderReg; - sqInt instSpecReg; - AbstractInstruction *jumpArrayFormat; - AbstractInstruction *jumpArrayTooBig; - AbstractInstruction *jumpByteFormat; - AbstractInstruction *jumpBytePrepDone; - AbstractInstruction *jumpByteTooBig; - AbstractInstruction *jumpFailCuzFixed; - AbstractInstruction *jumpHasSlots; - AbstractInstruction *jumpLongPrepDone; - AbstractInstruction *jumpLongTooBig; - AbstractInstruction *jumpNElementsNonInt; - AbstractInstruction *jumpNoSpace; - AbstractInstruction *jumpUnhashed; - sqInt maxSlots; - sqInt quickConstant; - sqInt quickConstant1; - sqInt quickConstant2; - AbstractInstruction *skip; - - if (methodOrBlockNumArgs == 2) { - return genPrimitiveMirrorNewWithArg(); - } - if (methodOrBlockNumArgs != 1) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - - /* inst spec will hold class's instance specification and then byte size and finally numSlots half of header */ - halfHeaderReg = (fillReg = SendNumArgsReg); - - /* The max slots we'll allocate here are those for a single header */ - instSpecReg = (byteSizeReg = ClassReg); - - /* get freeStart as early as possible so as not to wait later... */ - maxSlots = (numSlotsMask()) - 1; - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction = genoperandoperand(MoveAwR, freeStartAddress(), Arg1Reg); - genGetHashFieldNonImmOfinto(ReceiverResultReg, halfHeaderReg); - /* begin JumpZero: */ - jumpUnhashed = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - - /* get class's format inst var for inst spec (format field) */ - jumpNElementsNonInt = genJumpNotSmallInteger(Arg0Reg); - genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, ReceiverResultReg, instSpecReg); - /* begin LogicalShiftRightCq:R: */ - quickConstant = (fixedFieldsFieldWidth()) + 1 /* numSmallIntegerTagBits */; - genoperandoperand(LogicalShiftRightCqR, quickConstant, instSpecReg); - /* begin checkQuickConstant:forInstruction: */ - formatMask(); - anInstruction1 = genoperandoperand(AndCqR, formatMask(), instSpecReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instSpecReg, TempReg); - /* begin LogicalShiftLeftCq:R: */ - quickConstant1 = formatShift(); - genoperandoperand(LogicalShiftLeftCqR, quickConstant1, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, halfHeaderReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction2 = genoperandoperand(CmpCqR, arrayFormat(), instSpecReg); - /* begin JumpZero: */ - jumpArrayFormat = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction3 = genoperandoperand(CmpCqR, firstByteFormat(), instSpecReg); - /* begin JumpZero: */ - jumpByteFormat = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction4 = genoperandoperand(CmpCqR, firstLongFormat(), instSpecReg); - /* begin JumpNonZero: */ - jumpFailCuzFixed = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)maxSlots << 1) | 1); - anInstruction5 = genoperandoperand(CmpCqR, (((usqInt)maxSlots << 1) | 1), Arg0Reg); - /* begin JumpAbove: */ - jumpLongTooBig = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, instSpecReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperand(PushCq, 0); - /* begin Jump: */ - jumpLongPrepDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpByteFormat, checkQuickConstantforInstruction((((usqInt)(maxSlots * BytesPerWord) << 1) | 1), genoperandoperand(CmpCqR, (((usqInt)(maxSlots * BytesPerWord) << 1) | 1), Arg0Reg))); - /* begin JumpAbove: */ - jumpByteTooBig = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, instSpecReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(MoveCqR, BytesPerWord, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, instSpecReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(AndCqR, BytesPerWord - 1, TempReg); - /* begin LogicalShiftLeftCq:R: */ - quickConstant2 = formatShift(); - genoperandoperand(LogicalShiftLeftCqR, quickConstant2, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, halfHeaderReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(AddCqR, BytesPerWord - 1, instSpecReg); - /* begin LogicalShiftRightCq:R: */ - genoperandoperand(LogicalShiftRightCqR, shiftForWord(), instSpecReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperand(PushCq, 0); - /* begin Jump: */ - jumpBytePrepDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpArrayFormat, checkQuickConstantforInstruction((((usqInt)maxSlots << 1) | 1), genoperandoperand(CmpCqR, (((usqInt)maxSlots << 1) | 1), Arg0Reg))); - /* begin JumpAbove: */ - jumpArrayTooBig = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, instSpecReg); - /* begin checkLiteral:forInstruction: */ - nilObject(); - anInstruction11 = genoperand(PushCw, nilObject()); - jmpTarget(jumpBytePrepDone, jmpTarget(jumpLongPrepDone, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveRMwr, halfHeaderReg, 0, Arg1Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instSpecReg, halfHeaderReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperand(CmpCqR, 0, byteSizeReg); - /* begin JumpNonZero: */ - jumpHasSlots = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(MoveCqR, BaseHeaderSize * 2, byteSizeReg); - /* begin Jump: */ - skip = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpHasSlots, genoperandoperand(MoveRR, byteSizeReg, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperand(AndCqR, 1, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, byteSizeReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction16 = genoperandoperand(AddCqR, BaseHeaderSize / BytesPerWord, byteSizeReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), byteSizeReg); - jmpTarget(skip, genoperandoperand(LogicalShiftLeftCqR, numSlotsHalfShift(), halfHeaderReg)); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg1Reg, byteSizeReg); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction17 = genoperandoperand(CmpCqR, getScavengeThreshold(), byteSizeReg); - /* begin JumpAboveOrEqual: */ - jumpNoSpace = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction18 = genoperandoperand(MoveRAw, byteSizeReg, freeStartAddress()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperandoperand(MoveRMwr, halfHeaderReg, 4, ReceiverResultReg); - /* begin PopR: */ - genoperand(PopR, fillReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperandoperand(LoadEffectiveAddressMwrR, BaseHeaderSize, ReceiverResultReg, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperandoperand(MoveRMwr, fillReg, 0, Arg1Reg); - fillLoop = anInstruction21; - /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperandoperand(MoveRMwr, fillReg, 4, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction23 = genoperandoperand(AddCqR, 8, Arg1Reg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, byteSizeReg); - /* begin JumpAbove: */ - genConditionalBranchoperand(JumpAbove, ((sqInt)fillLoop)); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNoSpace, genoperand(PopR, TempReg)); - jmpTarget(jumpUnhashed, jmpTarget(jumpFailCuzFixed, jmpTarget(jumpArrayTooBig, jmpTarget(jumpByteTooBig, jmpTarget(jumpLongTooBig, jmpTarget(jumpNElementsNonInt, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))))); - return 0; -} - - -/* Implement primitiveShallowCopy/primitiveClone for convenient cases: - - the receiver is not a context - - the receiver is not a compiled method - - the result fits in eden (actually below scavengeThreshold) */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveShallowCopy */ -static sqInt -genPrimitiveShallowCopy(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction22; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - AbstractInstruction *continuance; - AbstractInstruction *copyLoop; - sqInt formatReg; - AbstractInstruction * jumpEmpty; - AbstractInstruction *jumpImmediate; - AbstractInstruction *jumpIsMethod; - AbstractInstruction *jumpNoSpace; - AbstractInstruction *jumpTooBig; - AbstractInstruction *jumpVariable; - sqInt ptrReg; - sqInt quickConstant; - sqInt quickConstant1; - sqInt resultReg; - sqInt slotsReg; - - jumpImmediate = genJumpImmediate(ReceiverResultReg); - resultReg = Arg0Reg; - - /* get freeStart as early as possible so as not to wait later... */ - slotsReg = Arg1Reg; - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction = genoperandoperand(MoveAwR, freeStartAddress(), resultReg); - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (ptrReg = (formatReg = SendNumArgsReg)), NoReg); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction1 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsMethod = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - indexablePointersFormat(); - anInstruction2 = genoperandoperand(CmpCqR, indexablePointersFormat(), formatReg); - /* begin JumpZero: */ - jumpVariable = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin Label */ - continuance = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - genGetRawSlotSizeOfNonImminto(ReceiverResultReg, slotsReg); - /* begin checkQuickConstant:forInstruction: */ - numSlotsMask(); - anInstruction3 = genoperandoperand(CmpCqR, numSlotsMask(), slotsReg); - /* begin JumpZero: */ - jumpTooBig = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, 0, slotsReg); - /* begin JumpZero: */ - jumpEmpty = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, slotsReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(AndCqR, 1, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, slotsReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(AddCqR, BaseHeaderSize / BytesPerWord, slotsReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), slotsReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, resultReg, slotsReg); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction7 = genoperandoperand(CmpCqR, getScavengeThreshold(), slotsReg); - /* begin JumpAboveOrEqual: */ - jumpNoSpace = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, resultReg, ptrReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction8 = genoperandoperand(MoveRAw, slotsReg, freeStartAddress()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(SubCqR, BytesPerWord * 2, slotsReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveMwrR, 0, ReceiverResultReg, TempReg); - /* begin AndCq:R: */ - quickConstant = (((sqInt)((usqInt)((formatMask())) << (formatShift())))) + (classIndexMask()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperand(AndCqR, quickConstant, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveRMwr, TempReg, 0, resultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperandoperand(MoveMwrR, BytesPerWord, ReceiverResultReg, TempReg); - /* begin AndCq:R: */ - quickConstant1 = ((sqInt)((usqInt)((numSlotsMask())) << (numSlotsHalfShift()))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(AndCqR, quickConstant1, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperandoperand(MoveRMwr, TempReg, BytesPerWord, resultReg); - /* begin Label */ - copyLoop = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - /* begin checkQuickConstant:forInstruction: */ - anInstruction16 = genoperandoperand(AddCqR, BytesPerWord * 2, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperand(AddCqR, BytesPerWord * 2, ptrReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction18 = genoperandoperandoperand(MoveMwrR, 0, ReceiverResultReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperandoperand(MoveRMwr, TempReg, 0, ptrReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperandoperand(MoveMwrR, BytesPerWord, ReceiverResultReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperandoperand(MoveRMwr, TempReg, BytesPerWord, ptrReg); - /* begin CmpR:R: */ - assert(!((ptrReg == SPReg))); - genoperandoperand(CmpRR, ptrReg, slotsReg); - /* begin JumpAbove: */ - genConditionalBranchoperand(JumpAbove, ((sqInt)copyLoop)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, resultReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpVariable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genGetClassIndexOfNonImminto(ReceiverResultReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, ClassReg); - /* begin JumpNonZero: */ - genConditionalBranchoperand(JumpNonZero, ((sqInt)continuance)); - jmpTarget(jumpImmediate, jmpTarget(jumpNoSpace, jmpTarget(jumpIsMethod, jmpTarget(jumpTooBig, jmpTarget(jumpEmpty, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))))); - return 0; -} - - -/* c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: - fixedFieldsOf:format:length: - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveStringAt */ -static sqInt -genPrimitiveStringAt(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - AbstractInstruction *done; - sqInt formatReg; - AbstractInstruction *jumpBadIndex; - AbstractInstruction *jumpBytesOutOfBounds; - AbstractInstruction *jumpIsBytes; - AbstractInstruction *jumpIsShorts; - AbstractInstruction *jumpNotIndexable; - AbstractInstruction *jumpShortsOutOfBounds; - AbstractInstruction *jumpWordsDone; - AbstractInstruction *jumpWordsOutOfBounds; - AbstractInstruction *jumpWordTooBig; - - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, Arg1Reg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpBadIndex = genJumpNotSmallInteger(Arg0Reg); - genConvertSmallIntegerToIntegerInReg(Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(SubCqR, 1, Arg1Reg); - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), NoReg); - genGetNumSlotsOfinto(ReceiverResultReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction2 = genoperandoperand(CmpCqR, firstByteFormat(), formatReg); - /* begin JumpGreaterOrEqual: */ - jumpIsBytes = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstShortFormat(); - anInstruction3 = genoperandoperand(CmpCqR, firstShortFormat(), formatReg); - /* begin JumpGreaterOrEqual: */ - jumpIsShorts = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction4 = genoperandoperand(CmpCqR, firstLongFormat(), formatReg); - /* begin JumpLess: */ - jumpNotIndexable = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, ClassReg); - /* begin JumpBelowOrEqual: */ - jumpWordsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddCq:R: */ - anInstruction5 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg1Reg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, Arg1Reg, ReceiverResultReg, TempReg); - jumpWordTooBig = jumpNotCharacterUnsignedValueInRegister(TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - /* begin Jump: */ - jumpWordsDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpIsBytes, genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), ClassReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(AndCqR, BytesPerWord - 1, formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, ClassReg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, ClassReg); - /* begin JumpBelowOrEqual: */ - jumpBytesOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(AddCqR, BaseHeaderSize, Arg1Reg); - /* begin MoveXbr:R:R: */ - genoperandoperandoperand(MoveXbrRR, Arg1Reg, ReceiverResultReg, ReceiverResultReg); - /* begin AndCq:R: */ - anInstruction = genoperandoperand(AndCqR, 0xFF, ReceiverResultReg); - jmpTarget(jumpWordsDone, (done = genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - genConvertIntegerToCharacterInReg(ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsShorts, gLogicalShiftLeftCqR((shiftForWord()) - 1, ClassReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(AndCqR, (BytesPerWord / 1) - 1, formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, ClassReg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, ClassReg); - /* begin JumpBelowOrEqual: */ - jumpShortsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg1Reg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperandoperand(MoveM16rR, BaseHeaderSize, ReceiverResultReg, ReceiverResultReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)done)); - jmpTarget(jumpWordTooBig, jmpTarget(jumpBytesOutOfBounds, jmpTarget(jumpShortsOutOfBounds, jmpTarget(jumpWordsOutOfBounds, jmpTarget(jumpNotIndexable, jmpTarget(jumpBadIndex, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))))); - return CompletePrimitive; -} - - -/* c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: - fixedFieldsOf:format:length: - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveStringAtPut */ -static sqInt -genPrimitiveStringAtPut(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt formatReg; - AbstractInstruction *jumpBadArg; - AbstractInstruction *jumpBadIndex; - AbstractInstruction *jumpBytesOutOfBounds; - AbstractInstruction *jumpBytesOutOfRange; - AbstractInstruction * jumpImmutable; - AbstractInstruction *jumpIsBytes; - AbstractInstruction * jumpIsCompiledMethod; - AbstractInstruction *jumpIsShorts; - AbstractInstruction * jumpNotString; - AbstractInstruction *jumpShortsOutOfBounds; - AbstractInstruction *jumpShortsOutOfRange; - AbstractInstruction *jumpWordsOutOfBounds; - AbstractInstruction *jumpWordsOutOfRange; - - jumpImmutable = ((AbstractInstruction *) 0); - /* begin genLoadArgAtDepth:into: */ - assert(1 < (numRegArgs())); - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - jumpBadIndex = genJumpNotSmallInteger(Arg0Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - jumpBadArg = genJumpNotCharacterInScratchReg(TempReg); - genConvertSmallIntegerToIntegerInReg(Arg0Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, 1, Arg0Reg); -# if IMMUTABILITY - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), TempReg); - /* begin genJumpBaseHeaderImmutable: */ - immutableBitMask(); - anInstruction12 = genoperandoperand(TstCqR, immutableBitMask(), TempReg); - /* begin JumpNonZero: */ - jumpImmutable = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -# else // IMMUTABILITY - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), NoReg); -# endif // IMMUTABILITY - genGetNumSlotsOfinto(ReceiverResultReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction1 = genoperandoperand(CmpCqR, firstLongFormat(), formatReg); - /* begin JumpBelow: */ - jumpNotString = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction2 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsCompiledMethod = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction3 = genoperandoperand(CmpCqR, firstByteFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsBytes = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstShortFormat(); - anInstruction4 = genoperandoperand(CmpCqR, firstShortFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsShorts = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(CmpCqR, 0, Arg1Reg); - /* begin JumpLess: */ - jumpWordsOutOfRange = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, ClassReg); - /* begin JumpBelowOrEqual: */ - jumpWordsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertCharacterToCodeInReg(TempReg); - /* begin AddCq:R: */ - anInstruction6 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg0Reg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, TempReg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsShorts, gCmpCqR(characterObjectOf(0xFFFF), Arg1Reg)); - /* begin JumpAbove: */ - jumpShortsOutOfRange = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (shiftForWord()) - 1, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(AndCqR, (BytesPerWord / 2) - 1, formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, ClassReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, ClassReg); - /* begin JumpBelowOrEqual: */ - jumpShortsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertCharacterToCodeInReg(TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperandoperand(MoveRM16r, TempReg, BaseHeaderSize, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsBytes, gCmpCqR(characterObjectOf(0xFF), Arg1Reg)); - /* begin JumpAbove: */ - jumpBytesOutOfRange = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(AndCqR, BytesPerWord - 1, formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, ClassReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, ClassReg); - /* begin JumpBelowOrEqual: */ - jumpBytesOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertCharacterToCodeInReg(TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperand(AddCqR, BaseHeaderSize, Arg0Reg); - /* begin MoveR:Xbr:R: */ - genoperandoperandoperand(MoveRXbrR, TempReg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotString, jmpTarget(jumpBytesOutOfRange, jmpTarget(jumpShortsOutOfRange, jmpTarget(jumpWordsOutOfRange, jmpTarget(jumpIsCompiledMethod, jmpTarget(jumpBytesOutOfBounds, jmpTarget(jumpShortsOutOfBounds, jmpTarget(jumpWordsOutOfBounds, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))))))); -# if IMMUTABILITY - jmpTarget(jumpImmutable, ((AbstractInstruction *) (((jumpNotString->operands))[0]))); -# endif - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperand(AddCqR, 1, Arg0Reg); - genConvertIntegerToSmallIntegerInReg(Arg0Reg); - jmpTarget(jumpBadArg, jmpTarget(jumpBadIndex, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - /* CogObjectRepresentationFor32BitSpur>>#genRemoveSmallIntegerTagsInScratchReg: */ -static sqInt NoDbgRegParms -genRemoveSmallIntegerTagsInScratchReg(sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, 1, scratchReg); - return 0; -} - - /* CogObjectRepresentationFor32BitSpur>>#genShiftAwaySmallIntegerTagsInScratchReg: */ -static sqInt NoDbgRegParms -genShiftAwaySmallIntegerTagsInScratchReg(sqInt scratchReg) -{ - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, 1, scratchReg); - return 0; -} - - -/* Get the literal count of a CompiledMethod into headerReg, plus one if - requested. If inBytes is true, scale the count by the word size. Deal with - the possibility of - the method being cogged. */ - - /* CogObjectRepresentationFor32BitSpur>>#getLiteralCountOf:plusOne:inBytes:into:scratch: */ -static sqInt NoDbgRegParms -getLiteralCountOfplusOneinBytesintoscratch(sqInt methodReg, sqInt plusOne, sqInt inBytes, sqInt litCountReg, sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - sqInt quickConstant; - sqInt quickConstant1; - - genGetMethodHeaderOfintoscratch(methodReg, litCountReg, scratchReg); - if (inBytes) { - /* begin AndCq:R: */ - quickConstant = ((sqInt)((usqInt)((alternateHeaderNumLiteralsMask())) << 1)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, quickConstant, litCountReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, 1, litCountReg); - } - else { - /* begin LogicalShiftRightCq:R: */ - genoperandoperand(LogicalShiftRightCqR, 1, litCountReg); - /* begin checkQuickConstant:forInstruction: */ - alternateHeaderNumLiteralsMask(); - anInstruction1 = genoperandoperand(AndCqR, alternateHeaderNumLiteralsMask(), litCountReg); - } - if (plusOne) { - /* begin AddCq:R: */ - quickConstant1 = (inBytes - ? BytesPerWord - : 1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AddCqR, quickConstant1, litCountReg); - } - return 0; -} - - -/* Answer the relevant inline cache tag for an instance. - c.f. getInlineCacheClassTagFrom:into: & inlineCacheTagForClass: */ - - /* CogObjectRepresentationFor32BitSpur>>#inlineCacheTagForInstance: */ -static sqInt NoDbgRegParms -inlineCacheTagForInstance(sqInt oop) -{ - return (isImmediate(oop) - ? oop & 1 - : classIndexOf(oop)); -} - - /* CogObjectRepresentationFor32BitSpur>>#jumpNotSmallIntegerUnsignedValueInRegister: */ -static AbstractInstruction * NoDbgRegParms -jumpNotSmallIntegerUnsignedValueInRegister(sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0x3FFFFFFF, reg); - /* begin JumpAbove: */ - return genConditionalBranchoperand(JumpAbove, ((sqInt)0)); -} - - -/* Mark and trace a literal in an inline cache preceding address in - cogMethodOrNil. Answer if code was modified. */ - - /* CogObjectRepresentationFor32BitSpur>>#markAndTraceCacheTagLiteral:in:atpc: */ -static sqInt NoDbgRegParms -markAndTraceCacheTagLiteralinatpc(sqInt literal, CogMethod *cogMethodOrNil, usqInt address) -{ - sqInt objOop; - - if (!(couldBeObject(literal))) { - return 0; - } - assert(addressCouldBeObj(literal)); - if (!(isForwarded(literal))) { - markAndTrace(literal); - return 0; - } - objOop = followForwarded(literal); - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheTagat(backEnd(), objOop, address); - markAndTraceUpdatedLiteralin(objOop, cogMethodOrNil); - return 1; -} - - /* CogObjectRepresentationFor32BitSpur>>#numSmallIntegerBits */ -static sqInt -numSmallIntegerBits(void) -{ - return 0x1F; -} - - -/* The two valid tag patterns are 0 (Character) and 1 (SmallInteger) */ - - /* CogObjectRepresentationFor32BitSpur>>#validInlineCacheTag: */ -static sqInt NoDbgRegParms -validInlineCacheTag(usqInt classIndexOrTagPattern) -{ - return (classIndexOrTagPattern <= 1) - || ((classAtIndex(classIndexOrTagPattern)) != null); -} - - /* CogObjectRepresentationForSpur>>#checkValidDerivedObjectReference: */ -static sqInt NoDbgRegParms -checkValidDerivedObjectReference(sqInt bodyAddress) -{ - return (heapMapAtWord(pointerForOop(bodyAddress - BaseHeaderSize))) != 0; -} - - /* CogObjectRepresentationForSpur>>#checkValidOopReference: */ -static sqInt NoDbgRegParms -checkValidOopReference(sqInt anOop) -{ - return (isImmediate(anOop)) - || ((heapMapAtWord(pointerForOop(anOop))) != 0); -} - - /* CogObjectRepresentationForSpur>>#couldBeDerivedObject: */ -static sqInt NoDbgRegParms -couldBeDerivedObject(sqInt bodyAddress) -{ - return oopisGreaterThanOrEqualTo(bodyAddress - BaseHeaderSize, startOfMemory()); -} - - /* CogObjectRepresentationForSpur>>#couldBeObject: */ -static sqInt NoDbgRegParms -couldBeObject(sqInt literal) -{ - return (isNonImmediate(literal)) - && (oopisGreaterThanOrEqualTo(literal, startOfMemory())); -} - - -/* Create a trampoline to answer the active context that will - answer it if a frame is already married, and create it otherwise. - Assume numArgs is in SendNumArgsReg and ClassReg is free. */ - - /* CogObjectRepresentationForSpur>>#genActiveContextTrampolineLarge:inBlock:called: */ -static usqInt NoDbgRegParms -genActiveContextTrampolineLargeinBlockcalled(sqInt isLarge, sqInt isInBlock, char *aString) -{ - usqInt startAddress; - - startAddress = methodZoneBase(); - zeroOpcodeIndex(); - genGetActiveContextLargeinBlock(isLarge, isInBlock); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress(aString, startAddress); - recordRunTimeObjectReferences(); - return startAddress; -} - - -/* Check the remembered bit of the object in objReg; answer the jump taken if - the bit is already set. - Only need to fetch the byte containing it, which reduces the size of the - mask constant. - */ - - /* CogObjectRepresentationForSpur>>#genCheckRememberedBitOf:scratch: */ -static AbstractInstruction * NoDbgRegParms -genCheckRememberedBitOfscratch(sqInt objReg, sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt mask; - sqInt rememberedBitByteOffset; - - rememberedBitByteOffset = (rememberedBitShift()) / 8; - mask = 1U << ((rememberedBitShift()) % 8); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMbrR, rememberedBitByteOffset, objReg, scratchReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(TstCqR, mask, scratchReg); - /* begin JumpNonZero: */ - return genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -} - - /* CogObjectRepresentationForSpur>>#genConvertCharacterToCodeInReg: */ -static sqInt NoDbgRegParms -genConvertCharacterToCodeInReg(sqInt reg) -{ - sqInt quickConstant; - - /* begin LogicalShiftRightCq:R: */ - quickConstant = numTagBits(); - genoperandoperand(LogicalShiftRightCqR, quickConstant, reg); - return 0; -} - - /* CogObjectRepresentationForSpur>>#genConvertIntegerToCharacterInReg: */ -static sqInt NoDbgRegParms -genConvertIntegerToCharacterInReg(sqInt reg) -{ - AbstractInstruction *anInstruction; - sqInt quickConstant; - - /* begin LogicalShiftLeftCq:R: */ - quickConstant = numTagBits(); - genoperandoperand(LogicalShiftLeftCqR, quickConstant, reg); - /* begin checkQuickConstant:forInstruction: */ - characterTag(); - anInstruction = genoperandoperand(AddCqR, characterTag(), reg); - return 0; -} - - -/* Create a closure with the given startpc, numArgs and numCopied - within a context with ctxtNumArgs, large if isLargeCtxt that is in a - block if isInBlock. If numCopied > 0 pop those values off the stack. */ - - /* CogObjectRepresentationForSpur>>#genCreateClosureAt:numArgs:numCopied:contextNumArgs:large:inBlock: */ -static sqInt NoDbgRegParms -genCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(sqInt bcpc, sqInt numArgs, sqInt numCopied, sqInt ctxtNumArgs, sqInt isLargeCtxt, sqInt isInBlock) -{ - AbstractInstruction *anInstruction; - sqInt i; - - genNoPopCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(bcpc, numArgs, numCopied, ctxtNumArgs, isLargeCtxt, isInBlock); - for (i = 1; i <= numCopied; i += 1) { - /* begin PopR: */ - genoperand(PopR, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveRMwr, TempReg, (((numCopied - i) + ClosureFirstCopiedValueIndex) * BytesPerOop) + BaseHeaderSize, ReceiverResultReg); - } - return 0; -} - - -/* Make sure that the object in reg is not forwarded. This routine assumes - the object will - never be forwarded to an immediate, as it is used to unforward literal - variables (associations). - Use the fact that isForwardedObjectClassIndexPun is a power of two to save - an instruction. */ - - /* CogObjectRepresentationForSpur>>#genEnsureObjInRegNotForwarded:scratchReg: */ -static sqInt NoDbgRegParms -genEnsureObjInRegNotForwardedscratchReg(sqInt reg, sqInt scratch) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *loop; - AbstractInstruction *ok; - sqInt quickConstant; - - assert(reg != scratch); - /* begin Label */ - loop = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, reg, scratch); - /* begin AndCq:R: */ - quickConstant = (classIndexMask()) - (isForwardedObjectClassIndexPun()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, quickConstant, scratch); - /* begin JumpNonZero: */ - ok = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(0, reg, reg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)loop)); - jmpTarget(ok, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - /* CogObjectRepresentationForSpur>>#genEnsureOopInRegNotForwarded:scratchReg: */ -static sqInt NoDbgRegParms -genEnsureOopInRegNotForwardedscratchReg(sqInt reg, sqInt scratch) -{ - AbstractInstruction *instruction; - - /* begin genEnsureOopInRegNotForwarded:scratchReg:jumpBackTo: */ - instruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - return genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(reg, scratch, instruction, 0); -} - - -/* Make sure that the oop in reg is not forwarded. - Use the fact that isForwardedObjectClassIndexPun is a power of two to save - an instruction. */ -/* maybe a fixup or an instruction */ -/* maybe a fixup or an instruction */ - - /* CogObjectRepresentationForSpur>>#genEnsureOopInRegNotForwarded:scratchReg:ifForwarder:ifNotForwarder: */ -static sqInt NoDbgRegParms -genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(sqInt reg, sqInt scratch, void *fwdJumpTarget, void *nonFwdJumpTargetOrZero) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction * finished; - AbstractInstruction * imm; - AbstractInstruction * ok; - sqInt quickConstant; - - assert(reg != scratch); - - /* notionally - self genGetClassIndexOfNonImm: reg into: scratch. - cogit CmpCq: objectMemory isForwardedObjectClassIndexPun R: TempReg. - but the following is an instruction shorter: */ - imm = genJumpImmediate(reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, reg, scratch); - /* begin AndCq:R: */ - quickConstant = (classIndexMask()) - (isForwardedObjectClassIndexPun()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, quickConstant, scratch); - /* begin JumpNonZero: */ - ok = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(0, reg, reg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)fwdJumpTarget)); - if ((((usqInt)nonFwdJumpTargetOrZero)) == 0) { - /* begin Label */ - finished = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - else { - finished = nonFwdJumpTargetOrZero; - } - jmpTarget(imm, jmpTarget(ok, finished)); - return 0; -} - - -/* Make sure that the oop in reg is not forwarded, and the field reg[offset] - is updated - if the object in reg is forwarded. Use the fact that - isForwardedObjectClassIndexPun is - a power of two to save an instruction. */ - - /* CogObjectRepresentationForSpur>>#genEnsureOopInRegNotForwarded:scratchReg:updatingMw:r: */ -static sqInt NoDbgRegParms -genEnsureOopInRegNotForwardedscratchRegupdatingMwr(sqInt reg, sqInt scratch, sqInt offset, sqInt baseReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *imm; - AbstractInstruction *loop; - AbstractInstruction *ok; - sqInt quickConstant; - - assert((reg != scratch) - && (baseReg != scratch)); - /* begin Label */ - loop = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - - /* notionally - self genGetClassIndexOfNonImm: reg into: scratch. - cogit CmpCq: objectMemory isForwardedObjectClassIndexPun R: TempReg. - but the following is an instruction shorter: */ - imm = genJumpImmediate(reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, reg, scratch); - /* begin AndCq:R: */ - quickConstant = (classIndexMask()) - (isForwardedObjectClassIndexPun()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, quickConstant, scratch); - /* begin JumpNonZero: */ - ok = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(0, reg, reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveRMwr, reg, offset, baseReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)loop)); - jmpTarget(ok, jmpTarget(imm, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return 0; -} - - -/* Make sure that the oop in reg is not forwarded, updating the slot in - objReg with the value. - */ - - /* CogObjectRepresentationForSpur>>#genEnsureOopInRegNotForwarded:scratchReg:updatingSlot:in: */ -static sqInt NoDbgRegParms -genEnsureOopInRegNotForwardedscratchRegupdatingSlotin(sqInt reg, sqInt scratch, sqInt index, sqInt objReg) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *imm; - AbstractInstruction *loop; - AbstractInstruction *ok; - sqInt quickConstant; - - - /* Open-code - self genEnsureOopInRegNotForwarded: reg - scratchReg: scratch - updatingMw: index * objectMemory wordSize + objectMemory baseHeaderSize - r: objReg. - to avoid calling the store check unless the receiver is forwarded. */ - assert((reg != scratch) - && (objReg != scratch)); - /* begin Label */ - loop = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - - /* notionally - self genGetClassIndexOfNonImm: reg into: scratch. - cogit CmpCq: objectMemory isForwardedObjectClassIndexPun R: TempReg. - but the following is an instruction shorter: */ - imm = genJumpImmediate(reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, reg, scratch); - /* begin AndCq:R: */ - quickConstant = (classIndexMask()) - (isForwardedObjectClassIndexPun()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, quickConstant, scratch); - /* begin JumpNonZero: */ - ok = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(0, reg, reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveRMwr, reg, (index * BytesPerWord) + BaseHeaderSize, objReg); - assert((reg == Arg0Reg) - && ((scratch == TempReg) - && (objReg == ReceiverResultReg))); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceStoreCheckContextReceiverTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin Jump: */ - genoperand(Jump, ((sqInt)loop)); - jmpTarget(ok, jmpTarget(imm, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return 0; -} - - -/* Do the store check. Answer the argument for the benefit of the code - generator; ReceiverResultReg may be caller-saved and hence smashed by this - call. Answering - it allows the code generator to reload ReceiverResultReg cheaply. - In Spur the only thing we leave to the run-time is adding the receiver to - the remembered set and setting its isRemembered bit. */ - - /* CogObjectRepresentationForSpur>>#generateObjectRepresentationTrampolines */ -static void -generateObjectRepresentationTrampolines(void) -{ - sqInt instVarIndex; - AbstractInstruction *jumpSC; - - -# if IMMUTABILITY - for (instVarIndex = 0; instVarIndex < NumStoreTrampolines; instVarIndex += 1) { - ceStoreTrampolines[instVarIndex] = (genStoreTrampolineCalledinstVarIndex(trampolineNamenumArgslimit("ceStoreTrampoline", instVarIndex, NumStoreTrampolines - 2), instVarIndex)); - } -# endif // IMMUTABILITY - ceNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceNewHash", 1, ReceiverResultReg, null, null, null, /* begin emptyRegisterMask */ 0, 1, ReceiverResultReg, 0); - /* begin genStoreCheckTrampoline */ - if (CheckRememberedInTrampoline) { - zeroOpcodeIndex(); - jumpSC = genCheckRememberedBitOfscratch(ReceiverResultReg, ABIResultReg); - assert(((jumpSC->opcode)) == JumpNonZero); - (jumpSC->opcode = JumpZero); - /* begin RetN: */ - genoperand(RetN, 0); - jmpTarget(jumpSC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) - ? ReceiverResultReg - : ABIResultReg), CheckRememberedInTrampoline); - ceStoreCheckContextReceiverTrampoline = genStoreCheckContextReceiverTrampoline(); - /* begin genTrampolineFor:called:regsToSave: */ - ceScheduleScavengeTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceScheduleScavenge, "ceScheduleScavengeTrampoline", 0, null, null, null, null, CallerSavedRegisterMask, 1, NoReg, 0); - ceSmallActiveContextInMethodTrampoline = genActiveContextTrampolineLargeinBlockcalled(0, 0, "ceSmallMethodContext"); - ceSmallActiveContextInBlockTrampoline = genActiveContextTrampolineLargeinBlockcalled(0, InVanillaBlock, "ceSmallBlockContext"); - ceLargeActiveContextInMethodTrampoline = genActiveContextTrampolineLargeinBlockcalled(1, 0, "ceLargeMethodContext"); - ceLargeActiveContextInBlockTrampoline = genActiveContextTrampolineLargeinBlockcalled(1, InVanillaBlock, "ceLargeBlockContext"); - } - - -/* Create a trampoline to answer the active context that will - answer it if a frame is already married, and create it otherwise. - Assume numArgs is in SendNumArgsReg and ClassReg is free. */ - - /* CogObjectRepresentationForSpur>>#genGetActiveContextLarge:inBlock: */ -static sqInt NoDbgRegParms -genGetActiveContextLargeinBlock(sqInt isLarge, sqInt isInBlock) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction22; - AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction24; - AbstractInstruction *anInstruction25; - AbstractInstruction *anInstruction26; - AbstractInstruction *anInstruction27; - AbstractInstruction *anInstruction28; - AbstractInstruction *anInstruction29; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction30; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction32; - AbstractInstruction *anInstruction33; - AbstractInstruction *anInstruction34; - AbstractInstruction *anInstruction35; - AbstractInstruction *anInstruction36; - AbstractInstruction *anInstruction37; - AbstractInstruction *anInstruction38; - AbstractInstruction *anInstruction39; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction40; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt constant; - AbstractInstruction * continuation; - AbstractInstruction * exit; - usqLong header; - AbstractInstruction * inst; - AbstractInstruction * jumpNeedScavenge; - AbstractInstruction * jumpSingle; - AbstractInstruction * loopHead; - sqInt offset; - sqInt offset1; - sqInt quickConstant; - sqInt quickConstant1; - sqInt slotSize; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, FoxMethod, FPReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(TstCqR, MFMethodFlagHasContextFlag, ClassReg); - /* begin JumpZero: */ - jumpSingle = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperandoperand(MoveMwrR, FoxThisContext, FPReg, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, 0); - jmpTarget(jumpSingle, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperand(OrCqR, MFMethodFlagHasContextFlag, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperandoperand(MoveRMwr, ClassReg, FoxMethod, FPReg); - switch (isInBlock) { - case InFullBlock: - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, 3, ClassReg); - break; - case InVanillaBlock: - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(SubCqR, 3, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveM16rR, 0, ClassReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, ClassReg); - break; - case 0: - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(SubCqR, 1, ClassReg); - break; - default: - error("Case not found and no otherwise clause"); - } - slotSize = (isLarge - ? LargeContextSlots - : SmallContextSlots); - header = headerForSlotsformatclassIndex(slotSize, indexablePointersFormat(), ClassMethodContextCompactIndex); - flag("endianness"); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction12 = genoperandoperand(MoveAwR, freeStartAddress(), ReceiverResultReg); - /* begin genStoreHeader:intoNewInstance:using: */ - anInstruction13 = genoperandoperand(MoveCqR, ((usqInt) header), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperandoperand(MoveRMwr, TempReg, 0, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperand(MoveCqR, (header) >> 32, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction31 = genoperandoperandoperand(MoveRMwr, TempReg, 4, ReceiverResultReg); - /* begin LoadEffectiveAddressMw:r:R: */ - offset = smallObjectBytesForSlots(slotSize); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperandoperand(LoadEffectiveAddressMwrR, offset, ReceiverResultReg, TempReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction16 = genoperandoperand(MoveRAw, TempReg, freeStartAddress()); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction17 = genoperandoperand(CmpCqR, getScavengeThreshold(), TempReg); - /* begin JumpAboveOrEqual: */ - jumpNeedScavenge = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin LoadEffectiveAddressMw:r:R: */ - anInstruction18 = genoperandoperandoperand(LoadEffectiveAddressMwrR, 1, FPReg, TempReg); - continuation = anInstruction18; - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperandoperand(MoveRMwr, TempReg, BaseHeaderSize + (SenderIndex * BytesPerOop), ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperandoperand(MoveMwrR, FoxSavedFP, FPReg, TempReg); - genSetSmallIntegerTagsIn(TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperandoperand(MoveRMwr, TempReg, BaseHeaderSize + (InstructionPointerIndex * BytesPerOop), ReceiverResultReg); - /* begin MoveMw:r:R: */ - offset1 = offsetof(CogMethod, methodObject); - /* begin checkQuickConstant:forInstruction: */ - anInstruction23 = genoperandoperandoperand(MoveMwrR, offset1, ClassReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction24 = genoperandoperandoperand(MoveRMwr, TempReg, BaseHeaderSize + (MethodIndex * BytesPerWord), ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction25 = genoperandoperandoperand(MoveRMwr, ReceiverResultReg, FoxThisContext, FPReg); - gSubRRR(SPReg, FPReg, TempReg); - /* begin LogicalShiftRightCq:R: */ - quickConstant = 2 /* log2BytesPerWord */; - genoperandoperand(LogicalShiftRightCqR, quickConstant, TempReg); - /* begin SubCq:R: */ - quickConstant1 = 3; - /* begin checkQuickConstant:forInstruction: */ - anInstruction26 = genoperandoperand(SubCqR, quickConstant1, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, SendNumArgsReg, TempReg); - genConvertIntegerToSmallIntegerInReg(TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction27 = genoperandoperandoperand(MoveRMwr, TempReg, BaseHeaderSize + (StackPointerIndex * BytesPerOop), ReceiverResultReg); - if (isInBlock > 0) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperandoperand(LoadEffectiveAddressMwrR, 2, SendNumArgsReg, TempReg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, TempReg, FPReg, TempReg); - } - else { - /* begin genMoveConstant:R: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, TempReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction40 = genoperandoperand(MoveCqR, constant, TempReg); - } - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction28 = genoperandoperandoperand(MoveRMwr, TempReg, BaseHeaderSize + (ClosureIndex * BytesPerOop), ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction29 = genoperandoperandoperand(MoveMwrR, FoxMFReceiver, FPReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction30 = genoperandoperandoperand(MoveRMwr, TempReg, BaseHeaderSize + (ReceiverIndex * BytesPerOop), ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction32 = genoperandoperand(MoveCqR, 1, ClassReg); - /* begin CmpR:R: */ - assert(!((SendNumArgsReg == SPReg))); - loopHead = genoperandoperand(CmpRR, SendNumArgsReg, ClassReg); - /* begin JumpGreater: */ - exit = genConditionalBranchoperand(JumpGreater, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SendNumArgsReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, ClassReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction33 = genoperandoperand(AddCqR, 2, TempReg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, TempReg, FPReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction34 = genoperandoperand(AddCqR, ReceiverIndex + (BaseHeaderSize / BytesPerWord), ClassReg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, TempReg, ClassReg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction35 = genoperandoperand(SubCqR, (ReceiverIndex + (BaseHeaderSize / BytesPerWord)) - 1, ClassReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)loopHead)); - jmpTarget(exit, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - nilObject(); - anInstruction5 = genoperandoperand(MoveCqR, nilObject(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction36 = genoperandoperandoperand(LoadEffectiveAddressMwrR, FoxMFReceiver, FPReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction37 = genoperandoperand(AddCqR, (ReceiverIndex + 1) + (BaseHeaderSize / BytesPerWord), SendNumArgsReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction38 = genoperandoperand(SubCqR, BytesPerWord, ClassReg); - loopHead = anInstruction38; - /* begin CmpR:R: */ - assert(!((ClassReg == SPReg))); - genoperandoperand(CmpRR, ClassReg, SPReg); - /* begin JumpAbove: */ - exit = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, TempReg, SendNumArgsReg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction39 = genoperandoperand(AddCqR, 1, SendNumArgsReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)loopHead)); - jmpTarget(exit, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin RetN: */ - genoperand(RetN, 0); - jmpTarget(jumpNeedScavenge, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - CallRTregistersToBeSavedMask(ceScheduleScavengeTrampoline, ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)) | (1U << ClassReg)); - /* begin PopR: */ - genoperand(PopR, LinkReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuation)); - return 0; -} - - -/* Get the active context into ReceiverResultReg, creating it if necessary. */ - - /* CogObjectRepresentationForSpur>>#genGetActiveContextNumArgs:large:inBlock: */ -static sqInt NoDbgRegParms -genGetActiveContextNumArgslargeinBlock(sqInt numArgs, sqInt isLargeContext, sqInt isInBlock) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - sqInt ceLargeActiveContextInFullBlockTrampoline; - sqInt ceSmallActiveContextInFullBlockTrampoline; - sqInt routine; - - if (isLargeContext) { - switch (isInBlock) { - case 0: - routine = ceLargeActiveContextInMethodTrampoline; - break; - - case InVanillaBlock: - routine = ceLargeActiveContextInBlockTrampoline; - break; - - case InFullBlock: - routine = ceLargeActiveContextInFullBlockTrampoline; - break; - - default: - error("Case not found and no otherwise clause"); - routine = -1; - } - } - else { - switch (isInBlock) { - case 0: - routine = ceSmallActiveContextInMethodTrampoline; - break; - - case InVanillaBlock: - routine = ceSmallActiveContextInBlockTrampoline; - break; - - case InFullBlock: - routine = ceSmallActiveContextInFullBlockTrampoline; - break; - - default: - error("Case not found and no otherwise clause"); - routine = -1; - } - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, numArgs, SendNumArgsReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, routine); - (abstractInstruction->annotation = IsRelativeCall); - return 0; -} - - /* CogObjectRepresentationForSpur>>#genGetBits:ofFormatByteOf:into: */ -static sqInt NoDbgRegParms -genGetBitsofFormatByteOfinto(sqInt mask, sqInt sourceReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - flag("endianness"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMbrR, 3, sourceReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, mask, destReg); - return 0; -} - - -/* Fetch the instance's class index into destReg. */ - - /* CogObjectRepresentationForSpur>>#genGetClassIndexOfNonImm:into: */ -static sqInt NoDbgRegParms -genGetClassIndexOfNonImminto(sqInt sourceReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, sourceReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - classIndexMask(); - anInstruction1 = genoperandoperand(AndCqR, classIndexMask(), destReg); - return 0; -} - - -/* Fetch the class object whose index is in instReg into destReg. - It is non-obvious, but the Cogit assumes loading a class does not involve - a runtime call, so do not call classAtIndex: */ - - /* CogObjectRepresentationForSpur>>#genGetClassObjectOfClassIndex:into:scratchReg: */ -static sqInt NoDbgRegParms -genGetClassObjectOfClassIndexintoscratchReg(sqInt instReg, sqInt destReg, sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - sqInt offset; - sqInt quickConstant; - - assert(instReg != destReg); - assert(instReg != scratchReg); - assert(destReg != scratchReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instReg, scratchReg); - /* begin LogicalShiftRightCq:R: */ - quickConstant = classTableMajorIndexShift(); - genoperandoperand(LogicalShiftRightCqR, quickConstant, scratchReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), scratchReg); - assert(!(shouldAnnotateObjectReference(classTableRootObj()))); - /* begin MoveMw:r:R: */ - offset = (classTableRootObj()) + BaseHeaderSize; - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, scratchReg, destReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instReg, scratchReg); - /* begin checkQuickConstant:forInstruction: */ - classTableMinorIndexMask(); - anInstruction3 = genoperandoperand(AndCqR, classTableMinorIndexMask(), scratchReg); - /* begin AddCq:R: */ - anInstruction4 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), scratchReg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, scratchReg, destReg, destReg); - return 0; -} - - -/* Fetch the instance's class into destReg. If the instance is not the - receiver and is forwarded, follow forwarding. */ - - /* CogObjectRepresentationForSpur>>#genGetClassObjectOf:into:scratchReg:mayBeAForwarder: */ -static sqInt NoDbgRegParms -genGetClassObjectOfintoscratchRegmayBeAForwarder(sqInt instReg, sqInt destReg, sqInt scratchReg, sqInt mayBeForwarder) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *jumpIsImm; - AbstractInstruction *jumpNotForwarded; - AbstractInstruction *loop; - - if ((instReg == destReg) - || ((instReg == scratchReg) - || (destReg == scratchReg))) { - return BadRegisterSet; - } - /* begin MoveR:R: */ - loop = genoperandoperand(MoveRR, instReg, scratchReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AndCqR, tagMask(), scratchReg); - /* begin JumpNonZero: */ - jumpIsImm = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - flag("endianness"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperandoperand(MoveMwrR, 0, instReg, scratchReg); - /* begin checkQuickConstant:forInstruction: */ - classIndexMask(); - anInstruction4 = genoperandoperand(AndCqR, classIndexMask(), scratchReg); - if (mayBeForwarder) { - - /* if it is forwarded... */ - /* begin checkQuickConstant:forInstruction: */ - isForwardedObjectClassIndexPun(); - anInstruction = genoperandoperand(CmpCqR, isForwardedObjectClassIndexPun(), scratchReg); - /* begin JumpNonZero: */ - jumpNotForwarded = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, BaseHeaderSize, instReg, instReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)loop)); - jmpTarget(jumpNotForwarded, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - jmpTarget(jumpIsImm, genoperandoperand(MoveRR, scratchReg, destReg)); - if (scratchReg == TempReg) { - /* begin PushR: */ - genoperand(PushR, instReg); - genGetClassObjectOfClassIndexintoscratchReg(destReg, instReg, TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instReg, destReg); - /* begin PopR: */ - genoperand(PopR, instReg); - } - else { - genGetClassObjectOfClassIndexintoscratchReg(destReg, scratchReg, TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, scratchReg, destReg); - } - return 0; -} - - /* CogObjectRepresentationForSpur>>#genGetClassTagOf:into:scratchReg: */ -static AbstractInstruction * NoDbgRegParms -genGetClassTagOfintoscratchReg(sqInt instReg, sqInt destReg, sqInt scratchReg) -{ - return genGetInlineCacheClassTagFromintoforEntry(instReg, destReg, 1); -} - - -/* Fetch the instance's class index into destReg. */ - - /* CogObjectRepresentationForSpur>>#genGetCompactClassIndexNonImmOf:into: */ -static sqInt NoDbgRegParms -genGetCompactClassIndexNonImmOfinto(sqInt instReg, sqInt destReg) -{ - return genGetClassIndexOfNonImminto(instReg, destReg); -} - - /* CogObjectRepresentationForSpur>>#genGetDoubleValueOf:into: */ -static sqInt NoDbgRegParms -genGetDoubleValueOfinto(sqInt srcReg, sqInt destFPReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveM64rRd, BaseHeaderSize, srcReg, destFPReg); - return 0; -} - - -/* Get the format field of the object in srcReg into destReg. - srcReg may equal destReg. */ - - /* CogObjectRepresentationForSpur>>#genGetFormatOf:into: */ -static sqInt NoDbgRegParms -genGetFormatOfinto(sqInt srcReg, sqInt destReg) -{ - return genGetBitsofFormatByteOfinto(formatMask(), srcReg, destReg); -} - - -/* Get the format of the object in sourceReg into destReg. If - scratchRegOrNone is not NoReg, load at least the least significant 32-bits - (64-bits in 64-bits) of the - header word, which contains the format, into scratchRegOrNone. */ - - /* CogObjectRepresentationForSpur>>#genGetFormatOf:into:leastSignificantHalfOfBaseHeaderIntoScratch: */ -static sqInt NoDbgRegParms -genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(sqInt sourceReg, sqInt destReg, sqInt scratchRegOrNone) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - - if (scratchRegOrNone == NoReg) { - flag("endianness"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMbrR, 3, sourceReg, destReg); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, 0, sourceReg, scratchRegOrNone); - gLogicalShiftRightCqRR(formatShift(), scratchRegOrNone, destReg); - } - /* begin checkQuickConstant:forInstruction: */ - formatMask(); - anInstruction2 = genoperandoperand(AndCqR, formatMask(), destReg); - return 0; -} - - -/* Get the size in word-sized slots of the object in srcReg into destReg. - srcReg may equal destReg. */ - - /* CogObjectRepresentationForSpur>>#genGetNumSlotsOf:into: */ -static sqInt NoDbgRegParms -genGetNumSlotsOfinto(sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *jmp; - - assert(srcReg != destReg); - genGetRawSlotSizeOfNonImminto(srcReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - numSlotsMask(); - anInstruction = genoperandoperand(CmpCqR, numSlotsMask(), destReg); - /* begin JumpLess: */ - jmp = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - genGetOverflowSlotsOfinto(srcReg, destReg); - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - -/* The raw numSlots field is the most significant byte of the 64-bit header - word. MoveMbrR zero-extends. */ - - /* CogObjectRepresentationForSpur>>#genGetRawSlotSizeOfNonImm:into: */ -static sqInt NoDbgRegParms -genGetRawSlotSizeOfNonImminto(sqInt sourceReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin MoveCq:R: */ - anInstruction = genoperandoperand(MoveCqR, 0, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMbrR, 7, sourceReg, destReg); - return 0; -} - - /* CogObjectRepresentationForSpur>>#genJumpImmediate: */ -static AbstractInstruction * NoDbgRegParms -genJumpImmediate(sqInt aRegister) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(TstCqR, tagMask(), aRegister); - /* begin JumpNonZero: */ - return genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -} - - /* CogObjectRepresentationForSpur>>#genJumpImmutable:scratchReg: */ -#if IMMUTABILITY -static AbstractInstruction * NoDbgRegParms -genJumpImmutablescratchReg(sqInt sourceReg, sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, sourceReg, scratchReg); - /* begin genJumpBaseHeaderImmutable: */ - immutableBitMask(); - anInstruction1 = genoperandoperand(TstCqR, immutableBitMask(), scratchReg); - /* begin JumpNonZero: */ - return genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -} -#endif /* IMMUTABILITY */ - - /* CogObjectRepresentationForSpur>>#genJumpMutable:scratchReg: */ -#if IMMUTABILITY -static AbstractInstruction * NoDbgRegParms -genJumpMutablescratchReg(sqInt sourceReg, sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, sourceReg, scratchReg); - /* begin genJumpBaseHeaderMutable: */ - immutableBitMask(); - anInstruction1 = genoperandoperand(TstCqR, immutableBitMask(), scratchReg); - /* begin JumpZero: */ - return genConditionalBranchoperand(JumpZero, ((sqInt)0)); -} -#endif /* IMMUTABILITY */ - - /* CogObjectRepresentationForSpur>>#genJumpNotCharacterInScratchReg: */ -static AbstractInstruction * NoDbgRegParms -genJumpNotCharacterInScratchReg(sqInt reg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, tagMask(), reg); - /* begin checkQuickConstant:forInstruction: */ - characterTag(); - anInstruction1 = genoperandoperand(CmpCqR, characterTag(), reg); - /* begin JumpNonZero: */ - return genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -} - - -/* Generate a call to code that allocates a new Array of size. - The Array should be initialized with nils iff initialize is true. - The size arg is passed in SendNumArgsReg, the result - must come back in ReceiverResultReg. */ - - /* CogObjectRepresentationForSpur>>#genNewArrayOfSize:initialized: */ -static sqInt NoDbgRegParms -genNewArrayOfSizeinitialized(sqInt size, sqInt initialize) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - usqLong header; - sqInt i; - sqInt offset; - sqInt quickConstant; - AbstractInstruction *skip; - - assert(size < (numSlotsMask())); - header = headerForSlotsformatclassIndex(size, arrayFormat(), ClassArrayCompactIndex); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction2 = genoperandoperand(MoveAwR, freeStartAddress(), ReceiverResultReg); - /* begin genStoreHeader:intoNewInstance:using: */ - anInstruction4 = genoperandoperand(MoveCqR, ((usqInt) header), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperandoperand(MoveRMwr, TempReg, 0, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperand(MoveCqR, (header) >> 32, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperandoperand(MoveRMwr, TempReg, 4, ReceiverResultReg); - if (initialize - && (size > 0)) { - if (shouldAnnotateObjectReference(nilObject())) { - annotateobjRef(gMoveCwR(nilObject(), TempReg), nilObject()); - } - else { - /* begin MoveCq:R: */ - quickConstant = nilObject(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, TempReg); - } - for (i = 0; i < size; i += 1) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveRMwr, TempReg, (i * BytesPerWord) + BaseHeaderSize, ReceiverResultReg); - } - } - /* begin LoadEffectiveAddressMw:r:R: */ - offset = smallObjectBytesForSlots(size); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(LoadEffectiveAddressMwrR, offset, ReceiverResultReg, TempReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction6 = genoperandoperand(MoveRAw, TempReg, freeStartAddress()); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction7 = genoperandoperand(CmpCqR, getScavengeThreshold(), TempReg); - /* begin JumpBelow: */ - skip = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceScheduleScavengeTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - -/* Create a closure with the given startpc, numArgs and numCopied - within a context with ctxtNumArgs, large if isLargeCtxt that is in a - block if isInBlock. Do /not/ initialize the copied values. */ - - /* CogObjectRepresentationForSpur>>#genNoPopCreateClosureAt:numArgs:numCopied:contextNumArgs:large:inBlock: */ -static sqInt NoDbgRegParms -genNoPopCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(sqInt bcpc, sqInt numArgs, sqInt numCopied, sqInt ctxtNumArgs, sqInt isLargeCtxt, sqInt isInBlock) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - usqInt byteSize; - usqLong header; - sqInt numSlots; - AbstractInstruction *skip; - - - /* First get thisContext into ReceiverResultRega and thence in ClassReg. */ - genGetActiveContextNumArgslargeinBlock(ctxtNumArgs, isLargeCtxt, isInBlock); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, ClassReg); - numSlots = ClosureFirstCopiedValueIndex + numCopied; - byteSize = smallObjectBytesForSlots(numSlots); - header = headerForSlotsformatclassIndex(numSlots, indexablePointersFormat(), ClassBlockClosureCompactIndex); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction = genoperandoperand(MoveAwR, freeStartAddress(), ReceiverResultReg); - /* begin genStoreHeader:intoNewInstance:using: */ - anInstruction4 = genoperandoperand(MoveCqR, ((usqInt) header), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveRMwr, TempReg, 0, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, (header) >> 32, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperandoperand(MoveRMwr, TempReg, 4, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(LoadEffectiveAddressMwrR, byteSize, ReceiverResultReg, TempReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction6 = genoperandoperand(MoveRAw, TempReg, freeStartAddress()); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction7 = genoperandoperand(CmpCqR, getScavengeThreshold(), TempReg); - /* begin JumpBelow: */ - skip = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceScheduleScavengeTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperandoperand(MoveRMwr, ClassReg, (ClosureOuterContextIndex * BytesPerOop) + BaseHeaderSize, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)bcpc << 1) | 1); - anInstruction9 = genoperandoperand(MoveCqR, (((usqInt)bcpc << 1) | 1), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveRMwr, TempReg, (ClosureStartPCIndex * BytesPerOop) + BaseHeaderSize, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)numArgs << 1) | 1); - anInstruction11 = genoperandoperand(MoveCqR, (((usqInt)numArgs << 1) | 1), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveRMwr, TempReg, (ClosureNumArgsIndex * BytesPerOop) + BaseHeaderSize, ReceiverResultReg); - return 0; -} - - /* CogObjectRepresentationForSpur>>#genPrimitiveAsCharacter */ -static sqInt -genPrimitiveAsCharacter(void) -{ - AbstractInstruction *jumpNotInt; - AbstractInstruction *jumpOutOfRange; - sqInt reg; - - jumpNotInt = ((AbstractInstruction *) 0); - if (methodOrBlockNumArgs == 0) { - reg = ReceiverResultReg; - } - else { - if (methodOrBlockNumArgs > 1) { - return UnimplementedPrimitive; - } - reg = Arg0Reg; - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotInt = genJumpNotSmallInteger(reg); - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - jumpOutOfRange = jumpNotCharacterUnsignedValueInRegister(TempReg); - genConvertSmallIntegerToCharacterInReg(reg); - if (reg != ReceiverResultReg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, reg, ReceiverResultReg); - } - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpOutOfRange, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (reg != ReceiverResultReg) { - jmpTarget(jumpNotInt, ((AbstractInstruction *) (((jumpOutOfRange->operands))[0]))); - } - return CompletePrimitive; -} - - -/* Generate primitive 60, at: with unsigned access for pure bits classes. */ - - /* CogObjectRepresentationForSpur>>#genPrimitiveAt */ -static sqInt -genPrimitiveAt(void) -{ - return genPrimitiveAtSigned(0); -} - - /* CogObjectRepresentationForSpur>>#genPrimitiveIdenticalOrNotIf: */ -static sqInt NoDbgRegParms -genPrimitiveIdenticalOrNotIf(sqInt orNot) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *comp; - sqInt constant; - sqInt constant1; - AbstractInstruction *jumpCmp; - - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - comp = genoperandoperand(CmpRR, Arg0Reg, ReceiverResultReg); - if (orNot) { - /* begin JumpZero: */ - jumpCmp = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin genEnsureOopInRegNotForwarded:scratchReg:jumpBackTo: */ - genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(Arg0Reg, TempReg, comp, 0); - } - else { - /* begin JumpNonZero: */ - jumpCmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - } - /* begin genMoveConstant:R: */ - constant = trueObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpCmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (!orNot) { - /* begin genEnsureOopInRegNotForwarded:scratchReg:jumpBackTo: */ - genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(Arg0Reg, TempReg, comp, 0); - } - /* begin genMoveConstant:R: */ - constant1 = falseObject(); - if (shouldAnnotateObjectReference(constant1)) { - annotateobjRef(checkLiteralforInstruction(constant1, genoperandoperand(MoveCwR, constant1, ReceiverResultReg)), constant1); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, constant1, ReceiverResultReg); - } - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - return UnfailingPrimitive; -} - - -/* Generate primitive 164, at: with signed access for pure bits classes. */ - - /* CogObjectRepresentationForSpur>>#genPrimitiveIntegerAt */ -static sqInt -genPrimitiveIntegerAt(void) -{ - return genPrimitiveAtSigned(1); -} - - -/* Generate primitive 165, at:put: with signed access for pure bits classes. */ - - /* CogObjectRepresentationForSpur>>#genPrimitiveIntegerAtPut */ -static sqInt -genPrimitiveIntegerAtPut(void) -{ - return genPrimitiveAtPutSigned(1); -} - - /* CogObjectRepresentationForSpur>>#genPrimitiveObjectAt */ -static sqInt -genPrimitiveObjectAt(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - sqInt headerReg; - AbstractInstruction *jumpBadIndex; - AbstractInstruction *jumpBounds; - AbstractInstruction *jumpNotHeaderIndex; - sqInt quickConstant; - - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpBadIndex = genJumpNotSmallInteger(Arg0Reg); - genGetMethodHeaderOfintoscratch(ReceiverResultReg, (headerReg = Arg1Reg), TempReg); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)1 << 1) | 1); - anInstruction = genoperandoperand(CmpCqR, (((usqInt)1 << 1) | 1), Arg0Reg); - /* begin JumpNonZero: */ - jumpNotHeaderIndex = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, headerReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotHeaderIndex, gAndCqR((((usqInt)(alternateHeaderNumLiteralsMask()) << 1) | 1), headerReg)); - /* begin SubCq:R: */ - quickConstant = ((((usqInt)1 << 1) | 1)) - (smallIntegerTag()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(SubCqR, quickConstant, Arg0Reg); - /* begin CmpR:R: */ - assert(!((headerReg == SPReg))); - genoperandoperand(CmpRR, headerReg, Arg0Reg); - /* begin JumpAbove: */ - jumpBounds = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - genConvertSmallIntegerToIntegerInReg(Arg0Reg); - /* begin AddCq:R: */ - anInstruction2 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg0Reg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, Arg0Reg, ReceiverResultReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpBounds, gAddCqR(((((usqInt)1 << 1) | 1)) - (smallIntegerTag()), Arg0Reg)); - jmpTarget(jumpBadIndex, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - -/* c.f. StackInterpreter>>stSizeOf: lengthOf:baseHeader:format: - fixedFieldsOf:format:length: - */ - - /* CogObjectRepresentationForSpur>>#genPrimitiveSize */ -static sqInt -genPrimitiveSize(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - AbstractInstruction * jump32BitLongsDone; - AbstractInstruction * jump64BitLongsDone; - AbstractInstruction * jumpArrayDone; - AbstractInstruction * jumpBytesDone; - AbstractInstruction * jumpHasFixedFields; - AbstractInstruction *jumpImm; - AbstractInstruction * jumpIs64BitLongs; - AbstractInstruction * jumpIsBytes; - AbstractInstruction *jumpIsContext; - AbstractInstruction * jumpIsContext1; - AbstractInstruction * jumpIsShorts; - AbstractInstruction *jumpNotIndexable; - AbstractInstruction * jumpNotIndexable1; - AbstractInstruction * jumpShortsDone; - - jumpImm = genJumpImmediate(ReceiverResultReg); - /* begin genGetSizeOf:into:formatReg:scratchReg:abortJumpsInto: */ - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, SendNumArgsReg, TempReg); - genGetNumSlotsOfinto(ReceiverResultReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction = genoperandoperand(CmpCqR, firstByteFormat(), SendNumArgsReg); - /* begin JumpGreaterOrEqual: */ - jumpIsBytes = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction1 = genoperandoperand(CmpCqR, arrayFormat(), SendNumArgsReg); - /* begin JumpZero: */ - jumpArrayDone = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin JumpLess: */ - jumpNotIndexable1 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - weakArrayFormat(); - anInstruction2 = genoperandoperand(CmpCqR, weakArrayFormat(), SendNumArgsReg); - /* begin JumpLessOrEqual: */ - jumpHasFixedFields = genConditionalBranchoperand(JumpLessOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstShortFormat(); - anInstruction3 = genoperandoperand(CmpCqR, firstShortFormat(), SendNumArgsReg); - /* begin JumpGreaterOrEqual: */ - jumpIsShorts = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction4 = genoperandoperand(CmpCqR, firstLongFormat(), SendNumArgsReg); - /* begin JumpGreaterOrEqual: */ - jump32BitLongsDone = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - sixtyFourBitIndexableFormat(); - anInstruction5 = genoperandoperand(CmpCqR, sixtyFourBitIndexableFormat(), SendNumArgsReg); - /* begin JumpZero: */ - jumpIs64BitLongs = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - jmpTarget(jumpNotIndexable1, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin Jump: */ - jumpNotIndexable1 = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpIsBytes, genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), ClassReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(AndCqR, BytesPerWord - 1, SendNumArgsReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, SendNumArgsReg, ClassReg); - /* begin Jump: */ - jumpBytesDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpIsShorts, gLogicalShiftLeftCqR((shiftForWord()) - 1, ClassReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(AndCqR, 1, SendNumArgsReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, SendNumArgsReg, ClassReg); - /* begin Jump: */ - jumpShortsDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpIs64BitLongs, genoperandoperand(LogicalShiftRightCqR, 1, ClassReg)); - /* begin Jump: */ - jump64BitLongsDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpHasFixedFields, checkQuickConstantforInstruction(classIndexMask(), genoperandoperand(AndCqR, classIndexMask(), TempReg))); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, SendNumArgsReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, TempReg); - /* begin JumpZero: */ - jumpIsContext1 = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin PushR: */ - genoperand(PushR, ClassReg); - genGetClassObjectOfClassIndexintoscratchReg(SendNumArgsReg, ClassReg, TempReg); - genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, ClassReg, SendNumArgsReg); - genConvertSmallIntegerToIntegerInReg(SendNumArgsReg); - /* begin PopR: */ - genoperand(PopR, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - fixedFieldsOfClassFormatMask(); - anInstruction9 = genoperandoperand(AndCqR, fixedFieldsOfClassFormatMask(), SendNumArgsReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, SendNumArgsReg, ClassReg); - jmpTarget(jumpArrayDone, jmpTarget(jump64BitLongsDone, jmpTarget(jump32BitLongsDone, jmpTarget(jumpShortsDone, jmpTarget(jumpBytesDone, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))))); - jumpNotIndexable = jumpNotIndexable1; - jumpIsContext = jumpIsContext1; - genConvertIntegerInRegtoSmallIntegerInReg(ClassReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpImm, jmpTarget(jumpNotIndexable, jmpTarget(jumpIsContext, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))); - return CompletePrimitive; -} - - /* CogObjectRepresentationForSpur>>#genSetSmallIntegerTagsIn: */ -static sqInt NoDbgRegParms -genSetSmallIntegerTagsIn(sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(OrCqR, 1, scratchReg); - return 0; -} - - -/* Create a trampoline to store-check the update of the receiver in a - closure's outerContext in compileBlockFrameBuild:. */ - - /* CogObjectRepresentationForSpur>>#genStoreCheckContextReceiverTrampoline */ -static usqInt -genStoreCheckContextReceiverTrampoline(void) -{ - usqInt startAddress; - - startAddress = methodZoneBase(); - zeroOpcodeIndex(); - genStoreCheckReceiverRegvalueRegscratchReginFrame(ReceiverResultReg, Arg0Reg, TempReg, 0); - /* begin RetN: */ - genoperand(RetN, 0); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress("ceStoreCheckContextReceiver", startAddress); - recordRunTimeObjectReferences(); - return startAddress; -} - - -/* Generate the code for a store check of valueReg into destReg. */ - - /* CogObjectRepresentationForSpur>>#genStoreCheckReceiverReg:valueReg:scratchReg:inFrame: */ -static sqInt NoDbgRegParms -genStoreCheckReceiverRegvalueRegscratchReginFrame(sqInt destReg, sqInt valueReg, sqInt scratchReg, sqInt inFrame) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction * inst; - AbstractInstruction *jmpAlreadyRemembered; - AbstractInstruction *jmpDestYoung; - AbstractInstruction *jmpImmediate; - AbstractInstruction *jmpSourceOld; - - - /* Is value stored an immediate? If so we're done */ - jmpAlreadyRemembered = ((AbstractInstruction *) 0); - - /* Get the old/new boundary in scratchReg */ - jmpImmediate = genJumpImmediate(valueReg); - /* begin checkLiteral:forInstruction: */ - storeCheckBoundary(); - anInstruction = genoperandoperand(MoveCwR, storeCheckBoundary(), scratchReg); - /* begin CmpR:R: */ - assert(!((scratchReg == SPReg))); - genoperandoperand(CmpRR, scratchReg, destReg); - /* begin JumpBelow: */ - jmpDestYoung = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((scratchReg == SPReg))); - genoperandoperand(CmpRR, scratchReg, valueReg); - /* begin JumpAboveOrEqual: */ - jmpSourceOld = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - if (!CheckRememberedInTrampoline) { - jmpAlreadyRemembered = genCheckRememberedBitOfscratch(destReg, scratchReg); - } - assert(destReg == ReceiverResultReg); - /* begin evaluateTrampolineCallBlock:protectLinkRegIfNot: */ - if (inFrame) { - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceStoreCheckTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - } - else { - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceStoreCheckTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin PopR: */ - genoperand(PopR, LinkReg); - } - jmpTarget(jmpImmediate, jmpTarget(jmpDestYoung, jmpTarget(jmpSourceOld, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))); - if (!CheckRememberedInTrampoline) { - jmpTarget(jmpAlreadyRemembered, ((AbstractInstruction *) (((jmpSourceOld->operands))[0]))); - } - return 0; -} - - /* CogObjectRepresentationForSpur>>#genStoreSourceReg:slotIndex:destReg:scratchReg:inFrame:needsStoreCheck: */ -static sqInt NoDbgRegParms -genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt inFrame, sqInt needsStoreCheck) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - - /* begin genTraceStores */ - if (traceStores > 0) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, TempReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceTraceStoreTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveRMwr, sourceReg, (index * BytesPerWord) + BaseHeaderSize, destReg); - if (needsStoreCheck) { - return genStoreCheckReceiverRegvalueRegscratchReginFrame(destReg, sourceReg, scratchReg, inFrame); - } - return 0; -} - - -/* This method is used for unchecked stores in objects after their creation - (typically, inlined creation of Array, closures and some temp vectors). - Currently there is no need to do the immutability check here - */ - - /* CogObjectRepresentationForSpur>>#genStoreSourceReg:slotIndex:intoNewObjectInDestReg: */ -static sqInt NoDbgRegParms -genStoreSourceRegslotIndexintoNewObjectInDestReg(sqInt sourceReg, sqInt index, sqInt destReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveRMwr, sourceReg, (index * BytesPerWord) + BaseHeaderSize, destReg); - return 0; -} - - -/* Convention: - - RcvrResultReg holds the object mutated. - If immutability failure: - - TempReg holds the instance variable index mutated - if instVarIndex > numDedicatedStoreTrampoline - - ClassReg holds the value to store - Registers are not lived across this trampoline as the - immutability failure may need new stack frames. */ - - /* CogObjectRepresentationForSpur>>#genStoreTrampolineCalled:instVarIndex: */ -#if IMMUTABILITY -static usqInt NoDbgRegParms -genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) -{ - AbstractInstruction * jumpImmutable; - AbstractInstruction * jumpImmutable1; - AbstractInstruction * jumpRC; - sqInt pushLinkReg; - usqInt startAddress; - - startAddress = methodZoneBase(); - zeroOpcodeIndex(); - if (CheckRememberedInTrampoline) { - /* begin genStoreTrampolineCheckingRememberedCalled:instVarIndex: */ - - /* Store check */ - /* If on 64-bits and doing the remembered bit test here, we can combine the tests to fetch the header once. */ - jumpImmutable = genJumpImmutablescratchReg(ReceiverResultReg, SendNumArgsReg); - jumpRC = genCheckRememberedBitOfscratch(ReceiverResultReg, SendNumArgsReg); - assert(((jumpRC->opcode)) == JumpNonZero); - (jumpRC->opcode = JumpZero); - /* begin RetN: */ - genoperand(RetN, 0); - jmpTarget(jumpRC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) - ? ReceiverResultReg - : ABIResultReg)); - jmpTarget(jumpImmutable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(ceCannotAssignTowithIndexvalueToAssign, 3, ReceiverResultReg, (instVarIndex < (NumStoreTrampolines - 1) - ? (/* begin trampolineArgConstant: */ - assert(instVarIndex >= 0), - -2 - instVarIndex) - : TempReg), ClassReg, null, 0 /* emptyRegisterMask */, 1, NoReg); - } - else { - /* begin genStoreTrampolineNotCheckingRememberedCalled:instVarIndex: */ - genSmalltalkToCStackSwitch((pushLinkReg = 1)); - - /* Store check */ - jumpImmutable1 = genJumpImmutablescratchReg(ReceiverResultReg, SendNumArgsReg); - compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) - ? ReceiverResultReg - : ABIResultReg), 0 /* emptyRegisterMask */); - genLoadStackPointers(backEnd()); - genTrampolineReturn(pushLinkReg); - jmpTarget(jumpImmutable1, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileCallFornumArgsargargargargresultRegregsToSave(ceCannotAssignTowithIndexvalueToAssign, 3, ReceiverResultReg, (instVarIndex < (NumStoreTrampolines - 1) - ? (/* begin trampolineArgConstant: */ - assert(instVarIndex >= 0), - -2 - instVarIndex) - : TempReg), ClassReg, null, NoReg, 0 /* emptyRegisterMask */); - genLoadStackPointers(backEnd()); - genTrampolineReturn(pushLinkReg); - } - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress(trampolineName, startAddress); - recordRunTimeObjectReferences(); - return startAddress; -} -#endif /* IMMUTABILITY */ - - -/* Store check code is duplicated to use a single trampoline */ - - /* CogObjectRepresentationForSpur>>#genStoreWithImmutabilityAndStoreCheckSourceReg:slotIndex:destReg:scratchReg:needRestoreRcvr: */ -#if IMMUTABILITY -static sqInt NoDbgRegParms -genStoreWithImmutabilityAndStoreCheckSourceRegslotIndexdestRegscratchRegneedRestoreRcvr(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt needRestoreRcvr) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *abstractInstruction2; - AbstractInstruction *abstractInstruction3; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *immutableJump; - AbstractInstruction *jmpAlreadyRemembered; - AbstractInstruction *jmpDestYoung; - AbstractInstruction *jmpImmediate; - AbstractInstruction *jmpSourceOld; - - jmpAlreadyRemembered = ((AbstractInstruction *) 0); - immutableJump = genJumpImmutablescratchReg(destReg, scratchReg); - /* begin genTraceStores */ - if (traceStores > 0) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, TempReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceTraceStoreTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveRMwr, sourceReg, (index * BytesPerWord) + BaseHeaderSize, destReg); - - /* Get the old/new boundary in scratchReg */ - jmpImmediate = genJumpImmediate(sourceReg); - /* begin checkLiteral:forInstruction: */ - storeCheckBoundary(); - anInstruction1 = genoperandoperand(MoveCwR, storeCheckBoundary(), scratchReg); - /* begin CmpR:R: */ - assert(!((scratchReg == SPReg))); - genoperandoperand(CmpRR, scratchReg, destReg); - /* begin JumpBelow: */ - jmpDestYoung = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((scratchReg == SPReg))); - genoperandoperand(CmpRR, scratchReg, sourceReg); - /* begin JumpAboveOrEqual: */ - jmpSourceOld = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - if (!CheckRememberedInTrampoline) { - jmpAlreadyRemembered = genCheckRememberedBitOfscratch(destReg, scratchReg); - } - jmpTarget(immutableJump, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin genStoreTrampolineCall: */ - assert(IMMUTABILITY); - if (index >= (NumStoreTrampolines - 1)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, index, TempReg); - /* begin CallRT: */ - abstractInstruction3 = genoperand(Call, ceStoreTrampolines[NumStoreTrampolines - 1]); - (abstractInstruction3->annotation = IsRelativeCall); - } - else { - /* begin CallRT: */ - abstractInstruction1 = genoperand(Call, ceStoreTrampolines[index]); - (abstractInstruction1->annotation = IsRelativeCall); - } - /* begin annotateBytecode: */ - abstractInstruction2 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction2->annotation = HasBytecodePC); - /* begin voidReceiverOptStatus */ - ((simSelf())->liveRegister = NoReg); - if (needRestoreRcvr) { - /* begin putSelfInReceiverResultReg */ - storeToReg(simSelf(), ReceiverResultReg); - } - jmpTarget(jmpImmediate, jmpTarget(jmpDestYoung, jmpTarget(jmpSourceOld, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))); - if (!CheckRememberedInTrampoline) { - jmpTarget(jmpAlreadyRemembered, ((AbstractInstruction *) (((jmpSourceOld->operands))[0]))); - } - return 0; -} -#endif /* IMMUTABILITY */ - - -/* Gen an immutability check with no store check (e.g. assigning an immediate - literal) - */ -/* imm check has its own trampoline */ - - /* CogObjectRepresentationForSpur>>#genStoreWithImmutabilityButNoStoreCheckSourceReg:slotIndex:destReg:scratchReg:needRestoreRcvr: */ -#if IMMUTABILITY -static sqInt NoDbgRegParms -genStoreWithImmutabilityButNoStoreCheckSourceRegslotIndexdestRegscratchRegneedRestoreRcvr(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt needRestoreRcvr) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *abstractInstruction2; - AbstractInstruction *abstractInstruction3; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *immutabilityFailure; - AbstractInstruction *mutableJump; - - mutableJump = genJumpMutablescratchReg(destReg, scratchReg); - /* begin genStoreTrampolineCall: */ - assert(IMMUTABILITY); - if (index >= (NumStoreTrampolines - 1)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, index, TempReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceStoreTrampolines[NumStoreTrampolines - 1]); - (abstractInstruction->annotation = IsRelativeCall); - } - else { - /* begin CallRT: */ - abstractInstruction1 = genoperand(Call, ceStoreTrampolines[index]); - (abstractInstruction1->annotation = IsRelativeCall); - } - /* begin annotateBytecode: */ - abstractInstruction2 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction2->annotation = HasBytecodePC); - /* begin voidReceiverOptStatus */ - ((simSelf())->liveRegister = NoReg); - if (needRestoreRcvr) { - /* begin putSelfInReceiverResultReg */ - storeToReg(simSelf(), ReceiverResultReg); - } - /* begin Jump: */ - immutabilityFailure = genoperand(Jump, ((sqInt)0)); - jmpTarget(mutableJump, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin genTraceStores */ - if (traceStores > 0) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, TempReg); - /* begin CallRT: */ - abstractInstruction3 = genoperand(Call, ceTraceStoreTrampoline); - (abstractInstruction3->annotation = IsRelativeCall); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveRMwr, sourceReg, (index * BytesPerWord) + BaseHeaderSize, destReg); - jmpTarget(immutabilityFailure, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} -#endif /* IMMUTABILITY */ - - -/* We know there is a frame as immutability check requires a frame */ -/* needRestoreRcvr has to be true to keep RcvrResultReg live with the - receiver in it across the trampoline - */ -/* Trampoline convention... */ - - /* CogObjectRepresentationForSpur>>#genStoreWithImmutabilityCheckSourceReg:slotIndex:destReg:scratchReg:needsStoreCheck:needRestoreRcvr: */ -#if IMMUTABILITY -static sqInt NoDbgRegParms -genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt needsStoreCheck, sqInt needRestoreRcvr) -{ - assert(destReg == ReceiverResultReg); - assert(scratchReg == TempReg); - assert(sourceReg == ClassReg); - if (needsStoreCheck) { - genStoreWithImmutabilityAndStoreCheckSourceRegslotIndexdestRegscratchRegneedRestoreRcvr(sourceReg, index, destReg, scratchReg, needRestoreRcvr); - } - else { - genStoreWithImmutabilityButNoStoreCheckSourceRegslotIndexdestRegscratchRegneedRestoreRcvr(sourceReg, index, destReg, scratchReg, needRestoreRcvr); - } - return 0; -} -#endif /* IMMUTABILITY */ - - -/* Make sure SendNumArgsReg and ClassReg are available in addition to - ReceiverResultReg and TempReg in - genGetActiveContextNumArgs:large:inBlock:. - */ - - /* CogObjectRepresentationForSpur>>#getActiveContextAllocatesInMachineCode */ -static sqInt -getActiveContextAllocatesInMachineCode(void) -{ - return 1; -} - - -/* Since all cache tags in Spur are class indices none of - them are young or have to be updated in a scavenge. */ - - /* CogObjectRepresentationForSpur>>#inlineCacheTagIsYoung: */ -static sqInt NoDbgRegParms -inlineCacheTagIsYoung(sqInt cacheTag) -{ - return 0; -} - - /* CogObjectRepresentationForSpur>>#jumpNotCharacterUnsignedValueInRegister: */ -static AbstractInstruction * NoDbgRegParms -jumpNotCharacterUnsignedValueInRegister(sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin CmpCq:R: */ - anInstruction = genoperandoperand(CmpCqR, 0x3FFFFFFF, reg); - /* begin JumpAbove: */ - return genConditionalBranchoperand(JumpAbove, ((sqInt)0)); -} - - -/* Mark and trace a literal in a machine code instruction preceding address - in cogMethodOrNil. - Answer if code was modified. */ - - /* CogObjectRepresentationForSpur>>#markAndTraceLiteral:in:atpc: */ -static sqInt NoDbgRegParms -markAndTraceLiteralinatpc(sqInt literal, CogMethod *cogMethodOrNil, usqInt address) -{ - sqInt objOop; - - if (!(couldBeObject(literal))) { - return 0; - } - assert(addressCouldBeObj(literal)); - if (!(isForwarded(literal))) { - markAndTrace(literal); - return 0; - } - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - objOop = followForwarded(literal); - storeLiteralbeforeFollowingAddress(backEnd(), objOop, address); - markAndTraceUpdatedLiteralin(objOop, cogMethodOrNil); - return 1; -} - - -/* Mark and trace a literal in a sqInt variable of cogMethod. */ - - /* CogObjectRepresentationForSpur>>#markAndTraceLiteral:in:at: */ -static void NoDbgRegParms -markAndTraceLiteralinat(sqInt literal, CogMethod *cogMethod, sqInt *address) -{ - sqInt objOop; - - if (!(couldBeObject(literal))) { - return; - } - assert(addressCouldBeObj(literal)); - if (!(isForwarded(literal))) { - markAndTrace(literal); - return; - } - objOop = followForwarded(literal); - address[0] = objOop; - markAndTraceUpdatedLiteralin(objOop, cogMethod); -} - - -/* Common code to mark a literal in cogMethod and add - the cogMethod to youngReferrers if the literal is young. */ - - /* CogObjectRepresentationForSpur>>#markAndTraceUpdatedLiteral:in: */ -static void NoDbgRegParms -markAndTraceUpdatedLiteralin(sqInt objOop, CogMethod *cogMethodOrNil) -{ - if (isNonImmediate(objOop)) { - if ((cogMethodOrNil != null) - && (isYoungObject(objOop))) { - ensureInYoungReferrers(cogMethodOrNil); - } - markAndTrace(objOop); - } -} - - -/* If primIndex has an accessorDepth and fails, or it is external and fails - with PrimErrNoMemory, - call ceCheckAndMaybeRetryPrimitive if so If ceCheck.... answers true, - retry the primitive. */ - - /* CogObjectRepresentationForSpur>>#maybeCompileRetryOnPrimitiveFail: */ -static sqInt NoDbgRegParms -maybeCompileRetryOnPrimitiveFail(sqInt primIndex) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *jmp; - - if ((accessorDepthForPrimitiveIndex(primIndex)) >= 0) { - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpZero: */ - jmp = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - } - else { - if ((primNumberExternalCall()) != primIndex) { - return 0; - } - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction2 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(CmpCqR, PrimErrNoMemory, TempReg); - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - } - compileCallFornumArgsargargargargresultRegregsToSave(ceCheckAndMaybeRetryPrimitive, 1, trampolineArgConstant(primIndex), null, null, null, TempReg, 0 /* emptyRegisterMask */); - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - -/* Generate a shift of the register containing the class tag in a method - cache probe. - c.f. SpurMemoryManager>>methodCacheHashOf:with: */ - - /* CogObjectRepresentationForSpur>>#maybeShiftClassTagRegisterForMethodCacheProbe: */ -static sqInt NoDbgRegParms -maybeShiftClassTagRegisterForMethodCacheProbe(sqInt classTagReg) -{ - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, 2, classTagReg); - return 0; -} - - /* CogObjectRepresentationForSpur>>#numCharacterBits */ -static sqInt -numCharacterBits(void) -{ - return 30; -} - - -/* Define how many register arguments a StackToRegisterMappingCogit can - and should use with the receiver. The value must be 0, 1 or 2. Note that a - SimpleStackBasedCogit always has 0 register args (although the receiver is - passed in a register). The Spur object representation is simple enough - that implementing at:put: is straight-forward and hence 2 register args - are worth - while. The method must be inlined in CoInterpreter, and dead code - eliminated so that the register-popping enilopmarts such as - enterRegisterArgCogMethod:- at:receiver: do not have to be implemented in - SimpleStackBasedCogit. */ - - /* CogObjectRepresentationForSpur>>#numRegArgs */ -sqInt -numRegArgs(void) -{ - return 2; -} - - /* CogObjectRepresentationForSpur>>#remapObject: */ -static sqInt NoDbgRegParms -remapObject(sqInt objOop) -{ - assert(addressCouldBeObj(objOop)); - return (shouldRemapObj(objOop) - ? remapObj(objOop) - : objOop); -} - - /* CogObjectRepresentationForSpur>>#remapOop: */ -static sqInt NoDbgRegParms -remapOop(sqInt objOop) -{ - return (shouldRemapOop(objOop) - ? remapObj(objOop) - : objOop); -} - - -/* Objects in newSpace or oldSpace except nil, true, false & - classTableRootObj need to be annotated. - */ - - /* CogObjectRepresentationForSpur>>#shouldAnnotateObjectReference: */ -static sqInt NoDbgRegParms -shouldAnnotateObjectReference(sqInt anOop) -{ - return (isNonImmediate(anOop)) - && ((oopisGreaterThan(anOop, classTableRootObj())) - || (oopisLessThan(anOop, nilObject()))); -} - - /* CogObjectRepresentationForSpur>>#slotOffsetOfInstVarIndex: */ -static sqInt NoDbgRegParms -slotOffsetOfInstVarIndex(sqInt index) -{ - return (index * BytesPerWord) + BaseHeaderSize; -} - - /* CogSimStackEntry>>#ensureSpilledAt:from: */ -static SimStackEntry * NoDbgRegParms -ensureSpilledAtfrom(SimStackEntry * self_in_ensureSpilledAtfrom, sqInt baseOffset, sqInt baseRegister) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *inst; - sqInt reg; - sqInt wordConstant; - - if ((self_in_ensureSpilledAtfrom->spilled)) { - if (((self_in_ensureSpilledAtfrom->type)) == SSSpill) { - assert(((((self_in_ensureSpilledAtfrom->offset)) == baseOffset) - && (((self_in_ensureSpilledAtfrom->registerr)) == baseRegister)) - || (violatesEnsureSpilledSpillAssert())); - return self_in_ensureSpilledAtfrom; - } - } - assert(((self_in_ensureSpilledAtfrom->type)) != SSSpill); - traceSpill(self_in_ensureSpilledAtfrom); - if (((self_in_ensureSpilledAtfrom->type)) == SSConstant) { - if (shouldAnnotateObjectReference((self_in_ensureSpilledAtfrom->constant))) { - inst = annotateobjRef(gPushCw((self_in_ensureSpilledAtfrom->constant)), (self_in_ensureSpilledAtfrom->constant)); - } - else { - /* begin PushCq: */ - wordConstant = (self_in_ensureSpilledAtfrom->constant); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperand(PushCq, wordConstant); - inst = anInstruction; - } - } - else { - if (((self_in_ensureSpilledAtfrom->type)) == SSBaseOffset) { - /* begin checkQuickConstant:forInstruction: */ - (self_in_ensureSpilledAtfrom->offset); - anInstruction1 = genoperandoperandoperand(MoveMwrR, (self_in_ensureSpilledAtfrom->offset), (self_in_ensureSpilledAtfrom->registerr), TempReg); - /* begin PushR: */ - inst = genoperand(PushR, TempReg); - } - else { - assert(((self_in_ensureSpilledAtfrom->type)) == SSRegister); - /* begin PushR: */ - reg = (self_in_ensureSpilledAtfrom->registerr); - inst = genoperand(PushR, reg); - } - (self_in_ensureSpilledAtfrom->type) = SSSpill; - (self_in_ensureSpilledAtfrom->offset) = baseOffset; - (self_in_ensureSpilledAtfrom->registerr) = baseRegister; - } - (self_in_ensureSpilledAtfrom->spilled) = 1; - return 0; -} - - /* CogSimStackEntry>>#isSameEntryAs: */ -static sqInt NoDbgRegParms -isSameEntryAs(SimStackEntry * self_in_isSameEntryAs, CogSimStackEntry *ssEntry) -{ - return (((self_in_isSameEntryAs->type)) == ((ssEntry->type))) - && ((((((self_in_isSameEntryAs->type)) == SSBaseOffset) - || (((self_in_isSameEntryAs->type)) == SSSpill)) - && ((((self_in_isSameEntryAs->offset)) == ((ssEntry->offset))) - && (((self_in_isSameEntryAs->registerr)) == ((ssEntry->registerr))))) - || (((((self_in_isSameEntryAs->type)) == SSRegister) - && (((self_in_isSameEntryAs->registerr)) == ((ssEntry->registerr)))) - || ((((self_in_isSameEntryAs->type)) == SSConstant) - && (((self_in_isSameEntryAs->constant)) == ((ssEntry->constant)))))); -} - - -/* Receiver is not a forwarder, except in blocks with no inst var access. - For now we optimize only the case where receiver is accessed in a method. */ - - /* CogSimStackEntry>>#mayBeAForwarder */ -static sqInt NoDbgRegParms -mayBeAForwarder(SimStackEntry * self_in_mayBeAForwarder) -{ - if ((((self_in_mayBeAForwarder->type)) == SSRegister) - && (isNonForwarderReceiver((self_in_mayBeAForwarder->registerr)))) { - return 0; - } - return ((self_in_mayBeAForwarder->type)) != SSConstant; -} - - /* CogSimStackEntry>>#popToReg: */ -static void NoDbgRegParms -popToReg(SimStackEntry * self_in_popToReg, sqInt reg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt quickConstant; - sqInt reg1; - - if ((self_in_popToReg->spilled)) { - /* begin PopR: */ - genoperand(PopR, reg); - } - else { - switch ((self_in_popToReg->type)) { - case SSBaseOffset: - /* begin checkQuickConstant:forInstruction: */ - (self_in_popToReg->offset); - anInstruction = genoperandoperandoperand(MoveMwrR, (self_in_popToReg->offset), (self_in_popToReg->registerr), reg); - break; - case SSConstant: - if (shouldAnnotateObjectReference((self_in_popToReg->constant))) { - annotateobjRef(gMoveCwR((self_in_popToReg->constant), reg), (self_in_popToReg->constant)); - } - else { - /* begin MoveCq:R: */ - quickConstant = (self_in_popToReg->constant); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, quickConstant, reg); - } - break; - case SSRegister: - if (reg != ((self_in_popToReg->registerr))) { - /* begin MoveR:R: */ - reg1 = (self_in_popToReg->registerr); - genoperandoperand(MoveRR, reg1, reg); - } - else { - /* begin Label */ - genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - break; - default: - error("Case not found and no otherwise clause"); - } - } -} - - -/* Answer a bit mask for the receiver's register, if any. */ - - /* CogSimStackEntry>>#registerMask */ -static sqInt NoDbgRegParms -registerMask(SimStackEntry * self_in_registerMask) -{ - sqInt reg; - - return ((((self_in_registerMask->type)) == SSBaseOffset) - || (((self_in_registerMask->type)) == SSRegister) - ? (/* begin registerMaskFor: */ - (reg = (self_in_registerMask->registerr)), - 1U << reg) - : 0); -} - - /* CogSimStackEntry>>#registerMaskOrNone */ -static sqInt NoDbgRegParms -registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone) -{ - sqInt reg; - - return (((self_in_registerMaskOrNone->type)) == SSRegister - ? (/* begin registerMaskFor: */ - (reg = (self_in_registerMaskOrNone->registerr)), - 1U << reg) - : 0); -} - - /* CogSimStackEntry>>#registerOrNone */ -static sqInt NoDbgRegParms -registerOrNone(SimStackEntry * self_in_registerOrNone) -{ - return (((self_in_registerOrNone->type)) == SSRegister - ? (self_in_registerOrNone->registerr) - : NoReg); -} - - /* CogSimStackEntry>>#storeToReg: */ -static void NoDbgRegParms -storeToReg(SimStackEntry * self_in_storeToReg, sqInt reg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt quickConstant; - sqInt reg1; - - switch ((self_in_storeToReg->type)) { - case SSBaseOffset: - case SSSpill: - /* begin checkQuickConstant:forInstruction: */ - (self_in_storeToReg->offset); - anInstruction = genoperandoperandoperand(MoveMwrR, (self_in_storeToReg->offset), (self_in_storeToReg->registerr), reg); - break; - case SSConstant: - if (shouldAnnotateObjectReference((self_in_storeToReg->constant))) { - annotateobjRef(gMoveCwR((self_in_storeToReg->constant), reg), (self_in_storeToReg->constant)); - } - else { - /* begin MoveCq:R: */ - quickConstant = (self_in_storeToReg->constant); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, quickConstant, reg); - } - break; - case SSRegister: - if (reg != ((self_in_storeToReg->registerr))) { - /* begin MoveR:R: */ - reg1 = (self_in_storeToReg->registerr); - genoperandoperand(MoveRR, reg1, reg); - } - else { - /* begin Label */ - genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - break; - default: - error("Case not found and no otherwise clause"); - } -} - - /* CogSSBytecodeFixup>>#isMergeFixup */ -static sqInt NoDbgRegParms -isMergeFixup(BytecodeFixup * self_in_isMergeFixup) -{ - return (((usqInt)((self_in_isMergeFixup->targetInstruction)))) == NeedsMergeFixupFlag; -} - - /* InLineLiteralsManager>>#checkLiteral:forInstruction: */ -static AbstractInstruction * NoDbgRegParms -checkLiteralforInstruction(sqInt literal, AbstractInstruction *anInstruction) -{ - return anInstruction; -} - - /* InLineLiteralsManager>>#checkQuickConstant:forInstruction: */ -static AbstractInstruction * NoDbgRegParms -checkQuickConstantforInstruction(sqInt literal, AbstractInstruction *anInstruction) -{ - return anInstruction; -} - - /* SimpleStackBasedCogit>>#cogMethodHasExternalPrim: */ -sqInt -cogMethodHasExternalPrim(CogMethod *aCogMethod) -{ - sqInt primIndex; - - primIndex = primitiveIndexOfMethodheader((aCogMethod->methodObject), (aCogMethod->methodHeader)); - return (primIndex == PrimNumberExternalCall) - || (primIndex == PrimNumberFFICall); -} - - /* SimpleStackBasedCogit>>#cogMethodHasMachineCodePrim: */ -sqInt -cogMethodHasMachineCodePrim(CogMethod *aCogMethod) -{ - sqInt primIndex; - - primIndex = primitiveIndexOfMethodheader((aCogMethod->methodObject), (aCogMethod->objectHeader)); - return (((primIndex >= 1) && (primIndex <= MaxCompiledPrimitiveIndex))) - && ((((primitiveGeneratorTable[primIndex]).primitiveGenerator)) != null); -} - - -/* Compile the jump instruction(s) at the end of the method that dispatch to - each block body. - */ - - /* SimpleStackBasedCogit>>#compileBlockDispatch */ -static sqInt -compileBlockDispatch(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *jumpSkip; - - assert(blockCount > 0); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 0, SendNumArgsReg); - blockEntryNoContextSwitch = anInstruction; - /* begin Jump: */ - jumpSkip = genoperand(Jump, ((sqInt)0)); - /* begin MoveR:R: */ - blockEntryLabel = genoperandoperand(MoveRR, ReceiverResultReg, SendNumArgsReg); - jmpTarget(jumpSkip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (blockCount > 1) { - genLoadSlotsourceRegdestReg(ClosureStartPCIndex, ReceiverResultReg, TempReg); - } - compileBlockDispatchFromto(0, blockCount - 1); - return 0; -} - - -/* After pushing the temporaries but before the stack limit check a primitive - method needs to fetch the error code, if any. If the primitive has failed, - call the trampoline - that will assign it to the last temp. */ - - /* SimpleStackBasedCogit>>#compileGetErrorCode */ -static void -compileGetErrorCode(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *jmpNoError; - - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpZero: */ - jmpNoError = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceReapAndResetErrorCodeTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - jmpTarget(jmpNoError, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); -} - - -/* Compile a call to an interpreter primitive. Call the C routine with the - usual stack-switching dance, test the primFailCode and then either - return on success or continue to the method body. */ -/* Save processor fp, sp and return pc in the interpreter's frame stack and - instruction pointers - */ - - /* SimpleStackBasedCogit>>#compileInterpreterPrimitive:flags: */ -static sqInt NoDbgRegParms -compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) -{ - sqInt address; - sqInt address1; - sqInt address2; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction24; - AbstractInstruction *anInstruction25; - AbstractInstruction *anInstruction26; - AbstractInstruction *anInstruction28; - AbstractInstruction *anInstruction30; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction33; - AbstractInstruction *anInstruction34; - AbstractInstruction *anInstruction35; - AbstractInstruction *anInstruction36; - AbstractInstruction *anInstruction37; - AbstractInstruction *anInstruction38; - AbstractInstruction *anInstruction39; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction * continuePostSampleNonPrim; - AbstractInstruction * continuePostSamplePrim; - AbstractInstruction * jmp; - AbstractInstruction * jmpSampleNonPrim; - AbstractInstruction * jmpSamplePrim; - sqInt offset; - sqInt offset1; - sqInt offset2; - sqInt operand1; - sqInt operand3; - sqInt reg; - sqInt retpc; - - continuePostSampleNonPrim = ((AbstractInstruction *) 0); - continuePostSamplePrim = ((AbstractInstruction *) 0); - jmpSampleNonPrim = ((AbstractInstruction *) 0); - jmpSamplePrim = ((AbstractInstruction *) 0); - genExternalizePointersForPrimitiveCall(); - /* begin genLoadCStackPointersForPrimCall */ - if (cFramePointerInUse) { - genLoadCStackPointers(backEnd); - } - else { - genLoadCStackPointer(backEnd); - } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick if so */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin MoveAw:R: */ - address = (nextProfileTickAddress()) + BytesPerWord; - /* begin checkLiteral:forInstruction: */ - anInstruction1 = genoperandoperand(MoveAwR, address, ClassReg); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSampleNonPrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSampleNonPrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - if (recordPrimTraceForMethod(methodObj)) { - genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction36 = genoperandoperand(MoveCqR, 0, TempReg); - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction37 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); - if (methodOrBlockNumArgs != 0) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(MoveCqR, methodOrBlockNumArgs, TempReg); - } - /* begin checkLiteral:forInstruction: */ - argumentCountAddress(); - anInstruction38 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); - if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { - /* begin checkLiteral:forInstruction: */ - ((sqInt)primitiveRoutine); - anInstruction5 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); - /* begin checkLiteral:forInstruction: */ - primitiveFunctionPointerAddress(); - anInstruction6 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); - primSetFunctionLabel = anInstruction6; - } - if (((flags & (PrimCallNeedsNewMethod + PrimCallMayEndureCodeCompaction)) != 0)) { - - /* The ceActivateFailingPrimitiveMethod: machinery can't handle framelessness. */ - if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - needsFrame = 1; - } - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); - /* begin MoveMw:r:R: */ - offset = offsetof(CogMethod, methodObject); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - /* begin checkLiteral:forInstruction: */ - newMethodAddress(); - anInstruction8 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); - } - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction39 = genoperand(PrefetchAw, primFailCodeAddress()); - if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - - /* Sideways call the C primitive routine so that we return through cePrimReturnEnterCogCode. */ - /* On Spur ceActivateFailingPrimitiveMethod: would like to retry if forwarders - are found. So insist on PrimCallNeedsPrimitiveFunction being set too. */ - assert(((flags & PrimCallNeedsPrimitiveFunction) != 0)); - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l32; - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction11 = genoperandoperand(MoveCqR, -2 - null, A0); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A0); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction12 = genoperandoperand(MoveCqR, -2 - null, A1); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A1); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction21 = genoperandoperand(MoveCqR, -2 - null, A2); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A2); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction31 = genoperandoperand(MoveCqR, -2 - null, A3); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A3); - } - l32: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin genSubstituteReturnAddress: */ - retpc = (((flags & PrimCallCollectsProfileSamples) != 0) - ? cePrimReturnEnterCogCodeProfiling - : cePrimReturnEnterCogCode); - /* begin checkLiteral:forInstruction: */ - anInstruction13 = genoperandoperand(MoveCwR, retpc, RA); - /* begin gen:literal: */ - anInstruction10 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); - primInvokeInstruction = anInstruction10; - jmp = (jmpSamplePrim = (continuePostSamplePrim = null)); - } - else { - - /* Call the C primitive routine. */ - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l48; - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, A0); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, A1); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, A2); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, A3); - l48: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin gen:literal: */ - anInstruction15 = genoperand(CallFull, ((sqInt)primitiveRoutine)); - primInvokeInstruction = anInstruction15; - /* begin genRemoveNArgsFromStack: */ - assert(0 <= 4); - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction16 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin MoveAw:R: */ - address1 = (nextProfileTickAddress()) + BytesPerWord; - /* begin checkLiteral:forInstruction: */ - anInstruction17 = genoperandoperand(MoveAwR, address1, ClassReg); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSamplePrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSamplePrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - maybeCompileRetryOnPrimitiveFail(primitiveIndex); - /* begin MoveAw:R: */ - address2 = instructionPointerAddress(); - reg = LinkReg; - /* begin checkLiteral:forInstruction: */ - anInstruction23 = genoperandoperand(MoveAwR, address2, reg); - genLoadStackPointers(backEnd); - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction24 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction25 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset1 = 0; - /* begin checkQuickConstant:forInstruction: */ - anInstruction26 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, BytesPerWord); - } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* The sample is collected by cePrimReturnEnterCogCode for external calls */ - if (!(jmpSamplePrim == null)) { - - /* Call ceCheckProfileTick: to record sample and then continue. */ - jmpTarget(jmpSamplePrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin gen:literal: */ - operand1 = ((usqIntptr_t)ceCheckProfileTick); - /* begin checkLiteral:forInstruction: */ - anInstruction28 = genoperand(CallFull, operand1); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSamplePrim)); - } - jmpTarget(jmpSampleNonPrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction33 = genoperandoperand(MoveCqR, 0, TempReg); - /* begin checkLiteral:forInstruction: */ - newMethodAddress(); - anInstruction34 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); - /* begin gen:literal: */ - operand3 = ((usqIntptr_t)ceCheckProfileTick); - /* begin checkLiteral:forInstruction: */ - anInstruction30 = genoperand(CallFull, operand3); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSampleNonPrim)); - } - if (!(jmp == null)) { - - /* Jump to restore of receiver reg and proceed to frame build for failure. */ - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin MoveMw:r:R: */ - offset2 = BytesPerWord * (methodOrBlockNumArgs + (0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction35 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); - } - return 0; -} - - -/* Compile a call to a machine-code convention interpreter primitive. Call - the C routine - on the Smalltalk stack, assuming it consumes little or no stack space. */ -/* for now handle functions with less than 4 arguments; our C call - marshalling machinery - extends up to 4 arguments only, and the first argument of an mcprim is the - receiver. - */ - - /* SimpleStackBasedCogit>>#compileMachineCodeInterpreterPrimitive: */ -static sqInt NoDbgRegParms -compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)) -{ - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction5; - AbstractInstruction * jmpFail; - sqInt liveRegsMask; - sqInt n; - sqInt offset; - - assert(methodOrBlockNumArgs <= 3); - if ((methodOrBlockNumArgs > 2 /* numRegArgs */) - || (methodOrBlockNumArgs == 0)) { - /* begin registerMaskFor: */ - liveRegsMask = 1U << ReceiverResultReg; - } - else { - if (methodOrBlockNumArgs > 1) { - /* begin registerMaskFor:and:and: */ - liveRegsMask = ((1U << ReceiverResultReg) | (1U << Arg0Reg)) | (1U << Arg1Reg); - } - else { - /* begin registerMaskFor:and: */ - liveRegsMask = (1U << ReceiverResultReg) | (1U << Arg0Reg); - } - } - genSaveRegs(backEnd, liveRegsMask & CallerSavedRegisterMask); - if (methodOrBlockNumArgs > 2 /* numRegArgs */) { - - /* Wrangle args into Arg0Reg, Arg1Reg, SendNumArgsReg & ClassReg */ - /* offset := self bitCountOf: (liveRegsMask bitAnd: CallerSavedRegisterMask). */ - error("shouldBeImplemented"); - } - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - if ((methodOrBlockNumArgs + 1) == 0) { - goto l18; - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, A0); - if ((methodOrBlockNumArgs + 1) == 1) { - goto l18; - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, A1); - if ((methodOrBlockNumArgs + 1) == 2) { - goto l18; - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, A2); - if ((methodOrBlockNumArgs + 1) == 3) { - goto l18; - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SendNumArgsReg, A3); - l18: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin saveAndRestoreLinkRegUsingCalleeSavedRegNotLiveAtPointOfSendAround: */ - /* begin gen:literal: */ - anInstruction1 = genoperand(CallFull, ((sqInt)primitiveRoutine)); - /* begin genRemoveNArgsFromStack: */ - n = methodOrBlockNumArgs + 1; - assert(n <= 4); - genRestoreRegs(backEnd, liveRegsMask & CallerSavedRegisterMask); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(CmpCqR, 0, ABIResultReg); - /* begin JumpZero: */ - jmpFail = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - genWriteCResultIntoReg(backEnd, ReceiverResultReg); - /* begin RetN: */ - offset = (methodOrBlockNumArgs > 2 /* numRegArgs */ - ? (methodOrBlockNumArgs + 1) * BytesPerWord - : 0); - genoperand(RetN, offset); - jmpTarget(jmpFail, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - -/* Compile a fast call of a C primitive using the current stack page, - avoiding the stack switch except on failure. - This convention still uses stackPointer and argumentCount to access - operands. Push all operands to the stack, - assign stackPointer, argumentCount, and zero primFailCode. Make the call - (saving a LinkReg if required). - Test for failure and return. On failure on Spur, if there is an accessor - depth, assign framePointer and newMethod, - do the stack switch, call checkForAndFollowForwardedPrimitiveState, and - loop back if forwarders are found. - Fall throguh tio frame build. */ -/* Clear the primFailCode and set argumentCount */ - - /* SimpleStackBasedCogit>>#compileOnStackExternalPrimitive: */ -static sqInt NoDbgRegParms -compileOnStackExternalPrimitive(void (*primitiveRoutine)(void)) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt calleeSavedReg; - AbstractInstruction * jmp; - sqInt offset; - sqInt operand1; - AbstractInstruction * retry; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(MoveCqR, 0, TempReg); - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction10 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); - if (methodOrBlockNumArgs != 0) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, methodOrBlockNumArgs, TempReg); - } - /* begin checkLiteral:forInstruction: */ - argumentCountAddress(); - anInstruction11 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); - genExternalizeStackPointerForFastPrimitiveCall(); - /* begin PushR: */ - genoperand(PushR, LinkReg); - /* begin Label */ - retry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - calleeSavedReg = NoReg; - /* begin gen:literal: */ - anInstruction2 = genoperand(CallFull, primitiveRoutine); - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction12 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - if (calleeSavedReg != NoReg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, calleeSavedReg, SPReg); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin PopR: */ - genoperand(PopR, LinkReg); - /* begin checkLiteral:forInstruction: */ - stackPointerAddress(); - anInstruction14 = genoperandoperand(MoveAwR, stackPointerAddress(), SPReg); - /* begin PopR: */ - genoperand(PopR, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, 0); - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if ((accessorDepthForExternalPrimitiveMethod(methodObj)) >= 0) { - - /* Given that following primitive state to the accessor depth is recursive, we're asking for - trouble if we run the fixup on the Smalltalk stack page. Run it on the full C stack instead. - This won't be a performance issue since primitive failure should be very rare. */ - /* begin checkLiteral:forInstruction: */ - framePointerAddress(); - anInstruction5 = genoperandoperand(MoveRAw, FPReg, framePointerAddress()); - /* begin genLoadCStackPointersForPrimCall */ - if (cFramePointerInUse) { - genLoadCStackPointers(backEnd); - } - else { - genLoadCStackPointer(backEnd); - } - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); - /* begin MoveMw:r:R: */ - offset = offsetof(CogMethod, methodObject); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - /* begin checkLiteral:forInstruction: */ - newMethodAddress(); - anInstruction7 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); - /* begin gen:literal: */ - operand1 = ((usqIntptr_t)checkForAndFollowForwardedPrimitiveState); - /* begin checkLiteral:forInstruction: */ - anInstruction4 = genoperand(CallFull, operand1); - genLoadStackPointers(backEnd); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(CmpCqR, 0, ABIResultReg); - /* begin JumpNonZero: */ - genConditionalBranchoperand(JumpNonZero, ((sqInt)retry)); - } - return 0; -} - - -/* Compile one method cache probe in an OpenPIC's lookup of selector. - Answer the jump taken if the selector probe fails. - The class tag of the receiver must be in SendNumArgsReg. ClassReg and - TempReg are used as scratch registers. - On a hit, the offset of the entry is in ClassReg. */ - - /* SimpleStackBasedCogit>>#compileOpenPICMethodCacheProbeFor:withShift:baseRegOrNone: */ -static AbstractInstruction * NoDbgRegParms -compileOpenPICMethodCacheProbeForwithShiftbaseRegOrNone(sqInt selector, sqInt shift, sqInt baseRegOrNone) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *jumpSelectorMiss; - sqInt offset; - sqInt offset1; - - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SendNumArgsReg, ClassReg); - maybeShiftClassTagRegisterForMethodCacheProbe(ClassReg); - annotateobjRef(checkLiteralforInstruction(selector, genoperandoperand(XorCwR, selector, ClassReg)), selector); - assert(shift <= (shiftForWord())); - if (shift < (shiftForWord())) { - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (shiftForWord()) - shift, ClassReg); - } - /* begin AndCq:R: */ - anInstruction4 = genoperandoperand(AndCqR, ((int)((usqInt)(MethodCacheMask) << (shiftForWord()))), ClassReg); - if (baseRegOrNone == NoReg) { - /* begin MoveMw:r:R: */ - offset = (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheSelector) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - } - else { - /* begin AddR:R: */ - genoperandoperand(AddRR, baseRegOrNone, ClassReg); - /* begin MoveMw:r:R: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, ((int)((usqInt)(MethodCacheSelector) << (shiftForWord()))), ClassReg, TempReg); - } - annotateobjRef(checkLiteralforInstruction(selector, genoperandoperand(CmpCwR, selector, TempReg)), selector); - /* begin JumpNonZero: */ - jumpSelectorMiss = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - if (baseRegOrNone == NoReg) { - /* begin MoveMw:r:R: */ - offset1 = (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheClass) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveMwrR, offset1, ClassReg, TempReg); - } - else { - /* begin MoveMw:r:R: */ - anInstruction3 = genoperandoperandoperand(MoveMwrR, ((int)((usqInt)(MethodCacheClass) << (shiftForWord()))), ClassReg, TempReg); - } - /* begin CmpR:R: */ - assert(!((SendNumArgsReg == SPReg))); - genoperandoperand(CmpRR, SendNumArgsReg, TempReg); - return jumpSelectorMiss; -} - - -/* Compile the code for an open PIC. Perform a probe of the first-level - method lookup cache followed by a call of ceSendFromInLineCacheMiss: if - the probe fails. */ - - /* SimpleStackBasedCogit>>#compileOpenPIC:numArgs: */ -static void NoDbgRegParms -compileOpenPICnumArgs(sqInt selector, sqInt numArgs) -{ - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - sqInt cacheBaseReg; - AbstractInstruction *itsAHit; - AbstractInstruction *jumpBCMethod; - AbstractInstruction *jumpClassMiss; - AbstractInstruction *jumpSelectorMiss; - sqInt offset; - - /* begin preenMethodLabel */ - (((((AbstractInstruction *) methodLabel))->operands))[1] = 0; - compilePICAbort(numArgs); - entry = genGetClassTagOfintoscratchReg(ReceiverResultReg, SendNumArgsReg, TempReg); - flag("lookupInMethodCacheSel:classTag:"); - cacheBaseReg = NoReg; - jumpSelectorMiss = compileOpenPICMethodCacheProbeForwithShiftbaseRegOrNone(selector, 0, cacheBaseReg); - /* begin JumpNonZero: */ - jumpClassMiss = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset = (cacheBaseReg == NoReg - ? (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheMethod) << (shiftForWord())))) - : ((int)((usqInt)(MethodCacheMethod) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, SendNumArgsReg); - itsAHit = anInstruction1; - genLoadSlotsourceRegdestReg(HeaderIndex, SendNumArgsReg, ClassReg); - jumpBCMethod = genJumpImmediate(ClassReg); - jmpTarget(jumpBCMethod, picInterpretAbort); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AddCqR, cmNoCheckEntryOffset, ClassReg); - /* begin JumpR: */ - genoperand(JumpR, ClassReg); - jmpTarget(jumpSelectorMiss, jmpTarget(jumpClassMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - jumpSelectorMiss = compileOpenPICMethodCacheProbeForwithShiftbaseRegOrNone(selector, 1, cacheBaseReg); - /* begin JumpZero: */ - genConditionalBranchoperand(JumpZero, ((sqInt)itsAHit)); - jmpTarget(jumpSelectorMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - jumpSelectorMiss = compileOpenPICMethodCacheProbeForwithShiftbaseRegOrNone(selector, 2, cacheBaseReg); - /* begin JumpZero: */ - genConditionalBranchoperand(JumpZero, ((sqInt)itsAHit)); - jmpTarget(jumpSelectorMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genPushRegisterArgsForNumArgsscratchReg(backEnd, numArgs, SendNumArgsReg); - genSmalltalkToCStackSwitch(1); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), SendNumArgsReg)))); - compileCallFornumArgsargargargargresultRegregsToSave(ceSendFromInLineCacheMiss, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); -} - - -/* Compile one method cache probe in a perform: primitive's lookup of - selector. Answer the jump taken if the selector probe fails. */ - - /* SimpleStackBasedCogit>>#compilePerformMethodCacheProbeFor:withShift:baseRegOrNone: */ -static AbstractInstruction * NoDbgRegParms -compilePerformMethodCacheProbeForwithShiftbaseRegOrNone(sqInt selectorReg, sqInt shift, sqInt baseRegOrNone) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *jumpSelectorMiss; - sqInt offset; - sqInt offset1; - - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SendNumArgsReg, ClassReg); - maybeShiftClassTagRegisterForMethodCacheProbe(ClassReg); - /* begin XorR:R: */ - genoperandoperand(XorRR, selectorReg, ClassReg); - assert(shift <= (shiftForWord())); - if (shift < (shiftForWord())) { - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (shiftForWord()) - shift, ClassReg); - } - /* begin AndCq:R: */ - anInstruction4 = genoperandoperand(AndCqR, ((int)((usqInt)(MethodCacheMask) << (shiftForWord()))), ClassReg); - if (baseRegOrNone == NoReg) { - /* begin MoveMw:r:R: */ - offset = (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheSelector) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - } - else { - /* begin AddR:R: */ - genoperandoperand(AddRR, baseRegOrNone, ClassReg); - /* begin MoveMw:r:R: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, ((int)((usqInt)(MethodCacheSelector) << (shiftForWord()))), ClassReg, TempReg); - } - /* begin CmpR:R: */ - assert(!((selectorReg == SPReg))); - genoperandoperand(CmpRR, selectorReg, TempReg); - /* begin JumpNonZero: */ - jumpSelectorMiss = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - if (baseRegOrNone == NoReg) { - /* begin MoveMw:r:R: */ - offset1 = (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheClass) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveMwrR, offset1, ClassReg, TempReg); - } - else { - /* begin MoveMw:r:R: */ - anInstruction3 = genoperandoperandoperand(MoveMwrR, ((int)((usqInt)(MethodCacheClass) << (shiftForWord()))), ClassReg, TempReg); - } - /* begin CmpR:R: */ - assert(!((SendNumArgsReg == SPReg))); - genoperandoperand(CmpRR, SendNumArgsReg, TempReg); - return jumpSelectorMiss; -} - - -/* Compile a primitive. If possible, performance-critical primitives will - be generated by their own routines (primitiveGenerator). Otherwise, - if there is a primitive at all, we call the C routine with the usual - stack-switching dance, test the primFailCode and then either return - on success or continue to the method body. */ - - /* SimpleStackBasedCogit>>#compilePrimitive */ -static sqInt -compilePrimitive(void) -{ - sqInt code; - sqInt flags; - sqInt opcodeIndexAtPrimitive; - PrimitiveDescriptor *primitiveDescriptor; - void (*primitiveRoutine)(void); - - flags = 0; - if (primitiveIndex == 0) { - return 0; - } - if ((((primitiveDescriptor = primitiveGeneratorOrNil())) != null) - && ((((primitiveDescriptor->primitiveGenerator)) != null) - && ((((primitiveDescriptor->primNumArgs)) < 0) - || (((primitiveDescriptor->primNumArgs)) == (argumentCountOf(methodObj)))))) { - - /* Note opcodeIndex so that any arg load instructions - for unimplemented primitives can be discarded. */ - opcodeIndexAtPrimitive = opcodeIndex; - code = ((primitiveDescriptor->primitiveGenerator))(); - if ((code < 0) - && (code != UnimplementedPrimitive)) { - - /* Generator failed, so no point continuing... */ - return code; - } - if (code == UnfailingPrimitive) { - return 0; - } - if ((code == CompletePrimitive) - && (!(((primitiveIndexOfMethodheader(methodObj, methodHeader)) > 0) - && ((longStoreBytecodeForHeader(methodHeader)) == (fetchByteofObject((startPCOfMethod(methodObj)) + (sizeOfCallPrimitiveBytecode(methodHeader)), methodObj)))))) { - return 0; - } - if (code == UnimplementedPrimitive) { - opcodeIndex = opcodeIndexAtPrimitive; - } - } - primitiveRoutine = functionPointerForCompiledMethodprimitiveIndexprimitivePropertyFlagsInto(methodObj, primitiveIndex, (&flags)); - if (((flags & PrimCallDoNotJIT) != 0)) { - return ShouldNotJIT; - } - if (((flags & PrimCallOnSmalltalkStack) != 0)) { - if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { - - /* TEMPORARY HACK!! */ - return compileOnStackExternalPrimitive(primitiveRoutine); - } - return compileMachineCodeInterpreterPrimitive(((void (*)(void)) (mcprimFunctionForPrimitiveIndex(primitiveIndex)))); - } - if ((primitiveRoutine == 0) - || (primitiveRoutine == (((void (*)(void)) primitiveFail)))) { - return genFastPrimFail(); - } - minValidCallAddress = ((minValidCallAddress < (((usqInt)primitiveRoutine))) ? minValidCallAddress : (((usqInt)primitiveRoutine))); - return compileInterpreterPrimitiveflags(primitiveRoutine, flags); -} - - /* SimpleStackBasedCogit>>#extendedPushBytecode */ -static sqInt -extendedPushBytecode(void) -{ - sqInt variableIndex; - sqInt variableType; - - variableType = (((usqInt)(byte1)) >> 6) & 3; - variableIndex = byte1 & 0x3F; - if (variableType == 0) { - return genPushReceiverVariable(variableIndex); - } - if (variableType == 1) { - return genPushTemporaryVariable(variableIndex); - } - if (variableType == 2) { - return genPushLiteralIndex(variableIndex); - } - return genPushLiteralVariable(variableIndex); -} - - /* SimpleStackBasedCogit>>#extendedStoreAndPopBytecode */ -static sqInt -extendedStoreAndPopBytecode(void) -{ - AbstractInstruction *abstractInstruction; - sqInt variableIndex; - sqInt variableType; - - variableType = (((usqInt)(byte1)) >> 6) & 3; - variableIndex = byte1 & 0x3F; - if (variableType == 0) { - return genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(1, variableIndex, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } - if (variableType == 1) { - genStorePopTemporaryVariable(1, variableIndex); -# if IMMUTABILITY - /* begin annotateBytecode: */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction->annotation = HasBytecodePC); -# endif // IMMUTABILITY - return 0; - } - if (variableType == 3) { - return genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(1, variableIndex, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } - return EncounteredUnknownBytecode; -} - - /* SimpleStackBasedCogit>>#extendedStoreBytecode */ -static sqInt -extendedStoreBytecode(void) -{ - AbstractInstruction *abstractInstruction; - sqInt variableIndex; - sqInt variableType; - - variableType = (((usqInt)(byte1)) >> 6) & 3; - variableIndex = byte1 & 0x3F; - if (variableType == 0) { - return genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(0, variableIndex, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } - if (variableType == 1) { - genStorePopTemporaryVariable(0, variableIndex); -# if IMMUTABILITY - /* begin annotateBytecode: */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction->annotation = HasBytecodePC); -# endif // IMMUTABILITY - return 0; - } - if (variableType == 3) { - return genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(0, variableIndex, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } - return EncounteredUnknownBytecode; -} - - /* SimpleStackBasedCogit>>#frameOffsetOfTemporary: */ -static sqInt NoDbgRegParms -frameOffsetOfTemporary(sqInt index) -{ - return (index < methodOrBlockNumArgs - ? FoxCallerSavedIP + ((methodOrBlockNumArgs - index) * BytesPerWord) - : (FoxMFReceiver - BytesPerWord) + ((methodOrBlockNumArgs - index) * BytesPerWord)); -} - - -/* Can use any of the first 32 literals for the selector and pass up to 7 - arguments. - */ - - /* SimpleStackBasedCogit>>#genExtendedSendBytecode */ -static sqInt -genExtendedSendBytecode(void) -{ - return genSendnumArgs(byte1 & 0x1F, ((usqInt)(byte1)) >> 5); -} - - /* SimpleStackBasedCogit>>#genExtendedSuperBytecode */ -static sqInt -genExtendedSuperBytecode(void) -{ - return genSendSupernumArgs(byte1 & 0x1F, ((usqInt)(byte1)) >> 5); -} - - -/* 244 11110100 i i i i i i i i Pop and Jump 0n False i i i i i i i i (+ - Extend B * 256, where Extend B >= 0) - */ - - /* SimpleStackBasedCogit>>#genExtJumpIfFalse */ -static sqInt -genExtJumpIfFalse(void) -{ - sqInt distance; - sqInt target; - - distance = byte1 + (((sqInt)((usqInt)(extB) << 8))); - assert(distance == (v4LongForwardBranchDistance(generatorAt(byte0), bytecodePC, ((extA != 0 - ? 1 - : 0)) + ((extB != 0 - ? 1 - : 0)), methodObj))); - extB = 0; - numExtB = 0; - target = (distance + 2) + bytecodePC; - return genJumpIfto(falseObject(), target); -} - - -/* 243 11110011 i i i i i i i i Pop and Jump 0n True i i i i i i i i (+ - Extend B * 256, where Extend B >= 0) - */ - - /* SimpleStackBasedCogit>>#genExtJumpIfTrue */ -static sqInt -genExtJumpIfTrue(void) -{ - sqInt distance; - sqInt target; - - distance = byte1 + (((sqInt)((usqInt)(extB) << 8))); - assert(distance == (v4LongForwardBranchDistance(generatorAt(byte0), bytecodePC, ((extA != 0 - ? 1 - : 0)) + ((extB != 0 - ? 1 - : 0)), methodObj))); - extB = 0; - numExtB = 0; - target = (distance + 2) + bytecodePC; - return genJumpIfto(trueObject(), target); -} - - -/* NewspeakV4: 221 11011101 Nop */ -/* SistaV1: 91 01011011' Nop */ - - /* SimpleStackBasedCogit>>#genExtNopBytecode */ -static sqInt -genExtNopBytecode(void) -{ - extA = (numExtB = (extB = 0)); - return 0; -} - - -/* NewsqueakV4: 229 11100101 iiiiiiii Push Integer #iiiiiiii (+ Extend B * - 256, where bbbbbbbb = sddddddd, e.g. -32768 = i=0, a=0, s=1) - SistaV1: 232 11101000 iiiiiiii Push Integer #iiiiiiii (+ Extend B * 256, - where bbbbbbbb = sddddddd, e.g. -32768 = i=0, a=0, s=1) - */ - - /* SimpleStackBasedCogit>>#genExtPushIntegerBytecode */ -static sqInt -genExtPushIntegerBytecode(void) -{ - sqInt value; - - value = byte1 + (((sqInt)((usqInt)(extB) << 8))); - extB = 0; - numExtB = 0; - return genPushLiteral((((usqInt)value << 1) | 1)); -} - - -/* 228 11100100 i i i i i i i i Push Literal #iiiiiiii (+ Extend A * 256) */ - - /* SimpleStackBasedCogit>>#genExtPushLiteralBytecode */ -static sqInt -genExtPushLiteralBytecode(void) -{ - sqInt index; - - index = byte1 + (((sqInt)((usqInt)(extA) << 8))); - extA = 0; - return genPushLiteralIndex(index); -} - - -/* 227 11100011 i i i i i i i i Push Literal Variable #iiiiiiii (+ Extend A - * 256) - */ - - /* SimpleStackBasedCogit>>#genExtPushLiteralVariableBytecode */ -static sqInt -genExtPushLiteralVariableBytecode(void) -{ - sqInt index; - - index = byte1 + (((sqInt)((usqInt)(extA) << 8))); - extA = 0; - return genPushLiteralVariable(index); -} - - -/* 77 01001101 Push false [* 1:true, 2:nil, 3:thisContext, ..., -N: - pushEnclosingObjectAt: N, N = Extend B] - */ - - /* SimpleStackBasedCogit>>#genExtPushPseudoVariableOrOuterBytecode */ -static sqInt -genExtPushPseudoVariableOrOuterBytecode(void) -{ - sqInt ext; - - ext = extB; - extB = 0; - numExtB = 0; - switch (ext) { - case 0: - return genPushLiteral(falseObject()); - - case 1: - return genPushLiteral(trueObject()); - - case 2: - return genPushLiteral(nilObject()); - - case 3: - return genPushActiveContextBytecode(); - - default: - if (ext < 0) { - return genPushEnclosingObjectAt(0 - ext); - } - warning("undefined extension for extPushPseudoVariableOrOuter"); - /* begin unknownBytecode */ - return EncounteredUnknownBytecode; - - } - return 0; -} - - -/* 226 11100010 i i i i i i i i Push Receiver Variable #iiiiiiii (+ Extend A - * 256) - */ - - /* SimpleStackBasedCogit>>#genExtPushReceiverVariableBytecode */ -static sqInt -genExtPushReceiverVariableBytecode(void) -{ - sqInt index; - - index = byte1 + (((sqInt)((usqInt)(extA) << 8))); - extA = 0; - return (isReadMediatedContextInstVarIndex(index) - ? genPushMaybeContextReceiverVariable(index) - : genPushReceiverVariable(index)); -} - - -/* 218 11011010 Return Stack Top From Block [* return from enclosing block - N, N = Extend A] - If extA is zero, return to the caller of the current block activation. - If extA is non-zero return to the caller of the Nth enclosing block - activation. - */ - - /* SimpleStackBasedCogit>>#genExtReturnTopFromBlock */ -static sqInt -genExtReturnTopFromBlock(void) -{ - if (extA == 0) { - return genReturnTopFromBlock(); - } - error("shouldBeImplemented"); - extA = 0; - return EncounteredUnknownBytecode; -} - - -/* 241 11110001 i i i i i j j j Send To Absent Dynamic Superclass Literal - Selector #iiiii (+ Extend A * 32) with jjj (+ Extend B * 8) Arguments - */ - - /* SimpleStackBasedCogit>>#genExtSendAbsentDynamicSuperBytecode */ -static sqInt -genExtSendAbsentDynamicSuperBytecode(void) -{ - sqInt litIndex; - sqInt nArgs; - - litIndex = (((usqInt)(byte1)) >> 3) + (((sqInt)((usqInt)(extA) << 5))); - extA = 0; - nArgs = (byte1 & 7) + (((sqInt)((usqInt)(extB) << 3))); - extB = 0; - numExtB = 0; - return genSendAbsentDynamicSupernumArgs(litIndex, nArgs); -} - - -/* 240 11110000 i i i i i j j j Send To Absent Implicit Receiver Literal - Selector #iiiii (+ Extend A * 32) with jjj (+ Extend B * 8) Arguments - */ - - /* SimpleStackBasedCogit>>#genExtSendAbsentImplicitBytecode */ -static sqInt -genExtSendAbsentImplicitBytecode(void) -{ - sqInt litIndex; - sqInt nArgs; - - litIndex = (((usqInt)(byte1)) >> 3) + (((sqInt)((usqInt)(extA) << 5))); - extA = 0; - nArgs = (byte1 & 7) + (((sqInt)((usqInt)(extB) << 3))); - extB = 0; - numExtB = 0; - return genSendAbsentImplicitnumArgs(litIndex, nArgs); -} - - -/* 254 11111110 i i i i i j j j kkkkkkkk Send To Absent Outer Literal - Selector #iiiii (+ Extend A * 32) with jjj (+ Extend B * 8) Arguments at - Depth kkkkkkkk - */ - - /* SimpleStackBasedCogit>>#genExtSendAbsentOuterBytecode */ -static sqInt -genExtSendAbsentOuterBytecode(void) -{ - sqInt depth; - sqInt litIndex; - sqInt nArgs; - - litIndex = (((usqInt)(byte1)) >> 3) + (((sqInt)((usqInt)(extA) << 5))); - extA = 0; - nArgs = (byte1 & 7) + (((sqInt)((usqInt)(extB) << 3))); - extB = 0; - numExtB = 0; - depth = byte2; - return genSendAbsentOuternumArgsdepth(litIndex, nArgs, depth); -} - - -/* 245 11110101 i i i i i j j j Send To Absent Self Literal Selector #iiiii - (+ Extend A * 32) with jjj (+ Extend B * 8) Arguments - */ - - /* SimpleStackBasedCogit>>#genExtSendAbsentSelfBytecode */ -static sqInt -genExtSendAbsentSelfBytecode(void) -{ - sqInt litIndex; - sqInt nArgs; - - litIndex = (((usqInt)(byte1)) >> 3) + (((sqInt)((usqInt)(extA) << 5))); - extA = 0; - nArgs = (byte1 & 7) + (((sqInt)((usqInt)(extB) << 3))); - extB = 0; - numExtB = 0; - return genSendAbsentSelfnumArgs(litIndex, nArgs); -} - - -/* 238 11101110 i i i i i j j j Send Literal Selector #iiiii (+ Extend A * - 32) with jjj (+ Extend B * 8) Arguments - */ - - /* SimpleStackBasedCogit>>#genExtSendBytecode */ -static sqInt -genExtSendBytecode(void) -{ - sqInt litIndex; - sqInt nArgs; - - litIndex = (((usqInt)(byte1)) >> 3) + (((sqInt)((usqInt)(extA) << 5))); - extA = 0; - nArgs = (byte1 & 7) + (((sqInt)((usqInt)(extB) << 3))); - extB = 0; - numExtB = 0; - return genSendnumArgs(litIndex, nArgs); -} - - -/* 239 11101111 i i i i i j j j Send To Superclass Literal Selector #iiiii - (+ Extend A * 32) with jjj (+ Extend B * 8) Arguments - */ - - /* SimpleStackBasedCogit>>#genExtSendSuperBytecode */ -static sqInt -genExtSendSuperBytecode(void) -{ - int isDirected; - sqInt litIndex; - sqInt nArgs; - - if ((isDirected = extB >= 64)) { - extB = extB & 0x3F; - } - litIndex = (((usqInt)(byte1)) >> 3) + (((sqInt)((usqInt)(extA) << 5))); - extA = 0; - nArgs = (byte1 & 7) + (((sqInt)((usqInt)(extB) << 3))); - extB = 0; - numExtB = 0; - return (isDirected - ? genSendDirectedSupernumArgs(litIndex, nArgs) - : genSendSupernumArgs(litIndex, nArgs)); -} - - -/* 236 11101100 i i i i i i i i Pop and Store Literal Variable #iiiiiiii (+ - Extend A * 256) - */ - - /* SimpleStackBasedCogit>>#genExtStoreAndPopLiteralVariableBytecode */ -static sqInt -genExtStoreAndPopLiteralVariableBytecode(void) -{ - sqInt index; - - index = byte1 + (((sqInt)((usqInt)(extA) << 8))); - extA = 0; - return genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(1, index, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); -} - - -/* 235 11101011 i i i i i i i i Pop and Store Receiver Variable #iiiiiii (+ - Extend A * 256) - */ - - /* SimpleStackBasedCogit>>#genExtStoreAndPopReceiverVariableBytecode */ -static sqInt -genExtStoreAndPopReceiverVariableBytecode(void) -{ - sqInt index; - - index = byte1 + (((sqInt)((usqInt)(extA) << 8))); - extA = 0; - return (isWriteMediatedContextInstVarIndex(index) - ? genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(1, index, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1) - : genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(1, index, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1)); -} - - -/* 233 11101001 i i i i i i i i Store Literal Variable #iiiiiiii (+ Extend A - * 256) - */ - - /* SimpleStackBasedCogit>>#genExtStoreLiteralVariableBytecode */ -static sqInt -genExtStoreLiteralVariableBytecode(void) -{ - sqInt index; - - index = byte1 + (((sqInt)((usqInt)(extA) << 8))); - extA = 0; - return genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(0, index, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); -} - - -/* 232 11101000 i i i i i i i i Store Receiver Variable #iiiiiii (+ Extend A - * 256) - */ - - /* SimpleStackBasedCogit>>#genExtStoreReceiverVariableBytecode */ -static sqInt -genExtStoreReceiverVariableBytecode(void) -{ - sqInt index; - - index = byte1 + (((sqInt)((usqInt)(extA) << 8))); - extA = 0; - return (isWriteMediatedContextInstVarIndex(index) - ? genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(0, index, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1) - : genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(0, index, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1)); -} - - -/* 242 11110010 i i i i i i i i Jump i i i i i i i i (+ Extend B * 256, - where bbbbbbbb = sddddddd, e.g. -32768 = i=0, a=0, s=1) - */ - - /* SimpleStackBasedCogit>>#genExtUnconditionalJump */ -static sqInt -genExtUnconditionalJump(void) -{ - AbstractInstruction *abstractInstruction; - sqInt distance; - sqInt target; - - distance = byte1 + (((sqInt)((usqInt)(extB) << 8))); - assert(distance == (v4LongBranchDistance(generatorAt(byte0), bytecodePC, ((extA != 0 - ? 1 - : 0)) + ((extB != 0 - ? 1 - : 0)), methodObj))); - extB = 0; - numExtB = 0; - target = (distance + 2) + bytecodePC; - if (distance < 0) { - return genJumpBackTo(target); - } - genJumpTo(target); - /* begin annotateBytecode: */ - abstractInstruction = lastOpcode(); - (abstractInstruction->annotation = HasBytecodePC); - return 0; -} - - /* SimpleStackBasedCogit>>#genFastPrimFail */ -static sqInt -genFastPrimFail(void) -{ - primitiveIndex = 0; - return UnfailingPrimitive; -} - - -/* Suport for compileInterpreterPrimitive. Generate inline code so as to - record the primitive - trace as fast as possible. */ - - /* SimpleStackBasedCogit>>#genFastPrimTraceUsing:and: */ -static void NoDbgRegParms -genFastPrimTraceUsingand(sqInt r1, sqInt r2) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - sqInt offset; - - /* begin MoveCq:R: */ - anInstruction = genoperandoperand(MoveCqR, 0, r2); - /* begin checkLiteral:forInstruction: */ - primTraceLogIndexAddress(); - anInstruction1 = genoperandoperand(MoveAbR, primTraceLogIndexAddress(), r2); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(LoadEffectiveAddressMwrR, 1, r2, r1); - /* begin checkLiteral:forInstruction: */ - primTraceLogIndexAddress(); - anInstruction3 = genoperandoperand(MoveRAb, r1, primTraceLogIndexAddress()); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), r1)))); - /* begin MoveMw:r:R: */ - offset = offsetof(CogMethod, selector); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperandoperand(MoveMwrR, offset, r1, TempReg); - /* begin checkLiteral:forInstruction: */ - ((sqInt)(primTraceLogAddress())); - anInstruction5 = genoperandoperand(MoveCwR, ((sqInt)(primTraceLogAddress())), r1); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, TempReg, r2, r1); -} - - /* SimpleStackBasedCogit>>#genLongJumpIfFalse */ -static sqInt -genLongJumpIfFalse(void) -{ - sqInt distance; - sqInt target; - - distance = v3LongForwardBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - target = (distance + 2) + bytecodePC; - return genJumpIfto(falseObject(), target); -} - - /* SimpleStackBasedCogit>>#genLongJumpIfTrue */ -static sqInt -genLongJumpIfTrue(void) -{ - sqInt distance; - sqInt target; - - distance = v3LongForwardBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - target = (distance + 2) + bytecodePC; - return genJumpIfto(trueObject(), target); -} - - -/* 230 11100110 i i i i i i i i Push Temporary Variable #iiiiiiii */ - - /* SimpleStackBasedCogit>>#genLongPushTemporaryVariableBytecode */ -static sqInt -genLongPushTemporaryVariableBytecode(void) -{ - return genPushTemporaryVariable(byte1); -} - - -/* 237 11101101 i i i i i i i i Pop and Store Temporary Variable #iiiiiiii */ - - /* SimpleStackBasedCogit>>#genLongStoreAndPopTemporaryVariableBytecode */ -static sqInt -genLongStoreAndPopTemporaryVariableBytecode(void) -{ - return genStorePopTemporaryVariable(1, byte1); -} - - -/* 234 11101010 i i i i i i i i Store Temporary Variable #iiiiiiii */ - - /* SimpleStackBasedCogit>>#genLongStoreTemporaryVariableBytecode */ -static sqInt -genLongStoreTemporaryVariableBytecode(void) -{ - return genStorePopTemporaryVariable(0, byte1); -} - - /* SimpleStackBasedCogit>>#genLongUnconditionalBackwardJump */ -static sqInt -genLongUnconditionalBackwardJump(void) -{ - sqInt distance; - - distance = v3LongBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - assert(distance < 0); - return genJumpBackTo((distance + 2) + bytecodePC); -} - - /* SimpleStackBasedCogit>>#genLongUnconditionalForwardJump */ -static sqInt -genLongUnconditionalForwardJump(void) -{ - sqInt distance; - sqInt targetpc; - - distance = v3LongBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - assert(distance >= 0); - targetpc = (distance + 2) + bytecodePC; - return genJumpTo(targetpc); -} - - -/* Compile the code for a probe of the first-level method cache for a perform - primitive. The selector is assumed to be in Arg0Reg. Defer to - adjustArgumentsForPerform: to - adjust the arguments before the jump to the method. */ - - /* SimpleStackBasedCogit>>#genLookupForPerformNumArgs: */ -static sqInt NoDbgRegParms -genLookupForPerformNumArgs(sqInt numArgs) -{ - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - sqInt cacheBaseReg; - AbstractInstruction *itsAHit; - AbstractInstruction *jumpClassMiss; - AbstractInstruction *jumpInterpret; - AbstractInstruction *jumpSelectorMiss; - sqInt offset; - - - /* N.B. Can't assume TempReg already contains the tag because a method can - of course be invoked via the unchecked entry-point, e.g. as does perform:. */ - genGetInlineCacheClassTagFromintoforEntry(ReceiverResultReg, SendNumArgsReg, 0); - flag("lookupInMethodCacheSel:classTag:"); - cacheBaseReg = NoReg; - jumpSelectorMiss = compilePerformMethodCacheProbeForwithShiftbaseRegOrNone(Arg0Reg, 0, cacheBaseReg); - /* begin JumpNonZero: */ - jumpClassMiss = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset = (cacheBaseReg == NoReg - ? (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheMethod) << (shiftForWord())))) - : ((int)((usqInt)(MethodCacheMethod) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, SendNumArgsReg); - itsAHit = anInstruction1; - genLoadSlotsourceRegdestReg(HeaderIndex, SendNumArgsReg, ClassReg); - - /* Adjust arguments and jump to the method's unchecked entry-point. */ - jumpInterpret = genJumpImmediate(ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AddCqR, cmNoCheckEntryOffset, ClassReg); - adjustArgumentsForPerform(numArgs); - /* begin JumpR: */ - genoperand(JumpR, ClassReg); - jmpTarget(jumpSelectorMiss, jmpTarget(jumpClassMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - jumpSelectorMiss = compilePerformMethodCacheProbeForwithShiftbaseRegOrNone(Arg0Reg, 1, cacheBaseReg); - /* begin JumpZero: */ - genConditionalBranchoperand(JumpZero, ((sqInt)itsAHit)); - jmpTarget(jumpSelectorMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - jumpSelectorMiss = compilePerformMethodCacheProbeForwithShiftbaseRegOrNone(Arg0Reg, 2, cacheBaseReg); - /* begin JumpZero: */ - genConditionalBranchoperand(JumpZero, ((sqInt)itsAHit)); - jmpTarget(jumpSelectorMiss, jmpTarget(jumpInterpret, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return 0; -} - - /* SimpleStackBasedCogit>>#genMustBeBooleanTrampolineFor:called: */ -static usqInt NoDbgRegParms -genMustBeBooleanTrampolineForcalled(sqInt boolean, char *trampolineName) -{ - AbstractInstruction *anInstruction; - - zeroOpcodeIndex(); - assert(!(shouldAnnotateObjectReference(boolean))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, boolean, TempReg); - return genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceSendMustBeBoolean, trampolineName, 1, TempReg, null, null, null, 0 /* emptyRegisterMask */, 1, NoReg, 1); -} - - -/* Generate the substitute return code for an external or FFI primitive call. - On success simply return, extracting numArgs from newMethod. - On primitive failure call ceActivateFailingPrimitiveMethod: newMethod. */ - - /* SimpleStackBasedCogit>>#genPrimReturnEnterCogCodeEnilopmart: */ -static void NoDbgRegParms -genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) -{ - sqInt address; - sqInt address1; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - sqInt callTarget; - AbstractInstruction *continuePostSample; - AbstractInstruction * inst; - AbstractInstruction *jmpFail; - AbstractInstruction *jmpSample; - sqInt quickConstant; - sqInt reg; - - continuePostSample = ((AbstractInstruction *) 0); - jmpSample = ((AbstractInstruction *) 0); - zeroOpcodeIndex(); - /* begin MoveCq:R: */ - quickConstant = varBaseAddress(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - if (profiling) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick: if so. - N.B. nextProfileTick is 64-bits so 32-bit systems need to test both halves. */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction1 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin MoveAw:R: */ - address = (nextProfileTickAddress()) + BytesPerWord; - /* begin checkLiteral:forInstruction: */ - anInstruction2 = genoperandoperand(MoveAwR, address, ClassReg); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSample = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction13 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadStackPointers(backEnd); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); - /* begin checkLiteral:forInstruction: */ - instructionPointerAddress(); - anInstruction7 = genoperandoperand(MoveAwR, instructionPointerAddress(), LinkReg); - /* begin RetN: */ - genoperand(RetN, BytesPerWord); - jmpTarget(jmpFail, checkLiteralforInstruction(newMethodAddress(), genoperandoperand(MoveAwR, newMethodAddress(), SendNumArgsReg))); - /* begin checkLiteral:forInstruction: */ - cStackPointerAddress(); - anInstruction15 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); - compileCallFornumArgsargargargargresultRegregsToSave(ceActivateFailingPrimitiveMethod, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); - /* begin MoveAw:R: */ - address1 = instructionPointerAddress(); - reg = LinkReg; - /* begin checkLiteral:forInstruction: */ - anInstruction16 = genoperandoperand(MoveAwR, address1, reg); - genLoadStackPointers(backEnd); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, BytesPerWord); - if (profiling) { - - /* Call ceCheckProfileTick: to record sample and then continue. newMethod - should be up-to-date. Need to save and restore the link reg around this call. */ - jmpTarget(jmpSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - /* begin CallFullRT: */ - callTarget = (usqIntptr_t)ceCheckProfileTick; - /* begin checkLiteral:forInstruction: */ - anInstruction18 = genoperand(CallFull, callTarget); - /* begin PopR: */ - genoperand(PopR, LinkReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSample)); - } -} - - /* SimpleStackBasedCogit>>#genPushConstantFalseBytecode */ -static sqInt -genPushConstantFalseBytecode(void) -{ - return genPushLiteral(falseObject()); -} - - /* SimpleStackBasedCogit>>#genPushConstantNilBytecode */ -static sqInt -genPushConstantNilBytecode(void) -{ - return genPushLiteral(nilObject()); -} - - -/* 79 01001111 Push 1 */ - - /* SimpleStackBasedCogit>>#genPushConstantOneBytecode */ -static sqInt -genPushConstantOneBytecode(void) -{ - return genPushLiteral((((usqInt)1 << 1) | 1)); -} - - /* SimpleStackBasedCogit>>#genPushConstantTrueBytecode */ -static sqInt -genPushConstantTrueBytecode(void) -{ - return genPushLiteral(trueObject()); -} - - -/* 78 01001110 Push 0 */ - - /* SimpleStackBasedCogit>>#genPushConstantZeroBytecode */ -static sqInt -genPushConstantZeroBytecode(void) -{ - return genPushLiteral((((usqInt)0 << 1) | 1)); -} - - /* SimpleStackBasedCogit>>#genPushLiteralConstantBytecode */ -static sqInt -genPushLiteralConstantBytecode(void) -{ - return genPushLiteralIndex(byte0 & 0x1F); -} - - -/* 16-31 0001 i i i i Push Literal Variable #iiii */ - - /* SimpleStackBasedCogit>>#genPushLiteralVariable16CasesBytecode */ -static sqInt -genPushLiteralVariable16CasesBytecode(void) -{ - return genPushLiteralVariable(byte0 & 15); -} - - /* SimpleStackBasedCogit>>#genPushLiteralVariableBytecode */ -static sqInt -genPushLiteralVariableBytecode(void) -{ - return genPushLiteralVariable(byte0 & 0x1F); -} - - /* SimpleStackBasedCogit>>#genPushQuickIntegerConstantBytecode */ -static sqInt -genPushQuickIntegerConstantBytecode(void) -{ - return genPushLiteral((((usqInt)(byte0 - 117) << 1) | 1)); -} - - /* SimpleStackBasedCogit>>#genPushReceiverVariableBytecode */ -static sqInt -genPushReceiverVariableBytecode(void) -{ - return genPushReceiverVariable(byte0 & 15); -} - - /* SimpleStackBasedCogit>>#genPushTemporaryVariableBytecode */ -static sqInt -genPushTemporaryVariableBytecode(void) -{ - return genPushTemporaryVariable(byte0 & 15); -} - - -/* because selected by CoInterpreter>>quickPrimitiveGeneratorFor: */ - - /* SimpleStackBasedCogit>>#genQuickReturnConst */ -sqInt -genQuickReturnConst(void) -{ - AbstractInstruction *anInstruction; - sqInt constant; - - constant = quickPrimitiveConstantFor(primitiveIndex); - /* begin genMoveConstant:R: */ - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - genUpArrowReturn(); - return UnfailingPrimitive; -} - - -/* because selected by CoInterpreter>>quickPrimitiveGeneratorFor: */ - - /* SimpleStackBasedCogit>>#genQuickReturnInstVar */ -sqInt -genQuickReturnInstVar(void) -{ - sqInt index; - - index = quickPrimitiveInstVarIndexFor(primitiveIndex); - genLoadSlotsourceRegdestReg(index, ReceiverResultReg, ReceiverResultReg); - genUpArrowReturn(); - return UnfailingPrimitive; -} - - -/* because selected by CoInterpreter>>quickPrimitiveGeneratorFor: */ - - /* SimpleStackBasedCogit>>#genQuickReturnSelf */ -sqInt -genQuickReturnSelf(void) -{ - genUpArrowReturn(); - return UnfailingPrimitive; -} - - /* SimpleStackBasedCogit>>#genReturnFalse */ -static sqInt -genReturnFalse(void) -{ - AbstractInstruction *anInstruction; - sqInt constant; - - /* begin genMoveFalseR: */ - constant = falseObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - return genUpArrowReturn(); -} - - /* SimpleStackBasedCogit>>#genReturnNil */ -static sqInt -genReturnNil(void) -{ - AbstractInstruction *anInstruction; - sqInt constant; - - /* begin genMoveNilR: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - return genUpArrowReturn(); -} - - /* SimpleStackBasedCogit>>#genReturnTrue */ -static sqInt -genReturnTrue(void) -{ - AbstractInstruction *anInstruction; - sqInt constant; - - /* begin genMoveTrueR: */ - constant = trueObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - return genUpArrowReturn(); -} - - -/* Can use any of the first 64 literals for the selector and pass up to 3 - arguments. - */ - - /* SimpleStackBasedCogit>>#genSecondExtendedSendBytecode */ -static sqInt -genSecondExtendedSendBytecode(void) -{ - return genSendnumArgs(byte1 & 0x3F, ((usqInt)(byte1)) >> 6); -} - - /* SimpleStackBasedCogit>>#genSendAbsentDynamicSuper:numArgs: */ -static sqInt NoDbgRegParms -genSendAbsentDynamicSupernumArgs(sqInt selectorIndex, sqInt numArgs) -{ - return genNSSendnumArgsdepthsendTable(selectorIndex, numArgs, LookupRuleDynamicSuper, dynamicSuperSendTrampolines); -} - - -/* 160-175 1010 i i i i Send To Absent Implicit Receiver Literal Selector - #iiii With 0 Arguments. - */ - - /* SimpleStackBasedCogit>>#genSendAbsentImplicit0ArgsBytecode */ -static sqInt -genSendAbsentImplicit0ArgsBytecode(void) -{ - return genSendAbsentImplicitnumArgs(byte0 & 15, 0); -} - - /* SimpleStackBasedCogit>>#genSendAbsentImplicit:numArgs: */ -static sqInt NoDbgRegParms -genSendAbsentImplicitnumArgs(sqInt selectorIndex, sqInt numArgs) -{ - return genNSSendnumArgsdepthsendTable(selectorIndex, numArgs, LookupRuleImplicit, implicitReceiverSendTrampolines); -} - - /* SimpleStackBasedCogit>>#genSendAbsentOuter:numArgs:depth: */ -static sqInt NoDbgRegParms -genSendAbsentOuternumArgsdepth(sqInt selectorIndex, sqInt numArgs, sqInt depth) -{ - return genNSSendnumArgsdepthsendTable(selectorIndex, numArgs, depth, outerSendTrampolines); -} - - /* SimpleStackBasedCogit>>#genSendAbsentSelf:numArgs: */ -static sqInt NoDbgRegParms -genSendAbsentSelfnumArgs(sqInt selectorIndex, sqInt numArgs) -{ - return genNSSendnumArgsdepthsendTable(selectorIndex, numArgs, LookupRuleSelf, selfSendTrampolines); -} - - /* SimpleStackBasedCogit>>#genSendLiteralSelector0ArgsBytecode */ -static sqInt -genSendLiteralSelector0ArgsBytecode(void) -{ - return genSendnumArgs(byte0 & 15, 0); -} - - /* SimpleStackBasedCogit>>#genSendLiteralSelector1ArgBytecode */ -static sqInt -genSendLiteralSelector1ArgBytecode(void) -{ - return genSendnumArgs(byte0 & 15, 1); -} - - /* SimpleStackBasedCogit>>#genSendLiteralSelector2ArgsBytecode */ -static sqInt -genSendLiteralSelector2ArgsBytecode(void) -{ - return genSendnumArgs(byte0 & 15, 2); -} - - /* SimpleStackBasedCogit>>#genShortJumpIfFalse */ -static sqInt -genShortJumpIfFalse(void) -{ - sqInt distance; - sqInt target; - - distance = v3ShortForwardBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - target = (distance + 1) + bytecodePC; - return genJumpIfto(falseObject(), target); -} - - /* SimpleStackBasedCogit>>#genShortJumpIfTrue */ -static sqInt -genShortJumpIfTrue(void) -{ - sqInt distance; - sqInt target; - - distance = v3ShortForwardBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - target = (distance + 1) + bytecodePC; - return genJumpIfto(trueObject(), target); -} - - /* SimpleStackBasedCogit>>#genShortUnconditionalJump */ -static sqInt -genShortUnconditionalJump(void) -{ - sqInt distance; - sqInt target; - - distance = v3ShortForwardBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - target = (distance + 1) + bytecodePC; - return genJumpTo(target); -} - - /* SimpleStackBasedCogit>>#genSpecialSelectorEqualsEquals */ -static sqInt -genSpecialSelectorEqualsEquals(void) -{ - return genInlinedIdenticalOrNotIf(0); -} - - /* SimpleStackBasedCogit>>#genSpecialSelectorNotEqualsEquals */ -static sqInt -genSpecialSelectorNotEqualsEquals(void) -{ - return genInlinedIdenticalOrNotIf(1); -} - - /* SimpleStackBasedCogit>>#genSpecialSelectorSend */ -static sqInt -genSpecialSelectorSend(void) -{ - sqInt index; - sqInt numArgs; - - index = byte0 - ( -#if MULTIPLEBYTECODESETS - (bytecodeSetOffset == 0x100 - ? AltFirstSpecialSelector + 0x100 - : FirstSpecialSelector) -#else - FirstSpecialSelector -#endif - ); - numArgs = specialSelectorNumArgs(index); - return genSendnumArgs((-index) - 1, numArgs); -} - - /* SimpleStackBasedCogit>>#genStoreAndPopReceiverVariableBytecode */ -static sqInt -genStoreAndPopReceiverVariableBytecode(void) -{ - return genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(1, byte0 & 7, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); -} - - /* SimpleStackBasedCogit>>#genStoreAndPopRemoteTempLongBytecode */ -static sqInt -genStoreAndPopRemoteTempLongBytecode(void) -{ - return genStorePopRemoteTempAtneedsStoreCheck(1, byte1, byte2, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant))))); -} - - /* SimpleStackBasedCogit>>#genStoreAndPopTemporaryVariableBytecode */ -static sqInt -genStoreAndPopTemporaryVariableBytecode(void) -{ - return genStorePopTemporaryVariable(1, byte0 & 7); -} - - /* SimpleStackBasedCogit>>#genStoreRemoteTempLongBytecode */ -static sqInt -genStoreRemoteTempLongBytecode(void) -{ - return genStorePopRemoteTempAtneedsStoreCheck(0, byte1, byte2, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant))))); -} - - -/* Collect the branch and send data for cogMethod, storing it into arrayObj. */ - - /* SimpleStackBasedCogit>>#mapPCDataFor:into: */ -sqInt -mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj) -{ - sqInt aMethodHeader; - sqInt aMethodHeader1; - sqInt aMethodObj; - sqInt annotation; - sqInt bcpc; - sqInt bsOffset; - sqInt byte; - BytecodeDescriptor *descriptor; - sqInt distance; - sqInt endbcpc; - sqInt errCode; - CogMethod *homeMethod; - sqInt isBackwardBranch; - sqInt isInBlock; - sqInt latestContinuation; - usqInt map; - sqInt mapByte; - usqInt mcpc; - sqInt nExts; - sqInt nextBcpc; - sqInt result; - sqInt startbcpc; - sqInt targetPC; - - latestContinuation = 0; - introspectionDataIndex = 0; - introspectionData = arrayObj; - if (((cogMethod->stackCheckOffset)) == 0) { - assert(introspectionDataIndex == 0); - storePointerUncheckedofObjectwithValue(0, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(1, introspectionData, (((usqInt)cmEntryOffset << 1) | 1)); - storePointerUncheckedofObjectwithValue(2, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(3, introspectionData, (((usqInt)cmNoCheckEntryOffset << 1) | 1)); - return 4; - } - /* begin mapFor:bcpc:performUntil:arg: */ - startbcpc = startPCOfMethod((cogMethod->methodObject)); - assert((((((CogBlockMethod *) cogMethod))->stackCheckOffset)) > 0); - - /* The stack check maps to the start of the first bytecode, - the first bytecode being effectively after frame build. */ - mcpc = (((usqInt)(((CogBlockMethod *) cogMethod)))) + (((((CogBlockMethod *) cogMethod))->stackCheckOffset)); - result = pcDataForAnnotationMcpcBcpcMethod(null, (0 + (((int)((usqInt)(HasBytecodePC) << 1)))), (((char *) mcpc)), startbcpc, (((void *)cogMethod))); - if (result != 0) { - errCode = result; - goto l7; - } - - /* In both CMMethod and CMBlock cases find the start of the map and - skip forward to the bytecode pc map entry for the stack check. */ - bcpc = startbcpc; - if ((((((CogBlockMethod *) cogMethod))->cmType)) == CMMethod) { - /* begin cmIsFullBlock */ - isInBlock = 0; - homeMethod = ((CogMethod *) (((CogBlockMethod *) cogMethod))); - assert(startbcpc == (startPCOfMethodHeader((homeMethod->methodHeader)))); - map = ((((usqInt)homeMethod)) + ((homeMethod->blockSize))) - 1; - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert((annotation == IsAbsPCReference) - || ((annotation == IsObjectReference) - || ((annotation == IsRelativeCall) - || (annotation == IsDisplacementX2N)))); - latestContinuation = startbcpc; - aMethodObj = (homeMethod->methodObject); - endbcpc = (numBytesOf(aMethodObj)) - 1; - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader) - ? 0x100 - : 0) -# else - 0 -# endif - ; - bcpc += deltaToSkipPrimAndErrorStoreInheader(aMethodObj, (homeMethod->methodHeader)); - } - else { - isInBlock = 1; - assert(bcpc == (((((CogBlockMethod *) cogMethod))->startpc))); - homeMethod = cmHomeMethod(((CogBlockMethod *) cogMethod)); - map = findMapLocationForMcpcinMethod((((usqInt)(((CogBlockMethod *) cogMethod)))) + (sizeof(CogBlockMethod)), homeMethod); - assert(map != 0); - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert(((((usqInt)(annotation)) >> AnnotationShift) == HasBytecodePC) - || ((((usqInt)(annotation)) >> AnnotationShift) == IsDisplacementX2N)); - while (((annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift)) != HasBytecodePC) { - map -= 1; - } - - /* skip fiducial; i.e. the map entry for the pc immediately following the method header. */ - map -= 1; - aMethodObj = (homeMethod->methodObject); - bcpc = startbcpc - ( -#if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet((homeMethod->methodHeader)) - ? AltBlockCreationBytecodeSize - : BlockCreationBytecodeSize) -#else // MULTIPLEBYTECODESETS - BlockCreationBytecodeSize -#endif - ); - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader1 = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader1) - ? 0x100 - : 0) -# else - 0 -# endif - ; - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - endbcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, -1, aMethodObj)) - : 0)); - bcpc = startbcpc; - } - nExts = 0; - while ((((usqInt)((byteAt(map)))) >> AnnotationShift) != HasBytecodePC) { - map -= 1; - } - map -= 1; - while (((mapByte = byteAt(map))) != MapEnd) { - - /* defensive; we exit on bcpc */ - if (mapByte >= FirstAnnotation) { - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if (annotation >= HasBytecodePC) { - if ((annotation == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - while (1) { - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - if (isInBlock) { - if (bcpc >= endbcpc) { - errCode = 0; - goto l7; - } - } - else { - if (((descriptor->isReturn)) - && (bcpc >= latestContinuation)) { - errCode = 0; - goto l7; - } - if ((isBranch(descriptor)) - || ((descriptor->isBlockCreation))) { - /* begin latestContinuationPCFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj); - targetPC = (bcpc + ((descriptor->numBytes))) + (((distance < 0) ? 0 : distance)); - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - /* latestContinuation = */ latestContinuation; - } - nextBcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) - : 0)); - if (((descriptor->isMapped)) - || (isInBlock - && ((descriptor->isMappedInBlock)))) break; - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - isBackwardBranch = (isBranch(descriptor)) - && ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) < 0)); - result = pcDataForAnnotationMcpcBcpcMethod(descriptor, ((isBackwardBranch - ? (((sqInt)((usqInt)(annotation) << 1))) + 1 - : ((sqInt)((usqInt)(annotation) << 1)))), (((char *) mcpc)), ((isBackwardBranch - ? bcpc - (2 * nExts) - : bcpc)), (((void *)cogMethod))); - if (result != 0) { - errCode = result; - goto l7; - } - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - } - else { - assert(((((usqInt)(mapByte)) >> AnnotationShift) == IsDisplacementX2N) - || ((((usqInt)(mapByte)) >> AnnotationShift) == IsAnnotationExtension)); - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - errCode = 0; - l7: /* end mapFor:bcpc:performUntil:arg: */; - if (errCode != 0) { - assert(errCode == PrimErrNoMemory); - return -1; - } - if (((cogMethod->blockEntryOffset)) != 0) { - errCode = blockDispatchTargetsForperformarg(cogMethod, pcDataForBlockEntryMethod, ((sqInt)cogMethod)); - if (errCode != 0) { - assert(errCode == PrimErrNoMemory); - return -1; - } - } - return introspectionDataIndex; -} - - /* SimpleStackBasedCogit>>#numSpecialSelectors */ -static sqInt -numSpecialSelectors(void) -{ - return -# if MULTIPLEBYTECODESETS - (bytecodeSetOffset == 0x100 - ? AltNumSpecialSelectors - : NumSpecialSelectors) -# else - NumSpecialSelectors -# endif - ; -} - - -/* Collect the branch and send data for the block method starting at - blockEntryMcpc, storing it into picData. - */ - - /* SimpleStackBasedCogit>>#pcDataForBlockEntry:Method: */ -static usqInt NoDbgRegParms -pcDataForBlockEntryMethod(sqInt blockEntryMcpc, sqInt cogMethod) -{ - storePointerUncheckedofObjectwithValue(introspectionDataIndex, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 1, introspectionData, (((usqInt)(blockEntryMcpc - blockNoContextSwitchOffset) << 1) | 1)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 2, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 3, introspectionData, (((usqInt)blockEntryMcpc << 1) | 1)); - introspectionDataIndex += 4; - return 0; -} - - /* SimpleStackBasedCogit>>#pcDataFor:Annotation:Mcpc:Bcpc:Method: */ -static sqInt NoDbgRegParms -pcDataForAnnotationMcpcBcpcMethod(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *cogMethodArg) -{ - sqInt actualBcpc; - sqInt actualMcpc; - - if (!descriptor) { - - /* this is the stackCheck offset */ - assert(introspectionDataIndex == 0); - storePointerUncheckedofObjectwithValue(introspectionDataIndex, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 1, introspectionData, (((usqInt)cmEntryOffset << 1) | 1)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 2, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 3, introspectionData, (((usqInt)cmNoCheckEntryOffset << 1) | 1)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 4, introspectionData, (((usqInt)(bcpc + 1) << 1) | 1)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 5, introspectionData, (((((((CogMethod *) cogMethodArg))->stackCheckOffset)) << 1) | 1)); - introspectionDataIndex += 6; - return 0; - } - if ((((usqInt)(isBackwardBranchAndAnnotation)) >> 1) >= HasBytecodePC) { - actualBcpc = (((isBackwardBranchAndAnnotation & 1) != 0) - ? bcpc + 1 - : (bcpc + ((descriptor->numBytes))) + 1); - actualMcpc = (((usqInt)mcpc)) - (((usqInt)cogMethodArg)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex, introspectionData, (((usqInt)actualBcpc << 1) | 1)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 1, introspectionData, (((usqInt)actualMcpc << 1) | 1)); - introspectionDataIndex += 2; - } - return 0; -} - - -/* If there is a generator for the current primitive then answer it; - otherwise answer nil. */ - - /* SimpleStackBasedCogit>>#primitiveGeneratorOrNil */ -static PrimitiveDescriptor * -primitiveGeneratorOrNil(void) -{ - PrimitiveDescriptor *primitiveDescriptor; - - if (isQuickPrimitiveIndex(primitiveIndex)) { - - /* an unused one */ - primitiveDescriptor = (&(primitiveGeneratorTable[0])); - (primitiveDescriptor->primitiveGenerator = quickPrimitiveGeneratorFor(primitiveIndex)); - return primitiveDescriptor; - } - if (((primitiveIndex >= 1) && (primitiveIndex <= MaxCompiledPrimitiveIndex))) { - return (&(primitiveGeneratorTable[primitiveIndex])); - } - return null; -} - - /* SimpleStackBasedCogit>>#v3:Block:Code:Size: */ -static sqInt NoDbgRegParms -v3BlockCodeSize(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - assert(nExts <= 0); - return (((sqInt)((usqInt)((fetchByteofObject(pc + 2, aMethodObj))) << 8))) + (fetchByteofObject(pc + 3, aMethodObj)); -} - - -/* Answer the distance of a two byte forward long jump. */ - - /* SimpleStackBasedCogit>>#v3:LongForward:Branch:Distance: */ -static sqInt NoDbgRegParms -v3LongForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - assert(nExts == 0); - return (((sqInt)((usqInt)(((fetchByteofObject(pc, aMethodObj)) & 3)) << 8))) + (fetchByteofObject(pc + 1, aMethodObj)); -} - - -/* Answer the distance of a two byte forward long jump. */ - - /* SimpleStackBasedCogit>>#v3:Long:Branch:Distance: */ -static sqInt NoDbgRegParms -v3LongBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - assert(nExts == 0); - return (((sqInt)((usqInt)((((fetchByteofObject(pc, aMethodObj)) & 7) - 4)) << 8))) + (fetchByteofObject(pc + 1, aMethodObj)); -} - - -/* N.B. This serves for both BlueBook/V3 and V4 short jumps. */ - - /* SimpleStackBasedCogit>>#v3:ShortForward:Branch:Distance: */ -static sqInt NoDbgRegParms -v3ShortForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - assert(nExts == 0); - return ((fetchByteofObject(pc, aMethodObj)) & 7) + 1; -} - - -/* 253 11111101 eei i i kkk jjjjjjjj Push Closure Num Copied iii (+ Ext A - // 16 * 8) Num Args kkk (+ Ext A \\ 16 * 8) BlockSize jjjjjjjj (+ Ext B * - 256). ee = num extensions - */ - - /* SimpleStackBasedCogit>>#v4:Block:Code:Size: */ -static sqInt NoDbgRegParms -v4BlockCodeSize(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - sqInt byte; - sqInt byteOne; - sqInt extAValue; - sqInt extBValue; - sqInt extBValue1; - sqInt extByte; - sqInt pc1; - - - /* If nExts < 0 it isn't known and we rely on the number of extensions encoded in the eeiiikkk byte. */ - byteOne = fetchByteofObject(pc + 1, aMethodObj); - assert((nExts < 0) - || (nExts == (((usqInt)(byteOne)) >> 6))); - /* begin parseV4Exts:priorTo:in:into: */ - extAValue = (extBValue1 = 0); - pc1 = (pc - (((usqInt)(byteOne)) >> 6)) - (((usqInt)(byteOne)) >> 6); - while (pc1 < pc) { - byte = fetchByteofObject(pc1, aMethodObj); - pc1 += 1; - extByte = fetchByteofObject(pc1, aMethodObj); - pc1 += 1; - assert((byte == 224) - || (byte == 225)); - if (byte == 224) { - extAValue = ((((sqInt)((usqInt)(extAValue) << 8)))) + extByte; - } - else { - extBValue1 = ((extBValue1 == 0) - && (extByte > 0x7F) - ? extByte - 0x100 - : ((((sqInt)((usqInt)(extBValue1) << 8)))) + extByte); - } - } - extBValue = extBValue1; - return (fetchByteofObject(pc + 2, aMethodObj)) + (((sqInt)((usqInt)(extBValue) << 8))); -} - - -/* 242 11110010 i i i i i i i i Jump i i i i i i i i (+ Extend B * 256, - where bbbbbbbb = sddddddd, e.g. -32768 = i=0, a=0, s=1) - */ -/* 243 11110011 i i i i i i i i Pop and Jump 0n True i i i i i i i i (+ - Extend A * 256) - */ -/* 244 11110100 i i i i i i i i Pop and Jump 0n False i i i i i i i i (+ - Extend A * 256) - */ - - /* SimpleStackBasedCogit>>#v4:LongForward:Branch:Distance: */ -static sqInt NoDbgRegParms -v4LongForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - sqInt byte; - sqInt extAValue; - sqInt extBValue; - sqInt extBValue1; - sqInt extByte; - sqInt pc1; - - assert(nExts >= 0); - /* begin parseV4Exts:priorTo:in:into: */ - extAValue = (extBValue1 = 0); - pc1 = (pc - nExts) - nExts; - while (pc1 < pc) { - byte = fetchByteofObject(pc1, aMethodObj); - pc1 += 1; - extByte = fetchByteofObject(pc1, aMethodObj); - pc1 += 1; - assert((byte == 224) - || (byte == 225)); - if (byte == 224) { - extAValue = ((((sqInt)((usqInt)(extAValue) << 8)))) + extByte; - } - else { - extBValue1 = ((extBValue1 == 0) - && (extByte > 0x7F) - ? extByte - 0x100 - : ((((sqInt)((usqInt)(extBValue1) << 8)))) + extByte); - } - } - extBValue = extBValue1; - return (fetchByteofObject(pc + 1, aMethodObj)) + (((sqInt)((usqInt)(extBValue) << 8))); -} - - -/* 242 11110010 i i i i i i i i Jump i i i i i i i i (+ Extend B * 256, - where bbbbbbbb = sddddddd, e.g. -32768 = i=0, a=0, s=1) - */ - - /* SimpleStackBasedCogit>>#v4:Long:Branch:Distance: */ -static sqInt NoDbgRegParms -v4LongBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - sqInt byte; - sqInt extAValue; - sqInt extBValue; - sqInt extBValue1; - sqInt extByte; - sqInt pc1; - - assert(nExts >= 0); - /* begin parseV4Exts:priorTo:in:into: */ - extAValue = (extBValue1 = 0); - pc1 = (pc - nExts) - nExts; - while (pc1 < pc) { - byte = fetchByteofObject(pc1, aMethodObj); - pc1 += 1; - extByte = fetchByteofObject(pc1, aMethodObj); - pc1 += 1; - assert((byte == 224) - || (byte == 225)); - if (byte == 224) { - extAValue = ((((sqInt)((usqInt)(extAValue) << 8)))) + extByte; - } - else { - extBValue1 = ((extBValue1 == 0) - && (extByte > 0x7F) - ? extByte - 0x100 - : ((((sqInt)((usqInt)(extBValue1) << 8)))) + extByte); - } - } - extBValue = extBValue1; - return (fetchByteofObject(pc + 1, aMethodObj)) + (((sqInt)((usqInt)(extBValue) << 8))); -} - - -/* Add a blockStart for an embedded block. For a binary tree walk block - dispatch blocks must be compiled in pc/depth-first order but are scanned - in breadth-first - order, so do an insertion sort (which of course is really a bubble sort - because we - have to move everything higher to make room). */ - - /* StackToRegisterMappingCogit>>#addBlockStartAt:numArgs:numCopied:span: */ -static BlockStart * NoDbgRegParms -addBlockStartAtnumArgsnumCopiedspan(sqInt bytecodepc, sqInt numArgs, sqInt numCopied, sqInt span) -{ - BlockStart *blockStart; - sqInt i; - sqInt j; - - - /* Transcript ensureCr; nextPutAll: 'addBlockStartAt: '; print: bytecodepc; cr; flush. */ - if (blockCount > 0) { - i = blockCount - 1; - while (1) { - - /* check for repeat addition during recompilation due to initialNil miscount. */ - blockStart = (&(blockStarts[i])); - if (((blockStart->startpc)) == bytecodepc) { - return blockStart; - } - if (!((((blockStart->startpc)) > bytecodepc) - && (i > 0))) break; - i -= 1; - } - for (j = blockCount; j >= (i + 1); j += -1) { - blockStarts[j] = (blockStarts[j - 1]); - } - blockStart = (&(blockStarts[i + 1])); - } - else { - blockStart = (&(blockStarts[blockCount])); - } - blockCount += 1; - (blockStart->startpc = bytecodepc); - (blockStart->numArgs = numArgs); - (blockStart->numCopied = numCopied); - (blockStart->numInitialNils = 0); - (blockStart->stackCheckLabel = null); - (blockStart->hasInstVarRef = 0); - (blockStart->span = span); - return blockStart; -} - - -/* e.g. Receiver Receiver or Receiver Receiver (RISC) - Selector/Arg0 => Arg1 Selector/Arg0 => Arg1 - Arg1 Arg2 Arg1 Arg2 - Arg2 Arg3 Arg2 sp-> Arg3 - Arg3 sp-> retpc sp-> Arg3 - sp-> retpc */ -/* Generate code to adjust the possibly stacked arguments immediately - before jumping to a method looked up by a perform primitive. */ - - /* StackToRegisterMappingCogit>>#adjustArgumentsForPerform: */ -static void NoDbgRegParms -adjustArgumentsForPerform(sqInt numArgs) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction3; - sqInt index; - - assert((numRegArgs()) <= 2); - assert(numArgs >= 1); - if (numArgs <= 2 /* numRegArgs */) { - if (numArgs == 2) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, Arg0Reg); - } - return; - } - if ((3) == numArgs) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, SPReg, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, BytesPerWord, SPReg, Arg0Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(AddCqR, (numArgs + 1) * BytesPerWord, SPReg); - return; - } - for (index = (numArgs - 2); index >= 0; index += -1) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveMwrR, index * BytesPerWord, SPReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperandoperand(MoveRMwr, TempReg, (index + 1) * BytesPerWord, SPReg); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperand(AddCqR, BytesPerWord, SPReg); -} - - -/* If the stack entry is already in a register not conflicting with regMask, - answers it, - else allocate a new register not conflicting with reg mask - */ - - /* StackToRegisterMappingCogit>>#allocateRegForStackEntryAt:notConflictingWith: */ -static sqInt NoDbgRegParms -allocateRegForStackEntryAtnotConflictingWith(sqInt index, sqInt regMask) -{ - sqInt mask; - CogSimStackEntry *stackEntry; - - stackEntry = ssValue(index); - mask = registerMaskOrNone(stackEntry); - if ((mask != 0) - && ((!(mask & regMask)))) { - flag("TODO"); - return registerOrNone(stackEntry); - } - return allocateRegNotConflictingWith(regMask); -} - - -/* if there's a free register, use it */ - - /* StackToRegisterMappingCogit>>#allocateRegNotConflictingWith: */ -static sqInt NoDbgRegParms -allocateRegNotConflictingWith(sqInt regMask) -{ - sqInt reg; - - reg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); - if (reg == NoReg) { - - /* No free register, choose one that does not conflict with regMask */ - reg = freeAnyRegNotConflictingWith(regMask); - } - if (reg == ReceiverResultReg) { - - /* If we've allocated RcvrResultReg, it's not live anymore */ - voidReceiverResultRegContainsSelf(); - } - return reg; -} - - /* StackToRegisterMappingCogit>>#anyReferencesToRegister:inTopNItems: */ -static sqInt NoDbgRegParms -anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n) -{ - sqInt i; - sqInt regMask; - - /* begin registerMaskFor: */ - regMask = 1U << reg; - for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { - if ((((registerMask(simStackAt(i))) & regMask) != 0)) { - return 1; - } - } - return 0; -} - - -/* This is a static version of ceCallCogCodePopReceiverArg0Regs - for break-pointing when debugging in C. */ -/* This exists only for break-pointing. */ - - /* StackToRegisterMappingCogit>>#callCogCodePopReceiverArg0Regs */ -void -callCogCodePopReceiverArg0Regs(void) -{ - realCECallCogCodePopReceiverArg0Regs(); -} - - -/* This is a static version of ceCallCogCodePopReceiverArg1Arg0Regs - for break-pointing when debugging in C. */ -/* This exists only for break-pointing. */ - - /* StackToRegisterMappingCogit>>#callCogCodePopReceiverArg1Arg0Regs */ -void -callCogCodePopReceiverArg1Arg0Regs(void) -{ - realCECallCogCodePopReceiverArg1Arg0Regs(); -} - - -/* Loop over bytecodes, dispatching to the generator for each bytecode, - handling fixups in due course. - */ - - /* StackToRegisterMappingCogit>>#compileAbstractInstructionsFrom:through: */ -static sqInt NoDbgRegParms -compileAbstractInstructionsFromthrough(sqInt start, sqInt end) -{ - BytecodeDescriptor *descriptor; - BytecodeFixup *fixup; - sqInt nExts; - sqInt nextOpcodeIndex; - sqInt result; - - traceSimStack(); - bytecodePC = start; - nExts = (result = 0); - descriptor = null; - deadCode = 0; - while (1) { - maybeHaltIfDebugPC(); - mergeWithFixupIfRequired((fixup = fixupAt(bytecodePC))); - descriptor = loadBytesAndGetDescriptor(); - nextOpcodeIndex = opcodeIndex; - result = (deadCode - ? mapDeadDescriptorIfNeeded(descriptor) - : ((descriptor->generator))()); - if (result == 0) { - /* begin assertExtsAreConsumed: */ - if (!((descriptor->isExtension))) { - assert((extA == 0) - && ((extB == 0) - && (numExtB == 0))); - } - } - traceDescriptor(descriptor); - traceSimStack(); - /* begin patchFixupTargetIfNeeded:nextOpcodeIndex: */ - if ((((((usqInt)((fixup->targetInstruction)))) >= NeedsNonMergeFixupFlag) && ((((usqInt)((fixup->targetInstruction)))) <= NeedsMergeFixupFlag))) { - - /* There is a fixup for this bytecode. It must point to the first generated - instruction for this bytecode. If there isn't one we need to add a label. */ - if (opcodeIndex == nextOpcodeIndex) { - /* begin Label */ - genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (fixup->targetInstruction = abstractInstructionAt(nextOpcodeIndex)); - } - /* begin maybeDumpLiterals: */ - if (((isBranch(descriptor)) - && (!(((descriptor->isBranchTrue)) - || ((descriptor->isBranchFalse))))) - || ((descriptor->isReturn))) { - /* begin dumpLiterals: */ - !(((isBranch(descriptor)) - && (!(((descriptor->isBranchTrue)) - || ((descriptor->isBranchFalse))))) - || ((descriptor->isReturn))); - } - /* begin nextBytecodePCFor:exts: */ - bytecodePC = (bytecodePC + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? ((descriptor->spanFunction))(descriptor, bytecodePC, nExts, methodObj) - : 0)); - if (!((result == 0) - && (bytecodePC <= end))) break; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - /* begin checkEnoughOpcodes */ - if (opcodeIndex > numAbstractOpcodes) { - error("Cog JIT internal error. Too many abstract opcodes. Num opcodes heuristic is too optimistic."); - } - return result; -} - - /* StackToRegisterMappingCogit>>#compileBlockBodies */ -static sqInt -compileBlockBodies(void) -{ - BlockStart *blockStart; - sqInt compiledBlocksCount; - sqInt initialCounterIndex; - sqInt initialIndexOfIRC; - sqInt initialOpcodeIndex; - sqInt initialStackPtr; - sqInt (* const pushNilSizeFunction)(sqInt,sqInt) = v3or4PushNilSizenumInitialNils; - sqInt result; - sqInt savedNeedsFrame; - sqInt savedNumArgs; - sqInt savedNumTemps; - - initialIndexOfIRC = 0; - assert(blockCount > 0); - savedNeedsFrame = needsFrame; - savedNumArgs = methodOrBlockNumArgs; - savedNumTemps = methodOrBlockNumTemps; - inBlock = InVanillaBlock; - compiledBlocksCount = 0; - while (compiledBlocksCount < blockCount) { - compilationPass = 1; - blockStart = blockStartAt(compiledBlocksCount); - if (((result = scanBlock(blockStart))) < 0) { - return result; - } - initialOpcodeIndex = opcodeIndex; - - /* for SistaCogit */ - initialCounterIndex = 0 /* maybeCounterIndex */; - initialIndexOfIRC = indexOfIRC; - while (1) { - compileBlockEntry(blockStart); - initialStackPtr = simStackPtr; - if (((result = compileAbstractInstructionsFromthrough(((blockStart->startpc)) + (pushNilSizeFunction(methodObj, ((blockStart->numInitialNils)))), (((blockStart->startpc)) + ((blockStart->span))) - 1))) < 0) { - return result; - } - if (initialStackPtr == simStackPtr) break; - assert((initialStackPtr > simStackPtr) - || (deadCode)); - - /* for asserts */ - compilationPass += 1; - (blockStart->numInitialNils = (((blockStart->numInitialNils)) + simStackPtr) - initialStackPtr); - (((blockStart->fakeHeader))->dependent = null); - reinitializeFixupsFromthrough(((blockStart->startpc)) + ((blockStart->numInitialNils)), (((blockStart->startpc)) + ((blockStart->span))) - 1); - bzero(abstractOpcodes + initialOpcodeIndex, - (opcodeIndex - initialOpcodeIndex) * sizeof(AbstractInstruction)); - opcodeIndex = initialOpcodeIndex; - indexOfIRC = initialIndexOfIRC; - } - compiledBlocksCount += 1; - } - needsFrame = savedNeedsFrame; - methodOrBlockNumArgs = savedNumArgs; - methodOrBlockNumTemps = savedNumTemps; - return 0; -} - - -/* Build a frame for a block activation. See CoInterpreter - class>>initializeFrameIndices. closure (in ReceiverResultReg) - arg0 - ... - argN - caller's saved ip/this stackPage (for a base frame) - fp-> saved fp - method - context (uninitialized?) - receiver - first temp - ... - sp-> Nth temp - Avoid use of SendNumArgsReg which is the flag determining whether - context switch is allowed on stack-overflow. */ -/* Build a frame for a block activation. See CoInterpreter - class>>initializeFrameIndices. Override to push the register receiver and - register arguments, if any, and to correctly - initialize the explicitly nilled/pushed temp entries (they are /not/ of - type constant nil). */ - - /* StackToRegisterMappingCogit>>#compileBlockFrameBuild: */ -static void NoDbgRegParms -compileBlockFrameBuild(BlockStart *blockStart) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction * cascade0; - sqInt constant; - sqInt constant1; - sqInt i; - sqInt ign; - - /* begin annotateBytecode: */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction->annotation = HasBytecodePC); - /* begin PushR: */ - genoperand(PushR, LinkReg); - /* begin PushR: */ - genoperand(PushR, FPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SPReg, FPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, ClassReg); - cascade0 = (blockStart->fakeHeader); - addDependent(cascade0, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)((blockStart->fakeHeader))), genoperand(PushCw, ((sqInt)((blockStart->fakeHeader))))))); - /* begin setLabelOffset: */ - ((cascade0->operands))[1] = MFMethodFlagIsBlockFlag; - annotateobjRef(checkLiteralforInstruction(nilObject(), genoperand(PushCw, nilObject())), nilObject()); - if ((blockStart->hasInstVarRef)) { - - /* Use ReceiverResultReg for Context to agree with store check trampoline */ - genLoadSlotsourceRegdestReg(ClosureOuterContextIndex, ClassReg, ReceiverResultReg); - genLoadSlotsourceRegdestReg(ReceiverIndex, ReceiverResultReg, Arg0Reg); - genEnsureOopInRegNotForwardedscratchRegupdatingSlotin(Arg0Reg, TempReg, ReceiverIndex, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ReceiverResultReg); - } - else { - genLoadSlotsourceRegdestReg(ClosureOuterContextIndex, ClassReg, Arg0Reg); - genLoadSlotsourceRegdestReg(ReceiverIndex, Arg0Reg, ReceiverResultReg); - } - /* begin PushR: */ - genoperand(PushR, ReceiverResultReg); - for (i = 0; i < ((blockStart->numCopied)); i += 1) { - genLoadSlotsourceRegdestReg(i + ClosureFirstCopiedValueIndex, ClassReg, TempReg); - /* begin PushR: */ - genoperand(PushR, TempReg); - } - (blockStart->stackCheckLabel = compileStackOverflowCheck(1)); - methodOrBlockNumTemps = (((blockStart->numArgs)) + ((blockStart->numCopied))) + ((blockStart->numInitialNils)); - initSimStackForFramefulMethod((blockStart->startpc)); - if (((blockStart->numInitialNils)) > 0) { - if (((blockStart->numInitialNils)) > 1) { - /* begin genMoveNilR: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, TempReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, TempReg); - } - for (ign = 1; ign <= ((blockStart->numInitialNils)); ign += 1) { - /* begin PushR: */ - genoperand(PushR, TempReg); - } - } - else { - /* begin genPushConstant: */ - constant1 = nilObject(); - if (shouldAnnotateObjectReference(constant1)) { - annotateobjRef(checkLiteralforInstruction(constant1, genoperand(PushCw, constant1)), constant1); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperand(PushCq, constant1); - } - } - } -} - - -/* Make sure ReceiverResultReg holds the receiver, loaded from the closure, - which is what is initially in ReceiverResultReg. We must annotate the - first instruction in vanilla blocks so that - findMethodForStartBcpc:inHomeMethod: can function. We need two annotations - because the first is a fiducial. */ -/* Make sure ReceiverResultReg holds the receiver, loaded from - the closure, which is what is initially in ReceiverResultReg */ - - /* StackToRegisterMappingCogit>>#compileBlockFramelessEntry: */ -static void NoDbgRegParms -compileBlockFramelessEntry(BlockStart *blockStart) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - - methodOrBlockNumTemps = (((blockStart->numArgs)) + ((blockStart->numCopied))) + ((blockStart->numInitialNils)); - initSimStackForFramelessBlock((blockStart->startpc)); - if (!(((blockStart->entryLabel)) == null)) { - /* begin annotateBytecode: */ - abstractInstruction = (blockStart->entryLabel); - (abstractInstruction->annotation = HasBytecodePC); - /* begin annotateBytecode: */ - abstractInstruction1 = (blockStart->entryLabel); - (abstractInstruction1->annotation = HasBytecodePC); - } - if ((blockStart->hasInstVarRef)) { - - /* Use ReceiverResultReg for Context to agree with store check trampoline */ - genLoadSlotsourceRegdestReg(ClosureOuterContextIndex, ReceiverResultReg, ReceiverResultReg); - genLoadSlotsourceRegdestReg(ReceiverIndex, ReceiverResultReg, Arg0Reg); - genEnsureOopInRegNotForwardedscratchRegupdatingSlotin(Arg0Reg, TempReg, ReceiverIndex, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ReceiverResultReg); - } - else { - genLoadSlotsourceRegdestReg(ClosureOuterContextIndex, ReceiverResultReg, TempReg); - genLoadSlotsourceRegdestReg(ReceiverIndex, TempReg, ReceiverResultReg); - } -} - - /* StackToRegisterMappingCogit>>#compileCogMethod: */ -static CogMethod * NoDbgRegParms -compileCogMethod(sqInt selector) -{ - sqInt allocBytes; - int extra; - sqInt fixupBytes; - sqInt numBlocks; - sqInt numBytecodes; - sqInt numberOfAbstractOpcodes; - sqInt numCleanBlocks; - sqInt opcodeBytes; - sqInt result; - - methodOrBlockNumTemps = tempCountOf(methodObj); - setHasMovableLiteral(0); - setHasYoungReferent((isYoungObject(methodObj)) - || (isYoung(selector))); - methodOrBlockNumArgs = argumentCountOf(methodObj); - inBlock = 0; - maxLitIndex = -1; - extra = ((((primitiveIndex = primitiveIndexOf(methodObj))) > 0) - && (!(isQuickPrimitiveIndex(primitiveIndex))) - ? 30 - : 10); - - /* initial estimate. Actual endPC is determined in scanMethod. */ - initialPC = startPCOfMethod(methodObj); - endPC = (isQuickPrimitiveIndex(primitiveIndex) - ? initialPC - 1 - : numBytesOf(methodObj)); - numBytecodes = (endPC - initialPC) + 1; - /* begin allocateOpcodes:bytecodes:ifFail: */ - numberOfAbstractOpcodes = (numBytecodes + extra) * 10 /* estimateOfAbstractOpcodesPerBytecodes */; - numAbstractOpcodes = numberOfAbstractOpcodes; - opcodeBytes = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupBytes = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - - /* Document the fact that the MaxStackAllocSize ensures that the number of abstract - opcodes fits in a 16 bit integer (e.g. CogBytecodeFixup's instructionIndex). */ - allocBytes = opcodeBytes + fixupBytes; - assert((((sizeof(CogAbstractInstruction)) + (sizeof(CogBytecodeFixup))) * 0xC000) > MaxStackAllocSize); - if (allocBytes > MaxStackAllocSize) { - return ((CogMethod *) MethodTooBig); - goto l1; - } - abstractOpcodes = alloca(allocBytes); - bzero(abstractOpcodes, allocBytes); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeBytes)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - l1: /* end allocateOpcodes:bytecodes:ifFail: */; - if (((numBlocks = scanMethod())) < 0) { - return ((CogMethod *) numBlocks); - } - numCleanBlocks = scanForCleanBlocks(); - if (methodFoundInvalidPostScan()) { - return ((CogMethod *) ShouldNotJIT); - } - allocateBlockStarts(numBlocks + numCleanBlocks); - blockCount = 0; - if (numCleanBlocks > 0) { - addCleanBlockStarts(); - } - if (!(maybeAllocAndInitIRCs())) { - - /* Inaccurate error code, but it'll do. This will likely never fail. */ - return ((CogMethod *) InsufficientCodeSpace); - } - blockEntryLabel = null; - (methodLabel->dependent = null); - if (((result = compileEntireMethod())) < 0) { - return ((CogMethod *) result); - } - return generateCogMethod(selector); -} - - -/* Compile the abstract instructions for the entire method, including blocks. */ -/* Compile the abstract instructions for the entire method, including blocks. */ - - /* StackToRegisterMappingCogit>>#compileEntireMethod */ -static sqInt -compileEntireMethod(void) -{ - sqInt result; - - regArgsHaveBeenPushed = 0; - /* begin preenMethodLabel */ - (((((AbstractInstruction *) methodLabel))->operands))[1] = 0; - compileAbort(); - compileEntry(); - if (((result = compilePrimitive())) < 0) { - return result; - } - compileFrameBuild(); - if (((result = compileMethodBody())) < 0) { - return result; - } - if (blockCount == 0) { - return 0; - } - if (((result = compileBlockBodies())) < 0) { - return result; - } - return compileBlockDispatch(); -} - - -/* Build a frame for a CogMethod activation. See CoInterpreter - class>>initializeFrameIndices. receiver (in ReceiverResultReg) - arg0 - ... - argN - caller's saved ip/this stackPage (for a base frame) - fp-> saved fp - method - context (uninitialized?) - receiver - first temp - ... - sp-> Nth temp - If there is a primitive and an error code the Nth temp is the error code. - Ensure SendNumArgsReg is set early on (incidentally to nilObj) because - it is the flag determining whether context switch is allowed on - stack-overflow. */ -/* Build a frame for a CogMethod activation. See CoInterpreter - class>>initializeFrameIndices. Override to push the register receiver and - register arguments, if any. */ - - /* StackToRegisterMappingCogit>>#compileFrameBuild */ -static void -compileFrameBuild(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt constant; - sqInt i; - sqInt iLimiT; - - -# if IMMUTABILITY - if (useTwoPaths) { - compileTwoPathFrameBuild(); - return; - } -# endif - if (!needsFrame) { - if (useTwoPaths) { - compileTwoPathFramelessInit(); - } - initSimStackForFramelessMethod(initialPC); - return; - } - assert(!(useTwoPaths)); - genPushRegisterArgs(); - if (!needsFrame) { - return; - } - /* begin PushR: */ - genoperand(PushR, LinkReg); - /* begin PushR: */ - genoperand(PushR, FPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SPReg, FPReg); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperand(PushCw, ((sqInt)methodLabel))))); - /* begin genMoveNilR: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, SendNumArgsReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, SendNumArgsReg); - } - /* begin PushR: */ - genoperand(PushR, SendNumArgsReg); - /* begin PushR: */ - genoperand(PushR, ReceiverResultReg); - for (i = (methodOrBlockNumArgs + 1), iLimiT = (temporaryCountOfMethodHeader(methodHeader)); i <= iLimiT; i += 1) { - /* begin PushR: */ - genoperand(PushR, SendNumArgsReg); - } - if (((primitiveIndexOfMethodheader(methodObj, methodHeader)) > 0) - && ((longStoreBytecodeForHeader(methodHeader)) == (fetchByteofObject((startPCOfMethod(methodObj)) + (sizeOfCallPrimitiveBytecode(methodHeader)), methodObj)))) { - compileGetErrorCode(); - } - stackCheckLabel = compileStackOverflowCheck(canContextSwitchIfActivatingheader(methodObj, methodHeader)); - if (numIRCs > 0) { - /* begin checkLiteral:forInstruction: */ - anInstruction1 = genoperand(PrefetchAw, theIRCs); - } - initSimStackForFramefulMethod(initialPC); -} - - -/* Build a frame for a CogMethod activation. See CoInterpreter - class>>initializeFrameIndices. receiver (in ReceiverResultReg) - arg0 - ... - argN - caller's saved ip/this stackPage (for a base frame) - fp-> saved fp - method - context (uninitialized?) - receiver - first temp - ... - sp-> Nth temp - If there is a primitive and an error code the Nth temp is the error code. - Ensure SendNumArgsReg is set early on (incidentally to nilObj) because - it is the flag determining whether context switch is allowed on - stack-overflow. */ -/* We are in a method where the frame is needed *only* for instance variable - store, typically a setter method. - This case has 20% overhead with Immutability compared to setter without - immutability because of the stack - frame creation. We compile two path, one where the object is immutable, - one where it isn't. At the beginning - of the frame build, we take one path or the other depending on the - receiver mutability. - - Note: this specific case happens only where there are only instance - variabel stores. We could do something - similar for literal variable stores, but we don't as it's too uncommon. - */ - - /* StackToRegisterMappingCogit>>#compileTwoPathFrameBuild */ -#if IMMUTABILITY -static void -compileTwoPathFrameBuild(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - sqInt constant; - sqInt i; - sqInt iLimiT; - AbstractInstruction * jumpImmutable; - AbstractInstruction * jumpOld; - - assert(useTwoPaths); - assert(blockCount == 0); - jumpImmutable = genJumpImmutablescratchReg(ReceiverResultReg, TempReg); - - /* first path. The receiver is mutable */ - - /* N.B. FLAGS := destReg - scratchReg */ - /* begin checkQuickConstant:forInstruction: */ - storeCheckBoundary(); - anInstruction = genoperandoperand(CmpCqR, storeCheckBoundary(), ReceiverResultReg); - /* begin JumpAboveOrEqual: */ - jumpOld = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - assert(!needsFrame); - initSimStackForFramelessMethod(initialPC); - /* begin compileMethodBody */ - if (endPC < initialPC) { - goto l3; - } - compileAbstractInstructionsFromthrough(initialPC + (deltaToSkipPrimAndErrorStoreInheader(methodObj, methodHeader)), endPC); - l3: /* end compileMethodBody */; - - /* reset because it impacts inst var store compilation */ - useTwoPaths = 0; - needsFrame = 1; - jmpTarget(jumpOld, jmpTarget(jumpImmutable, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - genPushRegisterArgs(); - if (!needsFrame) { - return; - } - /* begin PushR: */ - genoperand(PushR, LinkReg); - /* begin PushR: */ - genoperand(PushR, FPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SPReg, FPReg); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperand(PushCw, ((sqInt)methodLabel))))); - /* begin genMoveNilR: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, SendNumArgsReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, constant, SendNumArgsReg); - } - /* begin PushR: */ - genoperand(PushR, SendNumArgsReg); - /* begin PushR: */ - genoperand(PushR, ReceiverResultReg); - for (i = (methodOrBlockNumArgs + 1), iLimiT = (temporaryCountOfMethodHeader(methodHeader)); i <= iLimiT; i += 1) { - /* begin PushR: */ - genoperand(PushR, SendNumArgsReg); - } - if (((primitiveIndexOfMethodheader(methodObj, methodHeader)) > 0) - && ((longStoreBytecodeForHeader(methodHeader)) == (fetchByteofObject((startPCOfMethod(methodObj)) + (sizeOfCallPrimitiveBytecode(methodHeader)), methodObj)))) { - compileGetErrorCode(); - } - stackCheckLabel = compileStackOverflowCheck(canContextSwitchIfActivatingheader(methodObj, methodHeader)); - if (numIRCs > 0) { - /* begin checkLiteral:forInstruction: */ - anInstruction2 = genoperand(PrefetchAw, theIRCs); - } - initSimStackForFramefulMethod(initialPC); -} -#endif /* IMMUTABILITY */ - - -/* We are in a frameless method with at least two inst var stores. We compile - two paths, - one where the object is in new space, and one where it isn't. At the - beginning - of the method, we take one path or the other depending on the receiver - being in newSpace. - */ - - /* StackToRegisterMappingCogit>>#compileTwoPathFramelessInit */ -static void -compileTwoPathFramelessInit(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction * jumpOld; - - assert(!(IMMUTABILITY)); - assert(!(needsFrame)); - assert(useTwoPaths); - - /* first path. The receiver is young */ - - /* N.B. FLAGS := destReg - scratchReg */ - /* begin checkQuickConstant:forInstruction: */ - storeCheckBoundary(); - anInstruction = genoperandoperand(CmpCqR, storeCheckBoundary(), ReceiverResultReg); - /* begin JumpAboveOrEqual: */ - jumpOld = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - initSimStackForFramelessMethod(initialPC); - /* begin compileMethodBody */ - if (endPC < initialPC) { - goto l1; - } - compileAbstractInstructionsFromthrough(initialPC + (deltaToSkipPrimAndErrorStoreInheader(methodObj, methodHeader)), endPC); - l1: /* end compileMethodBody */; - - /* reset because it impacts inst var store compilation */ - useTwoPaths = 0; - jmpTarget(jumpOld, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); -} - - /* StackToRegisterMappingCogit>>#cPICMissTrampolineFor: */ -static sqInt NoDbgRegParms -cPICMissTrampolineFor(sqInt numArgs) -{ - return picMissTrampolines[((numArgs < (3)) ? numArgs : (3))]; -} - - -/* Replaces the Blue Book double-extended send [132], in which the first byte - was wasted on 8 bits of argument count. - Here we use 3 bits for the operation sub-type (opType), and the remaining - 5 bits for argument count where needed. - The last byte give access to 256 instVars or literals. - See also secondExtendedSendBytecode - */ - - /* StackToRegisterMappingCogit>>#doubleExtendedDoAnythingBytecode */ -static sqInt -doubleExtendedDoAnythingBytecode(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *abstractInstruction2; - sqInt opType; - - opType = ((usqInt)(byte1)) >> 5; - if (opType == 0) { - return genSendnumArgs(byte2, byte1 & 0x1F); - } - if (opType == 1) { - return genSendSupernumArgs(byte2, byte1 & 0x1F); - } - switch (opType) { - case 2: - if (isReadMediatedContextInstVarIndex(byte2)) { - genPushMaybeContextReceiverVariable(byte2); - } - else { - genPushReceiverVariable(byte2); - /* begin annotateInstructionForBytecode */ - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (abstractInstruction->annotation = HasBytecodePC); - return 0; - } - break; - case 3: - genPushLiteralIndex(byte2); - /* begin annotateInstructionForBytecode */ - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction1 = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction1 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (abstractInstruction1->annotation = HasBytecodePC); - return 0; - - case 4: - genPushLiteralVariable(byte2); - break; - case 7: - genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(0, byte2, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); -# if IMMUTABILITY - - /* genStorePop:LiteralVariable: annotates; don't annotate twice */ - return 0; -# endif - break; - default: - - /* 5 & 6 */ - if (isWriteMediatedContextInstVarIndex(byte2)) { - genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(opType == 6, byte2, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } - else { - genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(opType == 6, byte2, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } -# if IMMUTABILITY - - /* genStorePop:...ReceiverVariable: annotate; don't annotate twice */ - return 0; -# endif -; - } - assert(needsFrame); - assert(!(prevInstIsPCAnnotated())); - /* begin annotateBytecode: */ - abstractInstruction2 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction2->annotation = HasBytecodePC); - return 0; -} - - /* StackToRegisterMappingCogit>>#duplicateTopBytecode */ -static sqInt -duplicateTopBytecode(void) -{ - SimStackEntry desc; - - /* begin ssTopDescriptor */ - desc = simStack[simStackPtr]; - return ssPushDesc(desc); -} - - -/* Make sure there's a flagged fixup at the target pc in fixups. - Initially a fixup's target is just a flag. Later on it is replaced with a - proper instruction. */ - - /* StackToRegisterMappingCogit>>#ensureFixupAt: */ -static BytecodeFixup * NoDbgRegParms -ensureFixupAt(sqInt targetPC) -{ - BytecodeFixup *fixup; - - /* begin fixupAt: */ - fixup = fixupAtIndex(targetPC - initialPC); - traceFixupmerge(fixup, 1); - if ((((usqInt)((fixup->targetInstruction)))) <= NeedsNonMergeFixupFlag) { - - /* convert a non-merge into a merge */ - /* begin becomeMergeFixup */ - (fixup->targetInstruction) = ((AbstractInstruction *) NeedsMergeFixupFlag); - (fixup->simStackPtr = simStackPtr); - } - else { - if ((fixup->isTargetOfBackwardBranch)) { - - /* this is the target of a backward branch and - so doesn't have a simStackPtr assigned yet. */ - (fixup->simStackPtr = simStackPtr); - } - else { - assert(((fixup->simStackPtr)) == simStackPtr); - } - } - /* begin recordBcpc: */ - return fixup; -} - - -/* Make sure there's a flagged fixup at the target pc in fixups. - Initially a fixup's target is just a flag. Later on it is replaced with a - proper instruction. */ - - /* StackToRegisterMappingCogit>>#ensureNonMergeFixupAt: */ -static BytecodeFixup * NoDbgRegParms -ensureNonMergeFixupAt(sqInt targetPC) -{ - BytecodeFixup *fixup; - - /* begin fixupAt: */ - fixup = fixupAtIndex(targetPC - initialPC); - traceFixupmerge(fixup, 1); - if (((fixup->targetInstruction)) == 0) { - /* begin becomeNonMergeFixup */ - (fixup->targetInstruction) = ((AbstractInstruction *) NeedsNonMergeFixupFlag); - } - /* begin recordBcpc: */ - return fixup; -} - - /* StackToRegisterMappingCogit>>#ensureReceiverResultRegContainsSelf */ -static void -ensureReceiverResultRegContainsSelf(void) -{ - if (needsFrame) { - if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); - /* begin putSelfInReceiverResultReg */ - storeToReg(simSelf(), ReceiverResultReg); - ((simSelf())->liveRegister = ReceiverResultReg); - } - } - else { - assert(((((simSelf())->type)) == SSRegister) - && (((((simSelf())->registerr)) == ReceiverResultReg) - && (receiverIsInReceiverResultReg()))); - } -} - - /* StackToRegisterMappingCogit>>#evaluate:at: */ -static void NoDbgRegParms -evaluateat(BytecodeDescriptor *descriptor, sqInt pc) -{ - byte0 = fetchByteofObject(pc, methodObj); - assert(descriptor == (generatorAt(bytecodeSetOffset + byte0))); - loadSubsequentBytesForDescriptorat(descriptor, pc); - ((descriptor->generator))(); -} - - -/* Attempt to follow a branch to a pc. Handle branches to unconditional jumps - and branches to push: aBoolean; conditional branch pairs. If the branch - cannot be - followed answer targetBytecodePC. It is not possible to follow jumps to - conditional branches because the stack changes depth. That following is - left to the genJumpIf:to: - clients. */ - - /* StackToRegisterMappingCogit>>#eventualTargetOf: */ -static sqInt NoDbgRegParms -eventualTargetOf(sqInt targetBytecodePC) -{ - sqInt cond; - sqInt currentTarget; - BytecodeDescriptor *descriptor; - sqInt nExts; - sqInt nextPC; - sqInt span; - - cond = 0; - nextPC = (currentTarget = targetBytecodePC); - while (1) { - nExts = 0; - while (1) { - /* begin generatorForPC: */ - descriptor = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC, methodObj))); - if ((descriptor->isReturn)) { - return currentTarget; - } - if (!((descriptor->isExtension))) break; - nExts += 1; - nextPC += (descriptor->numBytes); - } - if ((isBranch(descriptor)) - && (!(((descriptor->isBranchTrue)) - || ((descriptor->isBranchFalse))))) { - /* begin spanFor:at:exts:in: */ - span = ((descriptor->spanFunction))(descriptor, nextPC, nExts, methodObj); - if (span < 0) { - - /* Do *not* follow backward branches; these are interrupt points and should not be elided. */ - return currentTarget; - } - nextPC = (nextPC + ((descriptor->numBytes))) + span; - } - else { - if (((descriptor->generator)) == genPushConstantTrueBytecode) { - cond = 1; - } - else { - if (((descriptor->generator)) == genPushConstantFalseBytecode) { - cond = 0; - } - else { - return currentTarget; - } - } - if (((fixupAt(nextPC))->isTargetOfBackwardBranch)) { - return currentTarget; - } - nextPC = eventualTargetOf(nextPC + ((descriptor->numBytes))); - nExts = 0; - while (1) { - /* begin generatorForPC: */ - descriptor = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC, methodObj))); - if ((descriptor->isReturn)) { - return currentTarget; - } - if (!((descriptor->isExtension))) break; - nExts += 1; - nextPC += (descriptor->numBytes); - } - if (!(isBranch(descriptor))) { - return currentTarget; - } - if ((isBranch(descriptor)) - && (!(((descriptor->isBranchTrue)) - || ((descriptor->isBranchFalse))))) { - return currentTarget; - } - nextPC = (cond == ((descriptor->isBranchTrue)) - ? (nextPC + ((descriptor->numBytes))) + (((descriptor->spanFunction))(descriptor, nextPC, nExts, methodObj)) - : nextPC + ((descriptor->numBytes))); - } - currentTarget = nextPC; - } - return 0; -} - - -/* Spill the closest register on stack not conflicting with regMask. - Assertion Failure if regMask has already all the registers */ - - /* StackToRegisterMappingCogit>>#freeAnyRegNotConflictingWith: */ -static sqInt NoDbgRegParms -freeAnyRegNotConflictingWith(sqInt regMask) -{ - CogSimStackEntry *desc; - sqInt index; - sqInt reg; - - assert(needsFrame); - reg = NoReg; - index = ((simSpillBase < 0) ? 0 : simSpillBase); - while ((reg == NoReg) - && (index < simStackPtr)) { - desc = simStackAt(index); - if (((desc->type)) == SSRegister) { - if (!(((regMask & (1U << ((desc->registerr)))) != 0))) { - reg = (desc->registerr); - } - } - index += 1; - } - assert(!((reg == NoReg))); - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << reg, simStackPtr, simNativeStackPtr); - return reg; -} - - -/* Return from block, assuming result already loaded into ReceiverResultReg. */ -/* Return from block, assuming result already loaded into ReceiverResultReg. */ - - /* StackToRegisterMappingCogit>>#genBlockReturn */ -static sqInt -genBlockReturn(void) -{ - if (needsFrame) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, FPReg, SPReg); - /* begin PopR: */ - genoperand(PopR, FPReg); - /* begin PopR: */ - genoperand(PopR, LinkReg); - } - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - - /* can't fall through */ - deadCode = 1; - return 0; -} - - -/* Generate special versions of the ceCallCogCodePopReceiverAndClassRegs - enilopmart that also pop register args from the stack to undo the pushing - of register args in the abort/miss trampolines. */ - - /* StackToRegisterMappingCogit>>#genCallPICEnilopmartNumArgs: */ -static void (*genCallPICEnilopmartNumArgs(sqInt numArgs))(void) - -{ - AbstractInstruction *anInstruction; - sqInt endAddress; - usqInt enilopmart; - sqInt quickConstant; - sqInt reg; - sqInt size; - - zeroOpcodeIndex(); - /* begin MoveCq:R: */ - quickConstant = varBaseAddress(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - genLoadStackPointers(backEnd); - /* begin PopR: */ - genoperand(PopR, ClassReg); - /* begin PopR: */ - genoperand(PopR, TempReg); - /* begin PopR: */ - reg = LinkReg; - genoperand(PopR, reg); - if (numArgs > 0) { - if (numArgs > 1) { - /* begin PopR: */ - genoperand(PopR, Arg1Reg); - assert((numRegArgs()) == 2); - } - /* begin PopR: */ - genoperand(PopR, Arg0Reg); - } - /* begin PopR: */ - genoperand(PopR, ReceiverResultReg); - /* begin JumpR: */ - genoperand(JumpR, TempReg); - computeMaximumSizes(); - size = generateInstructionsAt(methodZoneBase); - endAddress = outputInstructionsAt(methodZoneBase); - assert((methodZoneBase + size) == endAddress); - enilopmart = methodZoneBase; - methodZoneBase = alignUptoRoutineBoundary(endAddress); - stopsFromto(backEnd, endAddress, methodZoneBase - 1); - recordGeneratedRunTimeaddress(trampolineNamenumRegArgs("ceCallPIC", numArgs), enilopmart); - return ((void (*)(void)) enilopmart); -} - - -/* SistaV1: ** 248 (2) 11111000 iiiiiiii mssjjjjj Call Primitive #iiiiiiii - + (jjjjj * 256) - m=1 means inlined primitive, no hard return after execution. - ss defines the unsafe operation set used to encode the operations. - (ss = 0 means sista unsafe operations, ss = 01 means lowcode operations, - other numbers are as yet used). - See SistaCogit genCallPrimitiveBytecode, EncoderForSistaV1's class comment - and StackInterpreter>>#callPrimitiveBytecode for more information. */ - - /* StackToRegisterMappingCogit>>#genCallPrimitiveBytecode */ -static sqInt -genCallPrimitiveBytecode(void) -{ - sqInt prim; - sqInt primSet; - - if (byte2 < 128) { - return (bytecodePC == initialPC - ? 0 - : EncounteredUnknownBytecode); - } - prim = (((sqInt)((usqInt)((byte2 - 128)) << 8))) + byte1; - primSet = (((usqInt)(prim)) >> 13) & 3; - prim = prim & 0x1FFF; - return EncounteredUnknownBytecode; -} - - -/* Override to push the register receiver and register arguments, if any. */ - - /* StackToRegisterMappingCogit>>#genExternalizePointersForPrimitiveCall */ -static sqInt -genExternalizePointersForPrimitiveCall(void) -{ - AbstractInstruction *anInstruction; - - genPushRegisterArgs(); - /* begin checkLiteral:forInstruction: */ - instructionPointerAddress(); - anInstruction = genoperandoperand(MoveRAw, LinkReg, instructionPointerAddress()); - return genSaveStackPointers(backEnd); -} - - -/* Override to push the register receiver and register arguments, if any. */ - - /* StackToRegisterMappingCogit>>#genExternalizeStackPointerForFastPrimitiveCall */ -static AbstractInstruction * -genExternalizeStackPointerForFastPrimitiveCall(void) -{ - AbstractInstruction *anInstruction; - - genPushRegisterArgs(); - return (/* begin checkLiteral:forInstruction: */ - stackPointerAddress(), - (anInstruction = genoperandoperand(MoveRAw, SPReg, stackPointerAddress())), - anInstruction); -} - - -/* Block compilation. At this point in the method create the block. Note its - start and defer generating code for it until after the method and any - other preceding - blocks. The block's actual code will be compiled later. */ -/* 253 11111101 eei i i kkk jjjjjjjj Push Closure Num Copied iii (+ Ext A - // 16 * 8) Num Args kkk (+ Ext A \\ 16 * 8) BlockSize jjjjjjjj (+ Ext B * - 256). ee = num extensions - */ - - /* StackToRegisterMappingCogit>>#genExtPushClosureBytecode */ -static sqInt -genExtPushClosureBytecode(void) -{ - sqInt i; - sqInt numArgs; - sqInt numCopied; - sqInt reg; - sqInt startpc; - - assert(needsFrame); - startpc = bytecodePC + (((generatorAt(byte0))->numBytes)); - addBlockStartAtnumArgsnumCopiedspan(startpc, (numArgs = (byte1 & 7) + ((extA % 16) * 8)), (numCopied = ((((usqInt)(byte1)) >> 3) & 7) + ((extA / 16) * 8)), byte2 + (((sqInt)((usqInt)(extB) << 8)))); - extA = (numExtB = (extB = 0)); - /* begin genInlineClosure:numArgs:numCopied: */ - assert(getActiveContextAllocatesInMachineCode()); - voidReceiverResultRegContainsSelf(); - /* begin ssAllocateCallReg:and:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg) | (1U << SendNumArgsReg)) | (1U << ClassReg)), simStackPtr, simNativeStackPtr); - genNoPopCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(startpc + 1, numArgs, numCopied, methodOrBlockNumArgs, methodNeedsLargeContext(methodObj), inBlock); - for (i = 1; i <= numCopied; i += 1) { - reg = ssStorePoptoPreferredReg(1, TempReg); - genStoreSourceRegslotIndexintoNewObjectInDestReg(reg, (ClosureFirstCopiedValueIndex + numCopied) - i, ReceiverResultReg); - } - ssPushRegister(ReceiverResultReg); - return 0; -} - - -/* Enilopmarts transfer control from C into machine code (backwards - trampolines). - */ -/* Enilopmarts transfer control from C into machine code (backwards - trampolines). Override to add version for generic and PIC-specific entry - with reg args. */ - - /* StackToRegisterMappingCogit>>#generateEnilopmarts */ -static void -generateEnilopmarts(void) -{ - -# if Debug - /* begin genEnilopmartFor:forCall:called: */ - realCEEnterCogCodePopReceiverReg = genEnilopmartForandandforCallcalled(ReceiverResultReg, NoReg, NoReg, 0, "realCEEnterCogCodePopReceiverReg"); - ceEnterCogCodePopReceiverReg = enterCogCodePopReceiver; - /* begin genEnilopmartFor:forCall:called: */ - realCECallCogCodePopReceiverReg = genEnilopmartForandandforCallcalled(ReceiverResultReg, NoReg, NoReg, 1, "realCECallCogCodePopReceiverReg"); - ceCallCogCodePopReceiverReg = callCogCodePopReceiver; - /* begin genEnilopmartFor:and:forCall:called: */ - realCECallCogCodePopReceiverAndClassRegs = genEnilopmartForandandforCallcalled(ReceiverResultReg, ClassReg, NoReg, 1, "realCECallCogCodePopReceiverAndClassRegs"); - ceCallCogCodePopReceiverAndClassRegs = callCogCodePopReceiverAndClassRegs; -# else // Debug - /* begin genEnilopmartFor:forCall:called: */ - ceEnterCogCodePopReceiverReg = genEnilopmartForandandforCallcalled(ReceiverResultReg, NoReg, NoReg, 0, "ceEnterCogCodePopReceiverReg"); - /* begin genEnilopmartFor:forCall:called: */ - ceCallCogCodePopReceiverReg = genEnilopmartForandandforCallcalled(ReceiverResultReg, NoReg, NoReg, 1, "ceCallCogCodePopReceiverReg"); - /* begin genEnilopmartFor:and:forCall:called: */ - ceCallCogCodePopReceiverAndClassRegs = genEnilopmartForandandforCallcalled(ReceiverResultReg, ClassReg, NoReg, 1, "ceCallCogCodePopReceiverAndClassRegs"); -# endif // Debug - genPrimReturnEnterCogCodeEnilopmart(0); - cePrimReturnEnterCogCode = methodZoneBase; - outputInstructionsForGeneratedRuntimeAt(cePrimReturnEnterCogCode); - recordGeneratedRunTimeaddress("cePrimReturnEnterCogCode", cePrimReturnEnterCogCode); - genPrimReturnEnterCogCodeEnilopmart(1); - cePrimReturnEnterCogCodeProfiling = methodZoneBase; - outputInstructionsForGeneratedRuntimeAt(cePrimReturnEnterCogCodeProfiling); - recordGeneratedRunTimeaddress("cePrimReturnEnterCogCodeProfiling", cePrimReturnEnterCogCodeProfiling); -# if Debug - /* begin genEnilopmartFor:and:forCall:called: */ - realCECallCogCodePopReceiverArg0Regs = genEnilopmartForandandforCallcalled(ReceiverResultReg, Arg0Reg, NoReg, 1, "realCECallCogCodePopReceiverArg0Regs"); - ceCallCogCodePopReceiverArg0Regs = callCogCodePopReceiverArg0Regs; - realCECallCogCodePopReceiverArg1Arg0Regs = genEnilopmartForandandforCallcalled(ReceiverResultReg, Arg0Reg, Arg1Reg, 1, "realCECallCogCodePopReceiverArg1Arg0Regs"); - ceCallCogCodePopReceiverArg1Arg0Regs = callCogCodePopReceiverArg1Arg0Regs; -# else // Debug - /* begin genEnilopmartFor:and:forCall:called: */ - ceCallCogCodePopReceiverArg0Regs = genEnilopmartForandandforCallcalled(ReceiverResultReg, Arg0Reg, NoReg, 1, "ceCallCogCodePopReceiverArg0Regs"); - ceCallCogCodePopReceiverArg1Arg0Regs = genEnilopmartForandandforCallcalled(ReceiverResultReg, Arg0Reg, Arg1Reg, 1, "ceCallCogCodePopReceiverArg1Arg0Regs"); -# endif // Debug - ceCall0ArgsPIC = genCallPICEnilopmartNumArgs(0); - ceCall1ArgsPIC = genCallPICEnilopmartNumArgs(1); - ceCall2ArgsPIC = genCallPICEnilopmartNumArgs(2); - assert((numRegArgs()) == 2); -} - - -/* Size pc-dependent instructions and assign eventual addresses to all - instructions. Answer the size of the code. - Compute forward branches based on virtual address (abstract code starts at - 0), assuming that any branches branched over are long. - Compute backward branches based on actual address. - Reuse the fixups array to record the pc-dependent instructions that need - to have - their code generation postponed until after the others. - - Override to add handling for null branches (branches to the immediately - following instruction) occasioned by StackToRegisterMapping's following of - jumps. */ - - /* StackToRegisterMappingCogit>>#generateInstructionsAt: */ -static sqInt NoDbgRegParms -generateInstructionsAt(sqInt eventualAbsoluteAddress) -{ - sqInt absoluteAddress; - AbstractInstruction *abstractInstruction; - BytecodeFixup *fixup; - sqInt i; - sqInt j; - sqInt pcDependentIndex; - - absoluteAddress = eventualAbsoluteAddress; - pcDependentIndex = 0; - for (i = 0; i < opcodeIndex; i += 1) { - - /* N.B. if you want to break in resizing, break here, note the instruction index, back up to the - sender, restart, and step into computeMaximumSizes, breaking at this instruction's index. */ - abstractInstruction = abstractInstructionAt(i); - maybeBreakGeneratingFromto(absoluteAddress, absoluteAddress + ((abstractInstruction->maxSize))); - if (isPCDependent(abstractInstruction)) { - sizePCDependentInstructionAt(abstractInstruction, absoluteAddress); - if ((isJump(abstractInstruction)) - && ((((i + 1) < opcodeIndex) - && ((((AbstractInstruction *) (((abstractInstruction->operands))[0]))) == (abstractInstructionAt(i + 1)))) - || (((i + 2) < opcodeIndex) - && (((((AbstractInstruction *) (((abstractInstruction->operands))[0]))) == (abstractInstructionAt(i + 2))) - && ((((abstractInstructionAt(i + 1))->opcode)) == Nop))))) { - (abstractInstruction->opcode = Nop); - concretizeAt(abstractInstruction, absoluteAddress); - } - else { - fixup = fixupAtIndex(pcDependentIndex); - pcDependentIndex += 1; - (fixup->instructionIndex = i); - } - absoluteAddress += (abstractInstruction->machineCodeSize); - } - else { - - /* N.B. if you want to break in resizing, break here, note the instruction index, back up to the - sender, restart, and step into computeMaximumSizes, breaking at this instruction's index. */ - absoluteAddress = concretizeAt(abstractInstruction, absoluteAddress); - assert(((abstractInstruction->machineCodeSize)) == ((abstractInstruction->maxSize))); - } - } - for (j = 0; j < pcDependentIndex; j += 1) { - fixup = fixupAtIndex(j); - abstractInstruction = abstractInstructionAt((fixup->instructionIndex)); - maybeBreakGeneratingFromto((abstractInstruction->address), (((abstractInstruction->address)) + ((abstractInstruction->maxSize))) - 1); - concretizeAt(abstractInstruction, (abstractInstruction->address)); - } - return absoluteAddress - eventualAbsoluteAddress; -} - - -/* Generate the run-time entries for the various method and PIC entry misses - and aborts. - Read the class-side method trampolines for documentation on the various - trampolines - */ - - /* StackToRegisterMappingCogit>>#generateMissAbortTrampolines */ -static void -generateMissAbortTrampolines(void) -{ - sqInt numArgs; - sqInt numArgsLimiT; - - for (numArgs = 0, numArgsLimiT = (3); numArgs <= numArgsLimiT; numArgs += 1) { - methodAbortTrampolines[numArgs] = (genMethodAbortTrampolineFor(numArgs)); - } - for (numArgs = 0, numArgsLimiT = (3); numArgs <= numArgsLimiT; numArgs += 1) { - picAbortTrampolines[numArgs] = (genPICAbortTrampolineFor(numArgs)); - } - for (numArgs = 0, numArgsLimiT = (3); numArgs <= numArgsLimiT; numArgs += 1) { - picMissTrampolines[numArgs] = (genPICMissTrampolineFor(numArgs)); - } - /* begin genTrampolineFor:called:arg: */ - ceReapAndResetErrorCodeTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceReapAndResetErrorCodeFor, "ceReapAndResetErrorCodeTrampoline", 1, ClassReg, null, null, null, 0 /* emptyRegisterMask */, 1, NoReg, 0); -} - - -/* Override to generate code to push the register arg(s) for <= numRegArg - arity sends. - */ - - /* StackToRegisterMappingCogit>>#generateSendTrampolines */ -static void -generateSendTrampolines(void) -{ - sqInt numArgs; - - for (numArgs = 0; numArgs < NumSendTrampolines; numArgs += 1) { - ordinarySendTrampolines[numArgs] = (genSendTrampolineFornumArgscalledargargargarg(ceSendsupertonumArgs, numArgs, trampolineNamenumArgs("ceSend", numArgs), ClassReg, trampolineArgConstant(0), ReceiverResultReg, (numArgs <= (NumSendTrampolines - 2) - ? (/* begin trampolineArgConstant: */ - assert(numArgs >= 0), - -2 - numArgs) - : SendNumArgsReg))); - } - generateNewspeakSendTrampolines(); - for (numArgs = 0; numArgs < NumSendTrampolines; numArgs += 1) { - directedSuperSendTrampolines[numArgs] = (genSendTrampolineFornumArgscalledargargargarg(ceSendabovetonumArgs, numArgs, trampolineNamenumArgs("ceDirectedSuperSend", numArgs), ClassReg, TempReg, ReceiverResultReg, (numArgs <= (NumSendTrampolines - 2) - ? (/* begin trampolineArgConstant: */ - assert(numArgs >= 0), - -2 - numArgs) - : SendNumArgsReg))); - directedSuperBindingSendTrampolines[numArgs] = (genSendTrampolineFornumArgscalledargargargarg(ceSendaboveClassBindingtonumArgs, numArgs, trampolineNamenumArgs("ceDirectedSuperBindingSend", numArgs), ClassReg, TempReg, ReceiverResultReg, (numArgs <= (NumSendTrampolines - 2) - ? (/* begin trampolineArgConstant: */ - assert(numArgs >= 0), - -2 - numArgs) - : SendNumArgsReg))); - } - for (numArgs = 0; numArgs < NumSendTrampolines; numArgs += 1) { - superSendTrampolines[numArgs] = (genSendTrampolineFornumArgscalledargargargarg(ceSendsupertonumArgs, numArgs, trampolineNamenumArgs("ceSuperSend", numArgs), ClassReg, trampolineArgConstant(1), ReceiverResultReg, (numArgs <= (NumSendTrampolines - 2) - ? (/* begin trampolineArgConstant: */ - assert(numArgs >= 0), - -2 - numArgs) - : SendNumArgsReg))); - } - firstSend = ordinarySendTrampolines[0]; - lastSend = superSendTrampolines[NumSendTrampolines - 1]; -} - - -/* Generate trampolines for tracing. In the simulator we can save a lot of - time and avoid noise instructions in the lastNInstructions log by - short-cutting these - trampolines, but we need them in the real vm. */ - - /* StackToRegisterMappingCogit>>#generateTracingTrampolines */ -static void -generateTracingTrampolines(void) -{ - /* begin genTrampolineFor:called:arg:regsToSave: */ - ceTraceLinkedSendTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceTraceLinkedSend, "ceTraceLinkedSendTrampoline", 1, ReceiverResultReg, null, null, null, CallerSavedRegisterMask, 1, NoReg, 0); - /* begin genTrampolineFor:called:regsToSave: */ - ceTraceBlockActivationTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceTraceBlockActivation, "ceTraceBlockActivationTrampoline", 0, null, null, null, null, CallerSavedRegisterMask, 1, NoReg, 0); - /* begin genTrampolineFor:called:arg:arg:regsToSave: */ - ceTraceStoreTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceTraceStoreOfinto, "ceTraceStoreTrampoline", 2, TempReg, ReceiverResultReg, null, null, CallerSavedRegisterMask, 1, NoReg, 0); -} - - /* StackToRegisterMappingCogit>>#genForwardersInlinedIdenticalOrNotIf: */ -static sqInt NoDbgRegParms -genForwardersInlinedIdenticalOrNotIf(sqInt orNot) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - sqInt argConstant; - sqInt argNeedsReg; - sqInt argReg; - sqInt argReg1; - BytecodeDescriptor *branchDescriptor; - BytecodeDescriptor *branchDescriptor1; - sqInt constant; - sqInt constant1; - BytecodeFixup * fixup; - sqInt i; - void *jumpTarget; - void *jumpTarget1; - AbstractInstruction *label; - sqInt nExts; - sqInt nextPC; - sqInt nextPC1; - sqInt postBranchPC; - sqInt postBranchPC1; - BytecodeDescriptor *primDescriptor; - sqInt rcvrConstant; - sqInt rcvrNeedsReg; - sqInt rcvrReg; - sqInt rcvrReg1; - sqInt reg; - sqInt rNext1; - sqInt rTop1; - CogSimStackEntry *simStackEntry; - CogSimStackEntry *simStackEntry1; - sqInt targetBytecodePC; - sqInt targetBytecodePC1; - sqInt topRegistersMask; - sqInt unforwardArg; - sqInt unforwardRcvr; - - unforwardRcvr = mayBeAForwarder(ssValue(1)); - unforwardArg = mayBeAForwarder(ssTop()); - if ((!unforwardRcvr) - && (!unforwardArg)) { - return genVanillaInlinedIdenticalOrNotIf(orNot); - } - assert(unforwardArg - || (unforwardRcvr)); - /* begin isUnannotatableConstant: */ - simStackEntry = ssValue(1); - rcvrConstant = (((simStackEntry->type)) == SSConstant) - && ((isImmediate((simStackEntry->constant))) - || (!(shouldAnnotateObjectReference((simStackEntry->constant))))); - /* begin isUnannotatableConstant: */ - simStackEntry1 = ssTop(); - argConstant = (((simStackEntry1->type)) == SSConstant) - && ((isImmediate((simStackEntry1->constant))) - || (!(shouldAnnotateObjectReference((simStackEntry1->constant))))); - /* begin extractMaybeBranchDescriptorInto: */ - primDescriptor = generatorAt(byte0); - nextPC1 = bytecodePC + ((primDescriptor->numBytes)); - nExts = 0; - while (1) { - while (1) { - /* begin generatorForPC: */ - branchDescriptor1 = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC1, methodObj))); - if (!((branchDescriptor1->isExtension))) break; - nExts += 1; - nextPC1 += (branchDescriptor1->numBytes); - } - /* begin isUnconditionalBranch */ - if (!((isBranch(branchDescriptor1)) - && (!(((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse)))))) break; - nextPC1 = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - } - targetBytecodePC1 = (postBranchPC1 = 0); - if (((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse))) { - targetBytecodePC1 = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - postBranchPC1 = eventualTargetOf(nextPC1 + ((branchDescriptor1->numBytes))); - } - else { - nextPC1 = bytecodePC + ((primDescriptor->numBytes)); - } - branchDescriptor = branchDescriptor1; - nextPC = nextPC1; - postBranchPC = postBranchPC1; - targetBytecodePC = targetBytecodePC1; - /* begin allocateEqualsEqualsRegistersArgNeedsReg:rcvrNeedsReg:into: */ - argNeedsReg = !argConstant; - rcvrNeedsReg = !rcvrConstant; - assert(argNeedsReg - || (rcvrNeedsReg)); - argReg1 = (rcvrReg1 = NoReg); - if (argNeedsReg) { - if (rcvrNeedsReg) { - /* begin allocateRegForStackTopTwoEntriesInto: */ - topRegistersMask = 0; - rTop1 = (rNext1 = NoReg); - if ((registerOrNone(ssTop())) != NoReg) { - rTop1 = registerOrNone(ssTop()); - } - if ((registerOrNone(ssValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; - } - if (rTop1 == NoReg) { - rTop1 = allocateRegNotConflictingWith(topRegistersMask); - } - if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); - } - assert(!(((rTop1 == NoReg) - || (rNext1 == NoReg)))); - argReg1 = rTop1; - rcvrReg1 = rNext1; - popToReg(ssTop(), argReg1); - popToReg(ssValue(1), rcvrReg1); - } - else { - argReg1 = allocateRegForStackEntryAtnotConflictingWith(0, 0); - popToReg(ssTop(), argReg1); - if (((ssValue(1))->spilled)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AddCqR, BytesPerWord, SPReg); - } - } - } - else { - assert(rcvrNeedsReg); - assert(!((((ssTop())->spilled)))); - rcvrReg1 = allocateRegForStackEntryAtnotConflictingWith(1, 0); - popToReg(ssValue(1), rcvrReg1); - } - assert(!((argNeedsReg - && (argReg1 == NoReg)))); - assert(!((rcvrNeedsReg - && (rcvrReg1 == NoReg)))); - rcvrReg = rcvrReg1; - argReg = argReg1; - if (!(((branchDescriptor->isBranchTrue)) - || ((branchDescriptor->isBranchFalse)))) { - return genIdenticalNoBranchArgIsConstantrcvrIsConstantargRegrcvrRegorNotIf(argConstant, rcvrConstant, argReg, rcvrReg, orNot); - } - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 2)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 2)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 2))); i <= (simStackPtr - 2); i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 2) + 1; - } - /* begin Label */ - label = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - /* begin genCmpArgIsConstant:rcvrIsConstant:argReg:rcvrReg: */ - assert((argReg != NoReg) - || (rcvrReg != NoReg)); - if (argConstant) { - /* begin genCmpConstant:R: */ - constant = ((ssTop())->constant); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(CmpCwR, constant, rcvrReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, constant, rcvrReg); - } - } - else { - if (rcvrConstant) { - /* begin genCmpConstant:R: */ - constant1 = ((ssValue(1))->constant); - if (shouldAnnotateObjectReference(constant1)) { - annotateobjRef(checkLiteralforInstruction(constant1, genoperandoperand(CmpCwR, constant1, argReg)), constant1); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, constant1, argReg); - } - } - else { - /* begin CmpR:R: */ - assert(!((argReg == SPReg))); - genoperandoperand(CmpRR, argReg, rcvrReg); - } - } - ssPop(2); - if ((((fixupAt(nextPC))->targetInstruction)) == 0) { - - /* The next instruction is dead. we can skip it. */ - deadCode = 1; - ensureFixupAt(targetBytecodePC); - ensureFixupAt(postBranchPC); - } - else { - assert(!(deadCode)); - } - if (orNot == ((branchDescriptor->isBranchTrue))) { - - /* a == b ifFalse: ... or a ~~ b ifTrue: ... jump on equal to post-branch pc */ - fixup = ensureNonMergeFixupAt(targetBytecodePC); - /* begin JumpZero: */ - jumpTarget = ensureNonMergeFixupAt(postBranchPC); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget)); - } - else { - - /* orNot is true for ~~ */ - /* a == b ifTrue: ... or a ~~ b ifFalse: ... jump on equal to target pc */ - fixup = ensureNonMergeFixupAt(postBranchPC); - /* begin JumpZero: */ - jumpTarget1 = ensureNonMergeFixupAt(targetBytecodePC); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget1)); - } - if (unforwardArg - && (unforwardRcvr)) { - /* begin genEnsureOopInRegNotForwarded:scratchReg:jumpBackTo: */ - genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(argReg, TempReg, label, 0); - } - genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder((unforwardRcvr - ? rcvrReg - : argReg), TempReg, label, fixup); - if (!deadCode) { - ssPushConstant(trueObject()); - } - return 0; -} - - -/* Generates the machine code for #== in the case where the instruction is - not followed by a branch - */ - - /* StackToRegisterMappingCogit>>#genIdenticalNoBranchArgIsConstant:rcvrIsConstant:argReg:rcvrReg:orNotIf: */ -static sqInt NoDbgRegParms -genIdenticalNoBranchArgIsConstantrcvrIsConstantargRegrcvrRegorNotIf(sqInt argIsConstant, sqInt rcvrIsConstant, sqInt argReg, sqInt rcvrRegOrNone, sqInt orNot) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - sqInt constant; - sqInt constant1; - sqInt constant11; - sqInt constant2; - sqInt constant3; - sqInt constant4; - AbstractInstruction *jumpEqual; - AbstractInstruction *jumpNotEqual; - AbstractInstruction *label; - sqInt resultReg; - - /* begin Label */ - label = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - /* begin genCmpArgIsConstant:rcvrIsConstant:argReg:rcvrReg: */ - assert((argReg != NoReg) - || (rcvrRegOrNone != NoReg)); - if (argIsConstant) { - /* begin genCmpConstant:R: */ - constant4 = ((ssTop())->constant); - if (shouldAnnotateObjectReference(constant4)) { - annotateobjRef(checkLiteralforInstruction(constant4, genoperandoperand(CmpCwR, constant4, rcvrRegOrNone)), constant4); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, constant4, rcvrRegOrNone); - } - } - else { - if (rcvrIsConstant) { - /* begin genCmpConstant:R: */ - constant11 = ((ssValue(1))->constant); - if (shouldAnnotateObjectReference(constant11)) { - annotateobjRef(checkLiteralforInstruction(constant11, genoperandoperand(CmpCwR, constant11, argReg)), constant11); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, constant11, argReg); - } - } - else { - /* begin CmpR:R: */ - assert(!((argReg == SPReg))); - genoperandoperand(CmpRR, argReg, rcvrRegOrNone); - } - } - ssPop(2); - resultReg = (rcvrRegOrNone == NoReg - ? argReg - : rcvrRegOrNone); - /* begin JumpZero: */ - jumpEqual = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - if (!argIsConstant) { - /* begin genEnsureOopInRegNotForwarded:scratchReg:jumpBackTo: */ - genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(argReg, TempReg, label, 0); - } - if (!rcvrIsConstant) { - /* begin genEnsureOopInRegNotForwarded:scratchReg:jumpBackTo: */ - genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(rcvrRegOrNone, TempReg, label, 0); - } - if (orNot) { - /* begin genMoveTrueR: */ - constant = trueObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, resultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, constant, resultReg); - } - } - else { - /* begin genMoveFalseR: */ - constant1 = falseObject(); - if (shouldAnnotateObjectReference(constant1)) { - annotateobjRef(checkLiteralforInstruction(constant1, genoperandoperand(MoveCwR, constant1, resultReg)), constant1); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(MoveCqR, constant1, resultReg); - } - } - /* begin Jump: */ - jumpNotEqual = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpEqual, (orNot - ? (/* begin genMoveFalseR: */ - (constant2 = falseObject()), - (shouldAnnotateObjectReference(constant2) - ? annotateobjRef(checkLiteralforInstruction(constant2, genoperandoperand(MoveCwR, constant2, resultReg)), constant2) - : (/* begin checkQuickConstant:forInstruction: */ - (anInstruction4 = genoperandoperand(MoveCqR, constant2, resultReg)), - anInstruction4))) - : (/* begin genMoveTrueR: */ - (constant3 = trueObject()), - (shouldAnnotateObjectReference(constant3) - ? annotateobjRef(checkLiteralforInstruction(constant3, genoperandoperand(MoveCwR, constant3, resultReg)), constant3) - : (/* begin checkQuickConstant:forInstruction: */ - (anInstruction5 = genoperandoperand(MoveCqR, constant3, resultReg)), - anInstruction5))))); - jmpTarget(jumpNotEqual, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushRegister(resultReg); - return 0; -} - - -/* Decompose code generation for #== into a common constant-folding version, - followed by a double dispatch through the objectRepresentation to a - version that doesn't deal with forwarders and a version that does. */ - - /* StackToRegisterMappingCogit>>#genInlinedIdenticalOrNotIf: */ -static sqInt NoDbgRegParms -genInlinedIdenticalOrNotIf(sqInt orNot) -{ - BytecodeDescriptor *primDescriptor; - sqInt result; - - primDescriptor = generatorAt(byte0); - if ((isUnannotatableConstant(ssTop())) - && (isUnannotatableConstant(ssValue(1)))) { - assert(!((primDescriptor->isMapped))); - result = ((orNot - ? (((ssTop())->constant)) != (((ssValue(1))->constant)) - : (((ssTop())->constant)) == (((ssValue(1))->constant))) - ? trueObject() - : falseObject()); - ssPop(2); - return ssPushConstant(result); - } - /* begin genInlinedIdenticalOrNotIfGuts: */ - return genForwardersInlinedIdenticalOrNotIf(orNot); -} - - /* StackToRegisterMappingCogit>>#genJumpBackTo: */ -static sqInt NoDbgRegParms -genJumpBackTo(sqInt targetBytecodePC) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *anInstruction; - sqInt i; - void *jumpTarget; - void *jumpTarget1; - - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - - /* can't fall through */ - deadCode = 1; - /* begin checkLiteral:forInstruction: */ - stackLimitAddress(); - anInstruction = genoperandoperand(MoveAwR, stackLimitAddress(), TempReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, SPReg); - /* begin JumpAboveOrEqual: */ - jumpTarget = fixupAtIndex(targetBytecodePC - initialPC); - genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)jumpTarget)); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceCheckForInterruptTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin annotateBytecode: */ - abstractInstruction1 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction1->annotation = HasBytecodePC); - /* begin Jump: */ - jumpTarget1 = fixupAtIndex(targetBytecodePC - initialPC); - genoperand(Jump, ((sqInt)jumpTarget1)); - return 0; -} - - /* StackToRegisterMappingCogit>>#genJumpIf:to: */ -static sqInt NoDbgRegParms -genJumpIfto(sqInt boolean, sqInt targetBytecodePC) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - CogSimStackEntry *desc; - sqInt eventualTarget; - BytecodeFixup *fixup; - sqInt i; - void *jumpTarget; - AbstractInstruction *ok; - sqInt quickConstant; - - eventualTarget = eventualTargetOf(targetBytecodePC); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 1)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 1)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 1))); i < simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 1) + 1; - } - desc = ssTop(); - ssPop(1); - if ((((desc->type)) == SSConstant) - && ((((desc->constant)) == (trueObject())) - || (((desc->constant)) == (falseObject())))) { - - /* Must arrange there's a fixup at the target whether it is jumped to or - not so that the simStackPtr can be kept correct. */ - - /* Must annotate the bytecode for correct pc mapping. */ - fixup = ensureFixupAt(eventualTarget); - /* begin annotateBytecode: */ - if (((desc->constant)) == boolean) { - /* begin Jump: */ - abstractInstruction = genoperand(Jump, ((sqInt)fixup)); - } - else { - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - } - (abstractInstruction->annotation = HasBytecodePC); - extA = 0; - return 0; - } - popToReg(desc, TempReg); - assert((objectAfter(falseObject())) == (trueObject())); - /* begin genSubConstant:R: */ - if (shouldAnnotateObjectReference(boolean)) { - annotateobjRef(checkLiteralforInstruction(boolean, genoperandoperand(SubCwR, boolean, TempReg)), TempReg); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, boolean, TempReg); - } - /* begin JumpZero: */ - jumpTarget = ensureFixupAt(eventualTarget); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget)); - if (((extA & 1) != 0)) { - extA = 0; - /* begin annotateBytecode: */ - abstractInstruction1 = lastOpcode(); - (abstractInstruction1->annotation = HasBytecodePC); - return 0; - } - extA = 0; - /* begin CmpCq:R: */ - quickConstant = (boolean == (falseObject()) - ? (trueObject()) - (falseObject()) - : (falseObject()) - (trueObject())); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, quickConstant, TempReg); - /* begin JumpZero: */ - ok = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - genCallMustBeBooleanFor(boolean); - jmpTarget(ok, annotateBytecode(genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return 0; -} - - /* StackToRegisterMappingCogit>>#genJumpTo: */ -static sqInt NoDbgRegParms -genJumpTo(sqInt targetBytecodePC) -{ - sqInt eventualTarget; - BytecodeFixup * fixup; - BytecodeDescriptor * generator; - sqInt i; - sqInt i1; - - eventualTarget = eventualTargetOf(targetBytecodePC); - if ((eventualTarget > bytecodePC) - && (((simStackPtr >= methodOrBlockNumArgs) - && (stackEntryIsBoolean(ssTop()))) - && ((((generator = generatorForPC(eventualTarget))->isBranchTrue)) - || (((generator = generatorForPC(eventualTarget))->isBranchFalse))))) { - eventualTarget = (eventualTarget + ((generator->numBytes))) + ((((generator->isBranchTrue)) == ((((ssTop())->constant)) == (trueObject())) - ? (/* begin spanFor:at:exts:in: */ - ((generator->spanFunction))(generator, eventualTarget, 0, methodObj)) - : 0)); - ssPop(1); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - fixup = ensureFixupAt(eventualTarget); - ssPop(-1); - } - else { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i1 <= simStackPtr; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - fixup = ensureFixupAt(eventualTarget); - } - - /* can't fall through */ - deadCode = 1; - /* begin Jump: */ - genoperand(Jump, ((sqInt)fixup)); - return 0; -} - - /* StackToRegisterMappingCogit>>#genMarshalledSend:numArgs:sendTable: */ -static sqInt NoDbgRegParms -genMarshalledSendnumArgssendTable(sqInt selectorIndex, sqInt numArgs, sqInt *sendTable) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt annotation; - - assert(needsFrame); - /* begin annotationForSendTable: */ - if (sendTable == ordinarySendTrampolines) { - annotation = IsSendCall; - goto l2; - } - if (sendTable == directedSuperSendTrampolines) { - annotation = IsDirectedSuperSend; - goto l2; - } - if (sendTable == directedSuperBindingSendTrampolines) { - annotation = IsDirectedSuperBindingSend; - goto l2; - } - if (sendTable == implicitReceiverSendTrampolines) { - error("Unexpected implicit receiver send using dirty send machinery"); - } - if (sendTable == outerSendTrampolines) { - error("Unexpected outer send using dirty send machinery"); - } - if (sendTable == selfSendTrampolines) { - annotation = IsNSSelfSend; - goto l2; - } - if (sendTable == dynamicSuperSendTrampolines) { - annotation = IsNSDynamicSuperSend; - goto l2; - } - assert(sendTable == superSendTrampolines); - annotation = IsSuperSend; - l2: /* end annotationForSendTable: */; - if ((annotation == IsSuperSend) - || (((annotation >= IsDirectedSuperSend) && (annotation <= IsDirectedSuperBindingSend)))) { - genEnsureOopInRegNotForwardedscratchReg(ReceiverResultReg, TempReg); - } - if (numArgs >= (NumSendTrampolines - 1)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, numArgs, SendNumArgsReg); - } - if (((annotation >= IsDirectedSuperSend) && (annotation <= IsDirectedSuperBindingSend))) { - /* begin genMoveConstant:R: */ - if (shouldAnnotateObjectReference(tempOop)) { - annotateobjRef(checkLiteralforInstruction(tempOop, genoperandoperand(MoveCwR, tempOop, TempReg)), tempOop); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, tempOop, TempReg); - } - } - genLoadInlineCacheWithSelector(selectorIndex); - ((genoperand(Call, sendTable[((numArgs < (NumSendTrampolines - 1)) ? numArgs : (NumSendTrampolines - 1))]))->annotation = annotation); - /* begin voidReceiverOptStatus */ - ((simSelf())->liveRegister = NoReg); - return ssPushRegister(ReceiverResultReg); -} - - -/* Generate the abort for a method. This abort performs either a call of - ceSICMiss: to handle a single-in-line cache miss or a call of - ceStackOverflow: to handle a - stack overflow. It distinguishes the two by testing ResultReceiverReg. If - the register is zero then this is a stack-overflow because a) the receiver - has already - been pushed and so can be set to zero before calling the abort, and b) the - receiver must always contain an object (and hence be non-zero) on SIC - miss. */ - - /* StackToRegisterMappingCogit>>#genMethodAbortTrampolineFor: */ -static usqInt NoDbgRegParms -genMethodAbortTrampolineFor(sqInt numArgs) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *jumpSICMiss; - - zeroOpcodeIndex(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, ReceiverResultReg); - /* begin JumpNonZero: */ - jumpSICMiss = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveR:Mw:r: */ - anInstruction = genoperandoperandoperand(MoveRMwr, LinkReg, 0, SPReg); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(ceStackOverflow, 1, SendNumArgsReg, null, null, null, 0 /* emptyRegisterMask */, 0, NoReg); - jmpTarget(jumpSICMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genPushRegisterArgsForAbortMissNumArgs(backEnd, numArgs); - return genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceSICMiss, trampolineNamenumRegArgs("ceMethodAbort", numArgs), 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 0, NoReg, 1); -} - - /* StackToRegisterMappingCogit>>#genNSSend:numArgs:depth:sendTable: */ -static sqInt NoDbgRegParms -genNSSendnumArgsdepthsendTable(sqInt selectorIndex, sqInt numArgs, sqInt depth, sqInt *sendTable) -{ - AbstractInstruction *anInstruction; - sqInt nsSendCache; - NSSendCache * nsSendCache1; - sqInt selector; - - assert(((selectorIndex >= 0) && (selectorIndex <= ((literalCountOf(methodObj)) - 1)))); - selector = getLiteral(selectorIndex); - assert(addressCouldBeOop(selector)); - if (isNonImmediate(selector)) { - setHasMovableLiteral(1); - } - if (isYoung(selector)) { - setHasYoungReferent(1); - } - nsSendCache = theIRCs + ((NumOopsPerNSC * BytesPerOop) * indexOfIRC); - indexOfIRC += 1; - assert(isInOldSpace(nsSendCache)); - /* begin initializeNSSendCache:selector:numArgs:depth: */ - nsSendCache1 = ((NSSendCache *) nsSendCache); - (nsSendCache1->selector = selector); - (nsSendCache1->numArgs = numArgs); - (nsSendCache1->depth = depth); - (nsSendCache1->classTag = 2 /* illegalClassTag */); - /* begin ssAllocateCallReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (1U << SendNumArgsReg), simStackPtr, simNativeStackPtr); - marshallAbsentReceiverSendArguments(numArgs); - /* begin uniqueLiteral:forInstruction: */ - anInstruction = genoperandoperand(MoveCwR, nsSendCache, SendNumArgsReg); - CallNewspeakSend(sendTable[((numArgs < (NumSendTrampolines - 1)) ? numArgs : (NumSendTrampolines - 1))]); - /* begin voidReceiverOptStatus */ - ((simSelf())->liveRegister = NoReg); - ssPushRegister(ReceiverResultReg); - return 0; -} - - -/* Generate the abort for a PIC. This abort performs either a call of - ceInterpretMethodFromPIC:receiver: to handle invoking an uncogged - target or a call of ceMNUFromPICMNUMethod:receiver: to handle an - MNU dispatch in a closed PIC. It distinguishes the two by testing - ClassReg. If the register is zero then this is an MNU. */ - - /* StackToRegisterMappingCogit>>#genPICAbortTrampolineFor: */ -static usqInt NoDbgRegParms -genPICAbortTrampolineFor(sqInt numArgs) -{ - zeroOpcodeIndex(); - genPushRegisterArgsForAbortMissNumArgs(backEnd, numArgs); - return genInnerPICAbortTrampoline(trampolineNamenumRegArgs("cePICAbort", numArgs)); -} - - /* StackToRegisterMappingCogit>>#genPICMissTrampolineFor: */ -static usqInt NoDbgRegParms -genPICMissTrampolineFor(sqInt numArgs) -{ - usqInt startAddress; - - startAddress = methodZoneBase; - zeroOpcodeIndex(); - genPushRegisterArgsForNumArgsscratchReg(backEnd, numArgs, SendNumArgsReg); - genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceCPICMissreceiver, trampolineNamenumRegArgs("cePICMiss", numArgs), 2, ClassReg, ReceiverResultReg, null, null, 0 /* emptyRegisterMask */, 1, NoReg, 1); - return startAddress; -} - - /* StackToRegisterMappingCogit>>#genPopStackBytecode */ -static sqInt -genPopStackBytecode(void) -{ - AbstractInstruction *anInstruction; - - if (((ssTop())->spilled)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, BytesPerWord, SPReg); - } - ssPop(1); - return 0; -} - - -/* Check the argument count. Fail if wrong. - Get the method from the outerContext and see if it is cogged. If so, jump - to the - block entry or the no-context-switch entry, as appropriate, and we're - done. If not, - invoke the interpreter primitive. */ -/* Check the argument count. Fail if wrong. - Get the method from the outerContext and see if it is cogged. If so, jump - to the - block entry or the no-context-switch entry, as appropriate, and we're - done. If not, - invoke the interpreter primitive. - Override to push the register args first. */ - - /* StackToRegisterMappingCogit>>#genPrimitiveClosureValue */ -static sqInt -genPrimitiveClosureValue(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *jumpBCMethod; - AbstractInstruction *jumpFail1; - AbstractInstruction *jumpFail2; - AbstractInstruction *jumpFail3; - AbstractInstruction *jumpFail4; - AbstractInstruction *jumpFailNArgs; - sqInt offset; - void (*primitiveRoutine)(void); - sqInt result; - - genPushRegisterArgs(); - genLoadSlotsourceRegdestReg(ClosureNumArgsIndex, ReceiverResultReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)methodOrBlockNumArgs << 1) | 1); - anInstruction1 = genoperandoperand(CmpCqR, (((usqInt)methodOrBlockNumArgs << 1) | 1), TempReg); - /* begin JumpNonZero: */ - jumpFailNArgs = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(ClosureOuterContextIndex, ReceiverResultReg, ClassReg); - jumpFail1 = genJumpImmediate(ClassReg); - genGetCompactClassIndexNonImmOfinto(ClassReg, TempReg); - genCmpClassMethodContextCompactIndexR(TempReg); - /* begin JumpNonZero: */ - jumpFail2 = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(MethodIndex, ClassReg, SendNumArgsReg); - jumpFail3 = genJumpImmediate(SendNumArgsReg); - genGetFormatOfinto(SendNumArgsReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction2 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), TempReg); - /* begin JumpLess: */ - jumpFail4 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - genLoadSlotsourceRegdestReg(HeaderIndex, SendNumArgsReg, ClassReg); - jumpBCMethod = genJumpImmediate(ClassReg); - /* begin MoveM16:r:R: */ - offset = offsetof(CogMethod, blockEntryOffset); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperandoperand(MoveM16rR, offset, ClassReg, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, ClassReg, TempReg); - primitiveRoutine = functionPointerForCompiledMethodprimitiveIndexprimitivePropertyFlagsInto(methodObj, primitiveIndex, null); - if (primitiveRoutine == primitiveClosureValueNoContextSwitch) { - if (blockNoContextSwitchOffset == null) { - return NotFullyInitialized; - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, blockNoContextSwitchOffset, TempReg); - } - /* begin JumpR: */ - genoperand(JumpR, TempReg); - jmpTarget(jumpBCMethod, jmpTarget(jumpFail1, jmpTarget(jumpFail2, jmpTarget(jumpFail3, jmpTarget(jumpFail4, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))))); - if (((result = compileInterpreterPrimitiveflags(primitiveRoutine, primitivePropertyFlags(primitiveIndex)))) < 0) { - return result; - } - jmpTarget(jumpFailNArgs, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - -/* Generate an in-line perform primitive. The lookup code requires the - selector to be in Arg0Reg. - adjustArgumentsForPerform: adjusts the arguments once - genLookupForPerformNumArgs: has generated the code for the lookup. */ - - /* StackToRegisterMappingCogit>>#genPrimitivePerform */ -static sqInt -genPrimitivePerform(void) -{ - AbstractInstruction *anInstruction; - sqInt offset; - - if (methodOrBlockNumArgs > 2 /* numRegArgs */) { - /* begin MoveMw:r:R: */ - offset = (methodOrBlockNumArgs - 1) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, SPReg, Arg0Reg); - } - return genLookupForPerformNumArgs(methodOrBlockNumArgs); -} - - /* StackToRegisterMappingCogit>>#genPushActiveContextBytecode */ -static sqInt -genPushActiveContextBytecode(void) -{ - assert(needsFrame); - voidReceiverResultRegContainsSelf(); - /* begin ssAllocateCallReg:and:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg) | (1U << SendNumArgsReg)) | (1U << ClassReg)), simStackPtr, simNativeStackPtr); - genGetActiveContextNumArgslargeinBlock(methodOrBlockNumArgs, methodNeedsLargeContext(methodObj), inBlock); - return ssPushRegister(ReceiverResultReg); -} - - -/* Block compilation. At this point in the method create the block. Note its - start and defer generating code for it until after the method and any - other preceding - blocks. The block's actual code will be compiled later. */ -/* 143 10001111 llllkkkk jjjjjjjj iiiiiiii Push Closure Num Copied llll Num - Args kkkk BlockSize jjjjjjjjiiiiiiii */ - - /* StackToRegisterMappingCogit>>#genPushClosureCopyCopiedValuesBytecode */ -static sqInt -genPushClosureCopyCopiedValuesBytecode(void) -{ - sqInt i; - sqInt numArgs; - sqInt numCopied; - sqInt reg; - sqInt startpc; - - assert(needsFrame); - startpc = bytecodePC + (((generatorAt(byte0))->numBytes)); - addBlockStartAtnumArgsnumCopiedspan(startpc, (numArgs = byte1 & 15), (numCopied = ((usqInt)(byte1)) >> 4), (((sqInt)((usqInt)(byte2) << 8))) + byte3); - /* begin genInlineClosure:numArgs:numCopied: */ - assert(getActiveContextAllocatesInMachineCode()); - voidReceiverResultRegContainsSelf(); - /* begin ssAllocateCallReg:and:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg) | (1U << SendNumArgsReg)) | (1U << ClassReg)), simStackPtr, simNativeStackPtr); - genNoPopCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(startpc + 1, numArgs, numCopied, methodOrBlockNumArgs, methodNeedsLargeContext(methodObj), inBlock); - for (i = 1; i <= numCopied; i += 1) { - reg = ssStorePoptoPreferredReg(1, TempReg); - genStoreSourceRegslotIndexintoNewObjectInDestReg(reg, (ClosureFirstCopiedValueIndex + numCopied) - i, ReceiverResultReg); - } - ssPushRegister(ReceiverResultReg); - return 0; -} - - -/* Uncached push enclosing object */ - - /* StackToRegisterMappingCogit>>#genPushEnclosingObjectAt: */ -static sqInt NoDbgRegParms -genPushEnclosingObjectAt(sqInt level) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - - voidReceiverResultRegContainsSelf(); - /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, level, SendNumArgsReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceEnclosingObjectTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - return ssPushRegister(ReceiverResultReg); -} - - -/* */ -/* Override to avoid the BytecodeSetHasDirectedSuperSend check, which is - unnecessary here given the simulation stack. */ - - /* StackToRegisterMappingCogit>>#genPushLiteralIndex: */ -static sqInt NoDbgRegParms -genPushLiteralIndex(sqInt literalIndex) -{ - sqInt literal; - - literal = getLiteral(literalIndex); - return genPushLiteral(literal); -} - - /* StackToRegisterMappingCogit>>#genPushLiteralVariable: */ -static sqInt NoDbgRegParms -genPushLiteralVariable(sqInt literalIndex) -{ - AbstractInstruction *anInstruction; - sqInt association; - sqInt bcpc; - BytecodeDescriptor *descriptor1; - sqInt eA; - sqInt eB; - sqInt freeReg; - sqInt savedB0; - sqInt savedB1; - sqInt savedB2; - sqInt savedB3; - sqInt savedEA; - sqInt savedEB; - sqInt savedNEB; - - - /* If followed by a directed super send bytecode, avoid generating any code yet. - The association will be passed to the directed send trampoline in a register - and fully dereferenced only when first linked. It will be ignored in later sends. */ - association = getLiteral(literalIndex); - assert(!(directedSendUsesBinding)); - /* begin nextDescriptorExtensionsAndNextPCInto: */ - descriptor1 = generatorAt(byte0); - savedB0 = byte0; - savedB1 = byte1; - savedB2 = byte2; - savedB3 = byte3; - savedEA = extA; - savedEB = extB; - savedNEB = numExtB; - bcpc = bytecodePC + ((descriptor1->numBytes)); - do { - if (bcpc > endPC) { - goto l1; - } - byte0 = (fetchByteofObject(bcpc, methodObj)) + bytecodeSetOffset; - descriptor1 = generatorAt(byte0); - loadSubsequentBytesForDescriptorat(descriptor1, bcpc); - if (!((descriptor1->isExtension))) { - eA = extA; - eB = extB; - extA = savedEA; - extB = savedEB; - numExtB = savedNEB; - byte0 = savedB0; - byte1 = savedB1; - byte2 = savedB2; - byte3 = savedB3; - if ((descriptor1 != null) - && ((((descriptor1->generator)) == genExtSendSuperBytecode) - && (eB >= 64))) { - ssPushConstant(association); - directedSendUsesBinding = 1; - return 0; - } - goto l1; - } - ((descriptor1->generator))(); - bcpc += (descriptor1->numBytes); - } while(1); - l1: /* end nextDescriptorExtensionsAndNextPCInto: */; - - /* N.B. Do _not_ use ReceiverResultReg to avoid overwriting receiver in assignment in frameless methods. */ - /* So far descriptors are not rich enough to describe the entire dereference so generate the register - load but don't push the result. There is an order-of-evaluation issue if we defer the dereference. */ - freeReg = allocateRegNotConflictingWith(0); - /* begin genMoveConstant:R: */ - if (shouldAnnotateObjectReference(association)) { - annotateobjRef(checkLiteralforInstruction(association, genoperandoperand(MoveCwR, association, TempReg)), association); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, association, TempReg); - } - genLoadSlotsourceRegdestReg(ValueIndex, TempReg, freeReg); - ssPushRegister(freeReg); - return 0; -} - - /* StackToRegisterMappingCogit>>#genPushLiteral: */ -static sqInt NoDbgRegParms -genPushLiteral(sqInt literal) -{ - return ssPushConstant(literal); -} - - /* StackToRegisterMappingCogit>>#genPushMaybeContextReceiverVariable: */ -static sqInt NoDbgRegParms -genPushMaybeContextReceiverVariable(sqInt slotIndex) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *jmpDone; - AbstractInstruction *jmpSingle; - - /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); - ensureReceiverResultRegContainsSelf(); - /* begin genPushMaybeContextSlotIndex: */ - assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { - - /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ - voidReceiverResultRegContainsSelf(); - } - if (slotIndex == InstructionPointerIndex) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, slotIndex, SendNumArgsReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceFetchContextInstVarTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - return ssPushRegister(SendNumArgsReg); - } - genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); - jmpSingle = genJumpNotSmallIntegerInScratchReg(TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, slotIndex, SendNumArgsReg); - /* begin CallRT: */ - abstractInstruction1 = genoperand(Call, ceFetchContextInstVarTrampoline); - (abstractInstruction1->annotation = IsRelativeCall); - /* begin Jump: */ - jmpDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jmpSingle, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genLoadSlotsourceRegdestReg(slotIndex, ReceiverResultReg, SendNumArgsReg); - jmpTarget(jmpDone, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return ssPushRegister(SendNumArgsReg); -} - - /* StackToRegisterMappingCogit>>#genPushNewArrayBytecode */ -static sqInt -genPushNewArrayBytecode(void) -{ - sqInt i; - sqInt i1; - int popValues; - sqInt size; - - assert(needsFrame); - voidReceiverResultRegContainsSelf(); - if ((popValues = byte1 > 0x7F)) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i1 <= simStackPtr; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - } - else { - /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); - } - size = byte1 & 0x7F; - if (!popValues) { - if (tryCollapseTempVectorInitializationOfSize(size)) { - return 0; - } - } - genNewArrayOfSizeinitialized(size, !popValues); - if (popValues) { - for (i = (size - 1); i >= 0; i += -1) { - /* begin PopR: */ - genoperand(PopR, TempReg); - genStoreSourceRegslotIndexintoNewObjectInDestReg(TempReg, i, ReceiverResultReg); - } - ssPop(size); - } - return ssPushRegister(ReceiverResultReg); -} - - /* StackToRegisterMappingCogit>>#genPushReceiverBytecode */ -static sqInt -genPushReceiverBytecode(void) -{ - if ((((simSelf())->liveRegister)) == ReceiverResultReg) { - return ssPushRegister(ReceiverResultReg); - } - return ssPushDesc(ssSelfDescriptor()); -} - - /* StackToRegisterMappingCogit>>#genPushReceiverVariable: */ -static sqInt NoDbgRegParms -genPushReceiverVariable(sqInt index) -{ - ensureReceiverResultRegContainsSelf(); - return ssPushBaseoffset(ReceiverResultReg, slotOffsetOfInstVarIndex(index)); -} - - -/* Ensure that the register args are pushed before the retpc for methods with - arity <= self numRegArgs. - */ -/* This isn't as clumsy on a RISC. But putting the receiver and - args above the return address means the CoInterpreter has a - single machine-code frame format which saves us a lot of work. */ - - /* StackToRegisterMappingCogit>>#genPushRegisterArgs */ -static void -genPushRegisterArgs(void) -{ - if (!(regArgsHaveBeenPushed - || (methodOrBlockNumArgs > 2 /* numRegArgs */))) { - genPushRegisterArgsForNumArgsscratchReg(backEnd, methodOrBlockNumArgs, SendNumArgsReg); - regArgsHaveBeenPushed = 1; - } -} - - /* StackToRegisterMappingCogit>>#genPushRemoteTempLongBytecode */ -static sqInt -genPushRemoteTempLongBytecode(void) -{ - AbstractInstruction *anInstruction; - sqInt offset; - sqInt regMask; - sqInt remoteTempReg; - sqInt tempVectReg; - - tempVectReg = allocateRegNotConflictingWith(0); - /* begin MoveMw:r:R: */ - offset = frameOffsetOfTemporary(byte2); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, FPReg, tempVectReg); - /* begin availableRegOrNoneNotConflictingWith: */ - regMask = 1U << tempVectReg; - remoteTempReg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); - if (remoteTempReg == NoReg) { - remoteTempReg = tempVectReg; - } - genLoadSlotsourceRegdestReg(byte1, tempVectReg, remoteTempReg); - return ssPushRegister(remoteTempReg); -} - - -/* If a frameless method (not a block), only argument temps can be accessed. - This is assured by the use of needsFrameIfMod16GENumArgs: in pushTemp. */ - - /* StackToRegisterMappingCogit>>#genPushTemporaryVariable: */ -static sqInt NoDbgRegParms -genPushTemporaryVariable(sqInt index) -{ - assert((inBlock > 0) - || (needsFrame - || (index < methodOrBlockNumArgs))); - return ssPushDesc(simStack[index + 1]); -} - - -/* In a frameless method ReceiverResultReg already contains self. - In a frameful method, ReceiverResultReg /may/ contain self. */ - - /* StackToRegisterMappingCogit>>#genReturnReceiver */ -static sqInt -genReturnReceiver(void) -{ - if (needsFrame) { - if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { - /* begin putSelfInReceiverResultReg */ - storeToReg(simSelf(), ReceiverResultReg); - } - } - return genUpArrowReturn(); -} - - /* StackToRegisterMappingCogit>>#genReturnTopFromBlock */ -static sqInt -genReturnTopFromBlock(void) -{ - assert(inBlock > 0); - popToReg(ssTop(), ReceiverResultReg); - ssPop(1); - return genBlockReturn(); -} - - /* StackToRegisterMappingCogit>>#genReturnTopFromMethod */ -static sqInt -genReturnTopFromMethod(void) -{ - popToReg(ssTop(), ReceiverResultReg); - ssPop(1); - return genUpArrowReturn(); -} - - /* StackToRegisterMappingCogit>>#genSendDirectedSuper:numArgs: */ -static sqInt NoDbgRegParms -genSendDirectedSupernumArgs(sqInt selectorIndex, sqInt numArgs) -{ - sqInt result; - - assert((((ssTop())->type)) == SSConstant); - tempOop = ((ssTop())->constant); - ssPop(1); - marshallSendArguments(numArgs); - result = genMarshalledSendnumArgssendTable(selectorIndex, numArgs, (directedSendUsesBinding - ? directedSuperBindingSendTrampolines - : directedSuperSendTrampolines)); - directedSendUsesBinding = 0; - return result; -} - - /* StackToRegisterMappingCogit>>#genSendSuper:numArgs: */ -static sqInt NoDbgRegParms -genSendSupernumArgs(sqInt selectorIndex, sqInt numArgs) -{ - marshallSendArguments(numArgs); - return genMarshalledSendnumArgssendTable(selectorIndex, numArgs, superSendTrampolines); -} - - -/* Generate a trampoline with four arguments. - Hack: a negative value indicates an abstract register, a non-negative - value indicates a constant. */ - - /* StackToRegisterMappingCogit>>#genSendTrampolineFor:numArgs:called:arg:arg:arg:arg: */ -static usqInt NoDbgRegParms -genSendTrampolineFornumArgscalledargargargarg(void *aRoutine, sqInt numArgs, char *aString, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3) -{ - sqInt routine; - usqInt startAddress; - - startAddress = methodZoneBase; - zeroOpcodeIndex(); - genPushRegisterArgsForNumArgsscratchReg(backEnd, numArgs, SendNumArgsReg); - /* begin selectorIndexDereferenceRoutine */ - routine = null; - if (!(routine == null)) { - - /* Explicitly save LinkReg via ExtraReg2; it's presumably faster than pushing/popping */ - /* begin MoveR:R: */ - genoperandoperand(MoveRR, LinkReg, Extra2Reg); - /* begin Call: */ - genoperand(Call, routine); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Extra2Reg, LinkReg); - } - genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(aRoutine, aString, 4, regOrConst0, regOrConst1, regOrConst2, regOrConst3, 0 /* emptyRegisterMask */, 1, NoReg, 1); - return startAddress; -} - - /* StackToRegisterMappingCogit>>#genSend:numArgs: */ -static sqInt NoDbgRegParms -genSendnumArgs(sqInt selectorIndex, sqInt numArgs) -{ - marshallSendArguments(numArgs); - return genMarshalledSendnumArgssendTable(selectorIndex, numArgs, ordinarySendTrampolines); -} - - /* StackToRegisterMappingCogit>>#genSpecialSelectorArithmetic */ -static sqInt -genSpecialSelectorArithmetic(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - sqInt argInt; - int argIsConst; - sqInt argIsInt; - sqInt i; - sqInt index; - AbstractInstruction *jumpContinue; - AbstractInstruction *jumpNotSmallInts; - BytecodeDescriptor *primDescriptor; - sqInt rcvrInt; - int rcvrIsConst; - sqInt rcvrIsInt; - sqInt result; - - primDescriptor = generatorAt(byte0); - argIsInt = ((argIsConst = (((ssTop())->type)) == SSConstant)) - && ((((argInt = ((ssTop())->constant))) & 1)); - rcvrIsInt = (((rcvrIsConst = (((ssValue(1))->type)) == SSConstant)) - && ((((rcvrInt = ((ssValue(1))->constant))) & 1))) - || ((mclassIsSmallInteger()) - && (isSameEntryAs(ssValue(1), simSelf()))); - if (argIsInt - && (rcvrIsInt - && (rcvrIsConst))) { - rcvrInt = (rcvrInt >> 1); - argInt = (argInt >> 1); - switch ((primDescriptor->opcode)) { - case AddRR: - result = rcvrInt + argInt; - break; - case SubRR: - result = rcvrInt - argInt; - break; - case AndRR: - result = rcvrInt & argInt; - break; - case OrRR: - result = rcvrInt | argInt; - break; - default: - error("Case not found and no otherwise clause"); - } - if (isIntegerValue(result)) { - - /* Must annotate the bytecode for correct pc mapping. */ - return (ssPop(2), - ssPushAnnotatedConstant((((usqInt)result << 1) | 1))); - } - return genSpecialSelectorSend(); - } - if ((rcvrIsConst - && (!rcvrIsInt)) - || (argIsConst - && (!argIsInt))) { - return genSpecialSelectorSend(); - } - if (!(argIsInt - || (rcvrIsInt))) { - return genSpecialSelectorSend(); - } - if (argIsInt) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 2)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 2)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 2))); i <= (simStackPtr - 2); i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 2) + 1; - } - popToReg(ssValue(1), ReceiverResultReg); - ssPop(2); - } - else { - marshallSendArguments(1); - } - jumpNotSmallInts = (!(rcvrIsInt - && (argIsInt)) - ? (argIsInt - ? genJumpNotSmallInteger(ReceiverResultReg) - : (rcvrIsInt - ? genJumpNotSmallInteger(Arg0Reg) - : (/* begin genJumpNotSmallIntegersIn:and:scratch: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg), - /* begin AndR:R: */ - genoperandoperand(AndRR, Arg0Reg, TempReg), - genJumpNotSmallIntegerInScratchReg(TempReg)))) - : 0); - switch ((primDescriptor->opcode)) { - case AddRR: - if (argIsInt) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, argInt - ConstZero, ReceiverResultReg); - /* begin JumpNoOverflow: */ - jumpContinue = genConditionalBranchoperand(JumpNoOverflow, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(SubCqR, argInt - ConstZero, ReceiverResultReg); - } - else { - genRemoveSmallIntegerTagsInScratchReg(ReceiverResultReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - /* begin JumpNoOverflow: */ - jumpContinue = genConditionalBranchoperand(JumpNoOverflow, ((sqInt)0)); - if (rcvrIsInt - && (rcvrIsConst)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, rcvrInt, ReceiverResultReg); - } - else { - /* begin SubR:R: */ - genoperandoperand(SubRR, Arg0Reg, ReceiverResultReg); - genSetSmallIntegerTagsIn(ReceiverResultReg); - } - } - break; - case SubRR: - if (argIsInt) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(SubCqR, argInt - ConstZero, ReceiverResultReg); - /* begin JumpNoOverflow: */ - jumpContinue = genConditionalBranchoperand(JumpNoOverflow, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(AddCqR, argInt - ConstZero, ReceiverResultReg); - } - else { - genRemoveSmallIntegerTagsInScratchReg(Arg0Reg); - /* begin SubR:R: */ - genoperandoperand(SubRR, Arg0Reg, ReceiverResultReg); - /* begin JumpNoOverflow: */ - jumpContinue = genConditionalBranchoperand(JumpNoOverflow, ((sqInt)0)); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - genSetSmallIntegerTagsIn(Arg0Reg); - } - break; - case AndRR: - if (argIsInt) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(AndCqR, argInt, ReceiverResultReg); - } - else { - /* begin AndR:R: */ - genoperandoperand(AndRR, Arg0Reg, ReceiverResultReg); - } - jumpContinue = (!(jumpNotSmallInts == null) - ? (/* begin Jump: */ - genoperand(Jump, ((sqInt)0))) - : 0); - break; - case OrRR: - if (argIsInt) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(OrCqR, argInt, ReceiverResultReg); - } - else { - /* begin OrR:R: */ - genoperandoperand(OrRR, Arg0Reg, ReceiverResultReg); - } - jumpContinue = (!(jumpNotSmallInts == null) - ? (/* begin Jump: */ - genoperand(Jump, ((sqInt)0))) - : 0); - break; - default: - error("Case not found and no otherwise clause"); - } - if (jumpNotSmallInts == null) { - if (!jumpContinue) { - - /* overflow cannot happen */ - /* begin annotateInstructionForBytecode */ - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (abstractInstruction->annotation = HasBytecodePC); - ssPushRegister(ReceiverResultReg); - return 0; - } - } - else { - jmpTarget(jumpNotSmallInts, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - if (argIsInt) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(MoveCqR, argInt, Arg0Reg); - } - index = byte0 - ( -#if MULTIPLEBYTECODESETS - (bytecodeSetOffset == 0x100 - ? AltFirstSpecialSelector + 0x100 - : FirstSpecialSelector) -#else - FirstSpecialSelector -#endif - ); - genMarshalledSendnumArgssendTable((-index) - 1, 1, ordinarySendTrampolines); - jmpTarget(jumpContinue, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - /* StackToRegisterMappingCogit>>#genSpecialSelectorClass */ -static sqInt -genSpecialSelectorClass(void) -{ - sqInt requiredReg1; - sqInt topReg; - - topReg = registerOrNone(ssTop()); - ssPop(1); - if ((topReg == NoReg) - || (topReg == ClassReg)) { - /* begin ssAllocateRequiredReg:and: */ - requiredReg1 = (topReg = SendNumArgsReg); - ssAllocateRequiredRegMaskupThroughupThroughNative((1U << requiredReg1) | (1U << ClassReg), simStackPtr, simNativeStackPtr); - } - else { - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr, simNativeStackPtr); - } - ssPush(1); - popToReg(ssTop(), topReg); - genGetClassObjectOfintoscratchRegmayBeAForwarder(topReg, ClassReg, TempReg, mayBeAForwarder(ssTop())); - return (ssPop(1), - ssPushRegister(ClassReg)); -} - - /* StackToRegisterMappingCogit>>#genSpecialSelectorComparison */ -static sqInt -genSpecialSelectorComparison(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt argInt; - sqInt argIsIntConst; - BytecodeDescriptor *branchDescriptor; - BytecodeDescriptor *branchDescriptor1; - sqInt i; - sqInt index; - sqInt inlineCAB; - AbstractInstruction *jumpNotSmallInts; - void *jumpTarget; - sqInt nExts; - sqInt nextPC; - sqInt nextPC1; - sqInt postBranchPC; - sqInt postBranchPC1; - BytecodeDescriptor *primDescriptor; - BytecodeDescriptor *primDescriptor1; - int rcvrIsConst; - sqInt rcvrIsInt; - sqInt targetBytecodePC; - sqInt targetPC; - - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 2)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 2)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 2))); i <= (simStackPtr - 2); i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 2) + 1; - } - primDescriptor = generatorAt(byte0); - argIsIntConst = ((((ssTop())->type)) == SSConstant) - && ((((argInt = ((ssTop())->constant))) & 1)); - rcvrIsInt = (((rcvrIsConst = (((ssValue(1))->type)) == SSConstant)) - && (((((ssValue(1))->constant)) & 1))) - || ((mclassIsSmallInteger()) - && (isSameEntryAs(ssValue(1), simSelf()))); - if (argIsIntConst - && (rcvrIsInt - && (rcvrIsConst))) { - return genStaticallyResolvedSpecialSelectorComparison(); - } - /* begin extractMaybeBranchDescriptorInto: */ - primDescriptor1 = generatorAt(byte0); - nextPC1 = bytecodePC + ((primDescriptor1->numBytes)); - nExts = 0; - while (1) { - while (1) { - /* begin generatorForPC: */ - branchDescriptor1 = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC1, methodObj))); - if (!((branchDescriptor1->isExtension))) break; - nExts += 1; - nextPC1 += (branchDescriptor1->numBytes); - } - /* begin isUnconditionalBranch */ - if (!((isBranch(branchDescriptor1)) - && (!(((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse)))))) break; - nextPC1 = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - } - targetBytecodePC = (postBranchPC1 = 0); - if (((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse))) { - targetBytecodePC = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - postBranchPC1 = eventualTargetOf(nextPC1 + ((branchDescriptor1->numBytes))); - } - else { - nextPC1 = bytecodePC + ((primDescriptor1->numBytes)); - } - branchDescriptor = branchDescriptor1; - nextPC = nextPC1; - postBranchPC = postBranchPC1; - targetPC = targetBytecodePC; - - /* Further, only interested in inlining = and ~= if there's a SmallInteger constant involved. - The relational operators successfully statically predict SmallIntegers; the equality operators do not. */ - inlineCAB = ((branchDescriptor->isBranchTrue)) - || ((branchDescriptor->isBranchFalse)); - if (inlineCAB - && ((((primDescriptor->opcode)) == JumpZero) - || (((primDescriptor->opcode)) == JumpNonZero))) { - inlineCAB = argIsIntConst - || (rcvrIsInt); - } - if (!inlineCAB) { - return genSpecialSelectorSend(); - } - if (argIsIntConst) { - popToReg(ssValue(1), ReceiverResultReg); - ssPop(2); - } - else { - marshallSendArguments(1); - } - jumpNotSmallInts = (!(rcvrIsInt - && (argIsIntConst)) - ? (argIsIntConst - ? genJumpNotSmallInteger(ReceiverResultReg) - : (rcvrIsInt - ? genJumpNotSmallInteger(Arg0Reg) - : (/* begin genJumpNotSmallIntegersIn:and:scratch: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg), - /* begin AndR:R: */ - genoperandoperand(AndRR, Arg0Reg, TempReg), - genJumpNotSmallIntegerInScratchReg(TempReg)))) - : 0); - if (argIsIntConst) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, argInt, ReceiverResultReg); - } - else { - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, ReceiverResultReg); - } - genConditionalBranchoperand(((branchDescriptor->isBranchTrue) - ? (primDescriptor->opcode) - : inverseBranchFor((primDescriptor->opcode))), ((usqInt)(ensureNonMergeFixupAt(targetPC)))); - /* begin Jump: */ - jumpTarget = ensureNonMergeFixupAt(postBranchPC); - genoperand(Jump, ((sqInt)jumpTarget)); - if (!jumpNotSmallInts) { - /* begin annotateInstructionForBytecode */ - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (abstractInstruction->annotation = HasBytecodePC); - ensureFixupAt(postBranchPC); - ensureFixupAt(targetPC); - deadCode = 1; - return 0; - } - jmpTarget(jumpNotSmallInts, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (argIsIntConst) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, argInt, Arg0Reg); - } - index = byte0 - ( -#if MULTIPLEBYTECODESETS - (bytecodeSetOffset == 0x100 - ? AltFirstSpecialSelector + 0x100 - : FirstSpecialSelector) -#else - FirstSpecialSelector -#endif - ); - return genMarshalledSendnumArgssendTable((-index) - 1, 1, ordinarySendTrampolines); -} - - -/* Assumes both operands are ints */ - - /* StackToRegisterMappingCogit>>#genStaticallyResolvedSpecialSelectorComparison */ -static sqInt -genStaticallyResolvedSpecialSelectorComparison(void) -{ - sqInt argInt; - BytecodeDescriptor *primDescriptor; - sqInt rcvrInt; - int result; - - primDescriptor = generatorAt(byte0); - argInt = ((ssTop())->constant); - rcvrInt = ((ssValue(1))->constant); - switch ((primDescriptor->opcode)) { - case JumpLess: - result = rcvrInt < argInt; - break; - case JumpLessOrEqual: - result = rcvrInt <= argInt; - break; - case JumpGreater: - result = rcvrInt > argInt; - break; - case JumpGreaterOrEqual: - result = rcvrInt >= argInt; - break; - case JumpZero: - result = rcvrInt == argInt; - break; - case JumpNonZero: - result = rcvrInt != argInt; - break; - default: - error("Case not found and no otherwise clause"); - } - ssPop(2); - return ssPushAnnotatedConstant((result - ? trueObject() - : falseObject())); -} - - -/* We need a frame because the association has to be in ReceiverResultReg for - the various trampolines - and ReceiverResultReg holds only the receiver in frameless methods. - */ - - /* StackToRegisterMappingCogit>>#genStorePop:LiteralVariable:needsStoreCheck:needsImmutabilityCheck: */ -static sqInt NoDbgRegParms -genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt litVarIndex, sqInt needsStoreCheck, sqInt needsImmCheck) -{ - AbstractInstruction *anInstruction; - sqInt association; - sqInt i; - sqInt topReg; - - assert(needsFrame); - /* begin genLoadLiteralVariable:in: */ - association = getLiteral(litVarIndex); - voidReceiverResultRegContainsSelf(); - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); - /* begin genMoveConstant:R: */ - if (shouldAnnotateObjectReference(association)) { - annotateobjRef(checkLiteralforInstruction(association, genoperandoperand(MoveCwR, association, ReceiverResultReg)), association); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, association, ReceiverResultReg); - } - /* begin genGenericStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr:needsImmutabilityCheck: */ -# if IMMUTABILITY - if (needsImmCheck) { - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); - ssStoreAndReplacePoptoReg(popBoolean, ClassReg); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0); - } -# endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); - ssStorePoptoReg(popBoolean, topReg); - return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); -} - - -/* The reason we need a frame here is that assigning to an inst var of a - context may - involve wholesale reorganization of stack pages, and the only way to - preserve the - execution state of an activation in that case is if it has a frame. */ - - /* StackToRegisterMappingCogit>>#genStorePop:MaybeContextReceiverVariable:needsStoreCheck:needsImmutabilityCheck: */ -static sqInt NoDbgRegParms -genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt slotIndex, sqInt needsStoreCheck, sqInt needsImmCheck) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *abstractInstruction2; - AbstractInstruction *abstractInstruction3; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt i; - AbstractInstruction *immutabilityFailure; - AbstractInstruction *mutableJump; - - immutabilityFailure = ((AbstractInstruction *) 0); - assert(needsFrame); - ssFlushUpThroughReceiverVariable(slotIndex); - ensureReceiverResultRegContainsSelf(); - /* begin genGenericStorePop:MaybeContextSlotIndex:needsStoreCheck:needsRestoreRcvr:needsImmutabilityCheck: */ - assert(needsFrame); -# if IMMUTABILITY - if (needsImmCheck) { - mutableJump = genJumpMutablescratchReg(ReceiverResultReg, TempReg); - /* begin genStoreTrampolineCall: */ - assert(IMMUTABILITY); - if (slotIndex >= (NumStoreTrampolines - 1)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, slotIndex, TempReg); - /* begin CallRT: */ - abstractInstruction3 = genoperand(Call, ceStoreTrampolines[NumStoreTrampolines - 1]); - (abstractInstruction3->annotation = IsRelativeCall); - } - else { - /* begin CallRT: */ - abstractInstruction1 = genoperand(Call, ceStoreTrampolines[slotIndex]); - (abstractInstruction1->annotation = IsRelativeCall); - } - /* begin annotateBytecode: */ - abstractInstruction2 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction2->annotation = HasBytecodePC); - /* begin putSelfInReceiverResultReg */ - storeToReg(simSelf(), ReceiverResultReg); - /* begin Jump: */ - immutabilityFailure = genoperand(Jump, ((sqInt)0)); - jmpTarget(mutableJump, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } -# endif // IMMUTABILITY - ssPop(1); - /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); - ssPush(1); - genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); - ssStoreAndReplacePoptoReg(popBoolean, ClassReg); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, slotIndex, SendNumArgsReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceStoreContextInstVarTrampoline); - (abstractInstruction->annotation = IsRelativeCall); -# if IMMUTABILITY - if (needsImmCheck) { - jmpTarget(immutabilityFailure, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } -# endif - return 0; -} - - /* StackToRegisterMappingCogit>>#genStorePop:ReceiverVariable:needsStoreCheck:needsImmutabilityCheck: */ -static sqInt NoDbgRegParms -genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt slotIndex, sqInt needsStoreCheck, sqInt needsImmCheck) -{ - sqInt i; - sqInt needsImmCheck1; - sqInt needsStoreCheck1; - sqInt topReg; - - ssFlushUpThroughReceiverVariable(slotIndex); - ensureReceiverResultRegContainsSelf(); - /* begin genGenericStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr:needsImmutabilityCheck: */ - needsStoreCheck1 = (!useTwoPaths) - && (needsStoreCheck); - needsImmCheck1 = needsImmCheck - && (!useTwoPaths); -# if IMMUTABILITY - if (needsImmCheck1) { - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); - ssStoreAndReplacePoptoReg(popBoolean, ClassReg); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck1, 1); - } -# endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); - ssStorePoptoReg(popBoolean, topReg); - return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck1); -} - - -/* The only reason we assert needsFrame here is that in a frameless method - ReceiverResultReg must and does contain only self, but the ceStoreCheck - trampoline expects the target of the store to be in ReceiverResultReg. So - in a frameless method we would have a conflict between the receiver and - the temote temp store, unless we we smart enough to realise that - ReceiverResultReg was unused after the literal variable store, unlikely - given that methods return self by default. */ - - /* StackToRegisterMappingCogit>>#genStorePop:RemoteTemp:At:needsStoreCheck: */ -static sqInt NoDbgRegParms -genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt remoteTempIndex, sqInt needsStoreCheck) -{ - AbstractInstruction *anInstruction; - sqInt offset; - sqInt topReg; - - assert(needsFrame); - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); - voidReceiverResultRegContainsSelf(); - /* begin MoveMw:r:R: */ - offset = frameOffsetOfTemporary(remoteTempIndex); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, FPReg, ReceiverResultReg); - /* begin genGenericStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr:needsImmutabilityCheck: */ -# if IMMUTABILITY - -# endif - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); - ssStorePoptoReg(popBoolean, topReg); - return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); -} - - /* StackToRegisterMappingCogit>>#genStorePop:TemporaryVariable: */ -static sqInt NoDbgRegParms -genStorePopTemporaryVariable(sqInt popBoolean, sqInt tempIndex) -{ - AbstractInstruction *anInstruction; - sqInt offset; - sqInt reg; - - ssFlushUpThroughTemporaryVariable(tempIndex); - reg = ssStorePoptoPreferredReg(popBoolean, TempReg); - /* begin MoveR:Mw:r: */ - offset = frameOffsetOfTemporary(tempIndex); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveRMwr, reg, offset, FPReg); - ((simStackAt(tempIndex + 1))->bcptr = bytecodePC); - return 0; -} - - -/* Generate a method return from within a method or a block. - Frameless method activation looks like - CISCs (x86): - receiver - args - sp-> ret pc. - RISCs (ARM): - receiver - args - ret pc in LR. - A fully framed activation is described in CoInterpreter - class>initializeFrameIndices. Return pops receiver and arguments off the - stack. Callee pushes the result. */ - - /* StackToRegisterMappingCogit>>#genUpArrowReturn */ -static sqInt -genUpArrowReturn(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - sqInt i; - sqInt offset; - - - /* can't fall through */ - deadCode = 1; - if (inBlock > 0) { - assert(needsFrame); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceNonLocalReturnTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin annotateBytecode: */ - abstractInstruction1 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction1->annotation = HasBytecodePC); - return 0; - } - if ( -# if IMMUTABILITY - needsFrame - && (!useTwoPaths) -# else - needsFrame -# endif - ) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, FPReg, SPReg); - /* begin PopR: */ - genoperand(PopR, FPReg); - /* begin PopR: */ - genoperand(PopR, LinkReg); - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - else { - /* begin RetN: */ - offset = ((methodOrBlockNumArgs > 2 /* numRegArgs */) - || (regArgsHaveBeenPushed) - ? (methodOrBlockNumArgs + 1) * BytesPerWord - : 0); - genoperand(RetN, offset); - } - return 0; -} - - /* StackToRegisterMappingCogit>>#genVanillaInlinedIdenticalOrNotIf: */ -static sqInt NoDbgRegParms -genVanillaInlinedIdenticalOrNotIf(sqInt orNot) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - int argIsConstant; - sqInt argNeedsReg; - sqInt argReg; - sqInt argReg1; - BytecodeDescriptor *branchDescriptor; - BytecodeDescriptor *branchDescriptor1; - sqInt constant; - sqInt constant1; - sqInt i; - void *jumpTarget; - void *jumpTarget1; - void *jumpTarget2; - void *jumpTarget3; - sqInt nExts; - sqInt nextPC; - sqInt nextPC1; - sqInt postBranchPC; - sqInt postBranchPC1; - BytecodeDescriptor *primDescriptor; - sqInt rcvrIsConstant; - sqInt rcvrNeedsReg; - sqInt rcvrReg; - sqInt rcvrReg1; - sqInt reg; - sqInt rNext1; - sqInt rTop1; - sqInt targetBytecodePC; - sqInt targetPC; - sqInt topRegistersMask; - - /* begin extractMaybeBranchDescriptorInto: */ - primDescriptor = generatorAt(byte0); - nextPC1 = bytecodePC + ((primDescriptor->numBytes)); - nExts = 0; - while (1) { - while (1) { - /* begin generatorForPC: */ - branchDescriptor1 = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC1, methodObj))); - if (!((branchDescriptor1->isExtension))) break; - nExts += 1; - nextPC1 += (branchDescriptor1->numBytes); - } - /* begin isUnconditionalBranch */ - if (!((isBranch(branchDescriptor1)) - && (!(((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse)))))) break; - nextPC1 = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - } - targetBytecodePC = (postBranchPC1 = 0); - if (((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse))) { - targetBytecodePC = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - postBranchPC1 = eventualTargetOf(nextPC1 + ((branchDescriptor1->numBytes))); - } - else { - nextPC1 = bytecodePC + ((primDescriptor->numBytes)); - } - branchDescriptor = branchDescriptor1; - nextPC = nextPC1; - postBranchPC = postBranchPC1; - targetPC = targetBytecodePC; - - /* They can't be both constants to use correct machine opcodes. - However annotable constants can't be resolved statically, hence we need to careful. */ - argIsConstant = (((ssTop())->type)) == SSConstant; - rcvrIsConstant = (!argIsConstant) - && ((((ssValue(1))->type)) == SSConstant); - /* begin allocateEqualsEqualsRegistersArgNeedsReg:rcvrNeedsReg:into: */ - argNeedsReg = !argIsConstant; - rcvrNeedsReg = !rcvrIsConstant; - assert(argNeedsReg - || (rcvrNeedsReg)); - argReg1 = (rcvrReg1 = NoReg); - if (argNeedsReg) { - if (rcvrNeedsReg) { - /* begin allocateRegForStackTopTwoEntriesInto: */ - topRegistersMask = 0; - rTop1 = (rNext1 = NoReg); - if ((registerOrNone(ssTop())) != NoReg) { - rTop1 = registerOrNone(ssTop()); - } - if ((registerOrNone(ssValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; - } - if (rTop1 == NoReg) { - rTop1 = allocateRegNotConflictingWith(topRegistersMask); - } - if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); - } - assert(!(((rTop1 == NoReg) - || (rNext1 == NoReg)))); - argReg1 = rTop1; - rcvrReg1 = rNext1; - popToReg(ssTop(), argReg1); - popToReg(ssValue(1), rcvrReg1); - } - else { - argReg1 = allocateRegForStackEntryAtnotConflictingWith(0, 0); - popToReg(ssTop(), argReg1); - if (((ssValue(1))->spilled)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AddCqR, BytesPerWord, SPReg); - } - } - } - else { - assert(rcvrNeedsReg); - assert(!((((ssTop())->spilled)))); - rcvrReg1 = allocateRegForStackEntryAtnotConflictingWith(1, 0); - popToReg(ssValue(1), rcvrReg1); - } - assert(!((argNeedsReg - && (argReg1 == NoReg)))); - assert(!((rcvrNeedsReg - && (rcvrReg1 == NoReg)))); - rcvrReg = rcvrReg1; - argReg = argReg1; - if (!(((branchDescriptor->isBranchTrue)) - || ((branchDescriptor->isBranchFalse)))) { - return genIdenticalNoBranchArgIsConstantrcvrIsConstantargRegrcvrRegorNotIf(argIsConstant, rcvrIsConstant, argReg, rcvrReg, orNot); - } - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 2)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 2)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 2))); i <= (simStackPtr - 2); i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 2) + 1; - } - /* begin genCmpArgIsConstant:rcvrIsConstant:argReg:rcvrReg: */ - assert((argReg != NoReg) - || (rcvrReg != NoReg)); - if (argIsConstant) { - /* begin genCmpConstant:R: */ - constant = ((ssTop())->constant); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(CmpCwR, constant, rcvrReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, constant, rcvrReg); - } - } - else { - if (rcvrIsConstant) { - /* begin genCmpConstant:R: */ - constant1 = ((ssValue(1))->constant); - if (shouldAnnotateObjectReference(constant1)) { - annotateobjRef(checkLiteralforInstruction(constant1, genoperandoperand(CmpCwR, constant1, argReg)), constant1); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, constant1, argReg); - } - } - else { - /* begin CmpR:R: */ - assert(!((argReg == SPReg))); - genoperandoperand(CmpRR, argReg, rcvrReg); - } - } - ssPop(2); - if ((((fixupAt(nextPC))->targetInstruction)) == 0) { - - /* The next instruction is dead. we can skip it. */ - deadCode = 1; - ensureFixupAt(targetPC); - ensureFixupAt(postBranchPC); - } - else { - assert(!(deadCode)); - } - if (orNot == ((branchDescriptor->isBranchTrue))) { - - /* a == b ifFalse: ... or a ~~ b ifTrue: ... jump on equal to post-branch pc */ - ensureNonMergeFixupAt(targetPC); - /* begin JumpZero: */ - jumpTarget = ensureNonMergeFixupAt(postBranchPC); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget)); - /* begin Jump: */ - jumpTarget1 = ensureNonMergeFixupAt(targetPC); - genoperand(Jump, ((sqInt)jumpTarget1)); - } - else { - - /* orNot is true for ~~ */ - /* a == b ifTrue: ... or a ~~ b ifFalse: ... jump on equal to target pc */ - /* begin JumpZero: */ - jumpTarget2 = ensureNonMergeFixupAt(targetPC); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget2)); - /* begin Jump: */ - jumpTarget3 = ensureNonMergeFixupAt(postBranchPC); - genoperand(Jump, ((sqInt)jumpTarget3)); - } - if (!deadCode) { - ssPushConstant(trueObject()); - } - return 0; -} - - /* StackToRegisterMappingCogit>>#initSimStackForFramefulMethod: */ -static void NoDbgRegParms -initSimStackForFramefulMethod(sqInt startpc) -{ - CogSimStackEntry * cascade0; - CogSimStackEntry *desc; - sqInt i; - - - /* N.B. Includes num args */ - simStackPtr = methodOrBlockNumTemps; - simSpillBase = methodOrBlockNumTemps + 1; - cascade0 = simSelf(); - (cascade0->type = SSBaseOffset); - (cascade0->spilled = 1); - (cascade0->registerr = FPReg); - (cascade0->offset = FoxMFReceiver); - (cascade0->liveRegister = NoReg); - for (i = 1; i <= methodOrBlockNumArgs; i += 1) { - desc = simStackAt(i); - (desc->type = SSBaseOffset); - (desc->spilled = 1); - (desc->registerr = FPReg); - (desc->offset = FoxCallerSavedIP + (((methodOrBlockNumArgs - i) + 1) * BytesPerWord)); - (desc->bcptr = startpc); - } - for (i = (methodOrBlockNumArgs + 1); i <= simStackPtr; i += 1) { - desc = simStackAt(i); - (desc->type = SSBaseOffset); - (desc->spilled = 1); - (desc->registerr = FPReg); - (desc->offset = FoxMFReceiver - ((i - methodOrBlockNumArgs) * BytesPerWord)); - (desc->bcptr = startpc); - } -} - - -/* The register receiver (the closure itself) and args are pushed by the - closure value primitive(s) - and hence a frameless block has all arguments and copied values pushed to - the stack. However, - the method receiver (self) is put in the ReceiverResultReg by the block - entry. - */ - - /* StackToRegisterMappingCogit>>#initSimStackForFramelessBlock: */ -static void NoDbgRegParms -initSimStackForFramelessBlock(sqInt startpc) -{ - CogSimStackEntry * cascade0; - CogSimStackEntry *desc; - sqInt i; - - cascade0 = simSelf(); - (cascade0->type = SSRegister); - (cascade0->spilled = 0); - (cascade0->registerr = ReceiverResultReg); - (cascade0->liveRegister = ReceiverResultReg); - assert(methodOrBlockNumTemps >= methodOrBlockNumArgs); - for (i = 1; i <= methodOrBlockNumTemps; i += 1) { - desc = simStackAt(i); - (desc->type = SSBaseOffset); - (desc->spilled = 1); - (desc->registerr = SPReg); - (desc->offset = (methodOrBlockNumArgs - i) * BytesPerWord); - (desc->bcptr = startpc); - } - - /* N.B. Includes num args */ - simStackPtr = methodOrBlockNumTemps; - simSpillBase = methodOrBlockNumTemps + 1; - } - - /* StackToRegisterMappingCogit>>#initSimStackForFramelessMethod: */ -static void NoDbgRegParms -initSimStackForFramelessMethod(sqInt startpc) -{ - CogSimStackEntry * cascade0; - CogSimStackEntry *desc; - sqInt i; - - cascade0 = simSelf(); - (cascade0->type = SSRegister); - (cascade0->spilled = 0); - (cascade0->registerr = ReceiverResultReg); - (cascade0->liveRegister = ReceiverResultReg); - assert(methodOrBlockNumTemps == methodOrBlockNumArgs); - assert((numRegArgs()) <= 2); - if (((methodOrBlockNumArgs >= 1) && (methodOrBlockNumArgs <= 2 /* numRegArgs */))) { - desc = simStackAt(1); - (desc->type = SSRegister); - (desc->spilled = 0); - (desc->registerr = Arg0Reg); - (desc->bcptr = startpc); - if (methodOrBlockNumArgs > 1) { - desc = simStackAt(2); - (desc->type = SSRegister); - (desc->spilled = 0); - (desc->registerr = Arg1Reg); - (desc->bcptr = startpc); - } - } - else { - for (i = 1; i <= methodOrBlockNumArgs; i += 1) { - desc = simStackAt(i); - (desc->type = SSBaseOffset); - (desc->registerr = SPReg); - (desc->spilled = 1); - (desc->offset = (methodOrBlockNumArgs - i) * BytesPerWord); - (desc->bcptr = startpc); - } - } - simStackPtr = methodOrBlockNumArgs; - simSpillBase = methodOrBlockNumArgs + 1; - } - - -/* Do not inline (inBlock access) */ - - /* StackToRegisterMappingCogit>>#isNonForwarderReceiver: */ -static sqInt NoDbgRegParms -isNonForwarderReceiver(sqInt reg) -{ - return ((((simSelf())->liveRegister)) == ReceiverResultReg) - && ((inBlock == 0) - && (reg == ReceiverResultReg)); -} - - /* StackToRegisterMappingCogit>>#liveRegisters */ -static sqInt -liveRegisters(void) -{ - sqInt i; - sqInt regsSet; - - if (needsFrame) { - regsSet = 0; - } - else { - /* begin registerMaskFor: */ - regsSet = 1U << ReceiverResultReg; - if ((methodOrBlockNumArgs <= 2 /* numRegArgs */) - && (methodOrBlockNumArgs > 0)) { - regsSet = regsSet | (1U << Arg0Reg); - if (methodOrBlockNumArgs > 1) { - regsSet = regsSet | (1U << Arg1Reg); - } - } - } - for (i = (((simSpillBase < 0) ? 0 : simSpillBase)); i <= simStackPtr; i += 1) { - regsSet = regsSet | (registerMask(simStackAt(i))); - } - return regsSet; -} - - -/* insert nops for dead code that is mapped so that bc - to mc mapping is not many to one */ - - /* StackToRegisterMappingCogit>>#mapDeadDescriptorIfNeeded: */ -static sqInt NoDbgRegParms -mapDeadDescriptorIfNeeded(BytecodeDescriptor *descriptor) -{ - AbstractInstruction *abstractInstruction; - - flag("annotateInstruction"); - if (((descriptor->isMapped)) - || ((inBlock > 0) - && ((descriptor->isMappedInBlock)))) { - /* begin annotateBytecode: */ - abstractInstruction = gen(Nop); - (abstractInstruction->annotation = HasBytecodePC); - } - return 0; -} - - /* StackToRegisterMappingCogit>>#marshallAbsentReceiverSendArguments: */ -static void NoDbgRegParms -marshallAbsentReceiverSendArguments(sqInt numArgs) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - sqInt i; - sqInt i1; - sqInt index; - sqInt numSpilled; - - assert(needsFrame); - /* begin ssAllocateCallReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); - /* begin putSelfInReceiverResultReg */ - storeToReg(simSelf(), ReceiverResultReg); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - numArgs)) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - numArgs)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - numArgs))); i1 <= (simStackPtr - numArgs); i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = (simStackPtr - numArgs) + 1; - } - if (numArgs > 2 /* numRegArgs */) { - - /* The arguments must be pushed to the stack, and hence the receiver - must be inserted beneath the args. Reduce or eliminate the argument - shuffle by only moving already spilled items. */ - numSpilled = numberOfSpillsInTopNItems(numArgs); - if (numSpilled > 0) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveMwrR, 0, SPReg, TempReg); - /* begin PushR: */ - genoperand(PushR, TempReg); - for (index = 2; index <= numSpilled; index += 1) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, index * BytesPerWord, SPReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveRMwr, TempReg, (index - 1) * BytesPerWord, SPReg); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperandoperand(MoveRMwr, ReceiverResultReg, numSpilled * BytesPerWord, SPReg); - } - else { - /* begin PushR: */ - genoperand(PushR, ReceiverResultReg); - } - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - } - else { - if (numArgs > 0) { - if (numArgs > 1) { - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 2, simNativeStackPtr); - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg1Reg, simStackPtr - 1, simNativeStackPtr); - } - else { - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); - } - } - if (numArgs > 1) { - popToReg(simStackAt(simStackPtr), Arg1Reg); - } - if (numArgs > 0) { - popToReg(simStackAt((simStackPtr - numArgs) + 1), Arg0Reg); - } - } - ssPop(numArgs); -} - - -/* Spill everything on the simulated stack that needs spilling (that below - receiver and arguments). - Marshall receiver and arguments to stack and/or registers depending on arg - count. If the args don't fit in registers push receiver and args (spill - everything), but still assign - the receiver to ReceiverResultReg. */ - - /* StackToRegisterMappingCogit>>#marshallSendArguments: */ -static void NoDbgRegParms -marshallSendArguments(sqInt numArgs) -{ - sqInt anyRefs; - CogSimStackEntry * cascade0; - sqInt i; - sqInt i1; - sqInt i2; - sqInt numSpilled; - - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= ((simStackPtr - numArgs) - 1)) { - for (i2 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < ((simStackPtr - numArgs) - 1)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : ((simStackPtr - numArgs) - 1))); i2 < (simStackPtr - numArgs); i2 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i2), frameOffsetOfTemporary(i2 - 1), FPReg); - } - simSpillBase = ((simStackPtr - numArgs) - 1) + 1; - } - if (numArgs > 2 /* numRegArgs */) { - - /* If there are no spills and no references to ReceiverResultReg - the fetch of ReceiverResultReg from the stack can be avoided - by assigning directly to ReceiverResultReg and pushing it. */ - numSpilled = numberOfSpillsInTopNItems(numArgs + 1); - anyRefs = anyReferencesToRegisterinTopNItems(ReceiverResultReg, numArgs + 1); - if ((numSpilled > 0) - || (anyRefs)) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - storeToReg(simStackAt(simStackPtr - numArgs), ReceiverResultReg); - } - else { - cascade0 = simStackAt(simStackPtr - numArgs); - storeToReg(cascade0, ReceiverResultReg); - (cascade0->type = SSRegister); - (cascade0->registerr = ReceiverResultReg); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i1 <= simStackPtr; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - } - } - else { - - /* Move the args to the register arguments, being careful to do - so last to first so e.g. previous contents don't get overwritten. - Also check for any arg registers in use by other args. */ - if (numArgs > 0) { - if (numArgs > 1) { - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 2, simNativeStackPtr); - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg1Reg, simStackPtr - 1, simNativeStackPtr); - } - else { - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); - } - } - if (numArgs > 1) { - popToReg(simStackAt(simStackPtr), Arg1Reg); - } - if (numArgs > 0) { - popToReg(simStackAt((simStackPtr - numArgs) + 1), Arg0Reg); - } - popToReg(simStackAt(simStackPtr - numArgs), ReceiverResultReg); - } - ssPop(numArgs + 1); -} - - -/* For assert checking; or rather for avoiding assert fails when dealing with - the hack for block temps in the SqueakV3PlusClosures bytecode set. - */ - - /* StackToRegisterMappingCogit>>#maybeCompilingFirstPassOfBlockWithInitialPushNil */ -static sqInt -maybeCompilingFirstPassOfBlockWithInitialPushNil(void) -{ - return (inBlock == InVanillaBlock) - && ((methodOrBlockNumTemps > methodOrBlockNumArgs) - && (compilationPass == 1)); -} - - -/* If this bytecode has a fixup, some kind of merge needs to be done. There - are 4 cases: - 1) the bytecode has no fixup (fixup isNotAFixup) - do nothing - 2) the bytecode has a non merge fixup - the fixup has needsNonMergeFixup. - The code generating non merge fixup (currently only special selector code) - is responsible - for the merge so no need to do it. - We set deadCode to false as the instruction can be reached from jumps. - 3) the bytecode has a merge fixup, but execution flow *cannot* fall - through to the merge point. - the fixup has needsMergeFixup and deadCode = true. - ignores the current simStack as it does not mean anything - restores the simStack to the state the jumps to the merge point expects it - to be. - 4) the bytecode has a merge fixup and execution flow *can* fall through to - the merge point. - the fixup has needsMergeFixup and deadCode = false. - flushes the stack to the stack pointer so the fall through execution path - simStack is - in the state the merge point expects it to be. - restores the simStack to the state the jumps to the merge point expects it - to be. - - In addition, if this is a backjump merge point, we patch the fixup to hold - the current simStackPtr - for later assertions. */ - - /* StackToRegisterMappingCogit>>#mergeWithFixupIfRequired: */ -static sqInt NoDbgRegParms -mergeWithFixupIfRequired(BytecodeFixup *fixup) -{ - CogSimStackEntry * cascade0; - sqInt i; - sqInt i1; - - /* begin assertCorrectSimStackPtr */ - assert((simSpillBase >= methodOrBlockNumTemps) - || ((maybeCompilingFirstPassOfBlockWithInitialPushNil()) - && (simSpillBase > methodOrBlockNumArgs))); - if (needsFrame - && (simSpillBase > 0)) { - assert((((simStackAt(simSpillBase - 1))->spilled)) == 1); - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); - } - if (((fixup->targetInstruction)) == 0) { - return 0; - } - if ((((usqInt)((fixup->targetInstruction)))) == NeedsNonMergeFixupFlag) { - deadCode = 0; - return 0; - } - assert(isMergeFixup(fixup)); - traceMerge(fixup); - if (deadCode) { - - /* case 3 */ - /* Would like to assert fixup simStackPtr >= methodOrBlockNumTemps - but can't because of the initialNils hack. */ - assert((((fixup->simStackPtr)) >= methodOrBlockNumTemps) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - simStackPtr = (fixup->simStackPtr); - } - else { - - /* case 4 */ - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - } - deadCode = 0; - if ((fixup->isTargetOfBackwardBranch)) { - (fixup->simStackPtr = simStackPtr); - } - (fixup->targetInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(simStackPtr == ((fixup->simStackPtr))); - /* begin restoreSimStackAtMergePoint: */ - ((simSelf())->liveRegister = NoReg); - for (i1 = (methodOrBlockNumTemps + 1); i1 <= simStackPtr; i1 += 1) { - cascade0 = simStackAt(i1); - (cascade0->type = SSSpill); - (cascade0->offset = FoxMFReceiver - ((i1 - methodOrBlockNumArgs) * BytesPerOop)); - (cascade0->registerr = FPReg); - (cascade0->spilled = 1); - } - simSpillBase = simStackPtr + 1; - return 0; -} - - /* StackToRegisterMappingCogit>>#methodAbortTrampolineFor: */ -static sqInt NoDbgRegParms -methodAbortTrampolineFor(sqInt numArgs) -{ - return methodAbortTrampolines[((numArgs < (3)) ? numArgs : (3))]; -} - - -/* This is a hook for subclasses to filter out methods they can't deal with. */ -/* Frameless methods with local temporaries cause problems, - mostly in asserts, and yet they matter not at all for performance. - Shun them. */ - - /* StackToRegisterMappingCogit>>#methodFoundInvalidPostScan */ -static sqInt -methodFoundInvalidPostScan(void) -{ - if (!needsFrame) { - return methodOrBlockNumTemps > methodOrBlockNumArgs; - } - return 0; -} - - /* StackToRegisterMappingCogit>>#needsFrameIfExtBGT2: */ -static sqInt NoDbgRegParms -needsFrameIfExtBGT2(sqInt stackDelta) -{ - return (extB < 0) - || (extB > 2); -} - - /* StackToRegisterMappingCogit>>#needsFrameIfMod16GENumArgs: */ -static sqInt NoDbgRegParms -needsFrameIfMod16GENumArgs(sqInt stackDelta) -{ - return (byte0 % 16) >= methodOrBlockNumArgs; -} - - -/* As of August 2013, the code generator can't deal with spills in frameless - methods (the - issue is to do with the stack offset to get at an argument, which is - changed when there's a spill). - In e.g. TextColor>>#dominates: other ^other class == self class the second - send of class - needs also rto allocate a register that the first one used, but the first - one's register can't be - spilled. So avoid this by only allowing class to be sent if the stack - contains a single element. */ - - /* StackToRegisterMappingCogit>>#needsFrameIfStackGreaterThanOne: */ -static sqInt NoDbgRegParms -needsFrameIfStackGreaterThanOne(sqInt stackDelta) -{ - return stackDelta > 1; -} - - /* StackToRegisterMappingCogit>>#numberOfSpillsInTopNItems: */ -static sqInt NoDbgRegParms -numberOfSpillsInTopNItems(sqInt n) -{ - sqInt i; - - for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { - if ((((simStackAt(i))->type)) == SSSpill) { - return n - (simStackPtr - i); - } - } - return 0; -} - - /* StackToRegisterMappingCogit>>#picAbortTrampolineFor: */ -static sqInt NoDbgRegParms -picAbortTrampolineFor(sqInt numArgs) -{ - return picAbortTrampolines[((numArgs < (3)) ? numArgs : (3))]; -} - - /* StackToRegisterMappingCogit>>#prevInstIsPCAnnotated */ -static sqInt -prevInstIsPCAnnotated(void) -{ - sqInt prevIndex; - AbstractInstruction *prevInst; - - if (!(opcodeIndex > 0)) { - return 0; - } - prevIndex = opcodeIndex - 1; - while (1) { - if (prevIndex <= 0) { - return 0; - } - prevInst = abstractInstructionAt(prevIndex); - if (isPCMappedAnnotation((!((prevInst->annotation)) - ? 0 - : (prevInst->annotation)))) { - return 1; - } - if (!(((prevInst->opcode)) == Label)) break; - prevIndex -= 1; - } - return 0; -} - - -/* Used to mark ReceiverResultReg as dead or not containing simSelf. - Used when the simStack has already been flushed, e.g. for sends. */ - - /* StackToRegisterMappingCogit>>#receiverIsInReceiverResultReg */ -static sqInt -receiverIsInReceiverResultReg(void) -{ - return (((simSelf())->liveRegister)) == ReceiverResultReg; -} - - -/* When a block must be recompiled due to overestimating the - numInitialNils fixups must be restored, which means rescannning - since backward branches need their targets initialized. */ - - /* StackToRegisterMappingCogit>>#reinitializeFixupsFrom:through: */ -static void NoDbgRegParms -reinitializeFixupsFromthrough(sqInt start, sqInt end) -{ - BytecodeDescriptor *descriptor; - sqInt distance; - BytecodeFixup * fixup; - sqInt nExts; - sqInt pc; - BytecodeFixup * self_in_reinitialize; - sqInt targetPC; - - pc = start; - nExts = 0; - while (pc <= end) { - /* begin reinitialize */ - self_in_reinitialize = fixupAtIndex(pc - initialPC); - (self_in_reinitialize->targetInstruction) = 0; - (self_in_reinitialize->simStackPtr) = 0; - byte0 = (fetchByteofObject(pc, methodObj)) + bytecodeSetOffset; - descriptor = generatorAt(byte0); - if ((isBranch(descriptor)) - && ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, pc, nExts, methodObj)) < 0))) { - /* begin spanFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, pc, nExts, methodObj); - targetPC = (pc + ((descriptor->numBytes))) + distance; - /* begin initializeFixupAt: */ - fixup = fixupAtIndex(targetPC - initialPC); - /* begin initializeFixup: */ - (fixup->targetInstruction) = ((AbstractInstruction *) NeedsMergeFixupFlag); - /* begin setIsBackwardBranchFixup */ - (fixup->isTargetOfBackwardBranch) = 1; - } - if ((descriptor->isBlockCreation)) { - /* begin spanFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, pc, nExts, methodObj); - pc = (pc + ((descriptor->numBytes))) + distance; - } - else { - pc += (descriptor->numBytes); - } - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } -} - - -/* Scan the block to determine if the block needs a frame or not */ - - /* StackToRegisterMappingCogit>>#scanBlock: */ -static sqInt NoDbgRegParms -scanBlock(BlockStart *blockStart) -{ - BytecodeDescriptor *descriptor; - sqInt end; - sqInt framelessStackDelta; - sqInt nExts; - sqInt numPushNils; - sqInt (* const numPushNilsFunction)(struct _BytecodeDescriptor *,sqInt,sqInt,sqInt) = v3or4NumPushNils; - sqInt pc; - sqInt pushingNils; - - needsFrame = 0; - prevBCDescriptor = null; - methodOrBlockNumArgs = (blockStart->numArgs); - inBlock = InVanillaBlock; - pc = (blockStart->startpc); - end = ((blockStart->startpc)) + ((blockStart->span)); - framelessStackDelta = (nExts = (extA = (numExtB = (extB = 0)))); - pushingNils = 1; - while (pc < end) { - byte0 = (fetchByteofObject(pc, methodObj)) + bytecodeSetOffset; - descriptor = generatorAt(byte0); - if ((descriptor->isExtension)) { - loadSubsequentBytesForDescriptorat(descriptor, pc); - ((descriptor->generator))(); - } - if (!needsFrame) { - if ((((descriptor->needsFrameFunction)) == null) - || (((descriptor->needsFrameFunction))(framelessStackDelta))) { - needsFrame = 1; - } - else { - framelessStackDelta += (descriptor->stackDelta); - } - } - /* begin maybeNoteDescriptor:blockStart: */ - if ((descriptor->isInstVarRef)) { - (blockStart->hasInstVarRef = 1); - } - if (pushingNils - && (!((descriptor->isExtension)))) { - - /* Count the initial number of pushed nils acting as temp initializers. We can't tell - whether an initial pushNil is an operand reference or a temp initializer, except - when the pushNil is a jump target (has a fixup), which never happens: - self systemNavigation browseAllSelect: - [:m| | ebc | - (ebc := m embeddedBlockClosures - select: [:ea| ea decompile statements first isMessage] - thenCollect: [:ea| ea decompile statements first selector]) notEmpty - and: [(#(whileTrue whileFalse whileTrue: whileFalse:) intersection: ebc) notEmpty]] - or if the bytecode set has a push multiple nils bytecode. We simply count initial nils. - Rarely we may end up over-estimating. We will correct by checking the stack depth - at the end of the block in compileBlockBodies. */ - if (((numPushNils = numPushNilsFunction(descriptor, pc, nExts, methodObj))) > 0) { - assert(((descriptor->numBytes)) == 1); - (blockStart->numInitialNils = ((blockStart->numInitialNils)) + numPushNils); - } - else { - pushingNils = 0; - } - } - /* begin nextBytecodePCFor:at:exts:in: */ - pc = (pc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? ((descriptor->spanFunction))(descriptor, pc, nExts, methodObj) - : 0)); - if ((descriptor->isExtension)) { - nExts += 1; - } - else { - nExts = (extA = (numExtB = (extB = 0))); - } - prevBCDescriptor = descriptor; - } - if (!needsFrame) { - assert((framelessStackDelta >= 0) - && (((blockStart->numInitialNils)) >= framelessStackDelta)); - (blockStart->numInitialNils = ((blockStart->numInitialNils)) - framelessStackDelta); - } - return 0; -} - - -/* Scan the method (and all embedded blocks) to determine - - what the last bytecode is; extra bytes at the end of a method are used - to encode things like source pointers or temp names - - if the method needs a frame or not - - what are the targets of any backward branches. - - how many blocks it creates - Answer the block count or on error a negative error code */ - - /* StackToRegisterMappingCogit>>#scanMethod */ -static sqInt -scanMethod(void) -{ - BytecodeDescriptor *descriptor; - sqInt distance; - BytecodeFixup * fixup; - sqInt framelessStackDelta; - sqInt latestContinuation; - sqInt nExts; - sqInt numBlocks; - sqInt pc; - sqInt seenInstVarStore; - sqInt targetPC; - - needsFrame = (useTwoPaths = (seenInstVarStore = 0)); - prevBCDescriptor = null; - numIRCs = 0; - if ((primitiveIndex > 0) - && (isQuickPrimitiveIndex(primitiveIndex))) { - return 0; - } - pc = (latestContinuation = initialPC); - numBlocks = (framelessStackDelta = (nExts = (extA = (numExtB = (extB = 0))))); - while (pc <= endPC) { - byte0 = (fetchByteofObject(pc, methodObj)) + bytecodeSetOffset; - descriptor = generatorAt(byte0); - if ((descriptor->isExtension)) { - if (((descriptor->opcode)) == Nop) { - - /* unknown bytecode tag; see Cogit class>>#generatorTableFrom: */ - return EncounteredUnknownBytecode; - } - loadSubsequentBytesForDescriptorat(descriptor, pc); - ((descriptor->generator))(); - } - if (((descriptor->isReturn)) - && (pc >= latestContinuation)) { - endPC = pc; - } - if (!needsFrame) { - if ((((descriptor->needsFrameFunction)) == null) - || (((descriptor->needsFrameFunction))(framelessStackDelta))) { - - /* With immutability we win simply by avoiding a frame build if the receiver is young and not immutable. */ -# if IMMUTABILITY - if ((descriptor->is1ByteInstVarStore)) { - useTwoPaths = 1; - } - else { - needsFrame = 1; - useTwoPaths = 0; - } -# else // IMMUTABILITY - needsFrame = 1; - useTwoPaths = 0; -# endif - } - else { - - /* Without immutability we win if there are two or more stores and the receiver is new. */ - framelessStackDelta += (descriptor->stackDelta); -# if IMMUTABILITY -# else - if ((descriptor->is1ByteInstVarStore)) { - if (seenInstVarStore) { - useTwoPaths = 1; - } - else { - seenInstVarStore = 1; - } - } -# endif // IMMUTABILITY - } - } - if (isBranch(descriptor)) { - /* begin spanFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, pc, nExts, methodObj); - targetPC = (pc + ((descriptor->numBytes))) + distance; - if ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, pc, nExts, methodObj)) < 0)) { - /* begin initializeFixupAt: */ - fixup = fixupAtIndex(targetPC - initialPC); - /* begin initializeFixup: */ - (fixup->targetInstruction) = ((AbstractInstruction *) NeedsMergeFixupFlag); - /* begin setIsBackwardBranchFixup */ - (fixup->isTargetOfBackwardBranch) = 1; - } - else { - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - } - /* begin maybeDealWithUnsafeJumpForDescriptor:pc:latestContinuation: */ - /* latestContinuation = */ latestContinuation; - if ((descriptor->isBlockCreation)) { - numBlocks += 1; - /* begin spanFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, pc, nExts, methodObj); - targetPC = (pc + ((descriptor->numBytes))) + distance; - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - if ((descriptor->hasIRC)) { - numIRCs += 1; - } - pc += (descriptor->numBytes); - nExts = ((descriptor->isExtension) - ? nExts + 1 - : (extA = (numExtB = (extB = 0)))); - prevBCDescriptor = descriptor; - } - return numBlocks; -} - - /* StackToRegisterMappingCogit>>#ssAllocateRequiredRegMask:upThrough:upThroughNative: */ -static void NoDbgRegParms -ssAllocateRequiredRegMaskupThroughupThroughNative(sqInt requiredRegsMask, sqInt stackPtr, sqInt nativeStackPtr) -{ - sqInt i; - sqInt i1; - sqInt lastRequired; - sqInt lastRequiredNative; - sqInt liveRegs; - - lastRequired = -1; - - /* compute live regs while noting the last occurrence of required regs. - If these are not free we must spill from simSpillBase to last occurrence. - Note we are conservative here; we could allocate FPReg in frameless methods. */ - lastRequiredNative = -1; - /* begin registerMaskFor:and: */ - liveRegs = (1U << FPReg) | (1U << SPReg); - for (i = (((simSpillBase < 0) ? 0 : simSpillBase)); i <= stackPtr; i += 1) { - liveRegs = liveRegs | (registerMask(simStackAt(i))); - if ((((registerMask(simStackAt(i))) & requiredRegsMask) != 0)) { - lastRequired = i; - } - } - if (((liveRegs & requiredRegsMask) != 0)) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= lastRequired) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < lastRequired) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : lastRequired)); i1 <= lastRequired; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = lastRequired + 1; - } - assert(!(((((liveRegisters()) & requiredRegsMask) != 0)))); - } -} - - -/* Any occurrences on the stack of the value being stored (which is the top - of stack) - must be flushed, and hence any values colder than them stack. */ - - /* StackToRegisterMappingCogit>>#ssFlushUpThroughReceiverVariable: */ -static void NoDbgRegParms -ssFlushUpThroughReceiverVariable(sqInt slotIndex) -{ - sqInt i; - sqInt index; - - /* begin ssFlushUpThrough: */ - assert(simSpillBase >= 0); - for (index = (simStackPtr - 1); index >= simSpillBase; index += -1) { - if (((((simStackAt(index))->type)) == SSBaseOffset) - && (((((simStackAt(index))->registerr)) == ReceiverResultReg) - && ((((simStackAt(index))->offset)) == (slotOffsetOfInstVarIndex(slotIndex))))) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= index) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < index) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : index)); i <= index; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = index + 1; - } - goto l1; - } - } - l1: /* end ssFlushUpThrough: */; -} - - -/* Any occurrences on the stack of the value being stored (which is the top - of stack) - must be flushed, and hence any values colder than them stack. */ - - /* StackToRegisterMappingCogit>>#ssFlushUpThroughTemporaryVariable: */ -static void NoDbgRegParms -ssFlushUpThroughTemporaryVariable(sqInt tempIndex) -{ - sqInt i; - sqInt index; - sqInt offset; - - offset = ((simStackAt(tempIndex + 1))->offset); - assert(offset == (frameOffsetOfTemporary(tempIndex))); - /* begin ssFlushUpThrough: */ - assert(simSpillBase >= 0); - for (index = (simStackPtr - 1); index >= simSpillBase; index += -1) { - if (((((simStackAt(index))->type)) == SSBaseOffset) - && (((((simStackAt(index))->registerr)) == FPReg) - && ((((simStackAt(index))->offset)) == offset))) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= index) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < index) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : index)); i <= index; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = index + 1; - } - goto l1; - } - } - l1: /* end ssFlushUpThrough: */; -} - - /* StackToRegisterMappingCogit>>#ssPop: */ -static void NoDbgRegParms -ssPop(sqInt n) -{ - sqInt i; - - assert(((simStackPtr - n) >= methodOrBlockNumTemps) - || (((!needsFrame) - && ((simStackPtr - n) >= 0)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil()))); - simStackPtr -= n; - /* begin updateSimSpillBase */ - assert(((simSpillBase > methodOrBlockNumTemps) - && (simStackPtr >= methodOrBlockNumTemps)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - if (simSpillBase > simStackPtr) { - simSpillBase = simStackPtr + 1; - while (((simSpillBase - 1) > methodOrBlockNumTemps) - && (!(((simStackAt(simSpillBase - 1))->spilled)))) { - simSpillBase -= 1; - } - } - else { - while ((((simStackAt(simSpillBase))->spilled)) - && (simSpillBase <= simStackPtr)) { - simSpillBase += 1; - } - } - for (i = (methodOrBlockNumTemps + 1); i <= ((((simSpillBase - 1) < simStackPtr) ? (simSpillBase - 1) : simStackPtr)); i += 1) { - assert((((simStackAt(i))->spilled)) == 1); - } - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); -} - - /* StackToRegisterMappingCogit>>#ssPushAnnotatedConstant: */ -static sqInt NoDbgRegParms -ssPushAnnotatedConstant(sqInt literal) -{ - AbstractInstruction *abstractInstruction; - - ssPushConstant(literal); - /* begin annotateInstructionForBytecode */ - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (abstractInstruction->annotation = HasBytecodePC); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushBase:offset: */ -static sqInt NoDbgRegParms -ssPushBaseoffset(sqInt reg, sqInt offset) -{ - CogSimStackEntry * cascade0; - sqInt i; - - ssPush(1); - cascade0 = ssTop(); - (cascade0->type = SSBaseOffset); - (cascade0->spilled = 0); - (cascade0->registerr = reg); - (cascade0->offset = offset); - (cascade0->bcptr = bytecodePC); - /* begin updateSimSpillBase */ - assert(((simSpillBase > methodOrBlockNumTemps) - && (simStackPtr >= methodOrBlockNumTemps)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - if (simSpillBase > simStackPtr) { - simSpillBase = simStackPtr + 1; - while (((simSpillBase - 1) > methodOrBlockNumTemps) - && (!(((simStackAt(simSpillBase - 1))->spilled)))) { - simSpillBase -= 1; - } - } - else { - while ((((simStackAt(simSpillBase))->spilled)) - && (simSpillBase <= simStackPtr)) { - simSpillBase += 1; - } - } - for (i = (methodOrBlockNumTemps + 1); i <= ((((simSpillBase - 1) < simStackPtr) ? (simSpillBase - 1) : simStackPtr)); i += 1) { - assert((((simStackAt(i))->spilled)) == 1); - } - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushConstant: */ -static sqInt NoDbgRegParms -ssPushConstant(sqInt literal) -{ - CogSimStackEntry * cascade0; - sqInt i; - - ssPush(1); - cascade0 = ssTop(); - (cascade0->type = SSConstant); - (cascade0->spilled = 0); - (cascade0->constant = literal); - (cascade0->bcptr = bytecodePC); - /* begin updateSimSpillBase */ - assert(((simSpillBase > methodOrBlockNumTemps) - && (simStackPtr >= methodOrBlockNumTemps)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - if (simSpillBase > simStackPtr) { - simSpillBase = simStackPtr + 1; - while (((simSpillBase - 1) > methodOrBlockNumTemps) - && (!(((simStackAt(simSpillBase - 1))->spilled)))) { - simSpillBase -= 1; - } - } - else { - while ((((simStackAt(simSpillBase))->spilled)) - && (simSpillBase <= simStackPtr)) { - simSpillBase += 1; - } - } - for (i = (methodOrBlockNumTemps + 1); i <= ((((simSpillBase - 1) < simStackPtr) ? (simSpillBase - 1) : simStackPtr)); i += 1) { - assert((((simStackAt(i))->spilled)) == 1); - } - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushDesc: */ -static sqInt NoDbgRegParms -ssPushDesc(SimStackEntry simStackEntry) -{ - sqInt i; - - if (((simStackEntry.type)) == SSSpill) { - (simStackEntry.type = SSBaseOffset); - } - (simStackEntry.spilled = 0); - (simStackEntry.bcptr = bytecodePC); - simStack[(simStackPtr += 1)] = simStackEntry; - /* begin updateSimSpillBase */ - assert(((simSpillBase > methodOrBlockNumTemps) - && (simStackPtr >= methodOrBlockNumTemps)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - if (simSpillBase > simStackPtr) { - simSpillBase = simStackPtr + 1; - while (((simSpillBase - 1) > methodOrBlockNumTemps) - && (!(((simStackAt(simSpillBase - 1))->spilled)))) { - simSpillBase -= 1; - } - } - else { - while ((((simStackAt(simSpillBase))->spilled)) - && (simSpillBase <= simStackPtr)) { - simSpillBase += 1; - } - } - for (i = (methodOrBlockNumTemps + 1); i <= ((((simSpillBase - 1) < simStackPtr) ? (simSpillBase - 1) : simStackPtr)); i += 1) { - assert((((simStackAt(i))->spilled)) == 1); - } - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushRegister: */ -static sqInt NoDbgRegParms -ssPushRegister(sqInt reg) -{ - CogSimStackEntry * cascade0; - sqInt i; - - ssPush(1); - cascade0 = ssTop(); - (cascade0->type = SSRegister); - (cascade0->spilled = 0); - (cascade0->registerr = reg); - (cascade0->bcptr = bytecodePC); - /* begin updateSimSpillBase */ - assert(((simSpillBase > methodOrBlockNumTemps) - && (simStackPtr >= methodOrBlockNumTemps)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - if (simSpillBase > simStackPtr) { - simSpillBase = simStackPtr + 1; - while (((simSpillBase - 1) > methodOrBlockNumTemps) - && (!(((simStackAt(simSpillBase - 1))->spilled)))) { - simSpillBase -= 1; - } - } - else { - while ((((simStackAt(simSpillBase))->spilled)) - && (simSpillBase <= simStackPtr)) { - simSpillBase += 1; - } - } - for (i = (methodOrBlockNumTemps + 1); i <= ((((simSpillBase - 1) < simStackPtr) ? (simSpillBase - 1) : simStackPtr)); i += 1) { - assert((((simStackAt(i))->spilled)) == 1); - } - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPush: */ -static void NoDbgRegParms -ssPush(sqInt n) -{ - simStackPtr += n; -} - - /* StackToRegisterMappingCogit>>#ssSelfDescriptor */ -static SimStackEntry -ssSelfDescriptor(void) -{ - return simStack[0]; -} - - -/* In addition to ssStorePop:toReg:, if this is a store and not - a popInto I change the simulated stack to use the register - for the top value */ - - /* StackToRegisterMappingCogit>>#ssStoreAndReplacePop:toReg: */ -static void NoDbgRegParms -ssStoreAndReplacePoptoReg(sqInt popBoolean, sqInt reg) -{ - char topSpilled; - - topSpilled = ((ssTop())->spilled); - ssStorePoptoReg(popBoolean - || (topSpilled), reg); - if (!popBoolean) { - if (!topSpilled) { - ssPop(1); - } - ssPushRegister(reg); - } -} - - -/* Store or pop the top simulated stack entry to a register. - Use preferredReg if the entry is not itself a register. - Answer the actual register the result ends up in. */ - - /* StackToRegisterMappingCogit>>#ssStorePop:toPreferredReg: */ -static sqInt NoDbgRegParms -ssStorePoptoPreferredReg(sqInt popBoolean, sqInt preferredReg) -{ - sqInt actualReg; - - actualReg = preferredReg; - if ((((ssTop())->type)) == SSRegister) { - assert(!(((ssTop())->spilled))); - actualReg = ((ssTop())->registerr); - } - ssStorePoptoReg(popBoolean, actualReg); - return actualReg; -} - - -/* Store or pop the top simulated stack entry to a register. - N.B.: popToReg: and storeToReg: does not generate anything if - it moves a register to the same register. */ - - /* StackToRegisterMappingCogit>>#ssStorePop:toReg: */ -static void NoDbgRegParms -ssStorePoptoReg(sqInt popBoolean, sqInt reg) -{ - if (popBoolean) { - popToReg(ssTop(), reg); - ssPop(1); - } - else { - storeToReg(ssTop(), reg); - } -} - - /* StackToRegisterMappingCogit>>#ssTop */ -static CogSimStackEntry * -ssTop(void) -{ - return simStackAt(simStackPtr); -} - - /* StackToRegisterMappingCogit>>#ssValue: */ -static CogSimStackEntry * NoDbgRegParms -ssValue(sqInt n) -{ - return simStackAt(simStackPtr - n); -} - - /* StackToRegisterMappingCogit>>#stackEntryIsBoolean: */ -static sqInt NoDbgRegParms -stackEntryIsBoolean(CogSimStackEntry *simStackEntry) -{ - return (((simStackEntry->type)) == SSConstant) - && ((((simStackEntry->constant)) == (trueObject())) - || (((simStackEntry->constant)) == (falseObject()))); -} - - -/* Answer if the stack is valid up to, but not including, simSpillBase. */ - - /* StackToRegisterMappingCogit>>#tempsValidAndVolatileEntriesSpilled */ -static sqInt -tempsValidAndVolatileEntriesSpilled(void) -{ - sqInt culprit; - sqInt i; - - culprit = 0; - for (i = 1; i <= methodOrBlockNumTemps; i += 1) { - if (!(((((simStackAt(i))->type)) == SSBaseOffset) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil()))) { - if (!culprit) { - culprit = i; - } - return 0; - } - } - for (i = (methodOrBlockNumTemps + 1); i < simSpillBase; i += 1) { - if (!(((simStackAt(i))->spilled))) { - if (!culprit) { - culprit = i; - } - return 0; - } - } - return 1; -} - - -/* If the sequence of bytecodes is - push: (Array new: 1) - popIntoTemp: tempIndex - pushConstant: const or pushTemp: n - popIntoTemp: 0 inVectorAt: tempIndex - collapse this into - tempAt: tempIndex put: {const or temp} - and answer true, otherwise answer false. - One might think that we should look for a sequence of more than - one pushes and pops but this is extremely rare. - Exclude pushRcvr: n to avoid potential complications with context inst - vars. */ - - /* StackToRegisterMappingCogit>>#tryCollapseTempVectorInitializationOfSize: */ -static sqInt NoDbgRegParms -tryCollapseTempVectorInitializationOfSize(sqInt slots) -{ - sqInt pc; - sqInt pc1; - sqInt pc2; - BytecodeDescriptor *pushArrayDesc; - BytecodeDescriptor *pushValueDesc; - sqInt reg; - sqInt remoteTempIndex; - BytecodeDescriptor *storeArrayDesc; - BytecodeDescriptor *storeValueDesc; - sqInt tempIndex; - - if (slots != 1) { - return 0; - } - /* begin generatorForPC: */ - pushArrayDesc = generatorAt(bytecodeSetOffset + (fetchByteofObject(bytecodePC, methodObj))); - assert(((pushArrayDesc->generator)) == genPushNewArrayBytecode); - /* begin generatorForPC: */ - pc = bytecodePC + ((pushArrayDesc->numBytes)); - storeArrayDesc = generatorAt(bytecodeSetOffset + (fetchByteofObject(pc, methodObj))); - if (((storeArrayDesc->generator)) == genStoreAndPopTemporaryVariableBytecode) { - tempIndex = (fetchByteofObject(bytecodePC + ((pushArrayDesc->numBytes)), methodObj)) & 7; - } - else { - if (!(((storeArrayDesc->generator)) == genLongStoreAndPopTemporaryVariableBytecode)) { - return 0; - } - tempIndex = fetchByteofObject((bytecodePC + ((pushArrayDesc->numBytes))) + 1, methodObj); - } - /* begin generatorForPC: */ - pc1 = (bytecodePC + ((pushArrayDesc->numBytes))) + ((storeArrayDesc->numBytes)); - pushValueDesc = generatorAt(bytecodeSetOffset + (fetchByteofObject(pc1, methodObj))); - if (!((((pushValueDesc->generator)) == genPushLiteralConstantBytecode) - || ((((pushValueDesc->generator)) == genPushQuickIntegerConstantBytecode) - || (((pushValueDesc->generator)) == genPushTemporaryVariableBytecode)))) { - return 0; - } - /* begin generatorForPC: */ - pc2 = ((bytecodePC + ((pushArrayDesc->numBytes))) + ((storeArrayDesc->numBytes))) + ((pushValueDesc->numBytes)); - storeValueDesc = generatorAt(bytecodeSetOffset + (fetchByteofObject(pc2, methodObj))); - remoteTempIndex = fetchByteofObject((((bytecodePC + ((pushArrayDesc->numBytes))) + ((storeArrayDesc->numBytes))) + ((pushValueDesc->numBytes))) + 2, methodObj); - if (!((((storeValueDesc->generator)) == genStoreAndPopRemoteTempLongBytecode) - && (tempIndex == remoteTempIndex))) { - return 0; - } - genNewArrayOfSizeinitialized(1, 0); - evaluateat(pushValueDesc, (bytecodePC + ((pushArrayDesc->numBytes))) + ((storeArrayDesc->numBytes))); - reg = ssStorePoptoPreferredReg(1, TempReg); - genStoreSourceRegslotIndexintoNewObjectInDestReg(reg, 0, ReceiverResultReg); - ssPushRegister(ReceiverResultReg); - evaluateat(storeArrayDesc, bytecodePC + ((pushArrayDesc->numBytes))); - - /* + pushArrayDesc numBytes this gets added by nextBytecodePCFor:at:exts:in: */ - bytecodePC = ((bytecodePC + ((storeArrayDesc->numBytes))) + ((pushValueDesc->numBytes))) + ((storeValueDesc->numBytes)); - return 1; -} - - /* StackToRegisterMappingCogit>>#v3or4PushNilSize:numInitialNils: */ -static sqInt NoDbgRegParms -v3or4PushNilSizenumInitialNils(sqInt aMethodObj, sqInt numInitialNils) -{ - return (methodUsesAlternateBytecodeSet(aMethodObj) - ? 3 * numInitialNils - : numInitialNils); -} - - /* StackToRegisterMappingCogit>>#v3or4:Num:Push:Nils: */ -static sqInt NoDbgRegParms -v3or4NumPushNils(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - return (bytecodeSetOffset == 0 - ? (((descriptor->generator)) == genPushConstantNilBytecode - ? 1 - : 0) - : ((((descriptor->generator)) == genExtPushPseudoVariableOrOuterBytecode) - && ((assert((fetchByteofObject(pc, aMethodObj)) == 77), - (nExts == 1) - && ((fetchByteofObject(pc - 1, aMethodObj)) == 2))) - ? 1 - : 0)); -} - - /* StackToRegisterMappingCogit>>#violatesEnsureSpilledSpillAssert */ -static sqInt -violatesEnsureSpilledSpillAssert(void) -{ - return 1; -} - - -/* Used when ReceiverResultReg is allocated for other than simSelf, and - there may be references to ReceiverResultReg which need to be spilled. */ - - /* StackToRegisterMappingCogit>>#voidReceiverResultRegContainsSelf */ -static void -voidReceiverResultRegContainsSelf(void) -{ - sqInt i; - sqInt i1; - sqInt spillIndex; - - /* begin voidReceiverOptStatus */ - ((simSelf())->liveRegister = NoReg); - spillIndex = 0; - for (i = ((((methodOrBlockNumTemps + 1) < simSpillBase) ? simSpillBase : (methodOrBlockNumTemps + 1))); i <= simStackPtr; i += 1) { - if ((registerOrNone(simStackAt(i))) == ReceiverResultReg) { - spillIndex = i; - } - } - if (spillIndex > 0) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= spillIndex) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < spillIndex) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : spillIndex)); i1 <= spillIndex; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = spillIndex + 1; - } - } -} diff --git a/platforms/iOS/vm/OSX/sqMacUnixExternalPrims.m b/platforms/iOS/vm/OSX/sqMacUnixExternalPrims.m index 56bae93ba4..a2eaf2450e 100644 --- a/platforms/iOS/vm/OSX/sqMacUnixExternalPrims.m +++ b/platforms/iOS/vm/OSX/sqMacUnixExternalPrims.m @@ -199,6 +199,9 @@ return NULL; #endif +#if 0 // This seems like the right thing to do but it breaks ioLoadModule + // ioLoadModule for system dylibs found along the system path(2). + // Instead, filter-out noise errors below if (stat(libName, &buf)) { dprintf((stderr, "tryLoadingLinked(%s) does not exist\n", libName)); return 0; @@ -207,6 +210,7 @@ dprintf((stderr, "tryLoadingLinked(%s) is a directory\n", libName)); return 0; } +#endif handle = dlopen(libName, RTLD_NOW | RTLD_GLOBAL); #if DEBUG @@ -215,6 +219,15 @@ #endif if (!handle) { const char *why = dlerror(); + // filter out failures due to non-existent libraries + if (stat(libName, &buf)) { + dprintf((stderr, "tryLoadingLinked(%s) does not exist\n", libName)); + return 0; + } + else if (S_ISDIR(buf.st_mode)) { + dprintf((stderr, "tryLoadingLinked(%s) is a directory\n", libName)); + return 0; + } #if PRINT_DL_ERRORS // In practice these reasons are too important to hide fprintf(stderr, "tryLoadingLinked(%s):\t%s\n", libName, why); #else diff --git a/spur64src/vm/cogit.h b/spur64src/vm/cogit.h index 2a623169bf..403f0da618 100644 --- a/spur64src/vm/cogit.h +++ b/spur64src/vm/cogit.h @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + CCodeGenerator VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ diff --git a/spur64src/vm/cogitARMv8.c b/spur64src/vm/cogitARMv8.c index 68e79e7619..4432b5433e 100644 --- a/spur64src/vm/cogitARMv8.c +++ b/spur64src/vm/cogitARMv8.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + CCodeGenerator VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + StackToRegisterMappingCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 " __DATE__ ; +static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__cogitBuildInfo = __buildInfo; @@ -69,18 +69,18 @@ char *__cogitBuildInfo = __buildInfo; #define CArg1Reg 1 #define CArg2Reg 2 #define CArg3Reg 3 -#define CASAL 174 +#define CASAL 176 #define Call 6 #define CallerSavedRegisterMask 0x1F0 #define CallFull 7 -#define CBNZ 175 -#define CBZ 176 +#define CBNZ 177 +#define CBZ 178 #define CC 3 -#define CCMPNE 177 +#define CCMPNE 179 #if !defined(CheckRememberedInTrampoline) /* Allow this to be overridden on the compiler command line */ # define CheckRememberedInTrampoline 0 #endif -#define CLREX 179 +#define CLREX 181 #define ClassArray 7 #define ClassArrayCompactIndex 51 #define ClassBlockClosureCompactIndex 37 @@ -113,8 +113,8 @@ char *__cogitBuildInfo = __buildInfo; #define ConvertRdR 146 #define ConvertRRd 145 #define CS 2 -#define CSET 178 -#define DC 167 +#define CSET 180 +#define DC 169 #define DC_CIVAC 14 #define DC_CVAC 16 #define DC_CVAU 19 @@ -122,7 +122,7 @@ char *__cogitBuildInfo = __buildInfo; #define DisplacementMask 0x1F #define DisplacementX2N 0 #define DivRdRd 135 -#define DivRRR 161 +#define DivRRR 163 #define DPFPReg0 0 #define DPFPReg1 1 #define DPFPReg2 2 @@ -131,7 +131,7 @@ char *__cogitBuildInfo = __buildInfo; #define DPFPReg5 5 #define DPFPReg6 6 #define DPFPReg7 7 -#define DSB 170 +#define DSB 172 #define DSB_ALL 3 #define DSB_ISH 2 #define EncounteredUnknownBytecode -6 @@ -166,7 +166,7 @@ char *__cogitBuildInfo = __buildInfo; #define HashMultiplyMask 0xFFFFFFF #define HeaderIndex 0 #define HI 8 -#define IC 168 +#define IC 170 #define IC_IALLU 0 #define IC_IALLUIS 1 #define IC_IVAU 2 @@ -178,7 +178,7 @@ char *__cogitBuildInfo = __buildInfo; #define InstructionPointerIndex 1 #define InsufficientCodeSpace -2 #define InVanillaBlock 1 -#define ISB 171 +#define ISB 173 #define IsAbsPCReference 3 #define IsAnnotationExtension 1 #define IsDirectedSuperBindingSend 10 @@ -226,7 +226,7 @@ char *__cogitBuildInfo = __buildInfo; #define Label 1 #define LargeContextSlots 62 #define LastJump 42 -#define LDAXR 180 +#define LDAXR 182 #define LE 13 #define LinkReg 30 #define Literal 2 @@ -264,7 +264,7 @@ char *__cogitBuildInfo = __buildInfo; #define MI 4 #define MoveAbR 48 #define MoveAwR 44 -#define MoveAwRR 163 +#define MoveAwRR 165 #define MoveC32R 71 #define MoveCqR 69 #define MoveCwR 70 @@ -273,6 +273,8 @@ char *__cogitBuildInfo = __buildInfo; #define MoveM64rRd 75 #define MoveMbrR 65 #define MoveMwrR 50 +#define MovePerfCnt64RL 159 +#define MovePerfCnt64RRL 158 #define MoveRAb 49 #define MoveRAw 46 #define MoveRdM64r 76 @@ -282,7 +284,7 @@ char *__cogitBuildInfo = __buildInfo; #define MoveRMbr 66 #define MoveRMwr 51 #define MoveRR 43 -#define MoveRRAw 164 +#define MoveRRAw 166 #define MoveRRd 72 #define MoveRX16rR 60 #define MoveRX32rR 64 @@ -292,17 +294,17 @@ char *__cogitBuildInfo = __buildInfo; #define MoveX32rRR 63 #define MoveXbrRR 67 #define MoveXwrRR 52 -#define MRS_CTR_EL0 172 -#define MRS_ID_AA64ISAR0_EL1 173 -#define MSubRRR 162 +#define MRS_CTR_EL0 174 +#define MRS_ID_AA64ISAR0_EL1 175 +#define MSubRRR 164 #define MULTIPLEBYTECODESETS 1 -#define MulOverflowRRR 159 +#define MulOverflowRRR 161 #define MulRdRd 134 -#define MulRRR 158 +#define MulRRR 160 #define NativePopR 84 -#define NativePopRR 166 +#define NativePopRR 168 #define NativePushR 85 -#define NativePushRR 165 +#define NativePushRR 167 #define NativeRetN 86 #define NativeSPReg 31 #define NE 1 @@ -370,10 +372,11 @@ char *__cogitBuildInfo = __buildInfo; #define SSConstant 2 #define SSRegister 3 #define SSSpill 4 -#define STLR 182 -#define STLXR 181 +#define STLR 184 +#define STLXR 183 #define StackPointerIndex 2 #define Stop 11 +#define SubbRR 121 #define SubCqR 107 #define SubCwR 115 #define SubRdRd 133 @@ -519,7 +522,7 @@ static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self static void NoDbgRegParms cloneLiteralFrom(AbstractInstruction * self_in_cloneLiteralFrom, AbstractInstruction *existingLiteral); static sqInt NoDbgRegParms concretizeAt(AbstractInstruction * self_in_concretizeAt, sqInt actualAddress); static sqInt NoDbgRegParms genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer); -static sqInt NoDbgRegParms genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg); +static sqInt NoDbgRegParms genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg); static AbstractInstruction * NoDbgRegParms genSwapRRScratch(AbstractInstruction * self_in_genSwapRRScratch, sqInt regA, sqInt regB, sqInt regTmp); static void NoDbgRegParms genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister); static void NoDbgRegParms initializeSharableLiteral(AbstractInstruction * self_in_initializeSharableLiteral, sqInt literal); @@ -550,6 +553,7 @@ static sqInt NoDbgRegParms concretizeLoadEffectiveAddressMwrR(AbstractInstructio static sqInt NoDbgRegParms concretizeLogicalOpCqRDest(AbstractInstruction * self_in_concretizeLogicalOpCqRDest, sqInt op, sqInt destReg); static sqInt NoDbgRegParms concretizeMoveCqR(AbstractInstruction * self_in_concretizeMoveCqR); static sqInt NoDbgRegParms concretizeMoveMSrR(AbstractInstruction * self_in_concretizeMoveMSrR, sqInt unitSizeLog2MinusOne); +static sqInt NoDbgRegParms concretizeMovePerfCnt64RL(AbstractInstruction * self_in_concretizeMovePerfCnt64RL); static sqInt NoDbgRegParms concretizeMoveRMSr(AbstractInstruction * self_in_concretizeMoveRMSr, sqInt unitSizeLog2MinusOne); static sqInt NoDbgRegParms concretizeMoveRXSrR(AbstractInstruction * self_in_concretizeMoveRXSrR, sqInt unitSizeLog2MinusOne); static sqInt NoDbgRegParms concretizeMoveXSrRR(AbstractInstruction * self_in_concretizeMoveXSrRR, sqInt unitSizeLog2MinusOne); @@ -814,6 +818,8 @@ static BytecodeDescriptor * loadBytesAndGetDescriptor(void); static void NoDbgRegParms loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc); static AbstractInstruction * NoDbgRegParms gMoveAwR(sqInt address, sqInt reg); static AbstractInstruction * NoDbgRegParms gMoveCwR(sqInt wordConstant, sqInt reg); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters); static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg); static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC); @@ -861,6 +867,7 @@ static void NoDbgRegParms recordGeneratedRunTimeaddress(char *aString, sqInt add extern sqInt recordPrimTraceFunc(void); static void recordRunTimeObjectReferences(void); static sqInt NoDbgRegParms registerMaskFor(sqInt reg); +static sqInt NoDbgRegParms registerMaskForand(sqInt reg1, sqInt reg2); static void NoDbgRegParms relocateCallsAndSelfReferencesInMethod(CogMethod *cogMethod); static void NoDbgRegParms relocateCallsInClosedPIC(CogMethod *cPIC); static sqInt NoDbgRegParms relocateIfCallOrMethodReferencemcpcdelta(sqInt annotation, char *mcpc, CogMethod *refDeltaArg); @@ -1208,6 +1215,7 @@ static sqInt genStoreAndPopReceiverVariableBytecode(void); static sqInt genStoreAndPopRemoteTempLongBytecode(void); static sqInt genStoreAndPopTemporaryVariableBytecode(void); static sqInt genStoreRemoteTempLongBytecode(void); +static void genTakeProfileSample(void); static sqInt genUnconditionalTrapBytecode(void); extern sqInt mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj); static sqInt numSpecialSelectors(void); @@ -2770,28 +2778,28 @@ addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *an static sqInt NoDbgRegParms availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << DPFPReg0)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg0))) != 0))) { return DPFPReg0; } - if (!(((liveRegsMask & (1U << DPFPReg1)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg1))) != 0))) { return DPFPReg1; } - if (!(((liveRegsMask & (1U << DPFPReg2)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg2))) != 0))) { return DPFPReg2; } - if (!(((liveRegsMask & (1U << DPFPReg3)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg3))) != 0))) { return DPFPReg3; } - if (!(((liveRegsMask & (1U << DPFPReg4)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg4))) != 0))) { return DPFPReg4; } - if (!(((liveRegsMask & (1U << DPFPReg5)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg5))) != 0))) { return DPFPReg5; } - if (!(((liveRegsMask & (1U << DPFPReg6)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg6))) != 0))) { return DPFPReg6; } - if (!(((liveRegsMask & (1U << DPFPReg7)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg7))) != 0))) { return DPFPReg7; } return NoReg; @@ -2806,19 +2814,19 @@ availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegi static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << Arg1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg1Reg))) != 0))) { return Arg1Reg; } - if (!(((liveRegsMask & (1U << Arg0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg0Reg))) != 0))) { return Arg0Reg; } - if (!(((liveRegsMask & (1U << SendNumArgsReg)) != 0))) { + if (!(((liveRegsMask & ((1U << SendNumArgsReg))) != 0))) { return SendNumArgsReg; } - if (!(((liveRegsMask & (1U << ClassReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ClassReg))) != 0))) { return ClassReg; } - if (!(((liveRegsMask & (1U << ReceiverResultReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ReceiverResultReg))) != 0))) { return ReceiverResultReg; } return NoReg; @@ -2880,11 +2888,11 @@ genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer) used immediately afterwards. */ - /* CogAbstractInstruction>>#genLoadStackPointersForFastPrimCall: */ + /* CogAbstractInstruction>>#genLoadStackPointersForPrimCall: */ static sqInt NoDbgRegParms -genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg) +genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg) { - genLoadStackPointers(self_in_genLoadStackPointersForFastPrimCall); + genLoadStackPointers(self_in_genLoadStackPointersForPrimCall); return 0; } @@ -3911,6 +3919,18 @@ concretizeMoveMSrR(AbstractInstruction * self_in_concretizeMoveMSrR, sqInt unitS } +/* D13.8.26 CNTVCT_EL0, Counter-timer Virtual Count register p D13-3774 */ +/* MRS , CNTVCT_EL0 op0:0b11 op1:0b011 CRn:0b1110 CRm:0b0000 op2:0b010 */ + + /* CogARMv8Compiler>>#concretizeMovePerfCnt64RL */ +static sqInt NoDbgRegParms +concretizeMovePerfCnt64RL(AbstractInstruction * self_in_concretizeMovePerfCnt64RL) +{ + ((self_in_concretizeMovePerfCnt64RL->machineCode))[0] = ((3577471040U) + (((self_in_concretizeMovePerfCnt64RL->operands))[0])); + return 4; +} + + /* Mwr/M32r/M16r/Mbr - memory unit whose address is a constant M away from an address in a register */ @@ -5604,6 +5624,9 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) : 0))) + (((sqInt)((usqInt)((offset9 & (0x1FFFFF))) << 3)))) + reg9); return 4; + case MovePerfCnt64RL: + return concretizeMovePerfCnt64RL(self_in_dispatchConcretize); + default: error("Case not found and no otherwise clause"); } @@ -6446,7 +6469,7 @@ genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask) assert(!((registerisInMask(RISCTempReg, regMask)))); nRegs = 0; for (reg = R1; reg <= R17; reg += 1) { - if (((regMask & (1ULL << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0)) { nRegs += 1; } } @@ -6454,7 +6477,7 @@ genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask) ? NoReg : RISCTempReg); for (reg = R1; reg <= R17; reg += 1) { - if (((regMask & (1ULL << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0)) { if (pair == NoReg) { pair = reg; } @@ -6489,7 +6512,7 @@ genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask) assert(!((registerisInMask(RISCTempReg, regMask)))); pair = NoReg; for (reg = R17; reg >= R0; reg += -1) { - if (((regMask & (1ULL << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0)) { if (pair == NoReg) { pair = reg; } @@ -10265,7 +10288,7 @@ compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numAr regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1ULL << resultRegOrNone)) - (1ULL << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ } @@ -11916,7 +11939,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) startAddress = methodZoneBase; callerSavedReg = 0; pushedVarBaseReg = 0; - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { /* VarBaseReg is not caller-saved; must save and restore it, either by using an available caller-saved reg or push/pop. */ @@ -11966,7 +11989,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) operandTwo2 = cStackPointerAddress(); checkLiteralforInstruction(operandTwo2, genoperandoperand(MoveRAw, NativeSPReg, operandTwo2)); } - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { if (pushedVarBaseReg) { gNativePopR(VarBaseReg); } @@ -13567,6 +13590,22 @@ gMoveCwR(sqInt wordConstant, sqInt reg) return checkLiteralforInstruction(wordConstant, genoperandoperand(MoveCwR, wordConstant, reg)); } + /* Cogit>>#MovePerfCnt64R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters) +{ + assert(BytesPerWord == 8); + return genoperandoperand(MovePerfCnt64RL, destReg, liveRegisters); +} + + /* Cogit>>#MovePerfCnt64R:R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters) +{ + assert(BytesPerWord == 4); + return genoperandoperandoperand(MovePerfCnt64RRL, destRegLo, destRegHi, liveRegisters); +} + /* Answer the address of the null byte at the end of the method map. */ @@ -15235,11 +15274,21 @@ recordRunTimeObjectReferences(void) } } + +/* N.B. (self registerMaskFor: NoReg) = 0 */ + /* Cogit>>#registerMaskFor: */ static sqInt NoDbgRegParms registerMaskFor(sqInt reg) { - return 1ULL << reg; + return ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); +} + + /* Cogit>>#registerMaskFor:and: */ +static sqInt NoDbgRegParms +registerMaskForand(sqInt reg1, sqInt reg2) +{ + return (1ULL << reg1) | (1ULL << reg2); } /* Cogit>>#relocateCallsAndSelfReferencesInMethod: */ @@ -23060,7 +23109,7 @@ generateObjectRepresentationTrampolines(void) genoperand(RetN, 0); jmpTarget(jumpSC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); } - ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))), 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), CheckRememberedInTrampoline); ceStoreCheckContextReceiverTrampoline = genStoreCheckContextReceiverTrampoline(); @@ -25303,7 +25352,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jumpRC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg)); jmpTarget(jumpImmutable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); @@ -25319,7 +25368,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* Store check */ jumpImmutable1 = genJumpImmutablescratchReg(ReceiverResultReg, SendNumArgsReg); - compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), 0 /* emptyRegisterMask */); genLoadStackPointers(backEnd()); @@ -25921,7 +25970,7 @@ registerMask(SimStackEntry * self_in_registerMask) || (((self_in_registerMask->type)) == SSRegister) ? (/* begin registerMaskFor: */ (reg = (self_in_registerMask->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : 0); } @@ -25934,7 +25983,7 @@ registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone) return (((self_in_registerMaskOrNone->type)) == SSRegister ? (/* begin registerMaskFor: */ (reg = (self_in_registerMaskOrNone->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : 0); } @@ -26365,42 +26414,32 @@ compileInterpreterPrimitive(void) static sqInt NoDbgRegParms compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) { + sqInt address; + sqInt address1; sqInt address10; - sqInt address11; - sqInt address12; - sqInt address13; sqInt address2; - sqInt address3; sqInt address4; + sqInt address6; sqInt address7; sqInt address8; sqInt address9; AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; AbstractInstruction *anInstruction4; AbstractInstruction *anInstruction5; AbstractInstruction *anInstruction6; AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction * continuePostSampleNonPrim; - AbstractInstruction * continuePostSamplePrim; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; - AbstractInstruction * jmpSampleNonPrim; - AbstractInstruction * jmpSamplePrim; + AbstractInstruction * jumpToTakeSample; + sqInt liveRegisters; sqInt offset; sqInt offset1; sqInt offset2; - sqInt operand1; - sqInt operand3; sqInt reg; sqInt retpc; - continuePostSampleNonPrim = ((AbstractInstruction *) 0); - continuePostSamplePrim = ((AbstractInstruction *) 0); - jmpSampleNonPrim = ((AbstractInstruction *) 0); - jmpSamplePrim = ((AbstractInstruction *) 0); + jumpToTakeSample = ((AbstractInstruction *) 0); assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); genExternalizePointersForPrimitiveCall(); /* begin genLoadCStackPointersForPrimCall */ @@ -26410,53 +26449,36 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) else { genLoadCStackPointer(backEnd); } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick if so */ - /* begin MoveAw:R: */ - address2 = nextProfileTickAddress(); - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address2, genoperandoperand(MoveAwR, address2, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction)) { - (anInstruction->dependent = locateLiteralsize(0, BytesPerOop)); - } - /* begin JumpNonZero: */ - jmpSampleNonPrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSampleNonPrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } if (recordPrimTraceForMethod(methodObj)) { genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(MoveCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction8)) { - (anInstruction8->dependent = locateLiteralsize(0, BytesPerOop)); + anInstruction4 = genoperandoperand(MoveCqR, 0, TempReg); + if (usesOutOfLineLiteral(anInstruction4)) { + (anInstruction4->dependent = locateLiteralsize(0, BytesPerOop)); } /* begin MoveR:Aw: */ - address11 = primFailCodeAddress(); + address6 = primFailCodeAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address11, genoperandoperand(MoveRAw, TempReg, address11)); + checkLiteralforInstruction(address6, genoperandoperand(MoveRAw, TempReg, address6)); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); - if (usesOutOfLineLiteral(anInstruction1)) { - (anInstruction1->dependent = locateLiteralsize(methodOrBlockNumArgs, BytesPerOop)); + anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); + if (usesOutOfLineLiteral(anInstruction)) { + (anInstruction->dependent = locateLiteralsize(methodOrBlockNumArgs, BytesPerOop)); } } /* begin MoveR:Aw: */ - address12 = argumentCountAddress(); + address7 = argumentCountAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address12, genoperandoperand(MoveRAw, TempReg, address12)); + checkLiteralforInstruction(address7, genoperandoperand(MoveRAw, TempReg, address7)); if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { /* begin MoveCw:R: */ checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg)); /* begin MoveR:Aw: */ - address3 = primitiveFunctionPointerAddress(); + address = primitiveFunctionPointerAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address3, genoperandoperand(MoveRAw, TempReg, address3)); + checkLiteralforInstruction(address, genoperandoperand(MoveRAw, TempReg, address)); } if (((flags & (PrimCallNeedsNewMethod + PrimCallMayEndureCodeCompaction)) != 0)) { @@ -26468,22 +26490,21 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) /* begin MoveMw:r:R: */ offset = offsetof(CogMethod, methodObject); /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - if (usesOutOfLineLiteral(anInstruction2)) { - (anInstruction2->dependent = locateLiteralsize(offset, BytesPerOop)); + anInstruction1 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); + if (usesOutOfLineLiteral(anInstruction1)) { + (anInstruction1->dependent = locateLiteralsize(offset, BytesPerOop)); } /* begin MoveR:Aw: */ - address4 = newMethodAddress(); + address1 = newMethodAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address4, genoperandoperand(MoveRAw, TempReg, address4)); + checkLiteralforInstruction(address1, genoperandoperand(MoveRAw, TempReg, address1)); } /* begin PrefetchAw: */ - address13 = primFailCodeAddress(); + address8 = primFailCodeAddress(); /* begin gen:literal: */ - checkLiteralforInstruction(address13, genoperand(PrefetchAw, address13)); + checkLiteralforInstruction(address8, genoperand(PrefetchAw, address8)); if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - /* Sideways call the C primitive routine so that we return through cePrimReturnEnterCogCode. */ /* On Spur ceActivateFailingPrimitiveMethod: would like to retry if forwarders are found. So insist on PrimCallNeedsPrimitiveFunction being set too. */ assert(((flags & PrimCallNeedsPrimitiveFunction) != 0)); @@ -26496,102 +26517,75 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) checkLiteralforInstruction(retpc, genoperandoperand(MoveCwR, retpc, LR)); /* begin gen:literal: */ checkLiteralforInstruction(((sqInt)(((sqInt)primitiveRoutine))), genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine))))); - jmp = (jmpSamplePrim = (continuePostSamplePrim = null)); + return 0; } - else { - - /* Call the C primitive routine. */ - genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); - /* begin gen:literal: */ - checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperand(CallFull, ((sqInt)primitiveRoutine))); - /* begin genRemoveNArgsFromStack: */ - assert(0 <= 6); - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin MoveAw:R: */ - address7 = nextProfileTickAddress(); - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address7, genoperandoperand(MoveAwR, address7, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(CmpCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction3)) { - (anInstruction3->dependent = locateLiteralsize(0, BytesPerOop)); - } - /* begin JumpNonZero: */ - jmpSamplePrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSamplePrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - maybeCompileRetryOnPrimitiveFail(primitiveIndex); - /* begin MoveAw:R: */ - address8 = instructionPointerAddress(); - reg = LinkReg; - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address8, genoperandoperand(MoveAwR, address8, reg)); - genLoadStackPointers(backEnd); + genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); + /* begin gen:literal: */ + checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperand(CallFull, ((sqInt)primitiveRoutine))); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 6); + maybeCompileRetryOnPrimitiveFail(primitiveIndex); + genLoadStackPointersForPrimCall(backEnd, ClassReg); + /* begin MoveAw:R: */ + address2 = instructionPointerAddress(); + /* begin gen:literal:operand: */ + checkLiteralforInstruction(address2, genoperandoperand(MoveAwR, address2, LinkReg)); + /* begin MoveAw:R: */ + address9 = primFailCodeAddress(); + /* begin gen:literal:operand: */ + checkLiteralforInstruction(address9, genoperandoperand(MoveAwR, address9, TempReg)); + flag("ask concrete code gen if move sets condition codes?"); + /* begin checkQuickConstant:forInstruction: */ + anInstruction5 = genoperandoperand(CmpCqR, 0, TempReg); + if (usesOutOfLineLiteral(anInstruction5)) { + (anInstruction5->dependent = locateLiteralsize(0, BytesPerOop)); + } + /* begin JumpNonZero: */ + jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + reg = Arg0Reg; + gMovePerfCnt64RL(reg, liveRegisters); /* begin MoveAw:R: */ - address9 = primFailCodeAddress(); + address10 = nextProfileTickAddress(); /* begin gen:literal:operand: */ - checkLiteralforInstruction(address9, genoperandoperand(MoveAwR, address9, TempReg)); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction4)) { - (anInstruction4->dependent = locateLiteralsize(0, BytesPerOop)); - } - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset1 = 0; - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); - if (usesOutOfLineLiteral(anInstruction5)) { - (anInstruction5->dependent = locateLiteralsize(offset1, BytesPerOop)); - } - /* begin RetN: */ - genoperand(RetN, BytesPerWord); + checkLiteralforInstruction(address10, genoperandoperand(MoveAwR, address10, Arg1Reg)); + /* begin CmpR:R: */ + assert(!((reg == SPReg))); + genoperandoperand(CmpRR, reg, Arg1Reg); + /* begin JumpGreaterOrEqual: */ + jumpToTakeSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l31; + l31: /* end genCheckForProfileTimerTick: */; } + /* begin MoveMw:r:R: */ + offset1 = 0; + /* begin checkQuickConstant:forInstruction: */ + anInstruction6 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); + if (usesOutOfLineLiteral(anInstruction6)) { + (anInstruction6->dependent = locateLiteralsize(offset1, BytesPerOop)); + } + continueAfterProfileSample = anInstruction6; + /* begin RetN: */ + genoperand(RetN, BytesPerWord); if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* The sample is collected by cePrimReturnEnterCogCode for external calls */ - if (!(jmpSamplePrim == null)) { - - /* Call ceCheckProfileTick: to record sample and then continue. */ - jmpTarget(jmpSamplePrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin gen:literal: */ - operand1 = ((usqIntptr_t)ceCheckProfileTick); - checkLiteralforInstruction(operand1, genoperand(CallFull, operand1)); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSamplePrim)); - } - jmpTarget(jmpSampleNonPrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(MoveCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction6)) { - (anInstruction6->dependent = locateLiteralsize(0, BytesPerOop)); - } - /* begin MoveR:Aw: */ - address10 = newMethodAddress(); - /* begin gen:operand:literal: */ - checkLiteralforInstruction(address10, genoperandoperand(MoveRAw, TempReg, address10)); - /* begin gen:literal: */ - operand3 = ((usqIntptr_t)ceCheckProfileTick); - checkLiteralforInstruction(operand3, genoperand(CallFull, operand3)); + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); + /* begin MoveAw:R: */ + address4 = instructionPointerAddress(); + /* begin gen:literal:operand: */ + checkLiteralforInstruction(address4, genoperandoperand(MoveAwR, address4, LinkReg)); /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSampleNonPrim)); + genoperand(Jump, ((sqInt)continueAfterProfileSample)); } - if (!(jmp == null)) { - - /* Jump to restore of receiver reg and proceed to frame build for failure. */ - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin MoveMw:r:R: */ - offset2 = BytesPerWord * (methodOrBlockNumArgs + (0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); - if (usesOutOfLineLiteral(anInstruction7)) { - (anInstruction7->dependent = locateLiteralsize(offset2, BytesPerOop)); - } + jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + /* begin MoveMw:r:R: */ + offset2 = BytesPerWord * (methodOrBlockNumArgs + (0)); + /* begin checkQuickConstant:forInstruction: */ + anInstruction7 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); + if (usesOutOfLineLiteral(anInstruction7)) { + (anInstruction7->dependent = locateLiteralsize(offset2, BytesPerOop)); } return 0; } @@ -26621,7 +26615,7 @@ compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)) if ((methodOrBlockNumArgs > 2 /* numRegArgs */) || (methodOrBlockNumArgs == 0)) { /* begin registerMaskFor: */ - liveRegsMask = 1U << ReceiverResultReg; + liveRegsMask = (1U << ReceiverResultReg); } else { if (methodOrBlockNumArgs > 1) { @@ -26692,6 +26686,7 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags sqInt address5; sqInt address6; sqInt address7; + sqInt address8; AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; AbstractInstruction *anInstruction10; @@ -26701,15 +26696,20 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags AbstractInstruction *anInstruction8; AbstractInstruction *anInstruction9; sqInt calleeSavedRegisterMask; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; + AbstractInstruction * jumpToTakeSample; sqInt linkRegSaveRegister; + sqInt liveRegisters; sqInt offset; sqInt offset1; sqInt operand1; + sqInt reg; AbstractInstruction * retry; AbstractInstruction * skip; sqInt spRegSaveRegister; + jumpToTakeSample = ((AbstractInstruction *) 0); linkRegSaveRegister = 0; assert(((flags & PrimCallOnSmalltalkStack) != 0)); assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); @@ -26737,14 +26737,14 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags /* begin gen:operand:literal: */ checkLiteralforInstruction(address5, genoperandoperand(MoveRAw, TempReg, address5)); genExternalizeStackPointerForFastPrimitiveCall(); - calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | (1U << ClassReg)) - (1U << ClassReg)); + calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | ((1U << ClassReg))) - ((1U << ClassReg))); linkRegSaveRegister = availableRegisterOrNoneIn(calleeSavedRegisterMask); assert(!((linkRegSaveRegister == NoReg))); /* begin MoveR:R: */ genoperandoperand(MoveRR, LinkReg, linkRegSaveRegister); - calleeSavedRegisterMask = ((calleeSavedRegisterMask | (1ULL << linkRegSaveRegister)) - (1ULL << linkRegSaveRegister)); + calleeSavedRegisterMask = ((calleeSavedRegisterMask | (((linkRegSaveRegister < 0) ? (((usqInt)(1)) >> (-linkRegSaveRegister)) : (1ULL << linkRegSaveRegister)))) - (((linkRegSaveRegister < 0) ? (((usqInt)(1)) >> (-linkRegSaveRegister)) : (1ULL << linkRegSaveRegister)))); spRegSaveRegister = NoReg; - if (!(((ABICalleeSavedRegisterMask & (1U << SPReg)) != 0))) { + if (!(((ABICalleeSavedRegisterMask & ((1U << SPReg))) != 0))) { spRegSaveRegister = availableRegisterOrNoneIn(calleeSavedRegisterMask); assert(!((spRegSaveRegister == NoReg))); /* begin MoveR:R: */ @@ -26758,8 +26758,11 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags else { genLoadNativeSPRegWithAlignedSPReg(backEnd); } + genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); /* begin gen:literal: */ - checkLiteralforInstruction(primitiveRoutine, genoperand(CallFull, primitiveRoutine)); + checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperand(CallFull, ((sqInt)primitiveRoutine))); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 6); /* begin MoveAw:R: */ address6 = primFailCodeAddress(); /* begin gen:literal:operand: */ @@ -26776,10 +26779,27 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags /* begin JumpNonZero: */ jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); genLoadCStackPointer(backEnd); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + reg = Arg0Reg; + gMovePerfCnt64RL(reg, liveRegisters); + /* begin MoveAw:R: */ + address8 = nextProfileTickAddress(); + /* begin gen:literal:operand: */ + checkLiteralforInstruction(address8, genoperandoperand(MoveAwR, address8, Arg1Reg)); + /* begin CmpR:R: */ + assert(!((reg == SPReg))); + genoperandoperand(CmpRR, reg, Arg1Reg); + /* begin JumpGreaterOrEqual: */ + jumpToTakeSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l33; + l33: /* end genCheckForProfileTimerTick: */; + } /* begin MoveAw:R: */ address7 = stackPointerAddress(); /* begin gen:literal:operand: */ - checkLiteralforInstruction(address7, genoperandoperand(MoveAwR, address7, TempReg)); + continueAfterProfileSample = checkLiteralforInstruction(address7, genoperandoperand(MoveAwR, address7, TempReg)); /* begin checkQuickConstant:forInstruction: */ anInstruction1 = genoperandoperandoperand(MoveMwrR, 0, TempReg, ReceiverResultReg); if (usesOutOfLineLiteral(anInstruction1)) { @@ -26790,6 +26810,12 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags genoperandoperand(MoveRR, linkRegSaveRegister, LinkReg); /* begin RetN: */ genoperand(RetN, 0); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); + /* begin Jump: */ + genoperand(Jump, ((sqInt)continueAfterProfileSample)); + } jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); if ((accessorDepthForExternalPrimitiveMethod(methodObj)) >= 0) { @@ -26825,10 +26851,11 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags else { genLoadCStackPointer(backEnd); } + genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); /* begin gen:literal: */ operand1 = ((usqIntptr_t)checkForAndFollowForwardedPrimitiveState); checkLiteralforInstruction(operand1, genoperand(CallFull, operand1)); - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); /* begin checkQuickConstant:forInstruction: */ anInstruction6 = genoperandoperand(CmpCqR, 0, ABIResultReg); if (usesOutOfLineLiteral(anInstruction6)) { @@ -26853,13 +26880,13 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags /* must reload SPReg to undo any alignment change, */ if (((flags & PrimCallOnSmalltalkStackAlign2x) != 0)) { - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); } } genLoadCStackPointer(backEnd); /* begin MoveR:R: */ genoperandoperand(MoveRR, linkRegSaveRegister, LinkReg); - if (((ABICallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((ABICallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* begin MoveMw:r:R: */ offset1 = (methodOrBlockNumArgs + (0)) * BytesPerWord; /* begin checkQuickConstant:forInstruction: */ @@ -27907,23 +27934,24 @@ genPrimitiveHashMultiply(void) static void NoDbgRegParms genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) { - sqInt address2; + sqInt address; sqInt address4; sqInt address6; sqInt address7; sqInt address8; AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction7; + AbstractInstruction *anInstruction4; + AbstractInstruction *anInstruction6; sqInt callTarget; AbstractInstruction *continuePostSample; AbstractInstruction * inst; AbstractInstruction *jmpFail; AbstractInstruction *jmpSample; + sqInt liveRegisters; sqInt quickConstant; sqInt reg; + sqInt reg1; continuePostSample = ((AbstractInstruction *) 0); jmpSample = ((AbstractInstruction *) 0); @@ -27935,41 +27963,43 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) if (usesOutOfLineLiteral(anInstruction)) { (anInstruction->dependent = locateLiteralsize(quickConstant, BytesPerOop)); } - if (profiling) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick: if so. - N.B. nextProfileTick is 64-bits so 32-bit systems need to test both halves. */ - /* begin MoveAw:R: */ - address2 = nextProfileTickAddress(); - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address2, genoperandoperand(MoveAwR, address2, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction1)) { - (anInstruction1->dependent = locateLiteralsize(0, BytesPerOop)); - } - /* begin JumpNonZero: */ - jmpSample = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } /* begin MoveAw:R: */ address6 = primFailCodeAddress(); /* begin gen:literal:operand: */ checkLiteralforInstruction(address6, genoperandoperand(MoveAwR, address6, TempReg)); flag("ask concrete code gen if move sets condition codes?"); /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(CmpCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction7)) { - (anInstruction7->dependent = locateLiteralsize(0, BytesPerOop)); + anInstruction6 = genoperandoperand(CmpCqR, 0, TempReg); + if (usesOutOfLineLiteral(anInstruction6)) { + (anInstruction6->dependent = locateLiteralsize(0, BytesPerOop)); } /* begin JumpNonZero: */ jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (profiling + && (1)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + reg = Arg0Reg; + gMovePerfCnt64RL(reg, liveRegisters); + /* begin MoveAw:R: */ + address = nextProfileTickAddress(); + /* begin gen:literal:operand: */ + checkLiteralforInstruction(address, genoperandoperand(MoveAwR, address, Arg1Reg)); + /* begin CmpR:R: */ + assert(!((reg == SPReg))); + genoperandoperand(CmpRR, reg, Arg1Reg); + /* begin JumpGreaterOrEqual: */ + jmpSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l8; + l8: /* end genCheckForProfileTimerTick: */; + /* begin Label */ + continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); + } genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); - if (usesOutOfLineLiteral(anInstruction2)) { - (anInstruction2->dependent = locateLiteralsize(0, BytesPerOop)); + anInstruction1 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); + if (usesOutOfLineLiteral(anInstruction1)) { + (anInstruction1->dependent = locateLiteralsize(0, BytesPerOop)); } /* begin MoveAw:R: */ address4 = instructionPointerAddress(); @@ -27985,18 +28015,19 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) compileCallFornumArgsargargargargresultRegregsToSave(ceActivateFailingPrimitiveMethod, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); /* begin MoveAw:R: */ address8 = instructionPointerAddress(); - reg = LinkReg; + reg1 = LinkReg; /* begin gen:literal:operand: */ - checkLiteralforInstruction(address8, genoperandoperand(MoveAwR, address8, reg)); + checkLiteralforInstruction(address8, genoperandoperand(MoveAwR, address8, reg1)); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); - if (usesOutOfLineLiteral(anInstruction5)) { - (anInstruction5->dependent = locateLiteralsize(0, BytesPerOop)); + anInstruction4 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); + if (usesOutOfLineLiteral(anInstruction4)) { + (anInstruction4->dependent = locateLiteralsize(0, BytesPerOop)); } /* begin RetN: */ genoperand(RetN, BytesPerWord); - if (profiling) { + if (profiling + && (1)) { /* Call ceCheckProfileTick: to record sample and then continue. newMethod should be up-to-date. Need to save and restore the link reg around this call. */ @@ -28377,6 +28408,23 @@ genStoreRemoteTempLongBytecode(void) && (shouldAnnotateObjectReference(((ssTop())->constant))))); } + /* SimpleStackBasedCogit>>#genTakeProfileSample */ +static void +genTakeProfileSample(void) +{ + sqInt operand1; + + addDependent(methodLabel, annotateAbsolutePCRef(gMoveCwR(((sqInt)methodLabel), ClassReg))); + genMarshallNArgsargargargarg(backEnd, 1, ClassReg, null, null, null); + genLoadNativeSPRegWithAlignedSPReg(backEnd); + /* begin gen:literal: */ + operand1 = ((usqIntptr_t)ceTakeProfileSample); + checkLiteralforInstruction(operand1, genoperand(CallFull, operand1)); + /* begin genRemoveNArgsFromStack: */ + assert(1 <= 6); + genLoadCStackPointer(backEnd); +} + /* SistaV1: * 217 Trap */ @@ -28720,7 +28768,7 @@ primitiveGeneratorOrNil(void) static sqInt NoDbgRegParms registerisInMask(sqInt reg, sqInt mask) { - return ((mask & (1ULL << reg)) != 0); + return ((mask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0); } /* SimpleStackBasedCogit>>#v3:Block:Code:Size: */ @@ -29071,7 +29119,7 @@ anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n) sqInt regMask; /* begin registerMaskFor: */ - regMask = 1ULL << reg; + regMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { if ((((registerMask(simStackAt(i))) & regMask) != 0)) { return 1; @@ -30117,7 +30165,7 @@ ensureReceiverResultRegContainsSelf(void) if (needsFrame) { if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin putSelfInReceiverResultReg */ storeToReg(simSelf(), ReceiverResultReg); ((simSelf())->liveRegister = ReceiverResultReg); @@ -30249,7 +30297,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) && (index < simStackPtr)) { desc = simStackAt(index); if (((desc->type)) == SSRegister) { - if (!(((regMask & (1ULL << ((desc->registerr)))) != 0))) { + if (!(((regMask & (((((desc->registerr)) < 0) ? (((usqInt)(1)) >> (-((desc->registerr)))) : (1ULL << ((desc->registerr)))))) != 0))) { reg = (desc->registerr); } } @@ -30257,7 +30305,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) } assert(!((reg == NoReg))); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1ULL << reg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)), simStackPtr, simNativeStackPtr); return reg; } @@ -30802,13 +30850,13 @@ genForwardersInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -31789,11 +31837,11 @@ genPushMaybeContextReceiverVariable(sqInt slotIndex) AbstractInstruction *jmpSingle; /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ensureReceiverResultRegContainsSelf(); /* begin genPushMaybeContextSlotIndex: */ assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ voidReceiverResultRegContainsSelf(); @@ -31852,7 +31900,7 @@ genPushNewArrayBytecode(void) } else { /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << SendNumArgsReg)) | ((1U << ReceiverResultReg))), simStackPtr, simNativeStackPtr); } size = byte1 & 0x7F; if (!popValues) { @@ -31928,7 +31976,7 @@ genPushRemoteTempLongBytecode(void) (anInstruction->dependent = locateLiteralsize(offset, BytesPerOop)); } /* begin availableRegOrNoneNotConflictingWith: */ - regMask = 1ULL << tempVectReg; + regMask = ((tempVectReg < 0) ? (((usqInt)(1)) >> (-tempVectReg)) : (1ULL << tempVectReg)); remoteTempReg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); if (remoteTempReg == NoReg) { remoteTempReg = tempVectReg; @@ -32306,11 +32354,11 @@ genSpecialSelectorClass(void) || (topReg == ClassReg)) { /* begin ssAllocateRequiredReg:and: */ requiredReg1 = (topReg = SendNumArgsReg); - ssAllocateRequiredRegMaskupThroughupThroughNative((1ULL << requiredReg1) | (1U << ClassReg), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((((requiredReg1 < 0) ? (((usqInt)(1)) >> (-requiredReg1)) : (1ULL << requiredReg1))) | ((1U << ClassReg)), simStackPtr, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr, simNativeStackPtr); } ssPush(1); popToReg(ssTop(), topReg); @@ -32549,7 +32597,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean association = getLiteral(litVarIndex); voidReceiverResultRegContainsSelf(); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin genMoveConstant:R: */ if (shouldAnnotateObjectReference(association)) { annotateobjRef(gMoveCwR(association, ReceiverResultReg), association); @@ -32565,7 +32613,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean # if IMMUTABILITY if (needsImmCheck) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -32579,7 +32627,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -32643,7 +32691,7 @@ genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqI # endif // IMMUTABILITY ssPop(1); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ClassReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ssPush(1); genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); @@ -32691,7 +32739,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea # if IMMUTABILITY if (needsImmCheck1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -32705,7 +32753,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck1, 1); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck1); } @@ -32729,7 +32777,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt assert(needsFrame); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); /* begin MoveMw:r:R: */ offset = frameOffsetOfTemporary(remoteTempIndex); @@ -32742,7 +32790,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt # if IMMUTABILITY # endif - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -32933,13 +32981,13 @@ genVanillaInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -33202,12 +33250,12 @@ liveRegisters(void) } else { /* begin registerMaskFor: */ - regsSet = 1U << ReceiverResultReg; + regsSet = (1U << ReceiverResultReg); if ((methodOrBlockNumArgs <= 2 /* numRegArgs */) && (methodOrBlockNumArgs > 0)) { - regsSet = regsSet | (1U << Arg0Reg); + regsSet = regsSet | ((1U << Arg0Reg)); if (methodOrBlockNumArgs > 1) { - regsSet = regsSet | (1U << Arg1Reg); + regsSet = regsSet | ((1U << Arg1Reg)); } } } @@ -33310,13 +33358,13 @@ marshallSendArguments(sqInt numArgs) if (numArgs > 0) { if (numArgs > 1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 2, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 2, simNativeStackPtr); /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg1Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg1Reg), simStackPtr - 1, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 1, simNativeStackPtr); } } if (numArgs > 1) { diff --git a/spur64src/vm/cogitX64SysV.c b/spur64src/vm/cogitX64SysV.c index d815ca31c0..3284c1c1bc 100644 --- a/spur64src/vm/cogitX64SysV.c +++ b/spur64src/vm/cogitX64SysV.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + CCodeGenerator VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + StackToRegisterMappingCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 " __DATE__ ; +static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__cogitBuildInfo = __buildInfo; @@ -54,7 +54,7 @@ char *__cogitBuildInfo = __buildInfo; #define ArithmeticShiftRightRR 92 #define BadRegisterSet 1 #define BlockCreationBytecodeSize 4 -#define BSR 167 +#define BSR 169 #define BytecodeSetHasDirectedSuperSend 1 #define CArg0Reg 7 #define CArg1Reg 6 @@ -64,11 +64,11 @@ char *__cogitBuildInfo = __buildInfo; #define CallerSavedRegisterMask 0x2C6 #define CallFull 7 #define CallR 8 -#define CDQ 159 +#define CDQ 161 #if !defined(CheckRememberedInTrampoline) /* Allow this to be overridden on the compiler command line */ # define CheckRememberedInTrampoline 0 #endif -#define CLD 163 +#define CLD 165 #define ClassArray 7 #define ClassArrayCompactIndex 51 #define ClassBlockClosureCompactIndex 37 @@ -91,7 +91,7 @@ char *__cogitBuildInfo = __buildInfo; #define CMMaxUsageCount 7 #define CMMethod 2 #define CMOpenPIC 5 -#define CMPXCHGRMr 172 +#define CMPXCHGRMr 174 #define CmpC32R 113 #define CmpCqR 105 #define CmpCwR 112 @@ -106,7 +106,7 @@ char *__cogitBuildInfo = __buildInfo; #define ConvertRRs 150 #define ConvertRsR 149 #define ConvertRsRd 147 -#define CPUID 158 +#define CPUID 160 #define Debug DEBUGVM #define DisplacementMask 0x1F #define DisplacementX2N 0 @@ -150,11 +150,11 @@ char *__cogitBuildInfo = __buildInfo; #define HashMultiplyConstant 1664525 #define HashMultiplyMask 0xFFFFFFF #define HeaderIndex 0 -#define IDIVR 160 +#define IDIVR 162 #if !defined(IMMUTABILITY) /* Allow this to be overridden on the compiler command line */ # define IMMUTABILITY 1 #endif -#define IMULRR 161 +#define IMULRR 163 #define InFullBlock 2 #define InstanceSpecificationIndex 2 #define InstructionPointerIndex 1 @@ -205,11 +205,11 @@ char *__cogitBuildInfo = __buildInfo; #define Label 1 #define LargeContextSlots 62 #define LastJump 42 -#define LFENCE 168 +#define LFENCE 170 #undef LinkReg #define Literal 2 #define LiteralStart 1 -#define LOCK 171 +#define LOCK 173 #define LoadEffectiveAddressMwrR 88 #define LogicalShiftLeftCqR 95 #define LogicalShiftLeftCqRR 129 @@ -232,11 +232,11 @@ char *__cogitBuildInfo = __buildInfo; #define MethodCacheSelector 1 #define MethodIndex 3 #define MethodTooBig -4 -#define MFENCE 169 +#define MFENCE 171 #define MFMethodFlagHasContextFlag 1 #define MFMethodFlagIsBlockFlag 2 -#define MOVSB 165 -#define MOVSQ 166 +#define MOVSB 167 +#define MOVSQ 168 #define ModReg 3 #define ModRegInd 0 #define ModRegRegDisp32 2 @@ -255,10 +255,12 @@ char *__cogitBuildInfo = __buildInfo; #define MoveMbrR 65 #define MoveMs8rR 55 #define MoveMwrR 50 +#define MovePerfCnt64RL 159 +#define MovePerfCnt64RRL 158 #define MoveRA32 47 #define MoveRAb 49 #define MoveRAw 46 -#define MoveRAwNoVBR 174 +#define MoveRAwNoVBR 176 #define MoveRdM64r 76 #define MoveRdR 73 #define MoveRdRd 74 @@ -327,7 +329,7 @@ char *__cogitBuildInfo = __buildInfo; #define RCX 1 #define RDI 7 #define RDX 2 -#define REP 164 +#define REP 166 #define ReceiverIndex 5 #define ReceiverResultReg 2 #define RetN 9 @@ -336,12 +338,12 @@ char *__cogitBuildInfo = __buildInfo; #define RotateRightCqR 98 #define RSI 6 #define RSP 4 -#define SETE 173 +#define SETE 175 #define SelectorCannotInterpret 34 #define SelectorDoesNotUnderstand 20 #define SenderIndex 0 #define SendNumArgsReg 9 -#define SFENCE 170 +#define SFENCE 172 #define ShouldNotJIT -8 #define SIB1 0 #define SIB4 2 @@ -379,7 +381,7 @@ char *__cogitBuildInfo = __buildInfo; #define UnimplementedPrimitive -7 #define ValueIndex 1 #define VarBaseReg 3 -#define XCHGRR 162 +#define XCHGRR 164 #define XMM0L 0 #define XorCwR 118 #define XorRdRd 137 @@ -511,7 +513,7 @@ static sqInt NoDbgRegParms concretizeAt(AbstractInstruction * self_in_concretize static sqInt NoDbgRegParms genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer); static sqInt NoDbgRegParms genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers); static sqInt NoDbgRegParms genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers); -static sqInt NoDbgRegParms genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg); +static sqInt NoDbgRegParms genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg); static sqInt NoDbgRegParms genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers); static void NoDbgRegParms genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister); static void NoDbgRegParms initializeSharableLiteral(AbstractInstruction * self_in_initializeSharableLiteral, sqInt literal); @@ -690,6 +692,8 @@ extern void linkSendAtintooffsetreceiver(sqInt callSiteReturnAddress, CogMethod static BytecodeDescriptor * loadBytesAndGetDescriptor(void); static void NoDbgRegParms loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc); static AbstractInstruction * NoDbgRegParms gMoveCwR(sqInt wordConstant, sqInt reg); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters); static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg); static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC); @@ -1006,6 +1010,7 @@ static sqInt NoDbgRegParms computeShiftRRSize(AbstractInstruction * self_in_comp static sqInt NoDbgRegParms computeSizeOfPushCw(AbstractInstruction * self_in_computeSizeOfPushCw); static sqInt NoDbgRegParms concretizeArithCqRWithROraxOpcode(AbstractInstruction * self_in_concretizeArithCqRWithROraxOpcode, sqInt regOpcode, sqInt raxOpcode); static sqInt NoDbgRegParms concretizeFill32(AbstractInstruction * self_in_concretizeFill32); +static sqInt NoDbgRegParms concretizeMovePerfCnt64RL(AbstractInstruction * self_in_concretizeMovePerfCnt64RL); static sqInt NoDbgRegParms concretizeMoveRX32rR(AbstractInstruction * self_in_concretizeMoveRX32rR); static sqInt NoDbgRegParms concretizeMoveX32rRR(AbstractInstruction * self_in_concretizeMoveX32rRR); static sqInt NoDbgRegParms concretizeOpRR(AbstractInstruction * self_in_concretizeOpRR, sqInt x64opcode); @@ -1150,6 +1155,7 @@ static sqInt genStoreAndPopReceiverVariableBytecode(void); static sqInt genStoreAndPopRemoteTempLongBytecode(void); static sqInt genStoreAndPopTemporaryVariableBytecode(void); static sqInt genStoreRemoteTempLongBytecode(void); +static void genTakeProfileSample(void); static sqInt genUnconditionalTrapBytecode(void); extern sqInt mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj); static sqInt numSpecialSelectors(void); @@ -2701,28 +2707,28 @@ addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *an static sqInt NoDbgRegParms availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << DPFPReg0)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg0))) != 0))) { return DPFPReg0; } - if (!(((liveRegsMask & (1U << DPFPReg1)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg1))) != 0))) { return DPFPReg1; } - if (!(((liveRegsMask & (1U << DPFPReg2)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg2))) != 0))) { return DPFPReg2; } - if (!(((liveRegsMask & (1U << DPFPReg3)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg3))) != 0))) { return DPFPReg3; } - if (!(((liveRegsMask & (1U << DPFPReg4)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg4))) != 0))) { return DPFPReg4; } - if (!(((liveRegsMask & (1U << DPFPReg5)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg5))) != 0))) { return DPFPReg5; } - if (!(((liveRegsMask & (1U << DPFPReg6)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg6))) != 0))) { return DPFPReg6; } - if (!(((liveRegsMask & (1U << DPFPReg7)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg7))) != 0))) { return DPFPReg7; } return NoReg; @@ -2837,9 +2843,9 @@ genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers) used immediately afterwards. */ - /* CogAbstractInstruction>>#genLoadStackPointersForFastPrimCall: */ + /* CogAbstractInstruction>>#genLoadStackPointersForPrimCall: */ static sqInt NoDbgRegParms -genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg) +genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg) { AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; @@ -5628,7 +5634,7 @@ compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numAr regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1ULL << resultRegOrNone)) - (1ULL << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ regMaskCopy = ((usqInt)regsToSave); @@ -7272,7 +7278,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) startAddress = methodZoneBase; callerSavedReg = 0; pushedVarBaseReg = 0; - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { /* VarBaseReg is not caller-saved; must save and restore it, either by using an available caller-saved reg or push/pop. */ @@ -7305,7 +7311,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) /* begin checkLiteral:forInstruction: */ cStackPointerAddress(); anInstruction3 = genoperandoperand(MoveRAw, TempReg, cStackPointerAddress()); - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { if (pushedVarBaseReg) { gNativePopR(VarBaseReg); } @@ -8689,6 +8695,22 @@ gMoveCwR(sqInt wordConstant, sqInt reg) return anInstruction; } + /* Cogit>>#MovePerfCnt64R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters) +{ + assert(BytesPerWord == 8); + return genoperandoperand(MovePerfCnt64RL, destReg, liveRegisters); +} + + /* Cogit>>#MovePerfCnt64R:R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters) +{ + assert(BytesPerWord == 4); + return genoperandoperandoperand(MovePerfCnt64RRL, destRegLo, destRegHi, liveRegisters); +} + /* Answer the address of the null byte at the end of the method map. */ @@ -10212,11 +10234,14 @@ recordRunTimeObjectReferences(void) } } + +/* N.B. (self registerMaskFor: NoReg) = 0 */ + /* Cogit>>#registerMaskFor: */ static sqInt NoDbgRegParms registerMaskFor(sqInt reg) { - return 1ULL << reg; + return ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } /* Cogit>>#registerMaskFor:and: */ @@ -17025,7 +17050,7 @@ generateObjectRepresentationTrampolines(void) genoperand(RetN, 0); jmpTarget(jumpSC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); } - ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))), 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), CheckRememberedInTrampoline); ceStoreCheckContextReceiverTrampoline = genStoreCheckContextReceiverTrampoline(); @@ -18820,7 +18845,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jumpRC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg)); jmpTarget(jumpImmutable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); @@ -18836,7 +18861,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* Store check */ jumpImmutable1 = genJumpImmutablescratchReg(ReceiverResultReg, SendNumArgsReg); - compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), 0 /* emptyRegisterMask */); genLoadStackPointers(backEnd()); @@ -19394,7 +19419,7 @@ registerMask(SimStackEntry * self_in_registerMask) || (((self_in_registerMask->type)) == SSRegister) ? (/* begin registerMaskFor: */ (reg = (self_in_registerMask->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : 0); } @@ -19407,7 +19432,7 @@ registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone) return (((self_in_registerMaskOrNone->type)) == SSRegister ? (/* begin registerMaskFor: */ (reg = (self_in_registerMaskOrNone->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : 0); } @@ -19482,37 +19507,37 @@ isMergeFixup(BytecodeFixup * self_in_isMergeFixup) static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << Extra5Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra5Reg))) != 0))) { return Extra5Reg; } - if (!(((liveRegsMask & (1U << Extra4Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra4Reg))) != 0))) { return Extra4Reg; } - if (!(((liveRegsMask & (1U << Extra3Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra3Reg))) != 0))) { return Extra3Reg; } - if (!(((liveRegsMask & (1U << Extra2Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra2Reg))) != 0))) { return Extra2Reg; } - if (!(((liveRegsMask & (1U << Extra1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra1Reg))) != 0))) { return Extra1Reg; } - if (!(((liveRegsMask & (1U << Extra0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra0Reg))) != 0))) { return Extra0Reg; } - if (!(((liveRegsMask & (1U << Arg1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg1Reg))) != 0))) { return Arg1Reg; } - if (!(((liveRegsMask & (1U << Arg0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg0Reg))) != 0))) { return Arg0Reg; } - if (!(((liveRegsMask & (1U << SendNumArgsReg)) != 0))) { + if (!(((liveRegsMask & ((1U << SendNumArgsReg))) != 0))) { return SendNumArgsReg; } - if (!(((liveRegsMask & (1U << ClassReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ClassReg))) != 0))) { return ClassReg; } - if (!(((liveRegsMask & (1U << ReceiverResultReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ReceiverResultReg))) != 0))) { return ReceiverResultReg; } return NoReg; @@ -20091,6 +20116,11 @@ computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize) ? 1 : 0)); + case MovePerfCnt64RL: + + /* it is easier to calculate the right value by concretizing. We concretize twice, but so what? */ + return concretizeMovePerfCnt64RL(self_in_computeMaximumSize); + default: error("Case not found and no otherwise clause"); } @@ -20182,6 +20212,65 @@ concretizeFill32(AbstractInstruction * self_in_concretizeFill32) return 4; } + +/* Generate code for + 0x0: 50 pushq %rax + 0x1: 52 pushq %rdx + 0x2: 0f 31 rdtsc + 0x4: 48 c1 e2 20 shlq $0x20, %rdx + 0x8: 48 09 d0 orq %rdx, %rax + 0xb: 48 89 f8 movq %rdi, %rax + 0xe: 5a popq %rdx + 0xf: 58 popq %rax + et al */ + + /* CogX64Compiler>>#concretizeMovePerfCnt64RL */ +static sqInt NoDbgRegParms +concretizeMovePerfCnt64RL(AbstractInstruction * self_in_concretizeMovePerfCnt64RL) +{ + usqInt liveRegisters; + sqInt offset; + usqInt reg; + + reg = ((self_in_concretizeMovePerfCnt64RL->operands))[0]; + liveRegisters = ((self_in_concretizeMovePerfCnt64RL->operands))[1]; + offset = 0; + if (((liveRegisters & ((1U << RAX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[0] = 80; + offset += 1; + } + if (((liveRegisters & ((1U << RDX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 82; + offset += 1; + } + assert(!((reg == RDX))); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 15; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 1] = 49; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 2] = (rexRxb(self_in_concretizeMovePerfCnt64RL, 0, 0, RDX)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 3] = 193; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 4] = (modRMRO(self_in_concretizeMovePerfCnt64RL, ModReg, RDX, 4)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 5] = 32; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 6] = (rexRxb(self_in_concretizeMovePerfCnt64RL, RDX, 0, RAX)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 7] = 11; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 8] = (modRMRO(self_in_concretizeMovePerfCnt64RL, ModReg, RAX, RDX)); + offset += 9; + if (reg != RAX) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[11] = (rexRxb(self_in_concretizeMovePerfCnt64RL, reg, 0, RAX)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[12] = 137; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[13] = (modRMRO(self_in_concretizeMovePerfCnt64RL, ModReg, RAX, reg)); + offset += 3; + } + if (((liveRegisters & ((1U << RDX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 90; + offset += 1; + } + if (((liveRegisters & ((1U << RAX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 88; + offset += 1; + } + return offset; +} + /* CogX64Compiler>>#concretizeMoveRX32rR */ static sqInt NoDbgRegParms concretizeMoveRX32rR(AbstractInstruction * self_in_concretizeMoveRX32rR) @@ -23584,6 +23673,9 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) ((self_in_dispatchConcretize->machineCode))[skip28 + 1] = (modRMRO(self_in_dispatchConcretize, ModReg, srcReg28, destReg29)); return skip28 + 2; + case MovePerfCnt64RL: + return concretizeMovePerfCnt64RL(self_in_dispatchConcretize); + default: error("Case not found and no otherwise clause"); } @@ -24212,8 +24304,8 @@ genPushRegisterArgsForNumArgsscratchReg(AbstractInstruction * self_in_genPushReg /* This is a no-op on x64 SysV since the ABI passes up to 6 args in registers and trampolines currently observe a limit of 4. - But the WIN64 ABI allways reserve shadow space for saving up to 4 - parameter registers (even if less than 4 args). + But the WIN64 ABI always reserve shadow space for saving up to 4 parameter + registers (even if less than 4 args). */ /* CogX64Compiler>>#genRemoveNArgsFromStack: */ @@ -24235,7 +24327,7 @@ genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask) assert(!((((regMask & (registerMaskForand(RSP, RBP))) != 0)))); for (reg = RAX; reg <= R15; reg += 1) { - if (((regMask & (1ULL << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0)) { /* begin PopR: */ genoperand(PopR, reg); } @@ -24257,7 +24349,7 @@ genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask) assert(((R15 - RAX) + 1) == 16); assert(!((((regMask & (registerMaskForand(RSP, RBP))) != 0)))); for (reg = R15; reg >= RAX; reg += -1) { - if (((regMask & (1ULL << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0)) { /* begin PushR: */ genoperand(PushR, reg); } @@ -25078,53 +25170,42 @@ compileInterpreterPrimitive(void) static sqInt NoDbgRegParms compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) { - sqInt address2; + AbstractInstruction *anInstruction; + AbstractInstruction *anInstruction1; AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction12; + AbstractInstruction *anInstruction11; AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction15; + AbstractInstruction *anInstruction14; + AbstractInstruction *anInstruction16; + AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction18; AbstractInstruction *anInstruction19; AbstractInstruction *anInstruction2; + AbstractInstruction *anInstruction20; AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction24; - AbstractInstruction *anInstruction25; + AbstractInstruction *anInstruction22; AbstractInstruction *anInstruction26; AbstractInstruction *anInstruction27; + AbstractInstruction *anInstruction28; AbstractInstruction *anInstruction29; AbstractInstruction *anInstruction3; + AbstractInstruction *anInstruction30; AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction33; - AbstractInstruction *anInstruction34; - AbstractInstruction *anInstruction35; - AbstractInstruction *anInstruction36; - AbstractInstruction *anInstruction37; - AbstractInstruction *anInstruction38; - AbstractInstruction *anInstruction39; AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction40; AbstractInstruction *anInstruction41; - AbstractInstruction *anInstruction5; AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; AbstractInstruction *anInstruction8; - AbstractInstruction * continuePostSampleNonPrim; - AbstractInstruction * continuePostSamplePrim; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; - AbstractInstruction * jmpSampleNonPrim; - AbstractInstruction * jmpSamplePrim; + AbstractInstruction * jumpToTakeSample; + sqInt liveRegisters; sqInt offset; sqInt offset1; sqInt offset2; - sqInt operand1; - sqInt operand3; sqInt reg; sqInt retpc; - continuePostSampleNonPrim = ((AbstractInstruction *) 0); - continuePostSamplePrim = ((AbstractInstruction *) 0); - jmpSampleNonPrim = ((AbstractInstruction *) 0); - jmpSamplePrim = ((AbstractInstruction *) 0); + jumpToTakeSample = ((AbstractInstruction *) 0); assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); genExternalizePointersForPrimitiveCall(); /* begin genLoadCStackPointersForPrimCall */ @@ -25134,41 +25215,28 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) else { genLoadCStackPointer(backEnd); } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick if so */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction2 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpSampleNonPrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSampleNonPrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } if (recordPrimTraceForMethod(methodObj)) { genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction37 = genoperandoperand(MoveCqR, 0, TempReg); + anInstruction18 = genoperandoperand(MoveCqR, 0, TempReg); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction38 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); + anInstruction19 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); + anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); } /* begin checkLiteral:forInstruction: */ argumentCountAddress(); - anInstruction39 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); + anInstruction20 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { /* begin checkLiteral:forInstruction: */ ((sqInt)primitiveRoutine); - anInstruction5 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); + anInstruction1 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); /* begin checkLiteral:forInstruction: */ primitiveFunctionPointerAddress(); - anInstruction6 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); + anInstruction2 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); } if (((flags & (PrimCallNeedsNewMethod + PrimCallMayEndureCodeCompaction)) != 0)) { @@ -25180,26 +25248,25 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) /* begin MoveMw:r:R: */ offset = offsetof(CogMethod, methodObject); /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); + anInstruction3 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); /* begin checkLiteral:forInstruction: */ newMethodAddress(); - anInstruction8 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); + anInstruction4 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); } /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction40 = genoperand(PrefetchAw, primFailCodeAddress()); + anInstruction22 = genoperand(PrefetchAw, primFailCodeAddress()); if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - /* Sideways call the C primitive routine so that we return through cePrimReturnEnterCogCode. */ /* On Spur ceActivateFailingPrimitiveMethod: would like to retry if forwarders are found. So insist on PrimCallNeedsPrimitiveFunction being set too. */ assert(((flags & PrimCallNeedsPrimitiveFunction) != 0)); /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l32; + goto l20; assert(0 <= 4); if (null < NoReg) { /* begin MoveCq:R: */ - anInstruction12 = genoperandoperand(MoveCqR, -2 - null, CArg0Reg); + anInstruction11 = genoperandoperand(MoveCqR, -2 - null, CArg0Reg); } else { if (null != CArg0Reg) { @@ -25237,109 +25304,88 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) genoperandoperand(MoveRR, null, CArg3Reg); } } - l32: /* end genMarshallNArgs:arg:arg:arg:arg: */; + l20: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin genSubstituteReturnAddress: */ retpc = (((flags & PrimCallCollectsProfileSamples) != 0) ? cePrimReturnEnterCogCodeProfiling : cePrimReturnEnterCogCode); /* begin checkLiteral:forInstruction: */ - anInstruction13 = genoperand(PushCw, retpc); + anInstruction8 = genoperand(PushCw, retpc); /* begin gen:literal: */ - anInstruction10 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); - jmp = (jmpSamplePrim = (continuePostSamplePrim = null)); + anInstruction6 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); + return 0; } - else { - - /* Call the C primitive routine. */ - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l49; - assert(0 <= 4); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg0Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg1Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg2Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg3Reg); - l49: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin gen:literal: */ - anInstruction15 = genoperand(CallFull, ((sqInt)primitiveRoutine)); - /* begin genRemoveNArgsFromStack: */ - assert(0 <= 4); - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction18 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpSamplePrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSamplePrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - maybeCompileRetryOnPrimitiveFail(primitiveIndex); - /* begin MoveAw:R: */ - address2 = instructionPointerAddress(); - reg = ClassReg; - /* begin checkLiteral:forInstruction: */ - anInstruction24 = genoperandoperand(MoveAwR, address2, reg); - genLoadStackPointers(backEnd); + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + goto l43; + assert(0 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg0Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg1Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg2Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg3Reg); + l43: /* end genMarshallNArgs:arg:arg:arg:arg: */; + /* begin gen:literal: */ + anInstruction10 = genoperand(CallFull, ((sqInt)primitiveRoutine)); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 4); + maybeCompileRetryOnPrimitiveFail(primitiveIndex); + genLoadStackPointersForPrimCall(backEnd, ClassReg); + /* begin checkLiteral:forInstruction: */ + instructionPointerAddress(); + anInstruction13 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); + /* begin checkQuickConstant:forInstruction: */ + anInstruction14 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + /* begin checkLiteral:forInstruction: */ + primFailCodeAddress(); + anInstruction26 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + flag("ask concrete code gen if move sets condition codes?"); + /* begin checkQuickConstant:forInstruction: */ + anInstruction27 = genoperandoperand(CmpCqR, 0, TempReg); + /* begin JumpNonZero: */ + jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + /* begin preferredRegisterForMovePerfCnt64RL */ + reg = RAX; + gMovePerfCnt64RL(reg, liveRegisters); /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction25 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - /* begin PushR: */ - genoperand(PushR, ClassReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction26 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset1 = BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction27 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, BytesPerWord); + nextProfileTickAddress(); + anInstruction30 = genoperandoperand(MoveAwR, nextProfileTickAddress(), Arg1Reg); + /* begin CmpR:R: */ + assert(!((reg == SPReg))); + genoperandoperand(CmpRR, reg, Arg1Reg); + /* begin JumpGreaterOrEqual: */ + jumpToTakeSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l57; + l57: /* end genCheckForProfileTimerTick: */; } + /* begin MoveMw:r:R: */ + offset1 = BytesPerWord; + /* begin checkQuickConstant:forInstruction: */ + anInstruction28 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); + continueAfterProfileSample = anInstruction28; + /* begin RetN: */ + genoperand(RetN, BytesPerWord); if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* The sample is collected by cePrimReturnEnterCogCode for external calls */ - if (!(jmpSamplePrim == null)) { - - /* Call ceCheckProfileTick: to record sample and then continue. */ - jmpTarget(jmpSamplePrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin gen:literal: */ - operand1 = ((usqIntptr_t)ceCheckProfileTick); - /* begin checkLiteral:forInstruction: */ - anInstruction29 = genoperand(CallFull, operand1); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSamplePrim)); - } - jmpTarget(jmpSampleNonPrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction34 = genoperandoperand(MoveCqR, 0, TempReg); + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); /* begin checkLiteral:forInstruction: */ - newMethodAddress(); - anInstruction35 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); - /* begin gen:literal: */ - operand3 = ((usqIntptr_t)ceCheckProfileTick); - /* begin checkLiteral:forInstruction: */ - anInstruction33 = genoperand(CallFull, operand3); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSampleNonPrim)); - } - if (!(jmp == null)) { - - /* Jump to restore of receiver reg and proceed to frame build for failure. */ - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin MoveMw:r:R: */ - offset2 = BytesPerWord * (methodOrBlockNumArgs + (1)); + instructionPointerAddress(); + anInstruction16 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction36 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); + anInstruction17 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + /* begin Jump: */ + genoperand(Jump, ((sqInt)continueAfterProfileSample)); } + jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + /* begin MoveMw:r:R: */ + offset2 = BytesPerWord * (methodOrBlockNumArgs + (1)); + /* begin checkQuickConstant:forInstruction: */ + anInstruction29 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); return 0; } @@ -25369,7 +25415,7 @@ compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)) if ((methodOrBlockNumArgs > 2 /* numRegArgs */) || (methodOrBlockNumArgs == 0)) { /* begin registerMaskFor: */ - liveRegsMask = 1U << ReceiverResultReg; + liveRegsMask = (1U << ReceiverResultReg); } else { if (methodOrBlockNumArgs > 1) { @@ -25455,51 +25501,57 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags AbstractInstruction *anInstruction11; AbstractInstruction *anInstruction12; AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; AbstractInstruction *anInstruction16; AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction18; AbstractInstruction *anInstruction19; AbstractInstruction *anInstruction2; AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; AbstractInstruction *anInstruction22; AbstractInstruction *anInstruction23; + AbstractInstruction *anInstruction27; + AbstractInstruction *anInstruction28; + AbstractInstruction *anInstruction29; + AbstractInstruction *anInstruction30; AbstractInstruction *anInstruction4; AbstractInstruction *anInstruction5; AbstractInstruction *anInstruction6; AbstractInstruction *anInstruction8; AbstractInstruction *anInstruction9; sqInt calleeSavedRegisterMask; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; + AbstractInstruction * jumpToTakeSample; + sqInt liveRegisters; sqInt offset; sqInt offset1; sqInt operand1; + sqInt reg; sqInt retpcOffset; AbstractInstruction * retry; AbstractInstruction * skip; sqInt spRegSaveRegister; + jumpToTakeSample = ((AbstractInstruction *) 0); assert(((flags & PrimCallOnSmalltalkStack) != 0)); assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); if (recordFastCCallPrimTraceForMethod(methodObj)) { genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction18 = genoperandoperand(MoveCqR, 0, TempReg); + anInstruction20 = genoperandoperand(MoveCqR, 0, TempReg); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction19 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); + anInstruction22 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); } /* begin checkLiteral:forInstruction: */ argumentCountAddress(); - anInstruction20 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); + anInstruction23 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); genExternalizeStackPointerForFastPrimitiveCall(); - calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | (1U << ClassReg)) - (1U << ClassReg)); + calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | ((1U << ClassReg))) - ((1U << ClassReg))); spRegSaveRegister = NoReg; /* begin Label */ retry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); @@ -25508,22 +25560,54 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags } else { } + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + goto l53; + assert(0 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg0Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg1Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg2Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg3Reg); + l53: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin gen:literal: */ - anInstruction2 = genoperand(CallFull, primitiveRoutine); + anInstruction2 = genoperand(CallFull, ((sqInt)primitiveRoutine)); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 4); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction21 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + anInstruction27 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); if (spRegSaveRegister != NoReg) { /* begin MoveR:R: */ genoperandoperand(MoveRR, spRegSaveRegister, SPReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperand(CmpCqR, 0, TempReg); + anInstruction28 = genoperandoperand(CmpCqR, 0, TempReg); /* begin JumpNonZero: */ jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + /* begin preferredRegisterForMovePerfCnt64RL */ + reg = RAX; + gMovePerfCnt64RL(reg, liveRegisters); + /* begin checkLiteral:forInstruction: */ + nextProfileTickAddress(); + anInstruction30 = genoperandoperand(MoveAwR, nextProfileTickAddress(), Arg1Reg); + /* begin CmpR:R: */ + assert(!((reg == SPReg))); + genoperandoperand(CmpRR, reg, Arg1Reg); + /* begin JumpGreaterOrEqual: */ + jumpToTakeSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l66; + l66: /* end genCheckForProfileTimerTick: */; + } /* begin checkLiteral:forInstruction: */ stackPointerAddress(); - anInstruction23 = genoperandoperand(MoveAwR, stackPointerAddress(), TempReg); + anInstruction29 = genoperandoperand(MoveAwR, stackPointerAddress(), TempReg); + continueAfterProfileSample = anInstruction29; /* The original retpc is (argumentCount + 1) words below stackPointer. */ retpcOffset = -((methodOrBlockNumArgs + 1) * BytesPerWord); @@ -25537,6 +25621,12 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags anInstruction6 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, TempReg); /* begin RetN: */ genoperand(RetN, 0); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); + /* begin Jump: */ + genoperand(Jump, ((sqInt)continueAfterProfileSample)); + } jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); if ((accessorDepthForExternalPrimitiveMethod(methodObj)) >= 0) { @@ -25567,20 +25657,32 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags else { genLoadCStackPointer(backEnd); } + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + goto l36; + assert(0 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg0Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg1Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg2Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg3Reg); + l36: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin gen:literal: */ operand1 = ((usqIntptr_t)checkForAndFollowForwardedPrimitiveState); /* begin checkLiteral:forInstruction: */ anInstruction8 = genoperand(CallFull, operand1); - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(CmpCqR, 0, ABIResultReg); + anInstruction16 = genoperandoperand(CmpCqR, 0, ABIResultReg); /* begin JumpZero: */ skip = genConditionalBranchoperand(JumpZero, ((sqInt)0)); /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperand(MoveCqR, 0, TempReg); + anInstruction17 = genoperandoperand(MoveCqR, 0, TempReg); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction16 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); + anInstruction18 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); /* begin Jump: */ genoperand(Jump, ((sqInt)retry)); jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); @@ -25589,14 +25691,14 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags /* must reload SPReg to undo any alignment change, */ if (((flags & PrimCallOnSmalltalkStackAlign2x) != 0)) { - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); } } - if (((ABICallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((ABICallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* begin MoveMw:r:R: */ offset1 = (methodOrBlockNumArgs + (1)) * BytesPerWord; /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); + anInstruction19 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); } return 0; } @@ -26590,23 +26692,24 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) { sqInt address1; AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction10; + AbstractInstruction *anInstruction11; AbstractInstruction *anInstruction12; AbstractInstruction *anInstruction13; AbstractInstruction *anInstruction14; AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction18; + AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; + AbstractInstruction *anInstruction7; AbstractInstruction *anInstruction8; AbstractInstruction *anInstruction9; sqInt callTarget; AbstractInstruction *continuePostSample; AbstractInstruction *jmpFail; AbstractInstruction *jmpSample; + sqInt liveRegisters; sqInt quickConstant; sqInt reg; + sqInt reg1; continuePostSample = ((AbstractInstruction *) 0); jmpSample = ((AbstractInstruction *) 0); @@ -26615,56 +26718,63 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) quickConstant = varBaseAddress(); /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - if (profiling) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick: if so. - N.B. nextProfileTick is 64-bits so 32-bit systems need to test both halves. */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction3 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpSample = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction13 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + anInstruction12 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); flag("ask concrete code gen if move sets condition codes?"); /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(CmpCqR, 0, TempReg); + anInstruction13 = genoperandoperand(CmpCqR, 0, TempReg); /* begin JumpNonZero: */ jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (profiling + && (1)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + /* begin preferredRegisterForMovePerfCnt64RL */ + reg = RAX; + gMovePerfCnt64RL(reg, liveRegisters); + /* begin checkLiteral:forInstruction: */ + nextProfileTickAddress(); + anInstruction3 = genoperandoperand(MoveAwR, nextProfileTickAddress(), Arg1Reg); + /* begin CmpR:R: */ + assert(!((reg == SPReg))); + genoperandoperand(CmpRR, reg, Arg1Reg); + /* begin JumpGreaterOrEqual: */ + jmpSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l18; + l18: /* end genCheckForProfileTimerTick: */; + /* begin Label */ + continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); + } /* begin checkLiteral:forInstruction: */ instructionPointerAddress(); - anInstruction8 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); + anInstruction7 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); + anInstruction8 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + anInstruction9 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jmpFail, checkLiteralforInstruction(newMethodAddress(), genoperandoperand(MoveAwR, newMethodAddress(), SendNumArgsReg))); /* begin checkLiteral:forInstruction: */ cStackPointerAddress(); - anInstruction15 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); + anInstruction14 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); compileCallFornumArgsargargargargresultRegregsToSave(ceActivateFailingPrimitiveMethod, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); /* begin MoveAw:R: */ address1 = instructionPointerAddress(); - reg = ClassReg; + reg1 = ClassReg; /* begin checkLiteral:forInstruction: */ - anInstruction16 = genoperandoperand(MoveAwR, address1, reg); + anInstruction15 = genoperandoperand(MoveAwR, address1, reg1); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveMwrR, BytesPerWord, SPReg, ReceiverResultReg); + anInstruction11 = genoperandoperandoperand(MoveMwrR, BytesPerWord, SPReg, ReceiverResultReg); /* begin PushR: */ genoperand(PushR, ClassReg); /* begin RetN: */ genoperand(RetN, BytesPerWord); - if (profiling) { + if (profiling + && (1)) { /* Call ceCheckProfileTick: to record sample and then continue. newMethod should be up-to-date. Need to save and restore the link reg around this call. */ @@ -26673,7 +26783,7 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) /* begin CallFullRT: */ callTarget = (usqIntptr_t)ceCheckProfileTick; /* begin checkLiteral:forInstruction: */ - anInstruction18 = genoperand(CallFull, callTarget); + anInstruction17 = genoperand(CallFull, callTarget); /* begin Jump: */ genoperand(Jump, ((sqInt)continuePostSample)); } @@ -27028,6 +27138,61 @@ genStoreRemoteTempLongBytecode(void) && (shouldAnnotateObjectReference(((ssTop())->constant))))); } + /* SimpleStackBasedCogit>>#genTakeProfileSample */ +static void +genTakeProfileSample(void) +{ + AbstractInstruction *anInstruction1; + AbstractInstruction *anInstruction2; + AbstractInstruction *anInstruction3; + AbstractInstruction *anInstruction4; + sqInt operand1; + + addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + assert(1 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, ClassReg, CArg0Reg); + goto l12; + if (null < NoReg) { + /* begin MoveCq:R: */ + anInstruction2 = genoperandoperand(MoveCqR, -2 - null, CArg1Reg); + } + else { + if (null != CArg1Reg) { + /* begin MoveR:R: */ + genoperandoperand(MoveRR, null, CArg1Reg); + } + } + if (null < NoReg) { + /* begin MoveCq:R: */ + anInstruction3 = genoperandoperand(MoveCqR, -2 - null, CArg2Reg); + } + else { + if (null != CArg2Reg) { + /* begin MoveR:R: */ + genoperandoperand(MoveRR, null, CArg2Reg); + } + } + if (null < NoReg) { + /* begin MoveCq:R: */ + anInstruction4 = genoperandoperand(MoveCqR, -2 - null, CArg3Reg); + } + else { + if (null != CArg3Reg) { + /* begin MoveR:R: */ + genoperandoperand(MoveRR, null, CArg3Reg); + } + } + l12: /* end genMarshallNArgs:arg:arg:arg:arg: */; + /* begin gen:literal: */ + operand1 = ((usqIntptr_t)ceTakeProfileSample); + /* begin checkLiteral:forInstruction: */ + anInstruction1 = genoperand(CallFull, operand1); + /* begin genRemoveNArgsFromStack: */ + assert(1 <= 4); + } + /* SistaV1: * 217 Trap */ @@ -27371,7 +27536,7 @@ primitiveGeneratorOrNil(void) static sqInt NoDbgRegParms registerisInMask(sqInt reg, sqInt mask) { - return ((mask & (1ULL << reg)) != 0); + return ((mask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0); } /* SimpleStackBasedCogit>>#v3:Block:Code:Size: */ @@ -27712,7 +27877,7 @@ anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n) sqInt regMask; /* begin registerMaskFor: */ - regMask = 1ULL << reg; + regMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { if ((((registerMask(simStackAt(i))) & regMask) != 0)) { return 1; @@ -28716,7 +28881,7 @@ ensureReceiverResultRegContainsSelf(void) if (needsFrame) { if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin putSelfInReceiverResultReg */ storeToReg(simSelf(), ReceiverResultReg); ((simSelf())->liveRegister = ReceiverResultReg); @@ -28848,7 +29013,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) && (index < simStackPtr)) { desc = simStackAt(index); if (((desc->type)) == SSRegister) { - if (!(((regMask & (1ULL << ((desc->registerr)))) != 0))) { + if (!(((regMask & (((((desc->registerr)) < 0) ? (((usqInt)(1)) >> (-((desc->registerr)))) : (1ULL << ((desc->registerr)))))) != 0))) { reg = (desc->registerr); } } @@ -28856,7 +29021,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) } assert(!((reg == NoReg))); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1ULL << reg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)), simStackPtr, simNativeStackPtr); return reg; } @@ -29402,13 +29567,13 @@ genForwardersInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -30306,11 +30471,11 @@ genPushMaybeContextReceiverVariable(sqInt slotIndex) AbstractInstruction *jmpSingle; /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ensureReceiverResultRegContainsSelf(); /* begin genPushMaybeContextSlotIndex: */ assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ voidReceiverResultRegContainsSelf(); @@ -30363,7 +30528,7 @@ genPushNewArrayBytecode(void) } else { /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << SendNumArgsReg)) | ((1U << ReceiverResultReg))), simStackPtr, simNativeStackPtr); } size = byte1 & 0x7F; if (!popValues) { @@ -30436,7 +30601,7 @@ genPushRemoteTempLongBytecode(void) /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperandoperand(MoveMwrR, offset, FPReg, tempVectReg); /* begin availableRegOrNoneNotConflictingWith: */ - regMask = 1ULL << tempVectReg; + regMask = ((tempVectReg < 0) ? (((usqInt)(1)) >> (-tempVectReg)) : (1ULL << tempVectReg)); remoteTempReg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); if (remoteTempReg == NoReg) { remoteTempReg = tempVectReg; @@ -30786,11 +30951,11 @@ genSpecialSelectorClass(void) || (topReg == ClassReg)) { /* begin ssAllocateRequiredReg:and: */ requiredReg1 = (topReg = SendNumArgsReg); - ssAllocateRequiredRegMaskupThroughupThroughNative((1ULL << requiredReg1) | (1U << ClassReg), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((((requiredReg1 < 0) ? (((usqInt)(1)) >> (-requiredReg1)) : (1ULL << requiredReg1))) | ((1U << ClassReg)), simStackPtr, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr, simNativeStackPtr); } ssPush(1); popToReg(ssTop(), topReg); @@ -31023,7 +31188,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean association = getLiteral(litVarIndex); voidReceiverResultRegContainsSelf(); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin genMoveConstant:R: */ if (shouldAnnotateObjectReference(association)) { annotateobjRef(checkLiteralforInstruction(association, genoperandoperand(MoveCwR, association, ReceiverResultReg)), association); @@ -31036,7 +31201,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean # if IMMUTABILITY if (needsImmCheck) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -31050,7 +31215,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -31111,7 +31276,7 @@ genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqI # endif // IMMUTABILITY ssPop(1); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ClassReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ssPush(1); genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); @@ -31156,7 +31321,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea # if IMMUTABILITY if (needsImmCheck1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -31170,7 +31335,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck1, 1); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck1); } @@ -31194,7 +31359,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt assert(needsFrame); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); /* begin MoveMw:r:R: */ offset = frameOffsetOfTemporary(remoteTempIndex); @@ -31204,7 +31369,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt # if IMMUTABILITY # endif - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -31390,13 +31555,13 @@ genVanillaInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -31650,12 +31815,12 @@ liveRegisters(void) } else { /* begin registerMaskFor: */ - regsSet = 1U << ReceiverResultReg; + regsSet = (1U << ReceiverResultReg); if ((methodOrBlockNumArgs <= 2 /* numRegArgs */) && (methodOrBlockNumArgs > 0)) { - regsSet = regsSet | (1U << Arg0Reg); + regsSet = regsSet | ((1U << Arg0Reg)); if (methodOrBlockNumArgs > 1) { - regsSet = regsSet | (1U << Arg1Reg); + regsSet = regsSet | ((1U << Arg1Reg)); } } } @@ -31758,13 +31923,13 @@ marshallSendArguments(sqInt numArgs) if (numArgs > 0) { if (numArgs > 1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 2, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 2, simNativeStackPtr); /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg1Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg1Reg), simStackPtr - 1, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 1, simNativeStackPtr); } } if (numArgs > 1) { diff --git a/spur64src/vm/cogitX64WIN64.c b/spur64src/vm/cogitX64WIN64.c index adb0b92f62..02d729b8ba 100644 --- a/spur64src/vm/cogitX64WIN64.c +++ b/spur64src/vm/cogitX64WIN64.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + CCodeGenerator VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + StackToRegisterMappingCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 " __DATE__ ; +static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__cogitBuildInfo = __buildInfo; @@ -54,7 +54,7 @@ char *__cogitBuildInfo = __buildInfo; #define ArithmeticShiftRightRR 92 #define BadRegisterSet 1 #define BlockCreationBytecodeSize 4 -#define BSR 167 +#define BSR 169 #define BytecodeSetHasDirectedSuperSend 1 #define CArg0Reg 1 #define CArg1Reg 2 @@ -64,11 +64,11 @@ char *__cogitBuildInfo = __buildInfo; #define CallerSavedRegisterMask 0x706 #define CallFull 7 #define CallR 8 -#define CDQ 159 +#define CDQ 161 #if !defined(CheckRememberedInTrampoline) /* Allow this to be overridden on the compiler command line */ # define CheckRememberedInTrampoline 0 #endif -#define CLD 163 +#define CLD 165 #define ClassArray 7 #define ClassArrayCompactIndex 51 #define ClassBlockClosureCompactIndex 37 @@ -91,7 +91,7 @@ char *__cogitBuildInfo = __buildInfo; #define CMMaxUsageCount 7 #define CMMethod 2 #define CMOpenPIC 5 -#define CMPXCHGRMr 172 +#define CMPXCHGRMr 174 #define CmpC32R 113 #define CmpCqR 105 #define CmpCwR 112 @@ -106,7 +106,7 @@ char *__cogitBuildInfo = __buildInfo; #define ConvertRRs 150 #define ConvertRsR 149 #define ConvertRsRd 147 -#define CPUID 158 +#define CPUID 160 #define Debug DEBUGVM #define DisplacementMask 0x1F #define DisplacementX2N 0 @@ -150,11 +150,11 @@ char *__cogitBuildInfo = __buildInfo; #define HashMultiplyConstant 1664525 #define HashMultiplyMask 0xFFFFFFF #define HeaderIndex 0 -#define IDIVR 160 +#define IDIVR 162 #if !defined(IMMUTABILITY) /* Allow this to be overridden on the compiler command line */ # define IMMUTABILITY 1 #endif -#define IMULRR 161 +#define IMULRR 163 #define InFullBlock 2 #define InstanceSpecificationIndex 2 #define InstructionPointerIndex 1 @@ -205,11 +205,11 @@ char *__cogitBuildInfo = __buildInfo; #define Label 1 #define LargeContextSlots 62 #define LastJump 42 -#define LFENCE 168 +#define LFENCE 170 #undef LinkReg #define Literal 2 #define LiteralStart 1 -#define LOCK 171 +#define LOCK 173 #define LoadEffectiveAddressMwrR 88 #define LogicalShiftLeftCqR 95 #define LogicalShiftLeftCqRR 129 @@ -232,11 +232,11 @@ char *__cogitBuildInfo = __buildInfo; #define MethodCacheSelector 1 #define MethodIndex 3 #define MethodTooBig -4 -#define MFENCE 169 +#define MFENCE 171 #define MFMethodFlagHasContextFlag 1 #define MFMethodFlagIsBlockFlag 2 -#define MOVSB 165 -#define MOVSQ 166 +#define MOVSB 167 +#define MOVSQ 168 #define ModReg 3 #define ModRegInd 0 #define ModRegRegDisp32 2 @@ -255,10 +255,12 @@ char *__cogitBuildInfo = __buildInfo; #define MoveMbrR 65 #define MoveMs8rR 55 #define MoveMwrR 50 +#define MovePerfCnt64RL 159 +#define MovePerfCnt64RRL 158 #define MoveRA32 47 #define MoveRAb 49 #define MoveRAw 46 -#define MoveRAwNoVBR 174 +#define MoveRAwNoVBR 176 #define MoveRdM64r 76 #define MoveRdR 73 #define MoveRdRd 74 @@ -327,7 +329,7 @@ char *__cogitBuildInfo = __buildInfo; #define RCX 1 #define RDI 7 #define RDX 2 -#define REP 164 +#define REP 166 #define ReceiverIndex 5 #define ReceiverResultReg 9 #define RetN 9 @@ -336,12 +338,12 @@ char *__cogitBuildInfo = __buildInfo; #define RotateRightCqR 98 #define RSI 6 #define RSP 4 -#define SETE 173 +#define SETE 175 #define SelectorCannotInterpret 34 #define SelectorDoesNotUnderstand 20 #define SenderIndex 0 #define SendNumArgsReg 10 -#define SFENCE 170 +#define SFENCE 172 #define ShouldNotJIT -8 #define SIB1 0 #define SIB4 2 @@ -379,7 +381,7 @@ char *__cogitBuildInfo = __buildInfo; #define UnimplementedPrimitive -7 #define ValueIndex 1 #define VarBaseReg 3 -#define XCHGRR 162 +#define XCHGRR 164 #define XMM0L 0 #define XorCwR 118 #define XorRdRd 137 @@ -511,7 +513,7 @@ static sqInt NoDbgRegParms concretizeAt(AbstractInstruction * self_in_concretize static sqInt NoDbgRegParms genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer); static sqInt NoDbgRegParms genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers); static sqInt NoDbgRegParms genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers); -static sqInt NoDbgRegParms genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg); +static sqInt NoDbgRegParms genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg); static sqInt NoDbgRegParms genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers); static void NoDbgRegParms genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister); static void NoDbgRegParms initializeSharableLiteral(AbstractInstruction * self_in_initializeSharableLiteral, sqInt literal); @@ -690,6 +692,8 @@ extern void linkSendAtintooffsetreceiver(sqInt callSiteReturnAddress, CogMethod static BytecodeDescriptor * loadBytesAndGetDescriptor(void); static void NoDbgRegParms loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc); static AbstractInstruction * NoDbgRegParms gMoveCwR(sqInt wordConstant, sqInt reg); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters); static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg); static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC); @@ -1006,6 +1010,7 @@ static sqInt NoDbgRegParms computeShiftRRSize(AbstractInstruction * self_in_comp static sqInt NoDbgRegParms computeSizeOfPushCw(AbstractInstruction * self_in_computeSizeOfPushCw); static sqInt NoDbgRegParms concretizeArithCqRWithROraxOpcode(AbstractInstruction * self_in_concretizeArithCqRWithROraxOpcode, sqInt regOpcode, sqInt raxOpcode); static sqInt NoDbgRegParms concretizeFill32(AbstractInstruction * self_in_concretizeFill32); +static sqInt NoDbgRegParms concretizeMovePerfCnt64RL(AbstractInstruction * self_in_concretizeMovePerfCnt64RL); static sqInt NoDbgRegParms concretizeMoveRX32rR(AbstractInstruction * self_in_concretizeMoveRX32rR); static sqInt NoDbgRegParms concretizeMoveX32rRR(AbstractInstruction * self_in_concretizeMoveX32rRR); static sqInt NoDbgRegParms concretizeOpRR(AbstractInstruction * self_in_concretizeOpRR, sqInt x64opcode); @@ -1150,6 +1155,7 @@ static sqInt genStoreAndPopReceiverVariableBytecode(void); static sqInt genStoreAndPopRemoteTempLongBytecode(void); static sqInt genStoreAndPopTemporaryVariableBytecode(void); static sqInt genStoreRemoteTempLongBytecode(void); +static void genTakeProfileSample(void); static sqInt genUnconditionalTrapBytecode(void); extern sqInt mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj); static sqInt numSpecialSelectors(void); @@ -2701,28 +2707,28 @@ addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *an static sqInt NoDbgRegParms availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << DPFPReg0)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg0))) != 0))) { return DPFPReg0; } - if (!(((liveRegsMask & (1U << DPFPReg1)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg1))) != 0))) { return DPFPReg1; } - if (!(((liveRegsMask & (1U << DPFPReg2)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg2))) != 0))) { return DPFPReg2; } - if (!(((liveRegsMask & (1U << DPFPReg3)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg3))) != 0))) { return DPFPReg3; } - if (!(((liveRegsMask & (1U << DPFPReg4)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg4))) != 0))) { return DPFPReg4; } - if (!(((liveRegsMask & (1U << DPFPReg5)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg5))) != 0))) { return DPFPReg5; } - if (!(((liveRegsMask & (1U << DPFPReg6)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg6))) != 0))) { return DPFPReg6; } - if (!(((liveRegsMask & (1U << DPFPReg7)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg7))) != 0))) { return DPFPReg7; } return NoReg; @@ -2837,9 +2843,9 @@ genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers) used immediately afterwards. */ - /* CogAbstractInstruction>>#genLoadStackPointersForFastPrimCall: */ + /* CogAbstractInstruction>>#genLoadStackPointersForPrimCall: */ static sqInt NoDbgRegParms -genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg) +genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg) { AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; @@ -5630,7 +5636,7 @@ compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numAr regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1ULL << resultRegOrNone)) - (1ULL << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ regMaskCopy = ((usqInt)regsToSave); @@ -7280,7 +7286,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) startAddress = methodZoneBase; callerSavedReg = 0; pushedVarBaseReg = 0; - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { /* VarBaseReg is not caller-saved; must save and restore it, either by using an available caller-saved reg or push/pop. */ @@ -7313,7 +7319,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) /* begin checkLiteral:forInstruction: */ cStackPointerAddress(); anInstruction3 = genoperandoperand(MoveRAw, TempReg, cStackPointerAddress()); - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { if (pushedVarBaseReg) { gNativePopR(VarBaseReg); } @@ -8707,6 +8713,22 @@ gMoveCwR(sqInt wordConstant, sqInt reg) return anInstruction; } + /* Cogit>>#MovePerfCnt64R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters) +{ + assert(BytesPerWord == 8); + return genoperandoperand(MovePerfCnt64RL, destReg, liveRegisters); +} + + /* Cogit>>#MovePerfCnt64R:R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters) +{ + assert(BytesPerWord == 4); + return genoperandoperandoperand(MovePerfCnt64RRL, destRegLo, destRegHi, liveRegisters); +} + /* Answer the address of the null byte at the end of the method map. */ @@ -10230,11 +10252,14 @@ recordRunTimeObjectReferences(void) } } + +/* N.B. (self registerMaskFor: NoReg) = 0 */ + /* Cogit>>#registerMaskFor: */ static sqInt NoDbgRegParms registerMaskFor(sqInt reg) { - return 1ULL << reg; + return ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } /* Cogit>>#registerMaskFor:and: */ @@ -17043,7 +17068,7 @@ generateObjectRepresentationTrampolines(void) genoperand(RetN, 0); jmpTarget(jumpSC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); } - ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))), 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), CheckRememberedInTrampoline); ceStoreCheckContextReceiverTrampoline = genStoreCheckContextReceiverTrampoline(); @@ -18838,7 +18863,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jumpRC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg)); jmpTarget(jumpImmutable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); @@ -18854,7 +18879,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* Store check */ jumpImmutable1 = genJumpImmutablescratchReg(ReceiverResultReg, SendNumArgsReg); - compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), 0 /* emptyRegisterMask */); genLoadStackPointers(backEnd()); @@ -19412,7 +19437,7 @@ registerMask(SimStackEntry * self_in_registerMask) || (((self_in_registerMask->type)) == SSRegister) ? (/* begin registerMaskFor: */ (reg = (self_in_registerMask->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : 0); } @@ -19425,7 +19450,7 @@ registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone) return (((self_in_registerMaskOrNone->type)) == SSRegister ? (/* begin registerMaskFor: */ (reg = (self_in_registerMaskOrNone->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : 0); } @@ -19500,37 +19525,37 @@ isMergeFixup(BytecodeFixup * self_in_isMergeFixup) static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << Extra5Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra5Reg))) != 0))) { return Extra5Reg; } - if (!(((liveRegsMask & (1U << Extra4Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra4Reg))) != 0))) { return Extra4Reg; } - if (!(((liveRegsMask & (1U << Extra3Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra3Reg))) != 0))) { return Extra3Reg; } - if (!(((liveRegsMask & (1U << Extra2Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra2Reg))) != 0))) { return Extra2Reg; } - if (!(((liveRegsMask & (1U << Extra1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra1Reg))) != 0))) { return Extra1Reg; } - if (!(((liveRegsMask & (1U << Extra0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra0Reg))) != 0))) { return Extra0Reg; } - if (!(((liveRegsMask & (1U << Arg1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg1Reg))) != 0))) { return Arg1Reg; } - if (!(((liveRegsMask & (1U << Arg0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg0Reg))) != 0))) { return Arg0Reg; } - if (!(((liveRegsMask & (1U << SendNumArgsReg)) != 0))) { + if (!(((liveRegsMask & ((1U << SendNumArgsReg))) != 0))) { return SendNumArgsReg; } - if (!(((liveRegsMask & (1U << ClassReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ClassReg))) != 0))) { return ClassReg; } - if (!(((liveRegsMask & (1U << ReceiverResultReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ReceiverResultReg))) != 0))) { return ReceiverResultReg; } return NoReg; @@ -20109,6 +20134,11 @@ computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize) ? 1 : 0)); + case MovePerfCnt64RL: + + /* it is easier to calculate the right value by concretizing. We concretize twice, but so what? */ + return concretizeMovePerfCnt64RL(self_in_computeMaximumSize); + default: error("Case not found and no otherwise clause"); } @@ -20200,6 +20230,65 @@ concretizeFill32(AbstractInstruction * self_in_concretizeFill32) return 4; } + +/* Generate code for + 0x0: 50 pushq %rax + 0x1: 52 pushq %rdx + 0x2: 0f 31 rdtsc + 0x4: 48 c1 e2 20 shlq $0x20, %rdx + 0x8: 48 09 d0 orq %rdx, %rax + 0xb: 48 89 f8 movq %rdi, %rax + 0xe: 5a popq %rdx + 0xf: 58 popq %rax + et al */ + + /* CogX64Compiler>>#concretizeMovePerfCnt64RL */ +static sqInt NoDbgRegParms +concretizeMovePerfCnt64RL(AbstractInstruction * self_in_concretizeMovePerfCnt64RL) +{ + usqInt liveRegisters; + sqInt offset; + usqInt reg; + + reg = ((self_in_concretizeMovePerfCnt64RL->operands))[0]; + liveRegisters = ((self_in_concretizeMovePerfCnt64RL->operands))[1]; + offset = 0; + if (((liveRegisters & ((1U << RAX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[0] = 80; + offset += 1; + } + if (((liveRegisters & ((1U << RDX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 82; + offset += 1; + } + assert(!((reg == RDX))); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 15; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 1] = 49; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 2] = (rexRxb(self_in_concretizeMovePerfCnt64RL, 0, 0, RDX)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 3] = 193; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 4] = (modRMRO(self_in_concretizeMovePerfCnt64RL, ModReg, RDX, 4)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 5] = 32; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 6] = (rexRxb(self_in_concretizeMovePerfCnt64RL, RDX, 0, RAX)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 7] = 11; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 8] = (modRMRO(self_in_concretizeMovePerfCnt64RL, ModReg, RAX, RDX)); + offset += 9; + if (reg != RAX) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[11] = (rexRxb(self_in_concretizeMovePerfCnt64RL, reg, 0, RAX)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[12] = 137; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[13] = (modRMRO(self_in_concretizeMovePerfCnt64RL, ModReg, RAX, reg)); + offset += 3; + } + if (((liveRegisters & ((1U << RDX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 90; + offset += 1; + } + if (((liveRegisters & ((1U << RAX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 88; + offset += 1; + } + return offset; +} + /* CogX64Compiler>>#concretizeMoveRX32rR */ static sqInt NoDbgRegParms concretizeMoveRX32rR(AbstractInstruction * self_in_concretizeMoveRX32rR) @@ -23602,6 +23691,9 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) ((self_in_dispatchConcretize->machineCode))[skip28 + 1] = (modRMRO(self_in_dispatchConcretize, ModReg, srcReg28, destReg29)); return skip28 + 2; + case MovePerfCnt64RL: + return concretizeMovePerfCnt64RL(self_in_dispatchConcretize); + default: error("Case not found and no otherwise clause"); } @@ -24230,8 +24322,8 @@ genPushRegisterArgsForNumArgsscratchReg(AbstractInstruction * self_in_genPushReg /* This is a no-op on x64 SysV since the ABI passes up to 6 args in registers and trampolines currently observe a limit of 4. - But the WIN64 ABI allways reserve shadow space for saving up to 4 - parameter registers (even if less than 4 args). + But the WIN64 ABI always reserve shadow space for saving up to 4 parameter + registers (even if less than 4 args). */ /* CogX64Compiler>>#genRemoveNArgsFromStack: */ @@ -24257,7 +24349,7 @@ genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask) assert(!((((regMask & (registerMaskForand(RSP, RBP))) != 0)))); for (reg = RAX; reg <= R15; reg += 1) { - if (((regMask & (1ULL << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0)) { /* begin PopR: */ genoperand(PopR, reg); } @@ -24279,7 +24371,7 @@ genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask) assert(((R15 - RAX) + 1) == 16); assert(!((((regMask & (registerMaskForand(RSP, RBP))) != 0)))); for (reg = R15; reg >= RAX; reg += -1) { - if (((regMask & (1ULL << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0)) { /* begin PushR: */ genoperand(PushR, reg); } @@ -25100,56 +25192,45 @@ compileInterpreterPrimitive(void) static sqInt NoDbgRegParms compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) { - sqInt address2; + AbstractInstruction *anInstruction; + AbstractInstruction *anInstruction1; AbstractInstruction *anInstruction10; AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction15; + AbstractInstruction *anInstruction14; + AbstractInstruction *anInstruction16; + AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction18; AbstractInstruction *anInstruction19; AbstractInstruction *anInstruction2; AbstractInstruction *anInstruction20; AbstractInstruction *anInstruction21; + AbstractInstruction *anInstruction22; AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction24; AbstractInstruction *anInstruction25; AbstractInstruction *anInstruction26; AbstractInstruction *anInstruction27; + AbstractInstruction *anInstruction28; AbstractInstruction *anInstruction29; AbstractInstruction *anInstruction3; + AbstractInstruction *anInstruction30; AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction33; - AbstractInstruction *anInstruction34; - AbstractInstruction *anInstruction35; - AbstractInstruction *anInstruction36; - AbstractInstruction *anInstruction37; - AbstractInstruction *anInstruction38; - AbstractInstruction *anInstruction39; AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction40; AbstractInstruction *anInstruction41; - AbstractInstruction *anInstruction5; AbstractInstruction *anInstruction6; AbstractInstruction *anInstruction7; AbstractInstruction *anInstruction8; - AbstractInstruction * continuePostSampleNonPrim; - AbstractInstruction * continuePostSamplePrim; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; - AbstractInstruction * jmpSampleNonPrim; - AbstractInstruction * jmpSamplePrim; + AbstractInstruction * jumpToTakeSample; + sqInt liveRegisters; sqInt offset; sqInt offset1; sqInt offset2; - sqInt operand1; - sqInt operand3; sqInt reg; sqInt retpc; - continuePostSampleNonPrim = ((AbstractInstruction *) 0); - continuePostSamplePrim = ((AbstractInstruction *) 0); - jmpSampleNonPrim = ((AbstractInstruction *) 0); - jmpSamplePrim = ((AbstractInstruction *) 0); + jumpToTakeSample = ((AbstractInstruction *) 0); assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); genExternalizePointersForPrimitiveCall(); /* begin genLoadCStackPointersForPrimCall */ @@ -25159,41 +25240,28 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) else { genLoadCStackPointer(backEnd); } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick if so */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction2 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpSampleNonPrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSampleNonPrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } if (recordPrimTraceForMethod(methodObj)) { genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction37 = genoperandoperand(MoveCqR, 0, TempReg); + anInstruction18 = genoperandoperand(MoveCqR, 0, TempReg); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction38 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); + anInstruction19 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); + anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); } /* begin checkLiteral:forInstruction: */ argumentCountAddress(); - anInstruction39 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); + anInstruction20 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { /* begin checkLiteral:forInstruction: */ ((sqInt)primitiveRoutine); - anInstruction5 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); + anInstruction1 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); /* begin checkLiteral:forInstruction: */ primitiveFunctionPointerAddress(); - anInstruction6 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); + anInstruction2 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); } if (((flags & (PrimCallNeedsNewMethod + PrimCallMayEndureCodeCompaction)) != 0)) { @@ -25205,17 +25273,16 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) /* begin MoveMw:r:R: */ offset = offsetof(CogMethod, methodObject); /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); + anInstruction3 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); /* begin checkLiteral:forInstruction: */ newMethodAddress(); - anInstruction8 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); + anInstruction4 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); } /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction40 = genoperand(PrefetchAw, primFailCodeAddress()); + anInstruction22 = genoperand(PrefetchAw, primFailCodeAddress()); if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - /* Sideways call the C primitive routine so that we return through cePrimReturnEnterCogCode. */ /* On Spur ceActivateFailingPrimitiveMethod: would like to retry if forwarders are found. So insist on PrimCallNeedsPrimitiveFunction being set too. */ assert(((flags & PrimCallNeedsPrimitiveFunction) != 0)); @@ -25223,12 +25290,12 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) /* WIN64 ABI allways reserve shadow space on the stack for callee to save up to 4 register parameters */ /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperand(SubCqR, 32, RSP); - goto l32; + anInstruction7 = genoperandoperand(SubCqR, 32, RSP); + goto l20; assert(0 <= 4); if (null < NoReg) { /* begin MoveCq:R: */ - anInstruction12 = genoperandoperand(MoveCqR, -2 - null, CArg0Reg); + anInstruction11 = genoperandoperand(MoveCqR, -2 - null, CArg0Reg); } else { if (null != CArg0Reg) { @@ -25266,115 +25333,94 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) genoperandoperand(MoveRR, null, CArg3Reg); } } - l32: /* end genMarshallNArgs:arg:arg:arg:arg: */; + l20: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin genSubstituteReturnAddress: */ retpc = (((flags & PrimCallCollectsProfileSamples) != 0) ? cePrimReturnEnterCogCodeProfiling : cePrimReturnEnterCogCode); /* begin checkLiteral:forInstruction: */ - anInstruction13 = genoperand(PushCw, retpc); + anInstruction8 = genoperand(PushCw, retpc); /* begin gen:literal: */ - anInstruction10 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); - jmp = (jmpSamplePrim = (continuePostSamplePrim = null)); + anInstruction6 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); + return 0; } - else { - - /* Call the C primitive routine. */ - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - - /* WIN64 ABI allways reserve shadow space on the stack for callee to save up to 4 register parameters */ - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperand(SubCqR, 32, RSP); - goto l49; - assert(0 <= 4); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg0Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg1Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg2Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg3Reg); - l49: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin gen:literal: */ - anInstruction15 = genoperand(CallFull, ((sqInt)primitiveRoutine)); - /* begin genRemoveNArgsFromStack: */ - assert(0 <= 4); - /* begin checkQuickConstant:forInstruction: */ - anInstruction23 = genoperandoperand(AddCqR, 32, RSP); - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction18 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpSamplePrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSamplePrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - maybeCompileRetryOnPrimitiveFail(primitiveIndex); - /* begin MoveAw:R: */ - address2 = instructionPointerAddress(); - reg = ClassReg; - /* begin checkLiteral:forInstruction: */ - anInstruction24 = genoperandoperand(MoveAwR, address2, reg); - genLoadStackPointers(backEnd); + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + + /* WIN64 ABI allways reserve shadow space on the stack for callee to save up to 4 register parameters */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction23 = genoperandoperand(SubCqR, 32, RSP); + goto l43; + assert(0 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg0Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg1Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg2Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg3Reg); + l43: /* end genMarshallNArgs:arg:arg:arg:arg: */; + /* begin gen:literal: */ + anInstruction10 = genoperand(CallFull, ((sqInt)primitiveRoutine)); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 4); + /* begin checkQuickConstant:forInstruction: */ + anInstruction25 = genoperandoperand(AddCqR, 32, RSP); + maybeCompileRetryOnPrimitiveFail(primitiveIndex); + genLoadStackPointersForPrimCall(backEnd, ClassReg); + /* begin checkLiteral:forInstruction: */ + instructionPointerAddress(); + anInstruction13 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); + /* begin checkQuickConstant:forInstruction: */ + anInstruction14 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + /* begin checkLiteral:forInstruction: */ + primFailCodeAddress(); + anInstruction26 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + flag("ask concrete code gen if move sets condition codes?"); + /* begin checkQuickConstant:forInstruction: */ + anInstruction27 = genoperandoperand(CmpCqR, 0, TempReg); + /* begin JumpNonZero: */ + jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + /* begin preferredRegisterForMovePerfCnt64RL */ + reg = RAX; + gMovePerfCnt64RL(reg, liveRegisters); /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction25 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - /* begin PushR: */ - genoperand(PushR, ClassReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction26 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset1 = BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction27 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, BytesPerWord); + nextProfileTickAddress(); + anInstruction30 = genoperandoperand(MoveAwR, nextProfileTickAddress(), Arg1Reg); + /* begin CmpR:R: */ + assert(!((reg == SPReg))); + genoperandoperand(CmpRR, reg, Arg1Reg); + /* begin JumpGreaterOrEqual: */ + jumpToTakeSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l57; + l57: /* end genCheckForProfileTimerTick: */; } + /* begin MoveMw:r:R: */ + offset1 = BytesPerWord; + /* begin checkQuickConstant:forInstruction: */ + anInstruction28 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); + continueAfterProfileSample = anInstruction28; + /* begin RetN: */ + genoperand(RetN, BytesPerWord); if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* The sample is collected by cePrimReturnEnterCogCode for external calls */ - if (!(jmpSamplePrim == null)) { - - /* Call ceCheckProfileTick: to record sample and then continue. */ - jmpTarget(jmpSamplePrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin gen:literal: */ - operand1 = ((usqIntptr_t)ceCheckProfileTick); - /* begin checkLiteral:forInstruction: */ - anInstruction29 = genoperand(CallFull, operand1); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSamplePrim)); - } - jmpTarget(jmpSampleNonPrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction34 = genoperandoperand(MoveCqR, 0, TempReg); + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); /* begin checkLiteral:forInstruction: */ - newMethodAddress(); - anInstruction35 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); - /* begin gen:literal: */ - operand3 = ((usqIntptr_t)ceCheckProfileTick); - /* begin checkLiteral:forInstruction: */ - anInstruction33 = genoperand(CallFull, operand3); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSampleNonPrim)); - } - if (!(jmp == null)) { - - /* Jump to restore of receiver reg and proceed to frame build for failure. */ - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin MoveMw:r:R: */ - offset2 = BytesPerWord * (methodOrBlockNumArgs + (1)); + instructionPointerAddress(); + anInstruction16 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction36 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); + anInstruction17 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + /* begin Jump: */ + genoperand(Jump, ((sqInt)continueAfterProfileSample)); } + jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + /* begin MoveMw:r:R: */ + offset2 = BytesPerWord * (methodOrBlockNumArgs + (1)); + /* begin checkQuickConstant:forInstruction: */ + anInstruction29 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); return 0; } @@ -25406,7 +25452,7 @@ compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)) if ((methodOrBlockNumArgs > 2 /* numRegArgs */) || (methodOrBlockNumArgs == 0)) { /* begin registerMaskFor: */ - liveRegsMask = 1U << ReceiverResultReg; + liveRegsMask = (1U << ReceiverResultReg); } else { if (methodOrBlockNumArgs > 1) { @@ -25499,50 +25545,59 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags AbstractInstruction *anInstruction12; AbstractInstruction *anInstruction13; AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; AbstractInstruction *anInstruction16; AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction18; AbstractInstruction *anInstruction19; AbstractInstruction *anInstruction2; AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; AbstractInstruction *anInstruction22; AbstractInstruction *anInstruction23; + AbstractInstruction *anInstruction24; + AbstractInstruction *anInstruction26; + AbstractInstruction *anInstruction27; + AbstractInstruction *anInstruction28; + AbstractInstruction *anInstruction29; + AbstractInstruction *anInstruction30; AbstractInstruction *anInstruction4; AbstractInstruction *anInstruction5; AbstractInstruction *anInstruction6; AbstractInstruction *anInstruction8; AbstractInstruction *anInstruction9; sqInt calleeSavedRegisterMask; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; + AbstractInstruction * jumpToTakeSample; + sqInt liveRegisters; sqInt offset; sqInt offset1; sqInt operand1; + sqInt reg; sqInt retpcOffset; AbstractInstruction * retry; AbstractInstruction * skip; sqInt spRegSaveRegister; + jumpToTakeSample = ((AbstractInstruction *) 0); assert(((flags & PrimCallOnSmalltalkStack) != 0)); assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); if (recordFastCCallPrimTraceForMethod(methodObj)) { genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction18 = genoperandoperand(MoveCqR, 0, TempReg); + anInstruction20 = genoperandoperand(MoveCqR, 0, TempReg); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction19 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); + anInstruction22 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); } /* begin checkLiteral:forInstruction: */ argumentCountAddress(); - anInstruction20 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); + anInstruction23 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); genExternalizeStackPointerForFastPrimitiveCall(); - calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | (1U << ClassReg)) - (1U << ClassReg)); + calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | ((1U << ClassReg))) - ((1U << ClassReg))); spRegSaveRegister = NoReg; /* begin Label */ retry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); @@ -25551,22 +25606,60 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags } else { } + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + + /* WIN64 ABI allways reserve shadow space on the stack for callee to save up to 4 register parameters */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction24 = genoperandoperand(SubCqR, 32, RSP); + goto l53; + assert(0 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg0Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg1Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg2Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg3Reg); + l53: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin gen:literal: */ - anInstruction2 = genoperand(CallFull, primitiveRoutine); + anInstruction2 = genoperand(CallFull, ((sqInt)primitiveRoutine)); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 4); + /* begin checkQuickConstant:forInstruction: */ + anInstruction26 = genoperandoperand(AddCqR, 32, RSP); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction21 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + anInstruction27 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); if (spRegSaveRegister != NoReg) { /* begin MoveR:R: */ genoperandoperand(MoveRR, spRegSaveRegister, SPReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperand(CmpCqR, 0, TempReg); + anInstruction28 = genoperandoperand(CmpCqR, 0, TempReg); /* begin JumpNonZero: */ jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + /* begin preferredRegisterForMovePerfCnt64RL */ + reg = RAX; + gMovePerfCnt64RL(reg, liveRegisters); + /* begin checkLiteral:forInstruction: */ + nextProfileTickAddress(); + anInstruction30 = genoperandoperand(MoveAwR, nextProfileTickAddress(), Arg1Reg); + /* begin CmpR:R: */ + assert(!((reg == SPReg))); + genoperandoperand(CmpRR, reg, Arg1Reg); + /* begin JumpGreaterOrEqual: */ + jumpToTakeSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l66; + l66: /* end genCheckForProfileTimerTick: */; + } /* begin checkLiteral:forInstruction: */ stackPointerAddress(); - anInstruction23 = genoperandoperand(MoveAwR, stackPointerAddress(), TempReg); + anInstruction29 = genoperandoperand(MoveAwR, stackPointerAddress(), TempReg); + continueAfterProfileSample = anInstruction29; /* The original retpc is (argumentCount + 1) words below stackPointer. */ retpcOffset = -((methodOrBlockNumArgs + 1) * BytesPerWord); @@ -25580,6 +25673,12 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags anInstruction6 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, TempReg); /* begin RetN: */ genoperand(RetN, 0); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); + /* begin Jump: */ + genoperand(Jump, ((sqInt)continueAfterProfileSample)); + } jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); if ((accessorDepthForExternalPrimitiveMethod(methodObj)) >= 0) { @@ -25610,20 +25709,36 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags else { genLoadCStackPointer(backEnd); } + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + + /* WIN64 ABI allways reserve shadow space on the stack for callee to save up to 4 register parameters */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction14 = genoperandoperand(SubCqR, 32, RSP); + goto l36; + assert(0 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg0Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg1Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg2Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg3Reg); + l36: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin gen:literal: */ operand1 = ((usqIntptr_t)checkForAndFollowForwardedPrimitiveState); /* begin checkLiteral:forInstruction: */ anInstruction8 = genoperand(CallFull, operand1); - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(CmpCqR, 0, ABIResultReg); + anInstruction16 = genoperandoperand(CmpCqR, 0, ABIResultReg); /* begin JumpZero: */ skip = genConditionalBranchoperand(JumpZero, ((sqInt)0)); /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperand(MoveCqR, 0, TempReg); + anInstruction17 = genoperandoperand(MoveCqR, 0, TempReg); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction16 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); + anInstruction18 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); /* begin Jump: */ genoperand(Jump, ((sqInt)retry)); jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); @@ -25632,14 +25747,14 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags /* must reload SPReg to undo any alignment change, */ if (((flags & PrimCallOnSmalltalkStackAlign2x) != 0)) { - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); } } - if (((ABICallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((ABICallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* begin MoveMw:r:R: */ offset1 = (methodOrBlockNumArgs + (1)) * BytesPerWord; /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); + anInstruction19 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); } return 0; } @@ -26633,23 +26748,24 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) { sqInt address1; AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction10; + AbstractInstruction *anInstruction11; AbstractInstruction *anInstruction12; AbstractInstruction *anInstruction13; AbstractInstruction *anInstruction14; AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction18; + AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; + AbstractInstruction *anInstruction7; AbstractInstruction *anInstruction8; AbstractInstruction *anInstruction9; sqInt callTarget; AbstractInstruction *continuePostSample; AbstractInstruction *jmpFail; AbstractInstruction *jmpSample; + sqInt liveRegisters; sqInt quickConstant; sqInt reg; + sqInt reg1; continuePostSample = ((AbstractInstruction *) 0); jmpSample = ((AbstractInstruction *) 0); @@ -26658,56 +26774,63 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) quickConstant = varBaseAddress(); /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - if (profiling) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick: if so. - N.B. nextProfileTick is 64-bits so 32-bit systems need to test both halves. */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction3 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpSample = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction13 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + anInstruction12 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); flag("ask concrete code gen if move sets condition codes?"); /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(CmpCqR, 0, TempReg); + anInstruction13 = genoperandoperand(CmpCqR, 0, TempReg); /* begin JumpNonZero: */ jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (profiling + && (1)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + /* begin preferredRegisterForMovePerfCnt64RL */ + reg = RAX; + gMovePerfCnt64RL(reg, liveRegisters); + /* begin checkLiteral:forInstruction: */ + nextProfileTickAddress(); + anInstruction3 = genoperandoperand(MoveAwR, nextProfileTickAddress(), Arg1Reg); + /* begin CmpR:R: */ + assert(!((reg == SPReg))); + genoperandoperand(CmpRR, reg, Arg1Reg); + /* begin JumpGreaterOrEqual: */ + jmpSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l18; + l18: /* end genCheckForProfileTimerTick: */; + /* begin Label */ + continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); + } /* begin checkLiteral:forInstruction: */ instructionPointerAddress(); - anInstruction8 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); + anInstruction7 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); + anInstruction8 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + anInstruction9 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jmpFail, checkLiteralforInstruction(newMethodAddress(), genoperandoperand(MoveAwR, newMethodAddress(), SendNumArgsReg))); /* begin checkLiteral:forInstruction: */ cStackPointerAddress(); - anInstruction15 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); + anInstruction14 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); compileCallFornumArgsargargargargresultRegregsToSave(ceActivateFailingPrimitiveMethod, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); /* begin MoveAw:R: */ address1 = instructionPointerAddress(); - reg = ClassReg; + reg1 = ClassReg; /* begin checkLiteral:forInstruction: */ - anInstruction16 = genoperandoperand(MoveAwR, address1, reg); + anInstruction15 = genoperandoperand(MoveAwR, address1, reg1); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveMwrR, BytesPerWord, SPReg, ReceiverResultReg); + anInstruction11 = genoperandoperandoperand(MoveMwrR, BytesPerWord, SPReg, ReceiverResultReg); /* begin PushR: */ genoperand(PushR, ClassReg); /* begin RetN: */ genoperand(RetN, BytesPerWord); - if (profiling) { + if (profiling + && (1)) { /* Call ceCheckProfileTick: to record sample and then continue. newMethod should be up-to-date. Need to save and restore the link reg around this call. */ @@ -26716,7 +26839,7 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) /* begin CallFullRT: */ callTarget = (usqIntptr_t)ceCheckProfileTick; /* begin checkLiteral:forInstruction: */ - anInstruction18 = genoperand(CallFull, callTarget); + anInstruction17 = genoperand(CallFull, callTarget); /* begin Jump: */ genoperand(Jump, ((sqInt)continuePostSample)); } @@ -27071,6 +27194,69 @@ genStoreRemoteTempLongBytecode(void) && (shouldAnnotateObjectReference(((ssTop())->constant))))); } + /* SimpleStackBasedCogit>>#genTakeProfileSample */ +static void +genTakeProfileSample(void) +{ + AbstractInstruction *anInstruction1; + AbstractInstruction *anInstruction2; + AbstractInstruction *anInstruction3; + AbstractInstruction *anInstruction4; + AbstractInstruction *anInstruction5; + AbstractInstruction *anInstruction6; + sqInt operand1; + + addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + + /* WIN64 ABI allways reserve shadow space on the stack for callee to save up to 4 register parameters */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction5 = genoperandoperand(SubCqR, 32, RSP); + assert(1 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, ClassReg, CArg0Reg); + goto l12; + if (null < NoReg) { + /* begin MoveCq:R: */ + anInstruction2 = genoperandoperand(MoveCqR, -2 - null, CArg1Reg); + } + else { + if (null != CArg1Reg) { + /* begin MoveR:R: */ + genoperandoperand(MoveRR, null, CArg1Reg); + } + } + if (null < NoReg) { + /* begin MoveCq:R: */ + anInstruction3 = genoperandoperand(MoveCqR, -2 - null, CArg2Reg); + } + else { + if (null != CArg2Reg) { + /* begin MoveR:R: */ + genoperandoperand(MoveRR, null, CArg2Reg); + } + } + if (null < NoReg) { + /* begin MoveCq:R: */ + anInstruction4 = genoperandoperand(MoveCqR, -2 - null, CArg3Reg); + } + else { + if (null != CArg3Reg) { + /* begin MoveR:R: */ + genoperandoperand(MoveRR, null, CArg3Reg); + } + } + l12: /* end genMarshallNArgs:arg:arg:arg:arg: */; + /* begin gen:literal: */ + operand1 = ((usqIntptr_t)ceTakeProfileSample); + /* begin checkLiteral:forInstruction: */ + anInstruction1 = genoperand(CallFull, operand1); + /* begin genRemoveNArgsFromStack: */ + assert(1 <= 4); + /* begin checkQuickConstant:forInstruction: */ + anInstruction6 = genoperandoperand(AddCqR, 32, RSP); + } + /* SistaV1: * 217 Trap */ @@ -27414,7 +27600,7 @@ primitiveGeneratorOrNil(void) static sqInt NoDbgRegParms registerisInMask(sqInt reg, sqInt mask) { - return ((mask & (1ULL << reg)) != 0); + return ((mask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0); } /* SimpleStackBasedCogit>>#v3:Block:Code:Size: */ @@ -27755,7 +27941,7 @@ anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n) sqInt regMask; /* begin registerMaskFor: */ - regMask = 1ULL << reg; + regMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { if ((((registerMask(simStackAt(i))) & regMask) != 0)) { return 1; @@ -28759,7 +28945,7 @@ ensureReceiverResultRegContainsSelf(void) if (needsFrame) { if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin putSelfInReceiverResultReg */ storeToReg(simSelf(), ReceiverResultReg); ((simSelf())->liveRegister = ReceiverResultReg); @@ -28891,7 +29077,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) && (index < simStackPtr)) { desc = simStackAt(index); if (((desc->type)) == SSRegister) { - if (!(((regMask & (1ULL << ((desc->registerr)))) != 0))) { + if (!(((regMask & (((((desc->registerr)) < 0) ? (((usqInt)(1)) >> (-((desc->registerr)))) : (1ULL << ((desc->registerr)))))) != 0))) { reg = (desc->registerr); } } @@ -28899,7 +29085,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) } assert(!((reg == NoReg))); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1ULL << reg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)), simStackPtr, simNativeStackPtr); return reg; } @@ -29445,13 +29631,13 @@ genForwardersInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -30349,11 +30535,11 @@ genPushMaybeContextReceiverVariable(sqInt slotIndex) AbstractInstruction *jmpSingle; /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ensureReceiverResultRegContainsSelf(); /* begin genPushMaybeContextSlotIndex: */ assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ voidReceiverResultRegContainsSelf(); @@ -30406,7 +30592,7 @@ genPushNewArrayBytecode(void) } else { /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << SendNumArgsReg)) | ((1U << ReceiverResultReg))), simStackPtr, simNativeStackPtr); } size = byte1 & 0x7F; if (!popValues) { @@ -30479,7 +30665,7 @@ genPushRemoteTempLongBytecode(void) /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperandoperand(MoveMwrR, offset, FPReg, tempVectReg); /* begin availableRegOrNoneNotConflictingWith: */ - regMask = 1ULL << tempVectReg; + regMask = ((tempVectReg < 0) ? (((usqInt)(1)) >> (-tempVectReg)) : (1ULL << tempVectReg)); remoteTempReg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); if (remoteTempReg == NoReg) { remoteTempReg = tempVectReg; @@ -30829,11 +31015,11 @@ genSpecialSelectorClass(void) || (topReg == ClassReg)) { /* begin ssAllocateRequiredReg:and: */ requiredReg1 = (topReg = SendNumArgsReg); - ssAllocateRequiredRegMaskupThroughupThroughNative((1ULL << requiredReg1) | (1U << ClassReg), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((((requiredReg1 < 0) ? (((usqInt)(1)) >> (-requiredReg1)) : (1ULL << requiredReg1))) | ((1U << ClassReg)), simStackPtr, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr, simNativeStackPtr); } ssPush(1); popToReg(ssTop(), topReg); @@ -31066,7 +31252,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean association = getLiteral(litVarIndex); voidReceiverResultRegContainsSelf(); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin genMoveConstant:R: */ if (shouldAnnotateObjectReference(association)) { annotateobjRef(checkLiteralforInstruction(association, genoperandoperand(MoveCwR, association, ReceiverResultReg)), association); @@ -31079,7 +31265,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean # if IMMUTABILITY if (needsImmCheck) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -31093,7 +31279,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -31154,7 +31340,7 @@ genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqI # endif // IMMUTABILITY ssPop(1); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ClassReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ssPush(1); genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); @@ -31199,7 +31385,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea # if IMMUTABILITY if (needsImmCheck1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -31213,7 +31399,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck1, 1); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck1); } @@ -31237,7 +31423,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt assert(needsFrame); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); /* begin MoveMw:r:R: */ offset = frameOffsetOfTemporary(remoteTempIndex); @@ -31247,7 +31433,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt # if IMMUTABILITY # endif - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -31433,13 +31619,13 @@ genVanillaInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -31693,12 +31879,12 @@ liveRegisters(void) } else { /* begin registerMaskFor: */ - regsSet = 1U << ReceiverResultReg; + regsSet = (1U << ReceiverResultReg); if ((methodOrBlockNumArgs <= 2 /* numRegArgs */) && (methodOrBlockNumArgs > 0)) { - regsSet = regsSet | (1U << Arg0Reg); + regsSet = regsSet | ((1U << Arg0Reg)); if (methodOrBlockNumArgs > 1) { - regsSet = regsSet | (1U << Arg1Reg); + regsSet = regsSet | ((1U << Arg1Reg)); } } } @@ -31801,13 +31987,13 @@ marshallSendArguments(sqInt numArgs) if (numArgs > 0) { if (numArgs > 1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 2, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 2, simNativeStackPtr); /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg1Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg1Reg), simStackPtr - 1, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 1, simNativeStackPtr); } } if (numArgs > 1) { diff --git a/spur64src/vm/cointerp.c b/spur64src/vm/cointerp.c index bff3a55c80..27f013847a 100644 --- a/spur64src/vm/cointerp.c +++ b/spur64src/vm/cointerp.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - CoInterpreter VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CoInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 " __DATE__ ; +static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -487,6 +487,7 @@ extern void ceSendaboveClassBindingtonumArgs(sqInt selector, sqInt methodClassBi extern sqInt ceSendabovetonumArgs(sqInt selector, sqInt methodClass, sqInt rcvr, sqInt numArgs); extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethod); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); @@ -662,7 +663,6 @@ static void primitiveExitCriticalSection(void); static void primitiveFlushCacheByMethod(void); static void primitiveFlushCacheBySelector(void); extern usqInt primitiveFunctionPointerAddress(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); EXPORT(sqInt) primitiveMethodPCData(void); static void primitiveMethodXray(void); EXPORT(void) primitiveMinimumUnusedHeadroom(void); @@ -1206,7 +1206,6 @@ static sqInt NoDbgRegParms isPureBitsFormat(sqInt format); extern sqInt isReallyYoung(sqInt oop); static sqInt NoDbgRegParms isRemembered(sqInt objOop); static sqInt NoDbgRegParms isSegmentBridge(sqInt objOop); -static sqInt NoDbgRegParms isSemaphoreOop(sqInt anOop); extern sqInt isShorts(sqInt oop); extern sqInt isUnambiguouslyForwarder(sqInt objOop); extern sqInt isUnmarked(sqInt objOop); @@ -1432,7 +1431,6 @@ EXPORT(sqInt) callbackLeave(sqInt cbID); extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHeader); extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkForEventsMayContextSwitch(sqInt mayContextSwitch); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); @@ -1713,7 +1711,6 @@ static sqInt NoDbgRegParms updateDisplayLeftTopRightBottom(sqInt l, sqInt t, sqI static sqInt NoDbgRegParms validBCPCinMethod(sqInt thePC, usqInt aMethod); static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, char *fp); static sqInt validStackPageBaseFrames(void); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt wakeHighestPriority(void); static sqInt NeverInline writeImageFileIO(void); static usqInt NoDbgRegParms cloneContext(sqInt aContext); @@ -1736,7 +1733,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1811,15 +1807,14 @@ _iss usqInt lastMobileObject; _iss sqInt tempOop; _iss sqInt numClassTablePages; _iss sqInt lkupClass; -_iss sqInt futureSurvivorStart; _iss sqInt profileProcess; -_iss sqInt profileSemaphore; +_iss sqInt futureSurvivorStart; _iss sqInt mournQueue; _iss sqInt numRememberedEphemerons; +_iss sqInt profileMethod; _iss sqInt jmpDepth; _iss sqInt mobileStart; -_iss sqInt profileMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; +_iss sqInt profileSemaphore; _iss sqInt growHeadroom; _iss sqInt tenureThreshold; _iss sqInt lastCoggableInterpretedBlockMethod; @@ -1827,7 +1822,6 @@ _iss sqInt lastUncoggableInterpretedBlockMethod; _iss char * objStackInvalidBecause; _iss sqInt sweepIndex; _iss sqInt ephemeronList; -_iss sqInt longRunningPrimitiveCheckMethod; _iss sqInt tenureCriterion; _iss usqInt totalHeapSizeIncludingBridges; _iss sqInt becomeEffectsFlags; @@ -1851,19 +1845,15 @@ _iss sqInt gcMode; _iss sqInt highestRunnableProcessPriority; _iss sqInt metaclassNumSlots; _iss usqLong nextWakeupUsecs; -_iss usqLong statGCEndUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; _iss sqInt shrinkThreshold; -_iss usqLong statCheckForEvents; _iss sqInt statTenures; _iss sqInt weakList; _iss usqInt cogCodeSize; -_iss usqLong gcStartUsecs; _iss sqInt marking; _iss sqLong oldSpaceUsePriorToScavenge; _iss sqInt preemptionYields; _iss sqInt rememberedSetLimit; +_iss usqLong statGCEndUsecs; _iss sqInt statSurvivorCount; _iss sqInt thisClassIndex; _iss sqInt externalPrimitiveTableFirstFreeIndex; @@ -1878,6 +1868,7 @@ _iss sqInt statShrinkMemory; _iss sqInt biasForGC; _iss sqInt edenBytes; _iss sqInt fullScreenFlag; +_iss usqLong gcStartUsecs; _iss usqInt lastHash; _iss sqInt lastMethodCacheProbeWrite; _iss sqInt newFinalization; @@ -1892,10 +1883,10 @@ _iss sqInt freeSpaceCheckOopToIgnore; _iss usqInt heapSizeAtPreviousGC; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss sqInt methodDictLinearSearchLimit; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statCompactionUsecs; _iss usqLong statForceInterruptCheck; _iss usqLong statFullGCUsecs; @@ -1916,7 +1907,6 @@ _iss sqInt extraFramesToMoveOnOverflow; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; _iss sqInt inFFIFlags; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss sqInt refCountToShrinkRT; _iss sqInt signalLowSpace; @@ -1930,7 +1920,6 @@ _iss sqInt classByteArrayCompactIndex; _iss usqInt exceptionPC; _iss sqInt gcSemaphoreIndex; _iss usqLong gcSweepEndUsecs; -_iss usqLong longRunningPrimitiveGCUsecs; _iss sqInt overflowLimit; _iss StackPage * overflowedPage; _iss sqInt statCompactPassCount; @@ -1948,6 +1937,9 @@ _iss usqInt suspendedCallbacks[MaxJumpBuf + 1 /* 33 */]; _iss usqInt suspendedMethods[MaxJumpBuf + 1 /* 33 */]; _iss jmp_buf jmpBuf[MaxJumpBuf + 1 /* 33 */]; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; _iss sqInt preferredPinningSegment; _iss sqInt statCoalesces; _iss usqLong statFGCDeltaUsecs; @@ -2624,7 +2616,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Open Smalltalk Cog[Spur] VM [CoInterpreterPrimitives VMMaker.oscog-eem.3024]"; +const char *interpreterVersion = "Open Smalltalk Cog[Spur] VM [CoInterpreterPrimitives VMMaker.oscog-eem.3031]"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */; int displayWidth; int displayDepth; @@ -15503,6 +15495,27 @@ ceStackOverflow(sqInt contextSwitchIfNotNil) error("should not be reached"); } + +/* A primitive has succeeded and the nextProfileTick has been reached (all + done in machine code). + Now take a sample. c.f. checkProfileTick: */ + + /* CoInterpreter>>#ceTakeProfileSample: */ +void +ceTakeProfileSample(CogMethod *aCogMethod) +{ DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt objOop; + sqInt objOop1; + + /* begin fetchPointer:ofObject: */ + objOop1 = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(SchedulerAssociation) << (shiftForWord()))))); + objOop = longAt((objOop1 + BaseHeaderSize) + (((sqInt)((usqInt)(ValueIndex) << (shiftForWord()))))); + GIV(profileProcess) = longAt((objOop + BaseHeaderSize) + (((sqInt)((usqInt)(ActiveProcessIndex) << (shiftForWord()))))); + GIV(profileMethod) = (aCogMethod->methodObject); + forceInterruptCheck(); + GIV(nextProfileTick) = 0; +} + /* CoInterpreter>>#ceTraceBlockActivation */ void ceTraceBlockActivation(void) @@ -17496,24 +17509,6 @@ void forceInterruptCheckFromHeartbeat(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; sqLowLevelMFence(); if (GIV(deferSmash)) { GIV(deferredSmash) = 1; @@ -23760,56 +23755,6 @@ primitiveFunctionPointerAddress(void) return ((usqInt)((&primitiveFunctionPointer))); } - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* CoInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; - int flushState; - sqInt sema; - char *sp; - - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (sema == GIV(nilObj)) { - flushState = GIV(longRunningPrimitiveCheckSemaphore) != null; - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - flushState = GIV(longRunningPrimitiveCheckSemaphore) == null; - if (!(((!(sema & (tagMask())))) - && (((longAt(sema)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(ClassSemaphore) << (shiftForWord())))))))))) { - return (GIV(primFailCode) = PrimErrBadArgument); - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(longRunningPrimitiveCheckSemaphore) == null)) - || (((stackValue(0)) == GIV(longRunningPrimitiveCheckSemaphore)) - && (isSemaphoreOop(sema)))); - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - if (flushState) { - ceInvokeInterpret(); - } - return 0; -} - /* CoInterpreterPrimitives>>#primitiveMethodPCData */ EXPORT(sqInt) primitiveMethodPCData(void) @@ -24122,14 +24067,9 @@ primitiveObjectAtPut(void) EXPORT(sqInt) primitiveProfileSemaphore(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; int flushState; sqInt sema; - char *sp; - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); if (sema == GIV(nilObj)) { flushState = GIV(profileSemaphore) != GIV(nilObj); @@ -24141,28 +24081,21 @@ primitiveProfileSemaphore(void) return (GIV(primFailCode) = PrimErrBadArgument); } } + GIV(profileSemaphore) = sema; /* If we've switched profiling on or off we must void machine code (and machine code pcs in contexts) since we will start or stop testing the profile clock in machine code primitive invocations, and so generate slightly different code from here on in. */ - GIV(profileSemaphore) = sema; - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(profileSemaphore) == (nilObject()))) - || (((stackValue(0)) == GIV(profileSemaphore)) - && (isSemaphoreOop(sema)))); - } GIV(profileProcess) = (GIV(profileMethod) = GIV(nilObj)); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; if (flushState) { - ceInvokeInterpret(); + flushExternalPrimitives(); + } + else { + /* begin methodReturnReceiver */ + assert(!((failed()))); + /* begin pop: */ + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; } return 0; } @@ -32558,26 +32491,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -35218,15 +35153,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -35244,15 +35174,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -35276,39 +35201,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((((integerPointer) & 7) == 1)) { - deltaTicks = (integerPointer >> 3); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((((deltaTicks) & 7) == 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 3)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -50660,14 +50564,6 @@ isSegmentBridge(sqInt objOop) return ((longAt(objOop)) & (classIndexMask())) == (segmentBridgePun()); } - /* SpurMemoryManager>>#isSemaphoreOop: */ -static sqInt NoDbgRegParms -isSemaphoreOop(sqInt anOop) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - return ((!(anOop & (tagMask())))) - && (((longAt(anOop)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(ClassSemaphore) << (shiftForWord())))))))); -} - /* Answer if the argument contains only indexable 16-bit half words (no oops). See comment in formatOf: @@ -52947,8 +52843,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) sqInt referent; sqInt referent1; sqInt referent2; - sqInt referent3; - sqInt referent4; sqInt sizeOfUnusedEden; StackPage *thePage; @@ -53087,38 +52981,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - if ((!((longAt(GIV(longRunningPrimitiveCheckMethod))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckMethod))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((GIV(longRunningPrimitiveCheckMethod) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent3 & (tagMask())))) - && ((!((longAt(referent3)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((referent3 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckMethod) = referent3; - } - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - if ((!((longAt(GIV(longRunningPrimitiveCheckSemaphore))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckSemaphore))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((GIV(longRunningPrimitiveCheckSemaphore) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent4 & (tagMask())))) - && ((!((longAt(referent4)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((referent4 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckSemaphore) = referent4; - } - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -61166,7 +61028,7 @@ prepareForSnapshot(void) sqInt limit; sqInt newEndOfMemory; sqInt next; - usqInt node; + sqInt node; SpurSegmentInfo *seg; sqInt smallChild; sqInt treeNode; @@ -61997,33 +61859,6 @@ checkAllAccessibleObjectsOkay(void) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -62114,9 +61949,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { /* begin signalLowSpace: */ GIV(signalLowSpace) = 0; @@ -67113,23 +66945,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i = 1; i <= GIV(jmpDepth); i += 1) { oop = GIV(suspendedCallbacks)[i]; @@ -71215,8 +71030,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -71245,18 +71060,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -74407,22 +74224,6 @@ validStackPageBaseFrames(void) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Return the highest priority process that is ready to run. To save time looking at many empty lists before finding a runnable process the VM maintains a variable holding the @@ -76933,74 +76734,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((addressCouldBeObj(lrpcm)) - && ((!(((longAt(lrpcm)) & (classIndexMask())) == (isFreeObjectClassIndexPun()))) - && (((((usqInt)((longAt(lrpcm)))) >> (formatShift())) & (formatMask())) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - assert(!(isForwarded(result))); - if ((assert(isNonImmediate(result)), - oopisGreaterThanOrEqualTo(result, GIV(oldSpaceStart)))) { - - /* most stores into young objects */ - if (((!(lrpcm & (tagMask())))) - && (oopisLessThan(lrpcm, GIV(newSpaceLimit)))) { - /* begin possibleRootStoreInto: */ - if (!(((((usqInt)((longAt(result)))) >> (rememberedBitShift())) & 1) != 0)) { - remember(result); - } - } - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 3) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 3) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -79471,15 +79204,13 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveGreaterOrEqualLargeIntegers\000\377\000", (void*)primitiveGreaterOrEqualLargeIntegers}, {(void*)_m, "primitiveGreaterThanLargeIntegers\000\377\000", (void*)primitiveGreaterThanLargeIntegers}, {(void*)_m, "primitiveHeartbeatFrequency\000\377\000", (void*)primitiveHeartbeatFrequency}, - {(void*)_m, "primitiveHighResClock\000\377\000", (void*)primitiveHighResClock}, + {(void*)_m, "primitiveHighResClock\000\377\001", (void*)primitiveHighResClock}, {(void*)_m, "primitiveImageFormatVersion\000\377\000", (void*)primitiveImageFormatVersion}, {(void*)_m, "primitiveInterruptChecksPerMSec\000\377\000", (void*)primitiveInterruptChecksPerMSec}, {(void*)_m, "primitiveIsBigEnder\000\377\000", (void*)primitiveIsBigEnder}, {(void*)_m, "primitiveIsWindowObscured\000\377\000", (void*)primitiveIsWindowObscured}, {(void*)_m, "primitiveLessOrEqualLargeIntegers\000\377\000", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers\000\377\000", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive\000\377\000", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore\000\000\000", (void*)primitiveLongRunningPrimitiveSemaphore}, {(void*)_m, "primitiveMethodPCData\000\000\000", (void*)primitiveMethodPCData}, {(void*)_m, "primitiveMillisecondClockMask\000\377\000", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveMinimumUnusedHeadroom\000\377\000", (void*)primitiveMinimumUnusedHeadroom}, @@ -79487,10 +79218,10 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveMultiplyLargeIntegers\000\000\000", (void*)primitiveMultiplyLargeIntegers}, {(void*)_m, "primitiveNotEqualLargeIntegers\000\377\000", (void*)primitiveNotEqualLargeIntegers}, {(void*)_m, "primitivePathToUsing\000\000\000", (void*)primitivePathToUsing}, - {(void*)_m, "primitiveProfilePrimitive\000\377\000", (void*)primitiveProfilePrimitive}, - {(void*)_m, "primitiveProfileSample\000\377\000", (void*)primitiveProfileSample}, + {(void*)_m, "primitiveProfilePrimitive\000\377\001", (void*)primitiveProfilePrimitive}, + {(void*)_m, "primitiveProfileSample\000\377\001", (void*)primitiveProfileSample}, {(void*)_m, "primitiveProfileSemaphore\000\000\000", (void*)primitiveProfileSemaphore}, - {(void*)_m, "primitiveProfileStart\000\000\000", (void*)primitiveProfileStart}, + {(void*)_m, "primitiveProfileStart\000\000\001", (void*)primitiveProfileStart}, {(void*)_m, "primitiveQuoLargeIntegers\000\000\000", (void*)primitiveQuoLargeIntegers}, {(void*)_m, "primitiveRemLargeIntegers\000\000\000", (void*)primitiveRemLargeIntegers}, {(void*)_m, "primitiveScreenDepth\000\377\000", (void*)primitiveScreenDepth}, diff --git a/spur64src/vm/cointerp.h b/spur64src/vm/cointerp.h index 2c9bb6ac85..1712c2e368 100644 --- a/spur64src/vm/cointerp.h +++ b/spur64src/vm/cointerp.h @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ @@ -49,6 +49,7 @@ extern void ceSendaboveClassBindingtonumArgs(sqInt selector, sqInt methodClassBi extern sqInt ceSendabovetonumArgs(sqInt selector, sqInt methodClass, sqInt rcvr, sqInt numArgs); extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethod); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); diff --git a/spur64src/vm/cointerpmt.c b/spur64src/vm/cointerpmt.c index 642cfa0b24..4141ee7a2d 100644 --- a/spur64src/vm/cointerpmt.c +++ b/spur64src/vm/cointerpmt.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - CoInterpreterMT VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CoInterpreterMT VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "CoInterpreterMT VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 " __DATE__ ; +static char __buildInfo[] = "CoInterpreterMT VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -543,6 +543,7 @@ extern void ceSendaboveClassBindingtonumArgs(sqInt selector, sqInt methodClassBi extern sqInt ceSendabovetonumArgs(sqInt selector, sqInt methodClass, sqInt rcvr, sqInt numArgs); extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethod); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); @@ -742,7 +743,6 @@ static void primitiveExitCriticalSection(void); static void primitiveFlushCacheByMethod(void); static void primitiveFlushCacheBySelector(void); extern usqInt primitiveFunctionPointerAddress(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); EXPORT(sqInt) primitiveMethodPCData(void); static void primitiveMethodXray(void); EXPORT(void) primitiveMinimumUnusedHeadroom(void); @@ -1286,7 +1286,6 @@ static sqInt NoDbgRegParms isPureBitsFormat(sqInt format); extern sqInt isReallyYoung(sqInt oop); static sqInt NoDbgRegParms isRemembered(sqInt objOop); static sqInt NoDbgRegParms isSegmentBridge(sqInt objOop); -static sqInt NoDbgRegParms isSemaphoreOop(sqInt anOop); extern sqInt isShorts(sqInt oop); extern sqInt isUnambiguouslyForwarder(sqInt objOop); extern sqInt isUnmarked(sqInt objOop); @@ -1512,7 +1511,6 @@ EXPORT(sqInt) callbackLeave(sqInt cbID); extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHeader); extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); static sqInt checkInterpreterIntegrity(void); @@ -1788,7 +1786,6 @@ static sqInt NoDbgRegParms updateDisplayLeftTopRightBottom(sqInt l, sqInt t, sqI static sqInt NoDbgRegParms validBCPCinMethod(sqInt thePC, usqInt aMethod); static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, char *fp); static sqInt validStackPageBaseFrames(void); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt NeverInline writeImageFileIO(void); static usqInt NoDbgRegParms cloneContext(sqInt aContext); static sqInt NoDbgRegParms fieldOrSenderFPofContext(sqInt index, sqInt contextObj); @@ -1810,7 +1807,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1851,8 +1847,8 @@ _iss sqInt argumentCount; _iss sqLong nextProfileTick; _iss sqInt primTraceLog[256]; _iss StackPage * stackPage; -_iss sqInt nilObj; _iss usqInt method; +_iss sqInt nilObj; _iss sqInt bytecodeSetSelector; _iss usqInt oldSpaceStart; _iss usqInt endOfMemory; @@ -1886,17 +1882,16 @@ _iss usqInt lastMobileObject; _iss sqInt tempOop; _iss sqInt numClassTablePages; _iss sqInt lkupClass; +_iss sqInt profileProcess; _iss sqInt futureSurvivorStart; _iss sqInt numThreads; -_iss sqInt profileProcess; -_iss sqInt profileSemaphore; _iss CogVMThread * disowningVMThread; _iss sqInt mournQueue; _iss sqInt numRememberedEphemerons; +_iss sqInt profileMethod; +_iss sqInt profileSemaphore; _iss sqInt jmpDepth; _iss sqInt mobileStart; -_iss sqInt profileMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; _iss CogVMThread ** threads; _iss sqInt growHeadroom; _iss sqInt processHasThreadId; @@ -1906,7 +1901,6 @@ _iss sqInt lastUncoggableInterpretedBlockMethod; _iss char * objStackInvalidBecause; _iss sqInt sweepIndex; _iss sqInt ephemeronList; -_iss sqInt longRunningPrimitiveCheckMethod; _iss sqInt tenureCriterion; _iss usqInt totalHeapSizeIncludingBridges; _iss sqInt becomeEffectsFlags; @@ -1932,19 +1926,15 @@ _iss sqInt metaclassNumSlots; _iss usqLong nextWakeupUsecs; _iss sqInt preemptionYields; _iss sqInt relinquishing; -_iss usqLong statGCEndUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; _iss sqInt shrinkThreshold; -_iss usqLong statCheckForEvents; _iss sqInt statTenures; _iss sqInt weakList; _iss usqInt cogCodeSize; -_iss usqLong gcStartUsecs; _iss sqInt marking; _iss sqInt noThreadingOfGUIThread; _iss sqLong oldSpaceUsePriorToScavenge; _iss sqInt rememberedSetLimit; +_iss usqLong statGCEndUsecs; _iss sqInt statSurvivorCount; _iss sqInt thisClassIndex; _iss sqInt checkThreadActivation; @@ -1966,6 +1956,7 @@ _iss sqInt biasForGC; _iss sqInt edenBytes; _iss sqInt foreignCallbackPriority; _iss sqInt fullScreenFlag; +_iss usqLong gcStartUsecs; _iss usqInt lastHash; _iss sqInt lastMethodCacheProbeWrite; _iss sqInt newFinalization; @@ -1981,11 +1972,11 @@ _iss sqInt freeSpaceCheckOopToIgnore; _iss usqInt heapSizeAtPreviousGC; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss sqInt memoryIsScarce; _iss sqInt methodDictLinearSearchLimit; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statCompactionUsecs; _iss usqLong statForceInterruptCheck; _iss usqLong statFullGCUsecs; @@ -2004,7 +1995,6 @@ _iss sqInt deferredSmash; _iss sqInt extraFramesToMoveOnOverflow; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss sqInt refCountToShrinkRT; _iss sqInt signalLowSpace; @@ -2018,7 +2008,6 @@ _iss sqInt classByteArrayCompactIndex; _iss usqInt exceptionPC; _iss sqInt gcSemaphoreIndex; _iss usqLong gcSweepEndUsecs; -_iss usqLong longRunningPrimitiveGCUsecs; _iss sqInt overflowLimit; _iss StackPage * overflowedPage; _iss sqInt statCompactPassCount; @@ -2037,6 +2026,9 @@ _iss usqInt suspendedCallbacks[MaxJumpBuf + 1 /* 33 */]; _iss usqInt suspendedMethods[MaxJumpBuf + 1 /* 33 */]; _iss jmp_buf jmpBuf[MaxJumpBuf + 1 /* 33 */]; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; _iss sqInt preferredPinningSegment; _iss sqInt statCoalesces; _iss usqLong statFGCDeltaUsecs; @@ -2717,7 +2709,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Open Smalltalk Cog MT VM [CoInterpreterMT VMMaker.oscog-eem.3024]"; +const char *interpreterVersion = "Open Smalltalk Cog MT VM [CoInterpreterMT VMMaker.oscog-eem.3031]"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */; int displayWidth; int displayDepth; @@ -15930,6 +15922,27 @@ ceStackOverflow(sqInt contextSwitchIfNotNil) error("should not be reached"); } + +/* A primitive has succeeded and the nextProfileTick has been reached (all + done in machine code). + Now take a sample. c.f. checkProfileTick: */ + + /* CoInterpreter>>#ceTakeProfileSample: */ +void +ceTakeProfileSample(CogMethod *aCogMethod) +{ DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt objOop; + sqInt objOop1; + + /* begin fetchPointer:ofObject: */ + objOop1 = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(SchedulerAssociation) << (shiftForWord()))))); + objOop = longAt((objOop1 + BaseHeaderSize) + (((sqInt)((usqInt)(ValueIndex) << (shiftForWord()))))); + GIV(profileProcess) = longAt((objOop + BaseHeaderSize) + (((sqInt)((usqInt)(ActiveProcessIndex) << (shiftForWord()))))); + GIV(profileMethod) = (aCogMethod->methodObject); + forceInterruptCheck(); + GIV(nextProfileTick) = 0; +} + /* CoInterpreter>>#ceTraceBlockActivation */ void ceTraceBlockActivation(void) @@ -23318,9 +23331,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { GIV(signalLowSpace) = 0; /* begin fetchPointer:ofObject: */ @@ -23642,24 +23652,6 @@ void forceInterruptCheckFromHeartbeat(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; sqLowLevelMFence(); if (GIV(deferSmash)) { GIV(deferredSmash) = 1; @@ -23852,23 +23844,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i1 = 1; i1 <= GIV(jmpDepth); i1 += 1) { oop = GIV(suspendedCallbacks)[i1]; @@ -26225,56 +26200,6 @@ primitiveFunctionPointerAddress(void) return ((usqInt)((&primitiveFunctionPointer))); } - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* CoInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; - int flushState; - sqInt sema; - char *sp; - - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (sema == GIV(nilObj)) { - flushState = GIV(longRunningPrimitiveCheckSemaphore) != null; - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - flushState = GIV(longRunningPrimitiveCheckSemaphore) == null; - if (!(((!(sema & (tagMask())))) - && (((longAt(sema)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(ClassSemaphore) << (shiftForWord())))))))))) { - return (GIV(primFailCode) = PrimErrBadArgument); - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(longRunningPrimitiveCheckSemaphore) == null)) - || (((stackValue(0)) == GIV(longRunningPrimitiveCheckSemaphore)) - && (isSemaphoreOop(sema)))); - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - if (flushState) { - ceInvokeInterpret(); - } - return 0; -} - /* CoInterpreterPrimitives>>#primitiveMethodPCData */ EXPORT(sqInt) primitiveMethodPCData(void) @@ -26587,14 +26512,9 @@ primitiveObjectAtPut(void) EXPORT(sqInt) primitiveProfileSemaphore(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; int flushState; sqInt sema; - char *sp; - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); if (sema == GIV(nilObj)) { flushState = GIV(profileSemaphore) != GIV(nilObj); @@ -26606,28 +26526,21 @@ primitiveProfileSemaphore(void) return (GIV(primFailCode) = PrimErrBadArgument); } } + GIV(profileSemaphore) = sema; /* If we've switched profiling on or off we must void machine code (and machine code pcs in contexts) since we will start or stop testing the profile clock in machine code primitive invocations, and so generate slightly different code from here on in. */ - GIV(profileSemaphore) = sema; - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(profileSemaphore) == (nilObject()))) - || (((stackValue(0)) == GIV(profileSemaphore)) - && (isSemaphoreOop(sema)))); - } GIV(profileProcess) = (GIV(profileMethod) = GIV(nilObj)); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; if (flushState) { - ceInvokeInterpret(); + flushExternalPrimitives(); + } + else { + /* begin methodReturnReceiver */ + assert(!((failed()))); + /* begin pop: */ + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; } return 0; } @@ -35023,26 +34936,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -37683,15 +37598,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -37709,15 +37619,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -37741,39 +37646,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((((integerPointer) & 7) == 1)) { - deltaTicks = (integerPointer >> 3); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((((deltaTicks) & 7) == 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 3)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -53096,14 +52980,6 @@ isSegmentBridge(sqInt objOop) return ((longAt(objOop)) & (classIndexMask())) == (segmentBridgePun()); } - /* SpurMemoryManager>>#isSemaphoreOop: */ -static sqInt NoDbgRegParms -isSemaphoreOop(sqInt anOop) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - return ((!(anOop & (tagMask())))) - && (((longAt(anOop)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(ClassSemaphore) << (shiftForWord())))))))); -} - /* Answer if the argument contains only indexable 16-bit half words (no oops). See comment in formatOf: @@ -55385,8 +55261,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) sqInt referent; sqInt referent1; sqInt referent2; - sqInt referent3; - sqInt referent4; sqInt sizeOfUnusedEden; StackPage *thePage; CogVMThread *vmThread; @@ -55526,38 +55400,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - if ((!((longAt(GIV(longRunningPrimitiveCheckMethod))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckMethod))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((GIV(longRunningPrimitiveCheckMethod) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent3 & (tagMask())))) - && ((!((longAt(referent3)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((referent3 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckMethod) = referent3; - } - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - if ((!((longAt(GIV(longRunningPrimitiveCheckSemaphore))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckSemaphore))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((GIV(longRunningPrimitiveCheckSemaphore) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent4 & (tagMask())))) - && ((!((longAt(referent4)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((referent4 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckSemaphore) = referent4; - } - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -63620,7 +63462,7 @@ prepareForSnapshot(void) sqInt limit; sqInt newEndOfMemory; sqInt next; - sqInt node; + usqInt node; SpurSegmentInfo *seg; sqInt smallChild; sqInt treeNode; @@ -64451,33 +64293,6 @@ checkAllAccessibleObjectsOkay(void) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -73344,8 +73159,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -73374,18 +73189,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -76536,22 +76353,6 @@ validStackPageBaseFrames(void) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Write the image header and heap contents to imageFile for snapshot. c.f. writeImageFileIOSimulation. The game below is to maintain 64-bit alignment for all putLong:toFile: occurrences. */ @@ -78979,74 +78780,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((addressCouldBeObj(lrpcm)) - && ((!(((longAt(lrpcm)) & (classIndexMask())) == (isFreeObjectClassIndexPun()))) - && (((((usqInt)((longAt(lrpcm)))) >> (formatShift())) & (formatMask())) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - assert(!(isForwarded(result))); - if ((assert(isNonImmediate(result)), - oopisGreaterThanOrEqualTo(result, GIV(oldSpaceStart)))) { - - /* most stores into young objects */ - if (((!(lrpcm & (tagMask())))) - && (oopisLessThan(lrpcm, GIV(newSpaceLimit)))) { - /* begin possibleRootStoreInto: */ - if (!(((((usqInt)((longAt(result)))) >> (rememberedBitShift())) & 1) != 0)) { - remember(result); - } - } - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 3) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 3) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -81511,15 +81244,13 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveGreaterOrEqualLargeIntegers\000\377\000", (void*)primitiveGreaterOrEqualLargeIntegers}, {(void*)_m, "primitiveGreaterThanLargeIntegers\000\377\000", (void*)primitiveGreaterThanLargeIntegers}, {(void*)_m, "primitiveHeartbeatFrequency\000\377\000", (void*)primitiveHeartbeatFrequency}, - {(void*)_m, "primitiveHighResClock\000\377\000", (void*)primitiveHighResClock}, + {(void*)_m, "primitiveHighResClock\000\377\001", (void*)primitiveHighResClock}, {(void*)_m, "primitiveImageFormatVersion\000\377\000", (void*)primitiveImageFormatVersion}, {(void*)_m, "primitiveInterruptChecksPerMSec\000\377\000", (void*)primitiveInterruptChecksPerMSec}, {(void*)_m, "primitiveIsBigEnder\000\377\000", (void*)primitiveIsBigEnder}, {(void*)_m, "primitiveIsWindowObscured\000\377\000", (void*)primitiveIsWindowObscured}, {(void*)_m, "primitiveLessOrEqualLargeIntegers\000\377\000", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers\000\377\000", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive\000\377\000", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore\000\000\000", (void*)primitiveLongRunningPrimitiveSemaphore}, {(void*)_m, "primitiveMethodPCData\000\000\000", (void*)primitiveMethodPCData}, {(void*)_m, "primitiveMillisecondClockMask\000\377\000", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveMinimumUnusedHeadroom\000\377\000", (void*)primitiveMinimumUnusedHeadroom}, @@ -81529,10 +81260,10 @@ void* vm_exports[][3] = { {(void*)_m, "primitivePathToUsing\000\000\000", (void*)primitivePathToUsing}, {(void*)_m, "primitiveProcessBindToThreadId\000\000\000", (void*)primitiveProcessBindToThreadId}, {(void*)_m, "primitiveProcessBoundThreadId\000\000\000", (void*)primitiveProcessBoundThreadId}, - {(void*)_m, "primitiveProfilePrimitive\000\377\000", (void*)primitiveProfilePrimitive}, - {(void*)_m, "primitiveProfileSample\000\377\000", (void*)primitiveProfileSample}, + {(void*)_m, "primitiveProfilePrimitive\000\377\001", (void*)primitiveProfilePrimitive}, + {(void*)_m, "primitiveProfileSample\000\377\001", (void*)primitiveProfileSample}, {(void*)_m, "primitiveProfileSemaphore\000\000\000", (void*)primitiveProfileSemaphore}, - {(void*)_m, "primitiveProfileStart\000\000\000", (void*)primitiveProfileStart}, + {(void*)_m, "primitiveProfileStart\000\000\001", (void*)primitiveProfileStart}, {(void*)_m, "primitiveQuoLargeIntegers\000\000\000", (void*)primitiveQuoLargeIntegers}, {(void*)_m, "primitiveRemLargeIntegers\000\000\000", (void*)primitiveRemLargeIntegers}, {(void*)_m, "primitiveScreenDepth\000\377\000", (void*)primitiveScreenDepth}, diff --git a/spur64src/vm/cointerpmt.h b/spur64src/vm/cointerpmt.h index 69fdcf37a8..a6fadd41c6 100644 --- a/spur64src/vm/cointerpmt.h +++ b/spur64src/vm/cointerpmt.h @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ @@ -51,6 +51,7 @@ extern void ceSendaboveClassBindingtonumArgs(sqInt selector, sqInt methodClassBi extern sqInt ceSendabovetonumArgs(sqInt selector, sqInt methodClass, sqInt rcvr, sqInt numArgs); extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethod); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); diff --git a/spur64src/vm/gcc3x-cointerp.c b/spur64src/vm/gcc3x-cointerp.c index 512406a956..022730cdaa 100644 --- a/spur64src/vm/gcc3x-cointerp.c +++ b/spur64src/vm/gcc3x-cointerp.c @@ -2,11 +2,11 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - CoInterpreter VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CoInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 " __DATE__ ; +static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -490,6 +490,7 @@ extern void ceSendaboveClassBindingtonumArgs(sqInt selector, sqInt methodClassBi extern sqInt ceSendabovetonumArgs(sqInt selector, sqInt methodClass, sqInt rcvr, sqInt numArgs); extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethod); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); @@ -665,7 +666,6 @@ static void primitiveExitCriticalSection(void); static void primitiveFlushCacheByMethod(void); static void primitiveFlushCacheBySelector(void); extern usqInt primitiveFunctionPointerAddress(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); EXPORT(sqInt) primitiveMethodPCData(void); static void primitiveMethodXray(void); EXPORT(void) primitiveMinimumUnusedHeadroom(void); @@ -1209,7 +1209,6 @@ static sqInt NoDbgRegParms isPureBitsFormat(sqInt format); extern sqInt isReallyYoung(sqInt oop); static sqInt NoDbgRegParms isRemembered(sqInt objOop); static sqInt NoDbgRegParms isSegmentBridge(sqInt objOop); -static sqInt NoDbgRegParms isSemaphoreOop(sqInt anOop); extern sqInt isShorts(sqInt oop); extern sqInt isUnambiguouslyForwarder(sqInt objOop); extern sqInt isUnmarked(sqInt objOop); @@ -1435,7 +1434,6 @@ EXPORT(sqInt) callbackLeave(sqInt cbID); extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHeader); extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkForEventsMayContextSwitch(sqInt mayContextSwitch); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); @@ -1716,7 +1714,6 @@ static sqInt NoDbgRegParms updateDisplayLeftTopRightBottom(sqInt l, sqInt t, sqI static sqInt NoDbgRegParms validBCPCinMethod(sqInt thePC, usqInt aMethod); static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, char *fp); static sqInt validStackPageBaseFrames(void); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt wakeHighestPriority(void); static sqInt NeverInline writeImageFileIO(void); static usqInt NoDbgRegParms cloneContext(sqInt aContext); @@ -1739,7 +1736,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1814,15 +1810,14 @@ _iss usqInt lastMobileObject; _iss sqInt tempOop; _iss sqInt numClassTablePages; _iss sqInt lkupClass; -_iss sqInt futureSurvivorStart; _iss sqInt profileProcess; -_iss sqInt profileSemaphore; +_iss sqInt futureSurvivorStart; _iss sqInt mournQueue; _iss sqInt numRememberedEphemerons; +_iss sqInt profileMethod; _iss sqInt jmpDepth; _iss sqInt mobileStart; -_iss sqInt profileMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; +_iss sqInt profileSemaphore; _iss sqInt growHeadroom; _iss sqInt tenureThreshold; _iss sqInt lastCoggableInterpretedBlockMethod; @@ -1830,7 +1825,6 @@ _iss sqInt lastUncoggableInterpretedBlockMethod; _iss char * objStackInvalidBecause; _iss sqInt sweepIndex; _iss sqInt ephemeronList; -_iss sqInt longRunningPrimitiveCheckMethod; _iss sqInt tenureCriterion; _iss usqInt totalHeapSizeIncludingBridges; _iss sqInt becomeEffectsFlags; @@ -1854,19 +1848,15 @@ _iss sqInt gcMode; _iss sqInt highestRunnableProcessPriority; _iss sqInt metaclassNumSlots; _iss usqLong nextWakeupUsecs; -_iss usqLong statGCEndUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; _iss sqInt shrinkThreshold; -_iss usqLong statCheckForEvents; _iss sqInt statTenures; _iss sqInt weakList; _iss usqInt cogCodeSize; -_iss usqLong gcStartUsecs; _iss sqInt marking; _iss sqLong oldSpaceUsePriorToScavenge; _iss sqInt preemptionYields; _iss sqInt rememberedSetLimit; +_iss usqLong statGCEndUsecs; _iss sqInt statSurvivorCount; _iss sqInt thisClassIndex; _iss sqInt externalPrimitiveTableFirstFreeIndex; @@ -1881,6 +1871,7 @@ _iss sqInt statShrinkMemory; _iss sqInt biasForGC; _iss sqInt edenBytes; _iss sqInt fullScreenFlag; +_iss usqLong gcStartUsecs; _iss usqInt lastHash; _iss sqInt lastMethodCacheProbeWrite; _iss sqInt newFinalization; @@ -1895,10 +1886,10 @@ _iss sqInt freeSpaceCheckOopToIgnore; _iss usqInt heapSizeAtPreviousGC; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss sqInt methodDictLinearSearchLimit; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statCompactionUsecs; _iss usqLong statForceInterruptCheck; _iss usqLong statFullGCUsecs; @@ -1919,7 +1910,6 @@ _iss sqInt extraFramesToMoveOnOverflow; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; _iss sqInt inFFIFlags; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss sqInt refCountToShrinkRT; _iss sqInt signalLowSpace; @@ -1933,7 +1923,6 @@ _iss sqInt classByteArrayCompactIndex; _iss usqInt exceptionPC; _iss sqInt gcSemaphoreIndex; _iss usqLong gcSweepEndUsecs; -_iss usqLong longRunningPrimitiveGCUsecs; _iss sqInt overflowLimit; _iss StackPage * overflowedPage; _iss sqInt statCompactPassCount; @@ -1951,6 +1940,9 @@ _iss usqInt suspendedCallbacks[MaxJumpBuf + 1 /* 33 */]; _iss usqInt suspendedMethods[MaxJumpBuf + 1 /* 33 */]; _iss jmp_buf jmpBuf[MaxJumpBuf + 1 /* 33 */]; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; _iss sqInt preferredPinningSegment; _iss sqInt statCoalesces; _iss usqLong statFGCDeltaUsecs; @@ -2627,7 +2619,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Open Smalltalk Cog[Spur] VM [CoInterpreterPrimitives VMMaker.oscog-eem.3024]"; +const char *interpreterVersion = "Open Smalltalk Cog[Spur] VM [CoInterpreterPrimitives VMMaker.oscog-eem.3031]"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */; int displayWidth; int displayDepth; @@ -15512,6 +15504,27 @@ ceStackOverflow(sqInt contextSwitchIfNotNil) error("should not be reached"); } + +/* A primitive has succeeded and the nextProfileTick has been reached (all + done in machine code). + Now take a sample. c.f. checkProfileTick: */ + + /* CoInterpreter>>#ceTakeProfileSample: */ +void +ceTakeProfileSample(CogMethod *aCogMethod) +{ DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt objOop; + sqInt objOop1; + + /* begin fetchPointer:ofObject: */ + objOop1 = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(SchedulerAssociation) << (shiftForWord()))))); + objOop = longAt((objOop1 + BaseHeaderSize) + (((sqInt)((usqInt)(ValueIndex) << (shiftForWord()))))); + GIV(profileProcess) = longAt((objOop + BaseHeaderSize) + (((sqInt)((usqInt)(ActiveProcessIndex) << (shiftForWord()))))); + GIV(profileMethod) = (aCogMethod->methodObject); + forceInterruptCheck(); + GIV(nextProfileTick) = 0; +} + /* CoInterpreter>>#ceTraceBlockActivation */ void ceTraceBlockActivation(void) @@ -17505,24 +17518,6 @@ void forceInterruptCheckFromHeartbeat(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; sqLowLevelMFence(); if (GIV(deferSmash)) { GIV(deferredSmash) = 1; @@ -23769,56 +23764,6 @@ primitiveFunctionPointerAddress(void) return ((usqInt)((&primitiveFunctionPointer))); } - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* CoInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; - int flushState; - sqInt sema; - char *sp; - - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (sema == GIV(nilObj)) { - flushState = GIV(longRunningPrimitiveCheckSemaphore) != null; - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - flushState = GIV(longRunningPrimitiveCheckSemaphore) == null; - if (!(((!(sema & (tagMask())))) - && (((longAt(sema)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(ClassSemaphore) << (shiftForWord())))))))))) { - return (GIV(primFailCode) = PrimErrBadArgument); - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(longRunningPrimitiveCheckSemaphore) == null)) - || (((stackValue(0)) == GIV(longRunningPrimitiveCheckSemaphore)) - && (isSemaphoreOop(sema)))); - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - if (flushState) { - ceInvokeInterpret(); - } - return 0; -} - /* CoInterpreterPrimitives>>#primitiveMethodPCData */ EXPORT(sqInt) primitiveMethodPCData(void) @@ -24131,14 +24076,9 @@ primitiveObjectAtPut(void) EXPORT(sqInt) primitiveProfileSemaphore(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; int flushState; sqInt sema; - char *sp; - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); if (sema == GIV(nilObj)) { flushState = GIV(profileSemaphore) != GIV(nilObj); @@ -24150,28 +24090,21 @@ primitiveProfileSemaphore(void) return (GIV(primFailCode) = PrimErrBadArgument); } } + GIV(profileSemaphore) = sema; /* If we've switched profiling on or off we must void machine code (and machine code pcs in contexts) since we will start or stop testing the profile clock in machine code primitive invocations, and so generate slightly different code from here on in. */ - GIV(profileSemaphore) = sema; - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(profileSemaphore) == (nilObject()))) - || (((stackValue(0)) == GIV(profileSemaphore)) - && (isSemaphoreOop(sema)))); - } GIV(profileProcess) = (GIV(profileMethod) = GIV(nilObj)); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; if (flushState) { - ceInvokeInterpret(); + flushExternalPrimitives(); + } + else { + /* begin methodReturnReceiver */ + assert(!((failed()))); + /* begin pop: */ + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; } return 0; } @@ -32567,26 +32500,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -35227,15 +35162,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -35253,15 +35183,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -35285,39 +35210,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((((integerPointer) & 7) == 1)) { - deltaTicks = (integerPointer >> 3); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((((deltaTicks) & 7) == 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 3)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -50669,14 +50573,6 @@ isSegmentBridge(sqInt objOop) return ((longAt(objOop)) & (classIndexMask())) == (segmentBridgePun()); } - /* SpurMemoryManager>>#isSemaphoreOop: */ -static sqInt NoDbgRegParms -isSemaphoreOop(sqInt anOop) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - return ((!(anOop & (tagMask())))) - && (((longAt(anOop)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(ClassSemaphore) << (shiftForWord())))))))); -} - /* Answer if the argument contains only indexable 16-bit half words (no oops). See comment in formatOf: @@ -52956,8 +52852,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) sqInt referent; sqInt referent1; sqInt referent2; - sqInt referent3; - sqInt referent4; sqInt sizeOfUnusedEden; StackPage *thePage; @@ -53096,38 +52990,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - if ((!((longAt(GIV(longRunningPrimitiveCheckMethod))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckMethod))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((GIV(longRunningPrimitiveCheckMethod) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent3 & (tagMask())))) - && ((!((longAt(referent3)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((referent3 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckMethod) = referent3; - } - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - if ((!((longAt(GIV(longRunningPrimitiveCheckSemaphore))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckSemaphore))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((GIV(longRunningPrimitiveCheckSemaphore) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent4 & (tagMask())))) - && ((!((longAt(referent4)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((referent4 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckSemaphore) = referent4; - } - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -61175,7 +61037,7 @@ prepareForSnapshot(void) sqInt limit; sqInt newEndOfMemory; sqInt next; - usqInt node; + sqInt node; SpurSegmentInfo *seg; sqInt smallChild; sqInt treeNode; @@ -62006,33 +61868,6 @@ checkAllAccessibleObjectsOkay(void) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -62123,9 +61958,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { /* begin signalLowSpace: */ GIV(signalLowSpace) = 0; @@ -67122,23 +66954,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i = 1; i <= GIV(jmpDepth); i += 1) { oop = GIV(suspendedCallbacks)[i]; @@ -71224,8 +71039,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -71254,18 +71069,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -74416,22 +74233,6 @@ validStackPageBaseFrames(void) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Return the highest priority process that is ready to run. To save time looking at many empty lists before finding a runnable process the VM maintains a variable holding the @@ -76942,74 +76743,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((addressCouldBeObj(lrpcm)) - && ((!(((longAt(lrpcm)) & (classIndexMask())) == (isFreeObjectClassIndexPun()))) - && (((((usqInt)((longAt(lrpcm)))) >> (formatShift())) & (formatMask())) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - assert(!(isForwarded(result))); - if ((assert(isNonImmediate(result)), - oopisGreaterThanOrEqualTo(result, GIV(oldSpaceStart)))) { - - /* most stores into young objects */ - if (((!(lrpcm & (tagMask())))) - && (oopisLessThan(lrpcm, GIV(newSpaceLimit)))) { - /* begin possibleRootStoreInto: */ - if (!(((((usqInt)((longAt(result)))) >> (rememberedBitShift())) & 1) != 0)) { - remember(result); - } - } - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 3) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 3) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -79480,15 +79213,13 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveGreaterOrEqualLargeIntegers\000\377\000", (void*)primitiveGreaterOrEqualLargeIntegers}, {(void*)_m, "primitiveGreaterThanLargeIntegers\000\377\000", (void*)primitiveGreaterThanLargeIntegers}, {(void*)_m, "primitiveHeartbeatFrequency\000\377\000", (void*)primitiveHeartbeatFrequency}, - {(void*)_m, "primitiveHighResClock\000\377\000", (void*)primitiveHighResClock}, + {(void*)_m, "primitiveHighResClock\000\377\001", (void*)primitiveHighResClock}, {(void*)_m, "primitiveImageFormatVersion\000\377\000", (void*)primitiveImageFormatVersion}, {(void*)_m, "primitiveInterruptChecksPerMSec\000\377\000", (void*)primitiveInterruptChecksPerMSec}, {(void*)_m, "primitiveIsBigEnder\000\377\000", (void*)primitiveIsBigEnder}, {(void*)_m, "primitiveIsWindowObscured\000\377\000", (void*)primitiveIsWindowObscured}, {(void*)_m, "primitiveLessOrEqualLargeIntegers\000\377\000", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers\000\377\000", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive\000\377\000", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore\000\000\000", (void*)primitiveLongRunningPrimitiveSemaphore}, {(void*)_m, "primitiveMethodPCData\000\000\000", (void*)primitiveMethodPCData}, {(void*)_m, "primitiveMillisecondClockMask\000\377\000", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveMinimumUnusedHeadroom\000\377\000", (void*)primitiveMinimumUnusedHeadroom}, @@ -79496,10 +79227,10 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveMultiplyLargeIntegers\000\000\000", (void*)primitiveMultiplyLargeIntegers}, {(void*)_m, "primitiveNotEqualLargeIntegers\000\377\000", (void*)primitiveNotEqualLargeIntegers}, {(void*)_m, "primitivePathToUsing\000\000\000", (void*)primitivePathToUsing}, - {(void*)_m, "primitiveProfilePrimitive\000\377\000", (void*)primitiveProfilePrimitive}, - {(void*)_m, "primitiveProfileSample\000\377\000", (void*)primitiveProfileSample}, + {(void*)_m, "primitiveProfilePrimitive\000\377\001", (void*)primitiveProfilePrimitive}, + {(void*)_m, "primitiveProfileSample\000\377\001", (void*)primitiveProfileSample}, {(void*)_m, "primitiveProfileSemaphore\000\000\000", (void*)primitiveProfileSemaphore}, - {(void*)_m, "primitiveProfileStart\000\000\000", (void*)primitiveProfileStart}, + {(void*)_m, "primitiveProfileStart\000\000\001", (void*)primitiveProfileStart}, {(void*)_m, "primitiveQuoLargeIntegers\000\000\000", (void*)primitiveQuoLargeIntegers}, {(void*)_m, "primitiveRemLargeIntegers\000\000\000", (void*)primitiveRemLargeIntegers}, {(void*)_m, "primitiveScreenDepth\000\377\000", (void*)primitiveScreenDepth}, diff --git a/spur64src/vm/gcc3x-cointerpmt.c b/spur64src/vm/gcc3x-cointerpmt.c index 4b14397a95..268283d3a1 100644 --- a/spur64src/vm/gcc3x-cointerpmt.c +++ b/spur64src/vm/gcc3x-cointerpmt.c @@ -2,11 +2,11 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - CoInterpreterMT VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CoInterpreterMT VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "CoInterpreterMT VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 " __DATE__ ; +static char __buildInfo[] = "CoInterpreterMT VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -546,6 +546,7 @@ extern void ceSendaboveClassBindingtonumArgs(sqInt selector, sqInt methodClassBi extern sqInt ceSendabovetonumArgs(sqInt selector, sqInt methodClass, sqInt rcvr, sqInt numArgs); extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethod); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); @@ -745,7 +746,6 @@ static void primitiveExitCriticalSection(void); static void primitiveFlushCacheByMethod(void); static void primitiveFlushCacheBySelector(void); extern usqInt primitiveFunctionPointerAddress(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); EXPORT(sqInt) primitiveMethodPCData(void); static void primitiveMethodXray(void); EXPORT(void) primitiveMinimumUnusedHeadroom(void); @@ -1289,7 +1289,6 @@ static sqInt NoDbgRegParms isPureBitsFormat(sqInt format); extern sqInt isReallyYoung(sqInt oop); static sqInt NoDbgRegParms isRemembered(sqInt objOop); static sqInt NoDbgRegParms isSegmentBridge(sqInt objOop); -static sqInt NoDbgRegParms isSemaphoreOop(sqInt anOop); extern sqInt isShorts(sqInt oop); extern sqInt isUnambiguouslyForwarder(sqInt objOop); extern sqInt isUnmarked(sqInt objOop); @@ -1515,7 +1514,6 @@ EXPORT(sqInt) callbackLeave(sqInt cbID); extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHeader); extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); static sqInt checkInterpreterIntegrity(void); @@ -1791,7 +1789,6 @@ static sqInt NoDbgRegParms updateDisplayLeftTopRightBottom(sqInt l, sqInt t, sqI static sqInt NoDbgRegParms validBCPCinMethod(sqInt thePC, usqInt aMethod); static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, char *fp); static sqInt validStackPageBaseFrames(void); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt NeverInline writeImageFileIO(void); static usqInt NoDbgRegParms cloneContext(sqInt aContext); static sqInt NoDbgRegParms fieldOrSenderFPofContext(sqInt index, sqInt contextObj); @@ -1813,7 +1810,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1854,8 +1850,8 @@ _iss sqInt argumentCount; _iss sqLong nextProfileTick; _iss sqInt primTraceLog[256]; _iss StackPage * stackPage; -_iss sqInt nilObj; _iss usqInt method; +_iss sqInt nilObj; _iss sqInt bytecodeSetSelector; _iss usqInt oldSpaceStart; _iss usqInt endOfMemory; @@ -1889,17 +1885,16 @@ _iss usqInt lastMobileObject; _iss sqInt tempOop; _iss sqInt numClassTablePages; _iss sqInt lkupClass; +_iss sqInt profileProcess; _iss sqInt futureSurvivorStart; _iss sqInt numThreads; -_iss sqInt profileProcess; -_iss sqInt profileSemaphore; _iss CogVMThread * disowningVMThread; _iss sqInt mournQueue; _iss sqInt numRememberedEphemerons; +_iss sqInt profileMethod; +_iss sqInt profileSemaphore; _iss sqInt jmpDepth; _iss sqInt mobileStart; -_iss sqInt profileMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; _iss CogVMThread ** threads; _iss sqInt growHeadroom; _iss sqInt processHasThreadId; @@ -1909,7 +1904,6 @@ _iss sqInt lastUncoggableInterpretedBlockMethod; _iss char * objStackInvalidBecause; _iss sqInt sweepIndex; _iss sqInt ephemeronList; -_iss sqInt longRunningPrimitiveCheckMethod; _iss sqInt tenureCriterion; _iss usqInt totalHeapSizeIncludingBridges; _iss sqInt becomeEffectsFlags; @@ -1935,19 +1929,15 @@ _iss sqInt metaclassNumSlots; _iss usqLong nextWakeupUsecs; _iss sqInt preemptionYields; _iss sqInt relinquishing; -_iss usqLong statGCEndUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; _iss sqInt shrinkThreshold; -_iss usqLong statCheckForEvents; _iss sqInt statTenures; _iss sqInt weakList; _iss usqInt cogCodeSize; -_iss usqLong gcStartUsecs; _iss sqInt marking; _iss sqInt noThreadingOfGUIThread; _iss sqLong oldSpaceUsePriorToScavenge; _iss sqInt rememberedSetLimit; +_iss usqLong statGCEndUsecs; _iss sqInt statSurvivorCount; _iss sqInt thisClassIndex; _iss sqInt checkThreadActivation; @@ -1969,6 +1959,7 @@ _iss sqInt biasForGC; _iss sqInt edenBytes; _iss sqInt foreignCallbackPriority; _iss sqInt fullScreenFlag; +_iss usqLong gcStartUsecs; _iss usqInt lastHash; _iss sqInt lastMethodCacheProbeWrite; _iss sqInt newFinalization; @@ -1984,11 +1975,11 @@ _iss sqInt freeSpaceCheckOopToIgnore; _iss usqInt heapSizeAtPreviousGC; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss sqInt memoryIsScarce; _iss sqInt methodDictLinearSearchLimit; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statCompactionUsecs; _iss usqLong statForceInterruptCheck; _iss usqLong statFullGCUsecs; @@ -2007,7 +1998,6 @@ _iss sqInt deferredSmash; _iss sqInt extraFramesToMoveOnOverflow; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss sqInt refCountToShrinkRT; _iss sqInt signalLowSpace; @@ -2021,7 +2011,6 @@ _iss sqInt classByteArrayCompactIndex; _iss usqInt exceptionPC; _iss sqInt gcSemaphoreIndex; _iss usqLong gcSweepEndUsecs; -_iss usqLong longRunningPrimitiveGCUsecs; _iss sqInt overflowLimit; _iss StackPage * overflowedPage; _iss sqInt statCompactPassCount; @@ -2040,6 +2029,9 @@ _iss usqInt suspendedCallbacks[MaxJumpBuf + 1 /* 33 */]; _iss usqInt suspendedMethods[MaxJumpBuf + 1 /* 33 */]; _iss jmp_buf jmpBuf[MaxJumpBuf + 1 /* 33 */]; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; _iss sqInt preferredPinningSegment; _iss sqInt statCoalesces; _iss usqLong statFGCDeltaUsecs; @@ -2720,7 +2712,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Open Smalltalk Cog MT VM [CoInterpreterMT VMMaker.oscog-eem.3024]"; +const char *interpreterVersion = "Open Smalltalk Cog MT VM [CoInterpreterMT VMMaker.oscog-eem.3031]"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */; int displayWidth; int displayDepth; @@ -15939,6 +15931,27 @@ ceStackOverflow(sqInt contextSwitchIfNotNil) error("should not be reached"); } + +/* A primitive has succeeded and the nextProfileTick has been reached (all + done in machine code). + Now take a sample. c.f. checkProfileTick: */ + + /* CoInterpreter>>#ceTakeProfileSample: */ +void +ceTakeProfileSample(CogMethod *aCogMethod) +{ DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt objOop; + sqInt objOop1; + + /* begin fetchPointer:ofObject: */ + objOop1 = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(SchedulerAssociation) << (shiftForWord()))))); + objOop = longAt((objOop1 + BaseHeaderSize) + (((sqInt)((usqInt)(ValueIndex) << (shiftForWord()))))); + GIV(profileProcess) = longAt((objOop + BaseHeaderSize) + (((sqInt)((usqInt)(ActiveProcessIndex) << (shiftForWord()))))); + GIV(profileMethod) = (aCogMethod->methodObject); + forceInterruptCheck(); + GIV(nextProfileTick) = 0; +} + /* CoInterpreter>>#ceTraceBlockActivation */ void ceTraceBlockActivation(void) @@ -23327,9 +23340,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { GIV(signalLowSpace) = 0; /* begin fetchPointer:ofObject: */ @@ -23651,24 +23661,6 @@ void forceInterruptCheckFromHeartbeat(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; sqLowLevelMFence(); if (GIV(deferSmash)) { GIV(deferredSmash) = 1; @@ -23861,23 +23853,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i1 = 1; i1 <= GIV(jmpDepth); i1 += 1) { oop = GIV(suspendedCallbacks)[i1]; @@ -26234,56 +26209,6 @@ primitiveFunctionPointerAddress(void) return ((usqInt)((&primitiveFunctionPointer))); } - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* CoInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; - int flushState; - sqInt sema; - char *sp; - - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (sema == GIV(nilObj)) { - flushState = GIV(longRunningPrimitiveCheckSemaphore) != null; - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - flushState = GIV(longRunningPrimitiveCheckSemaphore) == null; - if (!(((!(sema & (tagMask())))) - && (((longAt(sema)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(ClassSemaphore) << (shiftForWord())))))))))) { - return (GIV(primFailCode) = PrimErrBadArgument); - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(longRunningPrimitiveCheckSemaphore) == null)) - || (((stackValue(0)) == GIV(longRunningPrimitiveCheckSemaphore)) - && (isSemaphoreOop(sema)))); - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - if (flushState) { - ceInvokeInterpret(); - } - return 0; -} - /* CoInterpreterPrimitives>>#primitiveMethodPCData */ EXPORT(sqInt) primitiveMethodPCData(void) @@ -26596,14 +26521,9 @@ primitiveObjectAtPut(void) EXPORT(sqInt) primitiveProfileSemaphore(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; int flushState; sqInt sema; - char *sp; - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); if (sema == GIV(nilObj)) { flushState = GIV(profileSemaphore) != GIV(nilObj); @@ -26615,28 +26535,21 @@ primitiveProfileSemaphore(void) return (GIV(primFailCode) = PrimErrBadArgument); } } + GIV(profileSemaphore) = sema; /* If we've switched profiling on or off we must void machine code (and machine code pcs in contexts) since we will start or stop testing the profile clock in machine code primitive invocations, and so generate slightly different code from here on in. */ - GIV(profileSemaphore) = sema; - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(profileSemaphore) == (nilObject()))) - || (((stackValue(0)) == GIV(profileSemaphore)) - && (isSemaphoreOop(sema)))); - } GIV(profileProcess) = (GIV(profileMethod) = GIV(nilObj)); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; if (flushState) { - ceInvokeInterpret(); + flushExternalPrimitives(); + } + else { + /* begin methodReturnReceiver */ + assert(!((failed()))); + /* begin pop: */ + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; } return 0; } @@ -35032,26 +34945,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -37692,15 +37607,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -37718,15 +37628,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -37750,39 +37655,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((((integerPointer) & 7) == 1)) { - deltaTicks = (integerPointer >> 3); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((((deltaTicks) & 7) == 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 3)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -53105,14 +52989,6 @@ isSegmentBridge(sqInt objOop) return ((longAt(objOop)) & (classIndexMask())) == (segmentBridgePun()); } - /* SpurMemoryManager>>#isSemaphoreOop: */ -static sqInt NoDbgRegParms -isSemaphoreOop(sqInt anOop) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - return ((!(anOop & (tagMask())))) - && (((longAt(anOop)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(ClassSemaphore) << (shiftForWord())))))))); -} - /* Answer if the argument contains only indexable 16-bit half words (no oops). See comment in formatOf: @@ -55394,8 +55270,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) sqInt referent; sqInt referent1; sqInt referent2; - sqInt referent3; - sqInt referent4; sqInt sizeOfUnusedEden; StackPage *thePage; CogVMThread *vmThread; @@ -55535,38 +55409,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - if ((!((longAt(GIV(longRunningPrimitiveCheckMethod))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckMethod))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((GIV(longRunningPrimitiveCheckMethod) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent3 & (tagMask())))) - && ((!((longAt(referent3)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((referent3 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckMethod) = referent3; - } - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - if ((!((longAt(GIV(longRunningPrimitiveCheckSemaphore))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckSemaphore))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((GIV(longRunningPrimitiveCheckSemaphore) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent4 & (tagMask())))) - && ((!((longAt(referent4)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((referent4 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckSemaphore) = referent4; - } - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -63629,7 +63471,7 @@ prepareForSnapshot(void) sqInt limit; sqInt newEndOfMemory; sqInt next; - sqInt node; + usqInt node; SpurSegmentInfo *seg; sqInt smallChild; sqInt treeNode; @@ -64460,33 +64302,6 @@ checkAllAccessibleObjectsOkay(void) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -73353,8 +73168,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -73383,18 +73198,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -76545,22 +76362,6 @@ validStackPageBaseFrames(void) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Write the image header and heap contents to imageFile for snapshot. c.f. writeImageFileIOSimulation. The game below is to maintain 64-bit alignment for all putLong:toFile: occurrences. */ @@ -78988,74 +78789,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((addressCouldBeObj(lrpcm)) - && ((!(((longAt(lrpcm)) & (classIndexMask())) == (isFreeObjectClassIndexPun()))) - && (((((usqInt)((longAt(lrpcm)))) >> (formatShift())) & (formatMask())) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - assert(!(isForwarded(result))); - if ((assert(isNonImmediate(result)), - oopisGreaterThanOrEqualTo(result, GIV(oldSpaceStart)))) { - - /* most stores into young objects */ - if (((!(lrpcm & (tagMask())))) - && (oopisLessThan(lrpcm, GIV(newSpaceLimit)))) { - /* begin possibleRootStoreInto: */ - if (!(((((usqInt)((longAt(result)))) >> (rememberedBitShift())) & 1) != 0)) { - remember(result); - } - } - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 3) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 3) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -81520,15 +81253,13 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveGreaterOrEqualLargeIntegers\000\377\000", (void*)primitiveGreaterOrEqualLargeIntegers}, {(void*)_m, "primitiveGreaterThanLargeIntegers\000\377\000", (void*)primitiveGreaterThanLargeIntegers}, {(void*)_m, "primitiveHeartbeatFrequency\000\377\000", (void*)primitiveHeartbeatFrequency}, - {(void*)_m, "primitiveHighResClock\000\377\000", (void*)primitiveHighResClock}, + {(void*)_m, "primitiveHighResClock\000\377\001", (void*)primitiveHighResClock}, {(void*)_m, "primitiveImageFormatVersion\000\377\000", (void*)primitiveImageFormatVersion}, {(void*)_m, "primitiveInterruptChecksPerMSec\000\377\000", (void*)primitiveInterruptChecksPerMSec}, {(void*)_m, "primitiveIsBigEnder\000\377\000", (void*)primitiveIsBigEnder}, {(void*)_m, "primitiveIsWindowObscured\000\377\000", (void*)primitiveIsWindowObscured}, {(void*)_m, "primitiveLessOrEqualLargeIntegers\000\377\000", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers\000\377\000", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive\000\377\000", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore\000\000\000", (void*)primitiveLongRunningPrimitiveSemaphore}, {(void*)_m, "primitiveMethodPCData\000\000\000", (void*)primitiveMethodPCData}, {(void*)_m, "primitiveMillisecondClockMask\000\377\000", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveMinimumUnusedHeadroom\000\377\000", (void*)primitiveMinimumUnusedHeadroom}, @@ -81538,10 +81269,10 @@ void* vm_exports[][3] = { {(void*)_m, "primitivePathToUsing\000\000\000", (void*)primitivePathToUsing}, {(void*)_m, "primitiveProcessBindToThreadId\000\000\000", (void*)primitiveProcessBindToThreadId}, {(void*)_m, "primitiveProcessBoundThreadId\000\000\000", (void*)primitiveProcessBoundThreadId}, - {(void*)_m, "primitiveProfilePrimitive\000\377\000", (void*)primitiveProfilePrimitive}, - {(void*)_m, "primitiveProfileSample\000\377\000", (void*)primitiveProfileSample}, + {(void*)_m, "primitiveProfilePrimitive\000\377\001", (void*)primitiveProfilePrimitive}, + {(void*)_m, "primitiveProfileSample\000\377\001", (void*)primitiveProfileSample}, {(void*)_m, "primitiveProfileSemaphore\000\000\000", (void*)primitiveProfileSemaphore}, - {(void*)_m, "primitiveProfileStart\000\000\000", (void*)primitiveProfileStart}, + {(void*)_m, "primitiveProfileStart\000\000\001", (void*)primitiveProfileStart}, {(void*)_m, "primitiveQuoLargeIntegers\000\000\000", (void*)primitiveQuoLargeIntegers}, {(void*)_m, "primitiveRemLargeIntegers\000\000\000", (void*)primitiveRemLargeIntegers}, {(void*)_m, "primitiveScreenDepth\000\377\000", (void*)primitiveScreenDepth}, diff --git a/spurlowcode64src/vm/cogit.h b/spurlowcode64src/vm/cogit.h index 1959c1e7fe..a22e8c6922 100644 --- a/spurlowcode64src/vm/cogit.h +++ b/spurlowcode64src/vm/cogit.h @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + CCodeGenerator VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ diff --git a/spurlowcode64src/vm/cogitARMv8.c b/spurlowcode64src/vm/cogitARMv8.c index 298dbafa08..1bcae80582 100644 --- a/spurlowcode64src/vm/cogitARMv8.c +++ b/spurlowcode64src/vm/cogitARMv8.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + CCodeGenerator VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + StackToRegisterMappingCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 " __DATE__ ; +static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__cogitBuildInfo = __buildInfo; @@ -73,19 +73,19 @@ char *__cogitBuildInfo = __buildInfo; #define CArg1Reg 1 #define CArg2Reg 2 #define CArg3Reg 3 -#define CASAL 174 +#define CASAL 176 #define Call 6 #define CallerSavedRegisterMask 0x1F0 #define CallFull 7 #define CallR 8 -#define CBNZ 175 -#define CBZ 176 +#define CBNZ 177 +#define CBZ 178 #define CC 3 -#define CCMPNE 177 +#define CCMPNE 179 #if !defined(CheckRememberedInTrampoline) /* Allow this to be overridden on the compiler command line */ # define CheckRememberedInTrampoline 0 #endif -#define CLREX 179 +#define CLREX 181 #define ClassArray 7 #define ClassArrayCompactIndex 51 #define ClassBlockClosureCompactIndex 37 @@ -125,8 +125,8 @@ char *__cogitBuildInfo = __buildInfo; #define ConvertRsR 149 #define ConvertRsRd 147 #define CS 2 -#define CSET 178 -#define DC 167 +#define CSET 180 +#define DC 169 #define DC_CIVAC 14 #define DC_CVAC 16 #define DC_CVAU 19 @@ -134,7 +134,7 @@ char *__cogitBuildInfo = __buildInfo; #define DisplacementMask 0x1F #define DisplacementX2N 0 #define DivRdRd 135 -#define DivRRR 161 +#define DivRRR 163 #define DivRsRs 142 #define DPFPReg0 0 #define DPFPReg1 1 @@ -144,7 +144,7 @@ char *__cogitBuildInfo = __buildInfo; #define DPFPReg5 5 #define DPFPReg6 6 #define DPFPReg7 7 -#define DSB 170 +#define DSB 172 #define DSB_ALL 3 #define DSB_ISH 2 #define EncounteredUnknownBytecode -6 @@ -179,7 +179,7 @@ char *__cogitBuildInfo = __buildInfo; #define HashMultiplyMask 0xFFFFFFF #define HeaderIndex 0 #define HI 8 -#define IC 168 +#define IC 170 #define IC_IALLU 0 #define IC_IALLUIS 1 #define IC_IVAU 2 @@ -191,7 +191,7 @@ char *__cogitBuildInfo = __buildInfo; #define InstructionPointerIndex 1 #define InsufficientCodeSpace -2 #define InVanillaBlock 1 -#define ISB 171 +#define ISB 173 #define IsAbsPCReference 3 #define IsAnnotationExtension 1 #define IsDirectedSuperBindingSend 10 @@ -239,7 +239,7 @@ char *__cogitBuildInfo = __buildInfo; #define Label 1 #define LargeContextSlots 62 #define LastJump 42 -#define LDAXR 180 +#define LDAXR 182 #define LE 13 #define LinkReg 30 #define Literal 2 @@ -278,7 +278,7 @@ char *__cogitBuildInfo = __buildInfo; #define MI 4 #define MoveAbR 48 #define MoveAwR 44 -#define MoveAwRR 163 +#define MoveAwRR 165 #define MoveC32R 71 #define MoveCqR 69 #define MoveCwR 70 @@ -289,6 +289,8 @@ char *__cogitBuildInfo = __buildInfo; #define MoveM8rR 54 #define MoveMbrR 65 #define MoveMwrR 50 +#define MovePerfCnt64RL 159 +#define MovePerfCnt64RRL 158 #define MoveRAb 49 #define MoveRAw 46 #define MoveRdM64r 76 @@ -300,7 +302,7 @@ char *__cogitBuildInfo = __buildInfo; #define MoveRMbr 66 #define MoveRMwr 51 #define MoveRR 43 -#define MoveRRAw 164 +#define MoveRRAw 166 #define MoveRRd 72 #define MoveRsM32r 79 #define MoveRsRs 77 @@ -312,18 +314,18 @@ char *__cogitBuildInfo = __buildInfo; #define MoveX32rRR 63 #define MoveXbrRR 67 #define MoveXwrRR 52 -#define MRS_CTR_EL0 172 -#define MRS_ID_AA64ISAR0_EL1 173 -#define MSubRRR 162 +#define MRS_CTR_EL0 174 +#define MRS_ID_AA64ISAR0_EL1 175 +#define MSubRRR 164 #define MULTIPLEBYTECODESETS 1 -#define MulOverflowRRR 159 +#define MulOverflowRRR 161 #define MulRdRd 134 -#define MulRRR 158 +#define MulRRR 160 #define MulRsRs 141 #define NativePopR 84 -#define NativePopRR 166 +#define NativePopRR 168 #define NativePushR 85 -#define NativePushRR 165 +#define NativePushRR 167 #define NativeRetN 86 #define NativeSPReg 31 #define NE 1 @@ -407,8 +409,8 @@ char *__cogitBuildInfo = __buildInfo; #define SSSpillFloat64 12 #define SSSpillInt64 10 #define SSSpillNative 9 -#define STLR 182 -#define STLXR 181 +#define STLR 184 +#define STLXR 183 #define StackPointerIndex 2 #define Stop 11 #define SubbRR 121 @@ -575,7 +577,7 @@ static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self static void NoDbgRegParms cloneLiteralFrom(AbstractInstruction * self_in_cloneLiteralFrom, AbstractInstruction *existingLiteral); static sqInt NoDbgRegParms concretizeAt(AbstractInstruction * self_in_concretizeAt, sqInt actualAddress); static sqInt NoDbgRegParms genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer); -static sqInt NoDbgRegParms genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg); +static sqInt NoDbgRegParms genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg); static AbstractInstruction * NoDbgRegParms genSwapRRScratch(AbstractInstruction * self_in_genSwapRRScratch, sqInt regA, sqInt regB, sqInt regTmp); static void NoDbgRegParms genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister); static void NoDbgRegParms genWriteCSecondResultIntoReg(AbstractInstruction * self_in_genWriteCSecondResultIntoReg, sqInt abstractRegister); @@ -607,6 +609,7 @@ static sqInt NoDbgRegParms concretizeLoadEffectiveAddressMwrR(AbstractInstructio static sqInt NoDbgRegParms concretizeLogicalOpCqRDest(AbstractInstruction * self_in_concretizeLogicalOpCqRDest, sqInt op, sqInt destReg); static sqInt NoDbgRegParms concretizeMoveCqR(AbstractInstruction * self_in_concretizeMoveCqR); static sqInt NoDbgRegParms concretizeMoveMSrR(AbstractInstruction * self_in_concretizeMoveMSrR, sqInt unitSizeLog2MinusOne); +static sqInt NoDbgRegParms concretizeMovePerfCnt64RL(AbstractInstruction * self_in_concretizeMovePerfCnt64RL); static sqInt NoDbgRegParms concretizeMoveRMSr(AbstractInstruction * self_in_concretizeMoveRMSr, sqInt unitSizeLog2MinusOne); static sqInt NoDbgRegParms concretizeMoveRXSrR(AbstractInstruction * self_in_concretizeMoveRXSrR, sqInt unitSizeLog2MinusOne); static sqInt NoDbgRegParms concretizeMoveXSrRR(AbstractInstruction * self_in_concretizeMoveXSrRR, sqInt unitSizeLog2MinusOne); @@ -886,6 +889,8 @@ static BytecodeDescriptor * loadBytesAndGetDescriptor(void); static void NoDbgRegParms loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc); static AbstractInstruction * NoDbgRegParms gMoveAwR(sqInt address, sqInt reg); static AbstractInstruction * NoDbgRegParms gMoveCwR(sqInt wordConstant, sqInt reg); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters); static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg); static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC); @@ -933,6 +938,7 @@ static void NoDbgRegParms recordGeneratedRunTimeaddress(char *aString, sqInt add extern sqInt recordPrimTraceFunc(void); static void recordRunTimeObjectReferences(void); static sqInt NoDbgRegParms registerMaskFor(sqInt reg); +static sqInt NoDbgRegParms registerMaskForand(sqInt reg1, sqInt reg2); static void NoDbgRegParms relocateCallsAndSelfReferencesInMethod(CogMethod *cogMethod); static void NoDbgRegParms relocateCallsInClosedPIC(CogMethod *cPIC); static sqInt NoDbgRegParms relocateIfCallOrMethodReferencemcpcdelta(sqInt annotation, char *mcpc, CogMethod *refDeltaArg); @@ -1335,6 +1341,7 @@ static sqInt genStoreAndPopReceiverVariableBytecode(void); static sqInt genStoreAndPopRemoteTempLongBytecode(void); static sqInt genStoreAndPopTemporaryVariableBytecode(void); static sqInt genStoreRemoteTempLongBytecode(void); +static void genTakeProfileSample(void); static sqInt genUnconditionalTrapBytecode(void); static void NoDbgRegParms loadNativeArgumentAddressto(sqInt baseOffset, sqInt reg); static void NoDbgRegParms loadNativeFramePointerInto(sqInt reg); @@ -2943,28 +2950,28 @@ addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *an static sqInt NoDbgRegParms availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << DPFPReg0)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg0))) != 0))) { return DPFPReg0; } - if (!(((liveRegsMask & (1U << DPFPReg1)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg1))) != 0))) { return DPFPReg1; } - if (!(((liveRegsMask & (1U << DPFPReg2)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg2))) != 0))) { return DPFPReg2; } - if (!(((liveRegsMask & (1U << DPFPReg3)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg3))) != 0))) { return DPFPReg3; } - if (!(((liveRegsMask & (1U << DPFPReg4)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg4))) != 0))) { return DPFPReg4; } - if (!(((liveRegsMask & (1U << DPFPReg5)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg5))) != 0))) { return DPFPReg5; } - if (!(((liveRegsMask & (1U << DPFPReg6)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg6))) != 0))) { return DPFPReg6; } - if (!(((liveRegsMask & (1U << DPFPReg7)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg7))) != 0))) { return DPFPReg7; } return NoReg; @@ -2979,19 +2986,19 @@ availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegi static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << Arg1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg1Reg))) != 0))) { return Arg1Reg; } - if (!(((liveRegsMask & (1U << Arg0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg0Reg))) != 0))) { return Arg0Reg; } - if (!(((liveRegsMask & (1U << SendNumArgsReg)) != 0))) { + if (!(((liveRegsMask & ((1U << SendNumArgsReg))) != 0))) { return SendNumArgsReg; } - if (!(((liveRegsMask & (1U << ClassReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ClassReg))) != 0))) { return ClassReg; } - if (!(((liveRegsMask & (1U << ReceiverResultReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ReceiverResultReg))) != 0))) { return ReceiverResultReg; } return NoReg; @@ -3053,11 +3060,11 @@ genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer) used immediately afterwards. */ - /* CogAbstractInstruction>>#genLoadStackPointersForFastPrimCall: */ + /* CogAbstractInstruction>>#genLoadStackPointersForPrimCall: */ static sqInt NoDbgRegParms -genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg) +genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg) { - genLoadStackPointers(self_in_genLoadStackPointersForFastPrimCall); + genLoadStackPointers(self_in_genLoadStackPointersForPrimCall); return 0; } @@ -4094,6 +4101,18 @@ concretizeMoveMSrR(AbstractInstruction * self_in_concretizeMoveMSrR, sqInt unitS } +/* D13.8.26 CNTVCT_EL0, Counter-timer Virtual Count register p D13-3774 */ +/* MRS , CNTVCT_EL0 op0:0b11 op1:0b011 CRn:0b1110 CRm:0b0000 op2:0b010 */ + + /* CogARMv8Compiler>>#concretizeMovePerfCnt64RL */ +static sqInt NoDbgRegParms +concretizeMovePerfCnt64RL(AbstractInstruction * self_in_concretizeMovePerfCnt64RL) +{ + ((self_in_concretizeMovePerfCnt64RL->machineCode))[0] = ((3577471040U) + (((self_in_concretizeMovePerfCnt64RL->operands))[0])); + return 4; +} + + /* Mwr/M32r/M16r/Mbr - memory unit whose address is a constant M away from an address in a register */ @@ -5787,6 +5806,9 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) : 0))) + (((sqInt)((usqInt)((offset9 & (0x1FFFFF))) << 3)))) + reg9); return 4; + case MovePerfCnt64RL: + return concretizeMovePerfCnt64RL(self_in_dispatchConcretize); + default: error("Case not found and no otherwise clause"); } @@ -6629,7 +6651,7 @@ genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask) assert(!((registerisInMask(RISCTempReg, regMask)))); nRegs = 0; for (reg = R1; reg <= R17; reg += 1) { - if (((regMask & (1ULL << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0)) { nRegs += 1; } } @@ -6637,7 +6659,7 @@ genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask) ? NoReg : RISCTempReg); for (reg = R1; reg <= R17; reg += 1) { - if (((regMask & (1ULL << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0)) { if (pair == NoReg) { pair = reg; } @@ -6672,7 +6694,7 @@ genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask) assert(!((registerisInMask(RISCTempReg, regMask)))); pair = NoReg; for (reg = R17; reg >= R0; reg += -1) { - if (((regMask & (1ULL << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0)) { if (pair == NoReg) { pair = reg; } @@ -10450,7 +10472,7 @@ compileCallFornumArgsargargargargfloatResultRegregsToSave(void *aRoutine, sqInt regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1ULL << resultRegOrNone)) - (1ULL << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ } @@ -10481,7 +10503,7 @@ compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numAr regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1ULL << resultRegOrNone)) - (1ULL << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ } @@ -10510,7 +10532,7 @@ compileCallFornumArgsargargargargresultRegresultRegregsToSave(void *aRoutine, sq regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1ULL << resultRegOrNone)) - (1ULL << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ } @@ -10540,7 +10562,7 @@ compileCallFornumArgsfloatArgfloatArgfloatArgfloatArgresultRegregsToSave(void *a regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1ULL << resultRegOrNone)) - (1ULL << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ } @@ -12247,7 +12269,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) startAddress = methodZoneBase; callerSavedReg = 0; pushedVarBaseReg = 0; - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { /* VarBaseReg is not caller-saved; must save and restore it, either by using an available caller-saved reg or push/pop. */ @@ -12297,7 +12319,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) operandTwo2 = cStackPointerAddress(); checkLiteralforInstruction(operandTwo2, genoperandoperand(MoveRAw, NativeSPReg, operandTwo2)); } - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { if (pushedVarBaseReg) { gNativePopR(VarBaseReg); } @@ -14068,6 +14090,22 @@ gMoveCwR(sqInt wordConstant, sqInt reg) return checkLiteralforInstruction(wordConstant, genoperandoperand(MoveCwR, wordConstant, reg)); } + /* Cogit>>#MovePerfCnt64R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters) +{ + assert(BytesPerWord == 8); + return genoperandoperand(MovePerfCnt64RL, destReg, liveRegisters); +} + + /* Cogit>>#MovePerfCnt64R:R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters) +{ + assert(BytesPerWord == 4); + return genoperandoperandoperand(MovePerfCnt64RRL, destRegLo, destRegHi, liveRegisters); +} + /* Answer the address of the null byte at the end of the method map. */ @@ -15736,11 +15774,21 @@ recordRunTimeObjectReferences(void) } } + +/* N.B. (self registerMaskFor: NoReg) = 0 */ + /* Cogit>>#registerMaskFor: */ static sqInt NoDbgRegParms registerMaskFor(sqInt reg) { - return 1ULL << reg; + return ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); +} + + /* Cogit>>#registerMaskFor:and: */ +static sqInt NoDbgRegParms +registerMaskForand(sqInt reg1, sqInt reg2) +{ + return (1ULL << reg1) | (1ULL << reg2); } /* Cogit>>#relocateCallsAndSelfReferencesInMethod: */ @@ -24078,7 +24126,7 @@ generateObjectRepresentationTrampolines(void) } # endif // IMMUTABILITY ceNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceNewHash", 1, ReceiverResultReg, null, null, null, /* begin emptyRegisterMask */ 0, 1, ReceiverResultReg, 0); - ceInlineNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceInlineNewHash", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, ReceiverResultReg, 0); + ceInlineNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceInlineNewHash", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))), 1, ReceiverResultReg, 0); /* begin genStoreCheckTrampoline */ if (CheckRememberedInTrampoline) { zeroOpcodeIndex(); @@ -24089,7 +24137,7 @@ generateObjectRepresentationTrampolines(void) genoperand(RetN, 0); jmpTarget(jumpSC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); } - ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))), 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), CheckRememberedInTrampoline); ceStoreCheckContextReceiverTrampoline = genStoreCheckContextReceiverTrampoline(); @@ -26780,7 +26828,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jumpRC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg)); jmpTarget(jumpImmutable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); @@ -26796,7 +26844,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* Store check */ jumpImmutable1 = genJumpImmutablescratchReg(ReceiverResultReg, SendNumArgsReg); - compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), 0 /* emptyRegisterMask */); genLoadStackPointers(backEnd()); @@ -27398,7 +27446,7 @@ registerMask(SimStackEntry * self_in_registerMask) || (((self_in_registerMask->type)) == SSRegister) ? (/* begin registerMaskFor: */ (reg = (self_in_registerMask->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : 0); } @@ -27411,7 +27459,7 @@ registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone) return (((self_in_registerMaskOrNone->type)) == SSRegister ? (/* begin registerMaskFor: */ (reg = (self_in_registerMaskOrNone->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : 0); } @@ -27657,7 +27705,7 @@ nativeFloatRegisterMask(CogSimStackNativeEntry * self_in_nativeFloatRegisterMask || (((self_in_nativeFloatRegisterMask->type)) == SSRegisterDoubleFloat) ? (/* begin registerMaskFor: */ (reg = (self_in_nativeFloatRegisterMask->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : 0); } @@ -27866,9 +27914,9 @@ nativeRegisterMask(CogSimStackNativeEntry * self_in_nativeRegisterMask) || (((self_in_nativeRegisterMask->type)) == SSRegisterDoubleFloat) ? (/* begin registerMaskFor: */ (reg = (self_in_nativeRegisterMask->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : (((self_in_nativeRegisterMask->type)) == SSRegisterPair - ? (1ULL << ((self_in_nativeRegisterMask->registerr))) | (1ULL << ((self_in_nativeRegisterMask->registerSecond))) + ? (((((self_in_nativeRegisterMask->registerr)) < 0) ? (((usqInt)(1)) >> (-((self_in_nativeRegisterMask->registerr)))) : (1ULL << ((self_in_nativeRegisterMask->registerr))))) | (((((self_in_nativeRegisterMask->registerSecond)) < 0) ? (((usqInt)(1)) >> (-((self_in_nativeRegisterMask->registerSecond)))) : (1ULL << ((self_in_nativeRegisterMask->registerSecond))))) : 0)); } @@ -28383,42 +28431,32 @@ compileInterpreterPrimitive(void) static sqInt NoDbgRegParms compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) { + sqInt address; + sqInt address1; sqInt address10; - sqInt address11; - sqInt address12; - sqInt address13; sqInt address2; - sqInt address3; sqInt address4; + sqInt address6; sqInt address7; sqInt address8; sqInt address9; AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; AbstractInstruction *anInstruction4; AbstractInstruction *anInstruction5; AbstractInstruction *anInstruction6; AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction * continuePostSampleNonPrim; - AbstractInstruction * continuePostSamplePrim; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; - AbstractInstruction * jmpSampleNonPrim; - AbstractInstruction * jmpSamplePrim; + AbstractInstruction * jumpToTakeSample; + sqInt liveRegisters; sqInt offset; sqInt offset1; sqInt offset2; - sqInt operand1; - sqInt operand3; sqInt reg; sqInt retpc; - continuePostSampleNonPrim = ((AbstractInstruction *) 0); - continuePostSamplePrim = ((AbstractInstruction *) 0); - jmpSampleNonPrim = ((AbstractInstruction *) 0); - jmpSamplePrim = ((AbstractInstruction *) 0); + jumpToTakeSample = ((AbstractInstruction *) 0); assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); genExternalizePointersForPrimitiveCall(); /* begin genLoadCStackPointersForPrimCall */ @@ -28428,53 +28466,36 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) else { genLoadCStackPointer(backEnd); } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick if so */ - /* begin MoveAw:R: */ - address2 = nextProfileTickAddress(); - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address2, genoperandoperand(MoveAwR, address2, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction)) { - (anInstruction->dependent = locateLiteralsize(0, BytesPerOop)); - } - /* begin JumpNonZero: */ - jmpSampleNonPrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSampleNonPrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } if (recordPrimTraceForMethod(methodObj)) { genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(MoveCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction8)) { - (anInstruction8->dependent = locateLiteralsize(0, BytesPerOop)); + anInstruction4 = genoperandoperand(MoveCqR, 0, TempReg); + if (usesOutOfLineLiteral(anInstruction4)) { + (anInstruction4->dependent = locateLiteralsize(0, BytesPerOop)); } /* begin MoveR:Aw: */ - address11 = primFailCodeAddress(); + address6 = primFailCodeAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address11, genoperandoperand(MoveRAw, TempReg, address11)); + checkLiteralforInstruction(address6, genoperandoperand(MoveRAw, TempReg, address6)); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); - if (usesOutOfLineLiteral(anInstruction1)) { - (anInstruction1->dependent = locateLiteralsize(methodOrBlockNumArgs, BytesPerOop)); + anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); + if (usesOutOfLineLiteral(anInstruction)) { + (anInstruction->dependent = locateLiteralsize(methodOrBlockNumArgs, BytesPerOop)); } } /* begin MoveR:Aw: */ - address12 = argumentCountAddress(); + address7 = argumentCountAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address12, genoperandoperand(MoveRAw, TempReg, address12)); + checkLiteralforInstruction(address7, genoperandoperand(MoveRAw, TempReg, address7)); if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { /* begin MoveCw:R: */ checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg)); /* begin MoveR:Aw: */ - address3 = primitiveFunctionPointerAddress(); + address = primitiveFunctionPointerAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address3, genoperandoperand(MoveRAw, TempReg, address3)); + checkLiteralforInstruction(address, genoperandoperand(MoveRAw, TempReg, address)); } if (((flags & (PrimCallNeedsNewMethod + PrimCallMayEndureCodeCompaction)) != 0)) { @@ -28486,22 +28507,21 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) /* begin MoveMw:r:R: */ offset = offsetof(CogMethod, methodObject); /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - if (usesOutOfLineLiteral(anInstruction2)) { - (anInstruction2->dependent = locateLiteralsize(offset, BytesPerOop)); + anInstruction1 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); + if (usesOutOfLineLiteral(anInstruction1)) { + (anInstruction1->dependent = locateLiteralsize(offset, BytesPerOop)); } /* begin MoveR:Aw: */ - address4 = newMethodAddress(); + address1 = newMethodAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address4, genoperandoperand(MoveRAw, TempReg, address4)); + checkLiteralforInstruction(address1, genoperandoperand(MoveRAw, TempReg, address1)); } /* begin PrefetchAw: */ - address13 = primFailCodeAddress(); + address8 = primFailCodeAddress(); /* begin gen:literal: */ - checkLiteralforInstruction(address13, genoperand(PrefetchAw, address13)); + checkLiteralforInstruction(address8, genoperand(PrefetchAw, address8)); if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - /* Sideways call the C primitive routine so that we return through cePrimReturnEnterCogCode. */ /* On Spur ceActivateFailingPrimitiveMethod: would like to retry if forwarders are found. So insist on PrimCallNeedsPrimitiveFunction being set too. */ assert(((flags & PrimCallNeedsPrimitiveFunction) != 0)); @@ -28514,102 +28534,75 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) checkLiteralforInstruction(retpc, genoperandoperand(MoveCwR, retpc, LR)); /* begin gen:literal: */ checkLiteralforInstruction(((sqInt)(((sqInt)primitiveRoutine))), genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine))))); - jmp = (jmpSamplePrim = (continuePostSamplePrim = null)); + return 0; } - else { - - /* Call the C primitive routine. */ - genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); - /* begin gen:literal: */ - checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperand(CallFull, ((sqInt)primitiveRoutine))); - /* begin genRemoveNArgsFromStack: */ - assert(0 <= 6); - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin MoveAw:R: */ - address7 = nextProfileTickAddress(); - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address7, genoperandoperand(MoveAwR, address7, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(CmpCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction3)) { - (anInstruction3->dependent = locateLiteralsize(0, BytesPerOop)); - } - /* begin JumpNonZero: */ - jmpSamplePrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSamplePrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - maybeCompileRetryOnPrimitiveFail(primitiveIndex); - /* begin MoveAw:R: */ - address8 = instructionPointerAddress(); - reg = LinkReg; - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address8, genoperandoperand(MoveAwR, address8, reg)); - genLoadStackPointers(backEnd); + genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); + /* begin gen:literal: */ + checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperand(CallFull, ((sqInt)primitiveRoutine))); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 6); + maybeCompileRetryOnPrimitiveFail(primitiveIndex); + genLoadStackPointersForPrimCall(backEnd, ClassReg); + /* begin MoveAw:R: */ + address2 = instructionPointerAddress(); + /* begin gen:literal:operand: */ + checkLiteralforInstruction(address2, genoperandoperand(MoveAwR, address2, LinkReg)); + /* begin MoveAw:R: */ + address9 = primFailCodeAddress(); + /* begin gen:literal:operand: */ + checkLiteralforInstruction(address9, genoperandoperand(MoveAwR, address9, TempReg)); + flag("ask concrete code gen if move sets condition codes?"); + /* begin checkQuickConstant:forInstruction: */ + anInstruction5 = genoperandoperand(CmpCqR, 0, TempReg); + if (usesOutOfLineLiteral(anInstruction5)) { + (anInstruction5->dependent = locateLiteralsize(0, BytesPerOop)); + } + /* begin JumpNonZero: */ + jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + reg = Arg0Reg; + gMovePerfCnt64RL(reg, liveRegisters); /* begin MoveAw:R: */ - address9 = primFailCodeAddress(); + address10 = nextProfileTickAddress(); /* begin gen:literal:operand: */ - checkLiteralforInstruction(address9, genoperandoperand(MoveAwR, address9, TempReg)); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction4)) { - (anInstruction4->dependent = locateLiteralsize(0, BytesPerOop)); - } - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset1 = 0; - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); - if (usesOutOfLineLiteral(anInstruction5)) { - (anInstruction5->dependent = locateLiteralsize(offset1, BytesPerOop)); - } - /* begin RetN: */ - genoperand(RetN, BytesPerWord); + checkLiteralforInstruction(address10, genoperandoperand(MoveAwR, address10, Arg1Reg)); + /* begin CmpR:R: */ + assert(!((reg == SPReg))); + genoperandoperand(CmpRR, reg, Arg1Reg); + /* begin JumpGreaterOrEqual: */ + jumpToTakeSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l31; + l31: /* end genCheckForProfileTimerTick: */; } + /* begin MoveMw:r:R: */ + offset1 = 0; + /* begin checkQuickConstant:forInstruction: */ + anInstruction6 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); + if (usesOutOfLineLiteral(anInstruction6)) { + (anInstruction6->dependent = locateLiteralsize(offset1, BytesPerOop)); + } + continueAfterProfileSample = anInstruction6; + /* begin RetN: */ + genoperand(RetN, BytesPerWord); if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* The sample is collected by cePrimReturnEnterCogCode for external calls */ - if (!(jmpSamplePrim == null)) { - - /* Call ceCheckProfileTick: to record sample and then continue. */ - jmpTarget(jmpSamplePrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin gen:literal: */ - operand1 = ((usqIntptr_t)ceCheckProfileTick); - checkLiteralforInstruction(operand1, genoperand(CallFull, operand1)); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSamplePrim)); - } - jmpTarget(jmpSampleNonPrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(MoveCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction6)) { - (anInstruction6->dependent = locateLiteralsize(0, BytesPerOop)); - } - /* begin MoveR:Aw: */ - address10 = newMethodAddress(); - /* begin gen:operand:literal: */ - checkLiteralforInstruction(address10, genoperandoperand(MoveRAw, TempReg, address10)); - /* begin gen:literal: */ - operand3 = ((usqIntptr_t)ceCheckProfileTick); - checkLiteralforInstruction(operand3, genoperand(CallFull, operand3)); + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); + /* begin MoveAw:R: */ + address4 = instructionPointerAddress(); + /* begin gen:literal:operand: */ + checkLiteralforInstruction(address4, genoperandoperand(MoveAwR, address4, LinkReg)); /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSampleNonPrim)); + genoperand(Jump, ((sqInt)continueAfterProfileSample)); } - if (!(jmp == null)) { - - /* Jump to restore of receiver reg and proceed to frame build for failure. */ - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin MoveMw:r:R: */ - offset2 = BytesPerWord * (methodOrBlockNumArgs + (0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); - if (usesOutOfLineLiteral(anInstruction7)) { - (anInstruction7->dependent = locateLiteralsize(offset2, BytesPerOop)); - } + jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + /* begin MoveMw:r:R: */ + offset2 = BytesPerWord * (methodOrBlockNumArgs + (0)); + /* begin checkQuickConstant:forInstruction: */ + anInstruction7 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); + if (usesOutOfLineLiteral(anInstruction7)) { + (anInstruction7->dependent = locateLiteralsize(offset2, BytesPerOop)); } return 0; } @@ -28639,7 +28632,7 @@ compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)) if ((methodOrBlockNumArgs > 2 /* numRegArgs */) || (methodOrBlockNumArgs == 0)) { /* begin registerMaskFor: */ - liveRegsMask = 1U << ReceiverResultReg; + liveRegsMask = (1U << ReceiverResultReg); } else { if (methodOrBlockNumArgs > 1) { @@ -28710,6 +28703,7 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags sqInt address5; sqInt address6; sqInt address7; + sqInt address8; AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; AbstractInstruction *anInstruction10; @@ -28719,15 +28713,20 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags AbstractInstruction *anInstruction8; AbstractInstruction *anInstruction9; sqInt calleeSavedRegisterMask; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; + AbstractInstruction * jumpToTakeSample; sqInt linkRegSaveRegister; + sqInt liveRegisters; sqInt offset; sqInt offset1; sqInt operand1; + sqInt reg; AbstractInstruction * retry; AbstractInstruction * skip; sqInt spRegSaveRegister; + jumpToTakeSample = ((AbstractInstruction *) 0); linkRegSaveRegister = 0; assert(((flags & PrimCallOnSmalltalkStack) != 0)); assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); @@ -28755,14 +28754,14 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags /* begin gen:operand:literal: */ checkLiteralforInstruction(address5, genoperandoperand(MoveRAw, TempReg, address5)); genExternalizeStackPointerForFastPrimitiveCall(); - calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | (1U << ClassReg)) - (1U << ClassReg)); + calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | ((1U << ClassReg))) - ((1U << ClassReg))); linkRegSaveRegister = availableRegisterOrNoneIn(calleeSavedRegisterMask); assert(!((linkRegSaveRegister == NoReg))); /* begin MoveR:R: */ genoperandoperand(MoveRR, LinkReg, linkRegSaveRegister); - calleeSavedRegisterMask = ((calleeSavedRegisterMask | (1ULL << linkRegSaveRegister)) - (1ULL << linkRegSaveRegister)); + calleeSavedRegisterMask = ((calleeSavedRegisterMask | (((linkRegSaveRegister < 0) ? (((usqInt)(1)) >> (-linkRegSaveRegister)) : (1ULL << linkRegSaveRegister)))) - (((linkRegSaveRegister < 0) ? (((usqInt)(1)) >> (-linkRegSaveRegister)) : (1ULL << linkRegSaveRegister)))); spRegSaveRegister = NoReg; - if (!(((ABICalleeSavedRegisterMask & (1U << SPReg)) != 0))) { + if (!(((ABICalleeSavedRegisterMask & ((1U << SPReg))) != 0))) { spRegSaveRegister = availableRegisterOrNoneIn(calleeSavedRegisterMask); assert(!((spRegSaveRegister == NoReg))); /* begin MoveR:R: */ @@ -28776,8 +28775,11 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags else { genLoadNativeSPRegWithAlignedSPReg(backEnd); } + genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); /* begin gen:literal: */ - checkLiteralforInstruction(primitiveRoutine, genoperand(CallFull, primitiveRoutine)); + checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperand(CallFull, ((sqInt)primitiveRoutine))); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 6); /* begin MoveAw:R: */ address6 = primFailCodeAddress(); /* begin gen:literal:operand: */ @@ -28794,10 +28796,27 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags /* begin JumpNonZero: */ jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); genLoadCStackPointer(backEnd); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + reg = Arg0Reg; + gMovePerfCnt64RL(reg, liveRegisters); + /* begin MoveAw:R: */ + address8 = nextProfileTickAddress(); + /* begin gen:literal:operand: */ + checkLiteralforInstruction(address8, genoperandoperand(MoveAwR, address8, Arg1Reg)); + /* begin CmpR:R: */ + assert(!((reg == SPReg))); + genoperandoperand(CmpRR, reg, Arg1Reg); + /* begin JumpGreaterOrEqual: */ + jumpToTakeSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l33; + l33: /* end genCheckForProfileTimerTick: */; + } /* begin MoveAw:R: */ address7 = stackPointerAddress(); /* begin gen:literal:operand: */ - checkLiteralforInstruction(address7, genoperandoperand(MoveAwR, address7, TempReg)); + continueAfterProfileSample = checkLiteralforInstruction(address7, genoperandoperand(MoveAwR, address7, TempReg)); /* begin checkQuickConstant:forInstruction: */ anInstruction1 = genoperandoperandoperand(MoveMwrR, 0, TempReg, ReceiverResultReg); if (usesOutOfLineLiteral(anInstruction1)) { @@ -28808,6 +28827,12 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags genoperandoperand(MoveRR, linkRegSaveRegister, LinkReg); /* begin RetN: */ genoperand(RetN, 0); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); + /* begin Jump: */ + genoperand(Jump, ((sqInt)continueAfterProfileSample)); + } jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); if ((accessorDepthForExternalPrimitiveMethod(methodObj)) >= 0) { @@ -28843,10 +28868,11 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags else { genLoadCStackPointer(backEnd); } + genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); /* begin gen:literal: */ operand1 = ((usqIntptr_t)checkForAndFollowForwardedPrimitiveState); checkLiteralforInstruction(operand1, genoperand(CallFull, operand1)); - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); /* begin checkQuickConstant:forInstruction: */ anInstruction6 = genoperandoperand(CmpCqR, 0, ABIResultReg); if (usesOutOfLineLiteral(anInstruction6)) { @@ -28871,13 +28897,13 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags /* must reload SPReg to undo any alignment change, */ if (((flags & PrimCallOnSmalltalkStackAlign2x) != 0)) { - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); } } genLoadCStackPointer(backEnd); /* begin MoveR:R: */ genoperandoperand(MoveRR, linkRegSaveRegister, LinkReg); - if (((ABICallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((ABICallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* begin MoveMw:r:R: */ offset1 = (methodOrBlockNumArgs + (0)) * BytesPerWord; /* begin checkQuickConstant:forInstruction: */ @@ -29953,23 +29979,24 @@ genPrimitiveHashMultiply(void) static void NoDbgRegParms genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) { - sqInt address2; + sqInt address; sqInt address4; sqInt address6; sqInt address7; sqInt address8; AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction7; + AbstractInstruction *anInstruction4; + AbstractInstruction *anInstruction6; sqInt callTarget; AbstractInstruction *continuePostSample; AbstractInstruction * inst; AbstractInstruction *jmpFail; AbstractInstruction *jmpSample; + sqInt liveRegisters; sqInt quickConstant; sqInt reg; + sqInt reg1; continuePostSample = ((AbstractInstruction *) 0); jmpSample = ((AbstractInstruction *) 0); @@ -29981,41 +30008,43 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) if (usesOutOfLineLiteral(anInstruction)) { (anInstruction->dependent = locateLiteralsize(quickConstant, BytesPerOop)); } - if (profiling) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick: if so. - N.B. nextProfileTick is 64-bits so 32-bit systems need to test both halves. */ - /* begin MoveAw:R: */ - address2 = nextProfileTickAddress(); - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address2, genoperandoperand(MoveAwR, address2, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction1)) { - (anInstruction1->dependent = locateLiteralsize(0, BytesPerOop)); - } - /* begin JumpNonZero: */ - jmpSample = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } /* begin MoveAw:R: */ address6 = primFailCodeAddress(); /* begin gen:literal:operand: */ checkLiteralforInstruction(address6, genoperandoperand(MoveAwR, address6, TempReg)); flag("ask concrete code gen if move sets condition codes?"); /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(CmpCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction7)) { - (anInstruction7->dependent = locateLiteralsize(0, BytesPerOop)); + anInstruction6 = genoperandoperand(CmpCqR, 0, TempReg); + if (usesOutOfLineLiteral(anInstruction6)) { + (anInstruction6->dependent = locateLiteralsize(0, BytesPerOop)); } /* begin JumpNonZero: */ jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (profiling + && (1)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + reg = Arg0Reg; + gMovePerfCnt64RL(reg, liveRegisters); + /* begin MoveAw:R: */ + address = nextProfileTickAddress(); + /* begin gen:literal:operand: */ + checkLiteralforInstruction(address, genoperandoperand(MoveAwR, address, Arg1Reg)); + /* begin CmpR:R: */ + assert(!((reg == SPReg))); + genoperandoperand(CmpRR, reg, Arg1Reg); + /* begin JumpGreaterOrEqual: */ + jmpSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l8; + l8: /* end genCheckForProfileTimerTick: */; + /* begin Label */ + continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); + } genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); - if (usesOutOfLineLiteral(anInstruction2)) { - (anInstruction2->dependent = locateLiteralsize(0, BytesPerOop)); + anInstruction1 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); + if (usesOutOfLineLiteral(anInstruction1)) { + (anInstruction1->dependent = locateLiteralsize(0, BytesPerOop)); } /* begin MoveAw:R: */ address4 = instructionPointerAddress(); @@ -30031,18 +30060,19 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) compileCallFornumArgsargargargargresultRegregsToSave(ceActivateFailingPrimitiveMethod, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); /* begin MoveAw:R: */ address8 = instructionPointerAddress(); - reg = LinkReg; + reg1 = LinkReg; /* begin gen:literal:operand: */ - checkLiteralforInstruction(address8, genoperandoperand(MoveAwR, address8, reg)); + checkLiteralforInstruction(address8, genoperandoperand(MoveAwR, address8, reg1)); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); - if (usesOutOfLineLiteral(anInstruction5)) { - (anInstruction5->dependent = locateLiteralsize(0, BytesPerOop)); + anInstruction4 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); + if (usesOutOfLineLiteral(anInstruction4)) { + (anInstruction4->dependent = locateLiteralsize(0, BytesPerOop)); } /* begin RetN: */ genoperand(RetN, BytesPerWord); - if (profiling) { + if (profiling + && (1)) { /* Call ceCheckProfileTick: to record sample and then continue. newMethod should be up-to-date. Need to save and restore the link reg around this call. */ @@ -30423,6 +30453,23 @@ genStoreRemoteTempLongBytecode(void) && (shouldAnnotateObjectReference(((ssTop())->constant))))); } + /* SimpleStackBasedCogit>>#genTakeProfileSample */ +static void +genTakeProfileSample(void) +{ + sqInt operand1; + + addDependent(methodLabel, annotateAbsolutePCRef(gMoveCwR(((sqInt)methodLabel), ClassReg))); + genMarshallNArgsargargargarg(backEnd, 1, ClassReg, null, null, null); + genLoadNativeSPRegWithAlignedSPReg(backEnd); + /* begin gen:literal: */ + operand1 = ((usqIntptr_t)ceTakeProfileSample); + checkLiteralforInstruction(operand1, genoperand(CallFull, operand1)); + /* begin genRemoveNArgsFromStack: */ + assert(1 <= 6); + genLoadCStackPointer(backEnd); +} + /* SistaV1: * 217 Trap */ @@ -30826,7 +30873,7 @@ primitiveGeneratorOrNil(void) static sqInt NoDbgRegParms registerisInMask(sqInt reg, sqInt mask) { - return ((mask & (1ULL << reg)) != 0); + return ((mask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0); } /* SimpleStackBasedCogit>>#v3:Block:Code:Size: */ @@ -31216,7 +31263,7 @@ anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n) sqInt regMask; /* begin registerMaskFor: */ - regMask = 1ULL << reg; + regMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { if ((((registerMask(simStackAt(i))) & regMask) != 0)) { return 1; @@ -32386,7 +32433,7 @@ ensureReceiverResultRegContainsSelf(void) if (needsFrame) { if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin putSelfInReceiverResultReg */ storeToReg(simSelf(), ReceiverResultReg); ((simSelf())->liveRegister = ReceiverResultReg); @@ -32520,7 +32567,7 @@ freeAnyFloatRegNotConflictingWith(sqInt regMask) desc = simNativeStackAt(index); if ((((desc->type)) == SSRegisterSingleFloat) || (((desc->type)) == SSRegisterDoubleFloat)) { - if (!(((regMask & (1ULL << ((desc->registerr)))) != 0))) { + if (!(((regMask & (((((desc->registerr)) < 0) ? (((usqInt)(1)) >> (-((desc->registerr)))) : (1ULL << ((desc->registerr)))))) != 0))) { reg = (desc->registerr); } } @@ -32550,7 +32597,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) && (index < simStackPtr)) { desc = simStackAt(index); if (((desc->type)) == SSRegister) { - if (!(((regMask & (1ULL << ((desc->registerr)))) != 0))) { + if (!(((regMask & (((((desc->registerr)) < 0) ? (((usqInt)(1)) >> (-((desc->registerr)))) : (1ULL << ((desc->registerr)))))) != 0))) { reg = (desc->registerr); } } @@ -32558,7 +32605,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) } assert(!((reg == NoReg))); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1ULL << reg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)), simStackPtr, simNativeStackPtr); return reg; } @@ -33117,13 +33164,13 @@ genForwardersInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -33779,7 +33826,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop19 == NoReg) { rOopTop19 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult10 = allocateRegNotConflictingWith(1ULL << rOopTop19); + rResult10 = allocateRegNotConflictingWith(((rOopTop19 < 0) ? (((usqInt)(1)) >> (-rOopTop19)) : (1ULL << rOopTop19))); assert(!(((rOopTop19 == NoReg) || (rResult10 == NoReg)))); object17 = rOopTop19; @@ -33875,7 +33922,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop2 == NoReg) { rOopTop2 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult = allocateRegNotConflictingWith(1ULL << rOopTop2); + rResult = allocateRegNotConflictingWith(((rOopTop2 < 0) ? (((usqInt)(1)) >> (-rOopTop2)) : (1ULL << rOopTop2))); assert(!(((rOopTop2 == NoReg) || (rResult == NoReg)))); object2 = rOopTop2; @@ -33906,7 +33953,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop3 == NoReg) { rOopTop3 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult1 = allocateRegNotConflictingWith(1ULL << rOopTop3); + rResult1 = allocateRegNotConflictingWith(((rOopTop3 < 0) ? (((usqInt)(1)) >> (-rOopTop3)) : (1ULL << rOopTop3))); assert(!(((rOopTop3 == NoReg) || (rResult1 == NoReg)))); object3 = rOopTop3; @@ -33937,7 +33984,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop4 == NoReg) { rOopTop4 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult2 = allocateRegNotConflictingWith(1ULL << rOopTop4); + rResult2 = allocateRegNotConflictingWith(((rOopTop4 < 0) ? (((usqInt)(1)) >> (-rOopTop4)) : (1ULL << rOopTop4))); assert(!(((rOopTop4 == NoReg) || (rResult2 == NoReg)))); object4 = rOopTop4; @@ -33968,7 +34015,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop5 == NoReg) { rOopTop5 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult3 = allocateRegNotConflictingWith(1ULL << rOopTop5); + rResult3 = allocateRegNotConflictingWith(((rOopTop5 < 0) ? (((usqInt)(1)) >> (-rOopTop5)) : (1ULL << rOopTop5))); assert(!(((rOopTop5 == NoReg) || (rResult3 == NoReg)))); object5 = rOopTop5; @@ -33999,7 +34046,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop6 == NoReg) { rOopTop6 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult4 = allocateRegNotConflictingWith(1ULL << rOopTop6); + rResult4 = allocateRegNotConflictingWith(((rOopTop6 < 0) ? (((usqInt)(1)) >> (-rOopTop6)) : (1ULL << rOopTop6))); assert(!(((rOopTop6 == NoReg) || (rResult4 == NoReg)))); object6 = rOopTop6; @@ -34030,7 +34077,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop7 == NoReg) { rOopTop7 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult5 = allocateRegNotConflictingWith(1ULL << rOopTop7); + rResult5 = allocateRegNotConflictingWith(((rOopTop7 < 0) ? (((usqInt)(1)) >> (-rOopTop7)) : (1ULL << rOopTop7))); assert(!(((rOopTop7 == NoReg) || (rResult5 == NoReg)))); object7 = rOopTop7; @@ -34061,7 +34108,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop8 == NoReg) { rOopTop8 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult6 = allocateRegNotConflictingWith(1ULL << rOopTop8); + rResult6 = allocateRegNotConflictingWith(((rOopTop8 < 0) ? (((usqInt)(1)) >> (-rOopTop8)) : (1ULL << rOopTop8))); assert(!(((rOopTop8 == NoReg) || (rResult6 == NoReg)))); object8 = rOopTop8; @@ -34121,7 +34168,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop11 == NoReg) { rOopTop11 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult11 = allocateRegNotConflictingWith(1ULL << rOopTop11); + rResult11 = allocateRegNotConflictingWith(((rOopTop11 < 0) ? (((usqInt)(1)) >> (-rOopTop11)) : (1ULL << rOopTop11))); assert(!(((rOopTop11 == NoReg) || (rResult11 == NoReg)))); object10 = rOopTop11; @@ -34182,7 +34229,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop14 == NoReg) { rOopTop14 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult12 = allocateRegNotConflictingWith(1ULL << rOopTop14); + rResult12 = allocateRegNotConflictingWith(((rOopTop14 < 0) ? (((usqInt)(1)) >> (-rOopTop14)) : (1ULL << rOopTop14))); assert(!(((rOopTop14 == NoReg) || (rResult12 == NoReg)))); object12 = rOopTop14; @@ -34337,7 +34384,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop110 == NoReg) { rOopTop110 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult13 = allocateRegNotConflictingWith(1ULL << rOopTop110); + rResult13 = allocateRegNotConflictingWith(((rOopTop110 < 0) ? (((usqInt)(1)) >> (-rOopTop110)) : (1ULL << rOopTop110))); assert(!(((rOopTop110 == NoReg) || (rResult13 == NoReg)))); object21 = rOopTop110; @@ -34406,7 +34453,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop16 == NoReg) { rOopTop16 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult9 = allocateRegNotConflictingWith(1ULL << rOopTop16); + rResult9 = allocateRegNotConflictingWith(((rOopTop16 < 0) ? (((usqInt)(1)) >> (-rOopTop16)) : (1ULL << rOopTop16))); assert(!(((rOopTop16 == NoReg) || (rResult9 == NoReg)))); object14 = rOopTop16; @@ -34437,7 +34484,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop24 == NoReg) { rOopTop24 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult15 = allocateRegNotConflictingWith(1ULL << rOopTop24); + rResult15 = allocateRegNotConflictingWith(((rOopTop24 < 0) ? (((usqInt)(1)) >> (-rOopTop24)) : (1ULL << rOopTop24))); assert(!(((rOopTop24 == NoReg) || (rResult15 == NoReg)))); object22 = rOopTop24; @@ -34480,7 +34527,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop111 == NoReg) { rOopTop111 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult16 = allocateRegNotConflictingWith(1ULL << rOopTop111); + rResult16 = allocateRegNotConflictingWith(((rOopTop111 < 0) ? (((usqInt)(1)) >> (-rOopTop111)) : (1ULL << rOopTop111))); assert(!(((rOopTop111 == NoReg) || (rResult16 == NoReg)))); object23 = rOopTop111; @@ -34631,7 +34678,7 @@ genLowcodeNullaryInlinePrimitive(sqInt prim) if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult = allocateRegNotConflictingWith(1ULL << rTop); + rResult = allocateRegNotConflictingWith(((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1ULL << rTop))); assert(!(((rTop == NoReg) || (rResult == NoReg)))); value = rTop; @@ -34669,7 +34716,7 @@ genLowcodeNullaryInlinePrimitive(sqInt prim) if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult1 = allocateRegNotConflictingWith(1ULL << rTop1); + rResult1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); assert(!(((rTop1 == NoReg) || (rResult1 == NoReg)))); value1 = rTop1; @@ -34918,7 +34965,7 @@ genLowcodeNullaryInlinePrimitive(sqInt prim) if (rTop12 == NoReg) { rTop12 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult11 = allocateRegNotConflictingWith(1ULL << rTop12); + rResult11 = allocateRegNotConflictingWith(((rTop12 < 0) ? (((usqInt)(1)) >> (-rTop12)) : (1ULL << rTop12))); assert(!(((rTop12 == NoReg) || (rResult11 == NoReg)))); value6 = rTop12; @@ -35029,14 +35076,14 @@ genLowcodeTrinaryInlinePrimitive(sqInt prim) l4: ; if (rOopNext != NoReg) { /* begin registerMaskFor: */ - oopTopRegisterMask = 1ULL << rOopNext; + oopTopRegisterMask = ((rOopNext < 0) ? (((usqInt)(1)) >> (-rOopNext)) : (1ULL << rOopNext)); } } if (rOopTop == NoReg) { rOopTop = allocateRegNotConflictingWith(oopTopRegisterMask); } if (rOopNext == NoReg) { - rOopNext = allocateRegNotConflictingWith(1ULL << rOopTop); + rOopNext = allocateRegNotConflictingWith(((rOopTop < 0) ? (((usqInt)(1)) >> (-rOopTop)) : (1ULL << rOopTop))); } rResult = allocateRegNotConflictingWith((1ULL << rOopTop) | (1ULL << rOopNext)); assert(!(((rOopTop == NoReg) @@ -35104,14 +35151,14 @@ genLowcodeTrinaryInlinePrimitive(sqInt prim) l18: ; if (rOopNext1 != NoReg) { /* begin registerMaskFor: */ - oopTopRegisterMask1 = 1ULL << rOopNext1; + oopTopRegisterMask1 = ((rOopNext1 < 0) ? (((usqInt)(1)) >> (-rOopNext1)) : (1ULL << rOopNext1)); } } if (rOopTop1 == NoReg) { rOopTop1 = allocateRegNotConflictingWith(oopTopRegisterMask1); } if (rOopNext1 == NoReg) { - rOopNext1 = allocateRegNotConflictingWith(1ULL << rOopTop1); + rOopNext1 = allocateRegNotConflictingWith(((rOopTop1 < 0) ? (((usqInt)(1)) >> (-rOopTop1)) : (1ULL << rOopTop1))); } assert(!(((rOopTop1 == NoReg) || (rOopNext1 == NoReg)))); @@ -35178,14 +35225,14 @@ genLowcodeTrinaryInlinePrimitive(sqInt prim) l23: ; if (rOopNext2 != NoReg) { /* begin registerMaskFor: */ - oopTopRegisterMask2 = 1ULL << rOopNext2; + oopTopRegisterMask2 = ((rOopNext2 < 0) ? (((usqInt)(1)) >> (-rOopNext2)) : (1ULL << rOopNext2)); } } if (rOopTop2 == NoReg) { rOopTop2 = allocateRegNotConflictingWith(oopTopRegisterMask2); } if (rOopNext2 == NoReg) { - rOopNext2 = allocateRegNotConflictingWith(1ULL << rOopTop2); + rOopNext2 = allocateRegNotConflictingWith(((rOopTop2 < 0) ? (((usqInt)(1)) >> (-rOopTop2)) : (1ULL << rOopTop2))); } assert(!(((rOopTop2 == NoReg) || (rOopNext2 == NoReg)))); @@ -35206,17 +35253,17 @@ genLowcodeTrinaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { rTop = nativeRegisterOrNone(ssNativeTop()); /* begin registerMaskFor: */ - oopTopRegisterMask3 = 1ULL << rTop; + oopTopRegisterMask3 = ((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1ULL << rTop)); } if ((registerOrNone(ssTop())) != NoReg) { rOopTop3 = registerOrNone(ssTop()); /* begin registerMaskFor: */ - topRegisterMask = 1ULL << rOopTop3; + topRegisterMask = ((rOopTop3 < 0) ? (((usqInt)(1)) >> (-rOopTop3)) : (1ULL << rOopTop3)); } if ((registerOrNone(ssValue(1))) != NoReg) { rOopNext3 = registerOrNone(ssValue(1)); - topRegisterMask = topRegisterMask | (1ULL << rOopNext3); - oopTopRegisterMask3 = oopTopRegisterMask3 | (1ULL << rOopNext3); + topRegisterMask = topRegisterMask | (((rOopNext3 < 0) ? (((usqInt)(1)) >> (-rOopNext3)) : (1ULL << rOopNext3))); + oopTopRegisterMask3 = oopTopRegisterMask3 | (((rOopNext3 < 0) ? (((usqInt)(1)) >> (-rOopNext3)) : (1ULL << rOopNext3))); } if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(topRegisterMask); @@ -35732,13 +35779,13 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((registerOrNone(ssTop())) != NoReg) { rOopTop1 = registerOrNone(ssTop()); /* begin registerMaskFor: */ - topRegisterMask1 = 1ULL << rOopTop1; + topRegisterMask1 = ((rOopTop1 < 0) ? (((usqInt)(1)) >> (-rOopTop1)) : (1ULL << rOopTop1)); } if (rTop31 == NoReg) { rTop31 = allocateRegNotConflictingWith(topRegisterMask1); } if (rOopTop1 == NoReg) { - rOopTop1 = allocateRegNotConflictingWith(1ULL << rTop31); + rOopTop1 = allocateRegNotConflictingWith(((rTop31 < 0) ? (((usqInt)(1)) >> (-rTop31)) : (1ULL << rTop31))); } rOopResult = allocateRegNotConflictingWith((1ULL << rTop31) | (1ULL << rOopTop1)); assert(!(((rTop31 == NoReg) @@ -35788,7 +35835,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if (rOopTop2 == NoReg) { rOopTop2 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult35 = allocateRegNotConflictingWith(1ULL << rOopTop2); + rResult35 = allocateRegNotConflictingWith(((rOopTop2 < 0) ? (((usqInt)(1)) >> (-rOopTop2)) : (1ULL << rOopTop2))); assert(!(((rOopTop2 == NoReg) || (rResult35 == NoReg)))); classOop1 = rOopTop2; @@ -35862,14 +35909,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask1 = 1ULL << reg; + topRegistersMask1 = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } } if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(topRegistersMask1); } if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1ULL << rTop); + rNext = allocateRegNotConflictingWith(((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1ULL << rTop))); } assert(!(((rTop == NoReg) || (rNext == NoReg)))); @@ -35915,14 +35962,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg1 = (rNext1 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask2 = 1ULL << reg1; + topRegistersMask2 = ((reg1 < 0) ? (((usqInt)(1)) >> (-reg1)) : (1ULL << reg1)); } } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask2); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -35968,14 +36015,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg2 = (rNext2 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask3 = 1ULL << reg2; + topRegistersMask3 = ((reg2 < 0) ? (((usqInt)(1)) >> (-reg2)) : (1ULL << reg2)); } } if (rTop2 == NoReg) { rTop2 = allocateRegNotConflictingWith(topRegistersMask3); } if (rNext2 == NoReg) { - rNext2 = allocateRegNotConflictingWith(1ULL << rTop2); + rNext2 = allocateRegNotConflictingWith(((rTop2 < 0) ? (((usqInt)(1)) >> (-rTop2)) : (1ULL << rTop2))); } assert(!(((rTop2 == NoReg) || (rNext2 == NoReg)))); @@ -36021,14 +36068,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg3 = (rNext3 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask4 = 1ULL << reg3; + topRegistersMask4 = ((reg3 < 0) ? (((usqInt)(1)) >> (-reg3)) : (1ULL << reg3)); } } if (rTop3 == NoReg) { rTop3 = allocateRegNotConflictingWith(topRegistersMask4); } if (rNext3 == NoReg) { - rNext3 = allocateRegNotConflictingWith(1ULL << rTop3); + rNext3 = allocateRegNotConflictingWith(((rTop3 < 0) ? (((usqInt)(1)) >> (-rTop3)) : (1ULL << rTop3))); } assert(!(((rTop3 == NoReg) || (rNext3 == NoReg)))); @@ -36074,14 +36121,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg4 = (rNext4 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask5 = 1ULL << reg4; + topRegistersMask5 = ((reg4 < 0) ? (((usqInt)(1)) >> (-reg4)) : (1ULL << reg4)); } } if (rTop4 == NoReg) { rTop4 = allocateRegNotConflictingWith(topRegistersMask5); } if (rNext4 == NoReg) { - rNext4 = allocateRegNotConflictingWith(1ULL << rTop4); + rNext4 = allocateRegNotConflictingWith(((rTop4 < 0) ? (((usqInt)(1)) >> (-rTop4)) : (1ULL << rTop4))); } assert(!(((rTop4 == NoReg) || (rNext4 == NoReg)))); @@ -36127,14 +36174,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg5 = (rNext5 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask6 = 1ULL << reg5; + topRegistersMask6 = ((reg5 < 0) ? (((usqInt)(1)) >> (-reg5)) : (1ULL << reg5)); } } if (rTop5 == NoReg) { rTop5 = allocateRegNotConflictingWith(topRegistersMask6); } if (rNext5 == NoReg) { - rNext5 = allocateRegNotConflictingWith(1ULL << rTop5); + rNext5 = allocateRegNotConflictingWith(((rTop5 < 0) ? (((usqInt)(1)) >> (-rTop5)) : (1ULL << rTop5))); } assert(!(((rTop5 == NoReg) || (rNext5 == NoReg)))); @@ -36241,14 +36288,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg6 = (rNext11 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask7 = 1ULL << reg6; + topRegistersMask7 = ((reg6 < 0) ? (((usqInt)(1)) >> (-reg6)) : (1ULL << reg6)); } } if (rTop11 == NoReg) { rTop11 = allocateRegNotConflictingWith(topRegistersMask7); } if (rNext11 == NoReg) { - rNext11 = allocateRegNotConflictingWith(1ULL << rTop11); + rNext11 = allocateRegNotConflictingWith(((rTop11 < 0) ? (((usqInt)(1)) >> (-rTop11)) : (1ULL << rTop11))); } assert(!(((rTop11 == NoReg) || (rNext11 == NoReg)))); @@ -36295,14 +36342,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg7 = (rNext7 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask8 = 1ULL << reg7; + topRegistersMask8 = ((reg7 < 0) ? (((usqInt)(1)) >> (-reg7)) : (1ULL << reg7)); } } if (rTop10 == NoReg) { rTop10 = allocateRegNotConflictingWith(topRegistersMask8); } if (rNext7 == NoReg) { - rNext7 = allocateRegNotConflictingWith(1ULL << rTop10); + rNext7 = allocateRegNotConflictingWith(((rTop10 < 0) ? (((usqInt)(1)) >> (-rTop10)) : (1ULL << rTop10))); } assert(!(((rTop10 == NoReg) || (rNext7 == NoReg)))); @@ -36333,14 +36380,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg8 = (rNext8 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask9 = 1ULL << reg8; + topRegistersMask9 = ((reg8 < 0) ? (((usqInt)(1)) >> (-reg8)) : (1ULL << reg8)); } } if (rTop12 == NoReg) { rTop12 = allocateRegNotConflictingWith(topRegistersMask9); } if (rNext8 == NoReg) { - rNext8 = allocateRegNotConflictingWith(1ULL << rTop12); + rNext8 = allocateRegNotConflictingWith(((rTop12 < 0) ? (((usqInt)(1)) >> (-rTop12)) : (1ULL << rTop12))); } assert(!(((rTop12 == NoReg) || (rNext8 == NoReg)))); @@ -36371,14 +36418,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg9 = (rNext9 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask10 = 1ULL << reg9; + topRegistersMask10 = ((reg9 < 0) ? (((usqInt)(1)) >> (-reg9)) : (1ULL << reg9)); } } if (rTop13 == NoReg) { rTop13 = allocateRegNotConflictingWith(topRegistersMask10); } if (rNext9 == NoReg) { - rNext9 = allocateRegNotConflictingWith(1ULL << rTop13); + rNext9 = allocateRegNotConflictingWith(((rTop13 < 0) ? (((usqInt)(1)) >> (-rTop13)) : (1ULL << rTop13))); } assert(!(((rTop13 == NoReg) || (rNext9 == NoReg)))); @@ -36409,14 +36456,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg10 = (rNext10 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask11 = 1ULL << reg10; + topRegistersMask11 = ((reg10 < 0) ? (((usqInt)(1)) >> (-reg10)) : (1ULL << reg10)); } } if (rTop14 == NoReg) { rTop14 = allocateRegNotConflictingWith(topRegistersMask11); } if (rNext10 == NoReg) { - rNext10 = allocateRegNotConflictingWith(1ULL << rTop14); + rNext10 = allocateRegNotConflictingWith(((rTop14 < 0) ? (((usqInt)(1)) >> (-rTop14)) : (1ULL << rTop14))); } assert(!(((rTop14 == NoReg) || (rNext10 == NoReg)))); @@ -36447,14 +36494,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg11 = (rNext13 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask12 = 1ULL << reg11; + topRegistersMask12 = ((reg11 < 0) ? (((usqInt)(1)) >> (-reg11)) : (1ULL << reg11)); } } if (rTop16 == NoReg) { rTop16 = allocateRegNotConflictingWith(topRegistersMask12); } if (rNext13 == NoReg) { - rNext13 = allocateRegNotConflictingWith(1ULL << rTop16); + rNext13 = allocateRegNotConflictingWith(((rTop16 < 0) ? (((usqInt)(1)) >> (-rTop16)) : (1ULL << rTop16))); } assert(!(((rTop16 == NoReg) || (rNext13 == NoReg)))); @@ -36557,14 +36604,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg13 = (rNext15 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask14 = 1ULL << reg13; + topRegistersMask14 = ((reg13 < 0) ? (((usqInt)(1)) >> (-reg13)) : (1ULL << reg13)); } } if (rTop21 == NoReg) { rTop21 = allocateRegNotConflictingWith(topRegistersMask14); } if (rNext15 == NoReg) { - rNext15 = allocateRegNotConflictingWith(1ULL << rTop21); + rNext15 = allocateRegNotConflictingWith(((rTop21 < 0) ? (((usqInt)(1)) >> (-rTop21)) : (1ULL << rTop21))); } assert(!(((rTop21 == NoReg) || (rNext15 == NoReg)))); @@ -36594,14 +36641,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg14 = (rNext16 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask15 = 1ULL << reg14; + topRegistersMask15 = ((reg14 < 0) ? (((usqInt)(1)) >> (-reg14)) : (1ULL << reg14)); } } if (rTop22 == NoReg) { rTop22 = allocateRegNotConflictingWith(topRegistersMask15); } if (rNext16 == NoReg) { - rNext16 = allocateRegNotConflictingWith(1ULL << rTop22); + rNext16 = allocateRegNotConflictingWith(((rTop22 < 0) ? (((usqInt)(1)) >> (-rTop22)) : (1ULL << rTop22))); } assert(!(((rTop22 == NoReg) || (rNext16 == NoReg)))); @@ -36898,7 +36945,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if (rTop25 == NoReg) { rTop25 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult29 = allocateRegNotConflictingWith(1ULL << rTop25); + rResult29 = allocateRegNotConflictingWith(((rTop25 < 0) ? (((usqInt)(1)) >> (-rTop25)) : (1ULL << rTop25))); assert(!(((rTop25 == NoReg) || (rResult29 == NoReg)))); pointer4 = rTop25; @@ -36927,7 +36974,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if (rTop26 == NoReg) { rTop26 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult30 = allocateRegNotConflictingWith(1ULL << rTop26); + rResult30 = allocateRegNotConflictingWith(((rTop26 < 0) ? (((usqInt)(1)) >> (-rTop26)) : (1ULL << rTop26))); assert(!(((rTop26 == NoReg) || (rResult30 == NoReg)))); pointer5 = rTop26; @@ -36953,7 +37000,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if (rTop110 == NoReg) { rTop110 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult112 = allocateRegNotConflictingWith(1ULL << rTop110); + rResult112 = allocateRegNotConflictingWith(((rTop110 < 0) ? (((usqInt)(1)) >> (-rTop110)) : (1ULL << rTop110))); assert(!(((rTop110 == NoReg) || (rResult112 == NoReg)))); pointer6 = rTop110; @@ -36979,7 +37026,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if (rTop28 == NoReg) { rTop28 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult32 = allocateRegNotConflictingWith(1ULL << rTop28); + rResult32 = allocateRegNotConflictingWith(((rTop28 < 0) ? (((usqInt)(1)) >> (-rTop28)) : (1ULL << rTop28))); assert(!(((rTop28 == NoReg) || (rResult32 == NoReg)))); pointer7 = rTop28; @@ -37229,13 +37276,13 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((registerOrNone(ssTop())) != NoReg) { rOopTop = registerOrNone(ssTop()); /* begin registerMaskFor: */ - topRegisterMask = 1ULL << rOopTop; + topRegisterMask = ((rOopTop < 0) ? (((usqInt)(1)) >> (-rOopTop)) : (1ULL << rOopTop)); } if (rTop29 == NoReg) { rTop29 = allocateRegNotConflictingWith(topRegisterMask); } if (rOopTop == NoReg) { - rOopTop = allocateRegNotConflictingWith(1ULL << rTop29); + rOopTop = allocateRegNotConflictingWith(((rTop29 < 0) ? (((usqInt)(1)) >> (-rTop29)) : (1ULL << rTop29))); } assert(!(((rTop29 == NoReg) || (rOopTop == NoReg)))); @@ -37494,7 +37541,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult = allocateRegNotConflictingWith(1ULL << rTop); + rResult = allocateRegNotConflictingWith(((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1ULL << rTop))); assert(!(((rTop == NoReg) || (rResult == NoReg)))); pointer = rTop; @@ -37519,7 +37566,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult1 = allocateRegNotConflictingWith(1ULL << rTop1); + rResult1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); assert(!(((rTop1 == NoReg) || (rResult1 == NoReg)))); pointer1 = rTop1; @@ -37544,7 +37591,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop2 == NoReg) { rTop2 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult2 = allocateRegNotConflictingWith(1ULL << rTop2); + rResult2 = allocateRegNotConflictingWith(((rTop2 < 0) ? (((usqInt)(1)) >> (-rTop2)) : (1ULL << rTop2))); assert(!(((rTop2 == NoReg) || (rResult2 == NoReg)))); pointer2 = rTop2; @@ -37570,7 +37617,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop11 == NoReg) { rTop11 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult11 = allocateRegNotConflictingWith(1ULL << rTop11); + rResult11 = allocateRegNotConflictingWith(((rTop11 < 0) ? (((usqInt)(1)) >> (-rTop11)) : (1ULL << rTop11))); assert(!(((rTop11 == NoReg) || (rResult11 == NoReg)))); pointer3 = rTop11; @@ -37596,7 +37643,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop4 == NoReg) { rTop4 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult4 = allocateRegNotConflictingWith(1ULL << rTop4); + rResult4 = allocateRegNotConflictingWith(((rTop4 < 0) ? (((usqInt)(1)) >> (-rTop4)) : (1ULL << rTop4))); assert(!(((rTop4 == NoReg) || (rResult4 == NoReg)))); pointer4 = rTop4; @@ -37707,7 +37754,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop28 == NoReg) { rTop28 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult8 = allocateRegNotConflictingWith(1ULL << rTop28); + rResult8 = allocateRegNotConflictingWith(((rTop28 < 0) ? (((usqInt)(1)) >> (-rTop28)) : (1ULL << rTop28))); assert(!(((rTop28 == NoReg) || (rResult8 == NoReg)))); size1 = rTop28; @@ -37748,7 +37795,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop111 == NoReg) { rTop111 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult13 = allocateRegNotConflictingWith(1ULL << rTop111); + rResult13 = allocateRegNotConflictingWith(((rTop111 < 0) ? (((usqInt)(1)) >> (-rTop111)) : (1ULL << rTop111))); assert(!(((rTop111 == NoReg) || (rResult13 == NoReg)))); size2 = rTop111; @@ -37806,18 +37853,18 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) nextRegisterMask2 = 0; if (rNext13 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask2 = 1ULL << rNext13; + nextRegisterMask2 = ((rNext13 < 0) ? (((usqInt)(1)) >> (-rNext13)) : (1ULL << rNext13)); } if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1ULL << rNextNext2); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNext2)) : (1ULL << rNextNext2))); } rTop30 = allocateRegNotConflictingWith(nextRegisterMask2); } if (rNext13 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask2 = 1ULL << rTop30; + nextRegisterMask2 = ((rTop30 < 0) ? (((usqInt)(1)) >> (-rTop30)) : (1ULL << rTop30)); if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1ULL << rNextNext2); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNext2)) : (1ULL << rNextNext2))); } rNext13 = allocateRegNotConflictingWith(nextRegisterMask2); } @@ -37880,18 +37927,18 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) nextRegisterMask3 = 0; if (rNext14 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask3 = 1ULL << rNext14; + nextRegisterMask3 = ((rNext14 < 0) ? (((usqInt)(1)) >> (-rNext14)) : (1ULL << rNext14)); } if (rNextNext3 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1ULL << rNextNext3); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNext3)) : (1ULL << rNextNext3))); } rTop31 = allocateRegNotConflictingWith(nextRegisterMask3); } if (rNext14 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask3 = 1ULL << rTop31; + nextRegisterMask3 = ((rTop31 < 0) ? (((usqInt)(1)) >> (-rTop31)) : (1ULL << rTop31)); if (rNextNext3 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1ULL << rNextNext3); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNext3)) : (1ULL << rNextNext3))); } rNext14 = allocateRegNotConflictingWith(nextRegisterMask3); } @@ -37942,14 +37989,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg11 = (rNext15 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask13 = 1ULL << reg11; + topRegistersMask13 = ((reg11 < 0) ? (((usqInt)(1)) >> (-reg11)) : (1ULL << reg11)); } } if (rTop32 == NoReg) { rTop32 = allocateRegNotConflictingWith(topRegistersMask13); } if (rNext15 == NoReg) { - rNext15 = allocateRegNotConflictingWith(1ULL << rTop32); + rNext15 = allocateRegNotConflictingWith(((rTop32 < 0) ? (((usqInt)(1)) >> (-rTop32)) : (1ULL << rTop32))); } assert(!(((rTop32 == NoReg) || (rNext15 == NoReg)))); @@ -38042,14 +38089,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } } if (rTop5 == NoReg) { rTop5 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1ULL << rTop5); + rNext = allocateRegNotConflictingWith(((rTop5 < 0) ? (((usqInt)(1)) >> (-rTop5)) : (1ULL << rTop5))); } assert(!(((rTop5 == NoReg) || (rNext == NoReg)))); @@ -38079,14 +38126,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg1 = (rNext1 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask1 = 1ULL << reg1; + topRegistersMask1 = ((reg1 < 0) ? (((usqInt)(1)) >> (-reg1)) : (1ULL << reg1)); } } if (rTop6 == NoReg) { rTop6 = allocateRegNotConflictingWith(topRegistersMask1); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop6); + rNext1 = allocateRegNotConflictingWith(((rTop6 < 0) ? (((usqInt)(1)) >> (-rTop6)) : (1ULL << rTop6))); } assert(!(((rTop6 == NoReg) || (rNext1 == NoReg)))); @@ -38191,14 +38238,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg4 = (rNext4 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask4 = 1ULL << reg4; + topRegistersMask4 = ((reg4 < 0) ? (((usqInt)(1)) >> (-reg4)) : (1ULL << reg4)); } } if (rTop14 == NoReg) { rTop14 = allocateRegNotConflictingWith(topRegistersMask4); } if (rNext4 == NoReg) { - rNext4 = allocateRegNotConflictingWith(1ULL << rTop14); + rNext4 = allocateRegNotConflictingWith(((rTop14 < 0) ? (((usqInt)(1)) >> (-rTop14)) : (1ULL << rTop14))); } assert(!(((rTop14 == NoReg) || (rNext4 == NoReg)))); @@ -38231,14 +38278,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg5 = (rNext11 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask5 = 1ULL << reg5; + topRegistersMask5 = ((reg5 < 0) ? (((usqInt)(1)) >> (-reg5)) : (1ULL << reg5)); } } if (rTop16 == NoReg) { rTop16 = allocateRegNotConflictingWith(topRegistersMask5); } if (rNext11 == NoReg) { - rNext11 = allocateRegNotConflictingWith(1ULL << rTop16); + rNext11 = allocateRegNotConflictingWith(((rTop16 < 0) ? (((usqInt)(1)) >> (-rTop16)) : (1ULL << rTop16))); } assert(!(((rTop16 == NoReg) || (rNext11 == NoReg)))); @@ -38356,14 +38403,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg6 = (rNext6 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask6 = 1ULL << reg6; + topRegistersMask6 = ((reg6 < 0) ? (((usqInt)(1)) >> (-reg6)) : (1ULL << reg6)); } } if (rTop18 == NoReg) { rTop18 = allocateRegNotConflictingWith(topRegistersMask6); } if (rNext6 == NoReg) { - rNext6 = allocateRegNotConflictingWith(1ULL << rTop18); + rNext6 = allocateRegNotConflictingWith(((rTop18 < 0) ? (((usqInt)(1)) >> (-rTop18)) : (1ULL << rTop18))); } assert(!(((rTop18 == NoReg) || (rNext6 == NoReg)))); @@ -38393,14 +38440,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg7 = (rNext12 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask7 = 1ULL << reg7; + topRegistersMask7 = ((reg7 < 0) ? (((usqInt)(1)) >> (-reg7)) : (1ULL << reg7)); } } if (rTop19 == NoReg) { rTop19 = allocateRegNotConflictingWith(topRegistersMask7); } if (rNext12 == NoReg) { - rNext12 = allocateRegNotConflictingWith(1ULL << rTop19); + rNext12 = allocateRegNotConflictingWith(((rTop19 < 0) ? (((usqInt)(1)) >> (-rTop19)) : (1ULL << rTop19))); } assert(!(((rTop19 == NoReg) || (rNext12 == NoReg)))); @@ -38429,14 +38476,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg8 = (rNext8 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask8 = 1ULL << reg8; + topRegistersMask8 = ((reg8 < 0) ? (((usqInt)(1)) >> (-reg8)) : (1ULL << reg8)); } } if (rTop21 == NoReg) { rTop21 = allocateRegNotConflictingWith(topRegistersMask8); } if (rNext8 == NoReg) { - rNext8 = allocateRegNotConflictingWith(1ULL << rTop21); + rNext8 = allocateRegNotConflictingWith(((rTop21 < 0) ? (((usqInt)(1)) >> (-rTop21)) : (1ULL << rTop21))); } assert(!(((rTop21 == NoReg) || (rNext8 == NoReg)))); @@ -38482,14 +38529,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg9 = (rNext9 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask9 = 1ULL << reg9; + topRegistersMask9 = ((reg9 < 0) ? (((usqInt)(1)) >> (-reg9)) : (1ULL << reg9)); } } if (rTop22 == NoReg) { rTop22 = allocateRegNotConflictingWith(topRegistersMask9); } if (rNext9 == NoReg) { - rNext9 = allocateRegNotConflictingWith(1ULL << rTop22); + rNext9 = allocateRegNotConflictingWith(((rTop22 < 0) ? (((usqInt)(1)) >> (-rTop22)) : (1ULL << rTop22))); } assert(!(((rTop22 == NoReg) || (rNext9 == NoReg)))); @@ -38548,7 +38595,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop110 == NoReg) { rTop110 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult12 = allocateRegNotConflictingWith(1ULL << rTop110); + rResult12 = allocateRegNotConflictingWith(((rTop110 < 0) ? (((usqInt)(1)) >> (-rTop110)) : (1ULL << rTop110))); assert(!(((rTop110 == NoReg) || (rResult12 == NoReg)))); pointer6 = rTop110; @@ -39064,14 +39111,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } } if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(topRegistersMask); } if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1ULL << rTop); + rNext = allocateRegNotConflictingWith(((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1ULL << rTop))); } assert(!(((rTop == NoReg) || (rNext == NoReg)))); @@ -39100,14 +39147,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg1 = (rNext1 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask1 = 1ULL << reg1; + topRegistersMask1 = ((reg1 < 0) ? (((usqInt)(1)) >> (-reg1)) : (1ULL << reg1)); } } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask1); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -39137,14 +39184,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg2 = (rNext2 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask2 = 1ULL << reg2; + topRegistersMask2 = ((reg2 < 0) ? (((usqInt)(1)) >> (-reg2)) : (1ULL << reg2)); } } if (rTop2 == NoReg) { rTop2 = allocateRegNotConflictingWith(topRegistersMask2); } if (rNext2 == NoReg) { - rNext2 = allocateRegNotConflictingWith(1ULL << rTop2); + rNext2 = allocateRegNotConflictingWith(((rTop2 < 0) ? (((usqInt)(1)) >> (-rTop2)) : (1ULL << rTop2))); } assert(!(((rTop2 == NoReg) || (rNext2 == NoReg)))); @@ -39174,14 +39221,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg3 = (rNext3 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask3 = 1ULL << reg3; + topRegistersMask3 = ((reg3 < 0) ? (((usqInt)(1)) >> (-reg3)) : (1ULL << reg3)); } } if (rTop3 == NoReg) { rTop3 = allocateRegNotConflictingWith(topRegistersMask3); } if (rNext3 == NoReg) { - rNext3 = allocateRegNotConflictingWith(1ULL << rTop3); + rNext3 = allocateRegNotConflictingWith(((rTop3 < 0) ? (((usqInt)(1)) >> (-rTop3)) : (1ULL << rTop3))); } assert(!(((rTop3 == NoReg) || (rNext3 == NoReg)))); @@ -39269,7 +39316,7 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if (rTop12 == NoReg) { rTop12 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult11 = allocateRegNotConflictingWith(1ULL << rTop12); + rResult11 = allocateRegNotConflictingWith(((rTop12 < 0) ? (((usqInt)(1)) >> (-rTop12)) : (1ULL << rTop12))); assert(!(((rTop12 == NoReg) || (rResult11 == NoReg)))); value5 = rTop12; @@ -39294,7 +39341,7 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if (rTop13 == NoReg) { rTop13 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult12 = allocateRegNotConflictingWith(1ULL << rTop13); + rResult12 = allocateRegNotConflictingWith(((rTop13 < 0) ? (((usqInt)(1)) >> (-rTop13)) : (1ULL << rTop13))); assert(!(((rTop13 == NoReg) || (rResult12 == NoReg)))); value6 = rTop13; @@ -39385,14 +39432,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg6 = (rNext6 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask6 = 1ULL << reg6; + topRegistersMask6 = ((reg6 < 0) ? (((usqInt)(1)) >> (-reg6)) : (1ULL << reg6)); } } if (rTop14 == NoReg) { rTop14 = allocateRegNotConflictingWith(topRegistersMask6); } if (rNext6 == NoReg) { - rNext6 = allocateRegNotConflictingWith(1ULL << rTop14); + rNext6 = allocateRegNotConflictingWith(((rTop14 < 0) ? (((usqInt)(1)) >> (-rTop14)) : (1ULL << rTop14))); } assert(!(((rTop14 == NoReg) || (rNext6 == NoReg)))); @@ -39425,14 +39472,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg7 = (rNext7 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask7 = 1ULL << reg7; + topRegistersMask7 = ((reg7 < 0) ? (((usqInt)(1)) >> (-reg7)) : (1ULL << reg7)); } } if (rTop15 == NoReg) { rTop15 = allocateRegNotConflictingWith(topRegistersMask7); } if (rNext7 == NoReg) { - rNext7 = allocateRegNotConflictingWith(1ULL << rTop15); + rNext7 = allocateRegNotConflictingWith(((rTop15 < 0) ? (((usqInt)(1)) >> (-rTop15)) : (1ULL << rTop15))); } assert(!(((rTop15 == NoReg) || (rNext7 == NoReg)))); @@ -39464,14 +39511,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg8 = (rNext11 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask8 = 1ULL << reg8; + topRegistersMask8 = ((reg8 < 0) ? (((usqInt)(1)) >> (-reg8)) : (1ULL << reg8)); } } if (rTop16 == NoReg) { rTop16 = allocateRegNotConflictingWith(topRegistersMask8); } if (rNext11 == NoReg) { - rNext11 = allocateRegNotConflictingWith(1ULL << rTop16); + rNext11 = allocateRegNotConflictingWith(((rTop16 < 0) ? (((usqInt)(1)) >> (-rTop16)) : (1ULL << rTop16))); } assert(!(((rTop16 == NoReg) || (rNext11 == NoReg)))); @@ -39503,14 +39550,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg9 = (rNext9 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask9 = 1ULL << reg9; + topRegistersMask9 = ((reg9 < 0) ? (((usqInt)(1)) >> (-reg9)) : (1ULL << reg9)); } } if (rTop18 == NoReg) { rTop18 = allocateRegNotConflictingWith(topRegistersMask9); } if (rNext9 == NoReg) { - rNext9 = allocateRegNotConflictingWith(1ULL << rTop18); + rNext9 = allocateRegNotConflictingWith(((rTop18 < 0) ? (((usqInt)(1)) >> (-rTop18)) : (1ULL << rTop18))); } assert(!(((rTop18 == NoReg) || (rNext9 == NoReg)))); @@ -39717,14 +39764,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg11 = (rNext12 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask13 = 1ULL << reg11; + topRegistersMask13 = ((reg11 < 0) ? (((usqInt)(1)) >> (-reg11)) : (1ULL << reg11)); } } if (rTop24 == NoReg) { rTop24 = allocateRegNotConflictingWith(topRegistersMask13); } if (rNext12 == NoReg) { - rNext12 = allocateRegNotConflictingWith(1ULL << rTop24); + rNext12 = allocateRegNotConflictingWith(((rTop24 < 0) ? (((usqInt)(1)) >> (-rTop24)) : (1ULL << rTop24))); } assert(!(((rTop24 == NoReg) || (rNext12 == NoReg)))); @@ -39755,14 +39802,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg12 = (rNext13 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask14 = 1ULL << reg12; + topRegistersMask14 = ((reg12 < 0) ? (((usqInt)(1)) >> (-reg12)) : (1ULL << reg12)); } } if (rTop25 == NoReg) { rTop25 = allocateRegNotConflictingWith(topRegistersMask14); } if (rNext13 == NoReg) { - rNext13 = allocateRegNotConflictingWith(1ULL << rTop25); + rNext13 = allocateRegNotConflictingWith(((rTop25 < 0) ? (((usqInt)(1)) >> (-rTop25)) : (1ULL << rTop25))); } assert(!(((rTop25 == NoReg) || (rNext13 == NoReg)))); @@ -39792,14 +39839,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg13 = (rNext15 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask15 = 1ULL << reg13; + topRegistersMask15 = ((reg13 < 0) ? (((usqInt)(1)) >> (-reg13)) : (1ULL << reg13)); } } if (rTop111 == NoReg) { rTop111 = allocateRegNotConflictingWith(topRegistersMask15); } if (rNext15 == NoReg) { - rNext15 = allocateRegNotConflictingWith(1ULL << rTop111); + rNext15 = allocateRegNotConflictingWith(((rTop111 < 0) ? (((usqInt)(1)) >> (-rTop111)) : (1ULL << rTop111))); } assert(!(((rTop111 == NoReg) || (rNext15 == NoReg)))); @@ -39911,7 +39958,7 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if (rTop114 == NoReg) { rTop114 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult13 = allocateRegNotConflictingWith(1ULL << rTop114); + rResult13 = allocateRegNotConflictingWith(((rTop114 < 0) ? (((usqInt)(1)) >> (-rTop114)) : (1ULL << rTop114))); assert(!(((rTop114 == NoReg) || (rResult13 == NoReg)))); value21 = rTop114; @@ -39940,14 +39987,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg17 = (rNext19 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask19 = 1ULL << reg17; + topRegistersMask19 = ((reg17 < 0) ? (((usqInt)(1)) >> (-reg17)) : (1ULL << reg17)); } } if (rTop32 == NoReg) { rTop32 = allocateRegNotConflictingWith(topRegistersMask19); } if (rNext19 == NoReg) { - rNext19 = allocateRegNotConflictingWith(1ULL << rTop32); + rNext19 = allocateRegNotConflictingWith(((rTop32 < 0) ? (((usqInt)(1)) >> (-rTop32)) : (1ULL << rTop32))); } assert(!(((rTop32 == NoReg) || (rNext19 == NoReg)))); @@ -39976,14 +40023,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg18 = (rNext20 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask20 = 1ULL << reg18; + topRegistersMask20 = ((reg18 < 0) ? (((usqInt)(1)) >> (-reg18)) : (1ULL << reg18)); } } if (rTop33 == NoReg) { rTop33 = allocateRegNotConflictingWith(topRegistersMask20); } if (rNext20 == NoReg) { - rNext20 = allocateRegNotConflictingWith(1ULL << rTop33); + rNext20 = allocateRegNotConflictingWith(((rTop33 < 0) ? (((usqInt)(1)) >> (-rTop33)) : (1ULL << rTop33))); } assert(!(((rTop33 == NoReg) || (rNext20 == NoReg)))); @@ -40013,14 +40060,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg19 = (rNext21 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask21 = 1ULL << reg19; + topRegistersMask21 = ((reg19 < 0) ? (((usqInt)(1)) >> (-reg19)) : (1ULL << reg19)); } } if (rTop34 == NoReg) { rTop34 = allocateRegNotConflictingWith(topRegistersMask21); } if (rNext21 == NoReg) { - rNext21 = allocateRegNotConflictingWith(1ULL << rTop34); + rNext21 = allocateRegNotConflictingWith(((rTop34 < 0) ? (((usqInt)(1)) >> (-rTop34)) : (1ULL << rTop34))); } assert(!(((rTop34 == NoReg) || (rNext21 == NoReg)))); @@ -40066,14 +40113,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg20 = (rNext22 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask22 = 1ULL << reg20; + topRegistersMask22 = ((reg20 < 0) ? (((usqInt)(1)) >> (-reg20)) : (1ULL << reg20)); } } if (rTop35 == NoReg) { rTop35 = allocateRegNotConflictingWith(topRegistersMask22); } if (rNext22 == NoReg) { - rNext22 = allocateRegNotConflictingWith(1ULL << rTop35); + rNext22 = allocateRegNotConflictingWith(((rTop35 < 0) ? (((usqInt)(1)) >> (-rTop35)) : (1ULL << rTop35))); } assert(!(((rTop35 == NoReg) || (rNext22 == NoReg)))); @@ -40119,14 +40166,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg21 = (rNext23 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask23 = 1ULL << reg21; + topRegistersMask23 = ((reg21 < 0) ? (((usqInt)(1)) >> (-reg21)) : (1ULL << reg21)); } } if (rTop36 == NoReg) { rTop36 = allocateRegNotConflictingWith(topRegistersMask23); } if (rNext23 == NoReg) { - rNext23 = allocateRegNotConflictingWith(1ULL << rTop36); + rNext23 = allocateRegNotConflictingWith(((rTop36 < 0) ? (((usqInt)(1)) >> (-rTop36)) : (1ULL << rTop36))); } assert(!(((rTop36 == NoReg) || (rNext23 == NoReg)))); @@ -40172,14 +40219,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg22 = (rNext24 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask24 = 1ULL << reg22; + topRegistersMask24 = ((reg22 < 0) ? (((usqInt)(1)) >> (-reg22)) : (1ULL << reg22)); } } if (rTop37 == NoReg) { rTop37 = allocateRegNotConflictingWith(topRegistersMask24); } if (rNext24 == NoReg) { - rNext24 = allocateRegNotConflictingWith(1ULL << rTop37); + rNext24 = allocateRegNotConflictingWith(((rTop37 < 0) ? (((usqInt)(1)) >> (-rTop37)) : (1ULL << rTop37))); } assert(!(((rTop37 == NoReg) || (rNext24 == NoReg)))); @@ -40270,14 +40317,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg23 = (rNext25 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask25 = 1ULL << reg23; + topRegistersMask25 = ((reg23 < 0) ? (((usqInt)(1)) >> (-reg23)) : (1ULL << reg23)); } } if (rTop40 == NoReg) { rTop40 = allocateRegNotConflictingWith(topRegistersMask25); } if (rNext25 == NoReg) { - rNext25 = allocateRegNotConflictingWith(1ULL << rTop40); + rNext25 = allocateRegNotConflictingWith(((rTop40 < 0) ? (((usqInt)(1)) >> (-rTop40)) : (1ULL << rTop40))); } assert(!(((rTop40 == NoReg) || (rNext25 == NoReg)))); @@ -40308,14 +40355,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg24 = (rNext26 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask26 = 1ULL << reg24; + topRegistersMask26 = ((reg24 < 0) ? (((usqInt)(1)) >> (-reg24)) : (1ULL << reg24)); } } if (rTop41 == NoReg) { rTop41 = allocateRegNotConflictingWith(topRegistersMask26); } if (rNext26 == NoReg) { - rNext26 = allocateRegNotConflictingWith(1ULL << rTop41); + rNext26 = allocateRegNotConflictingWith(((rTop41 < 0) ? (((usqInt)(1)) >> (-rTop41)) : (1ULL << rTop41))); } assert(!(((rTop41 == NoReg) || (rNext26 == NoReg)))); @@ -40346,14 +40393,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg25 = (rNext27 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask27 = 1ULL << reg25; + topRegistersMask27 = ((reg25 < 0) ? (((usqInt)(1)) >> (-reg25)) : (1ULL << reg25)); } } if (rTop42 == NoReg) { rTop42 = allocateRegNotConflictingWith(topRegistersMask27); } if (rNext27 == NoReg) { - rNext27 = allocateRegNotConflictingWith(1ULL << rTop42); + rNext27 = allocateRegNotConflictingWith(((rTop42 < 0) ? (((usqInt)(1)) >> (-rTop42)) : (1ULL << rTop42))); } assert(!(((rTop42 == NoReg) || (rNext27 == NoReg)))); @@ -40384,14 +40431,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg26 = (rNext28 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask28 = 1ULL << reg26; + topRegistersMask28 = ((reg26 < 0) ? (((usqInt)(1)) >> (-reg26)) : (1ULL << reg26)); } } if (rTop43 == NoReg) { rTop43 = allocateRegNotConflictingWith(topRegistersMask28); } if (rNext28 == NoReg) { - rNext28 = allocateRegNotConflictingWith(1ULL << rTop43); + rNext28 = allocateRegNotConflictingWith(((rTop43 < 0) ? (((usqInt)(1)) >> (-rTop43)) : (1ULL << rTop43))); } assert(!(((rTop43 == NoReg) || (rNext28 == NoReg)))); @@ -40461,14 +40508,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg27 = (rNext29 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask29 = 1ULL << reg27; + topRegistersMask29 = ((reg27 < 0) ? (((usqInt)(1)) >> (-reg27)) : (1ULL << reg27)); } } if (rTop46 == NoReg) { rTop46 = allocateRegNotConflictingWith(topRegistersMask29); } if (rNext29 == NoReg) { - rNext29 = allocateRegNotConflictingWith(1ULL << rTop46); + rNext29 = allocateRegNotConflictingWith(((rTop46 < 0) ? (((usqInt)(1)) >> (-rTop46)) : (1ULL << rTop46))); } assert(!(((rTop46 == NoReg) || (rNext29 == NoReg)))); @@ -40498,14 +40545,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg28 = (rNext30 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask30 = 1ULL << reg28; + topRegistersMask30 = ((reg28 < 0) ? (((usqInt)(1)) >> (-reg28)) : (1ULL << reg28)); } } if (rTop47 == NoReg) { rTop47 = allocateRegNotConflictingWith(topRegistersMask30); } if (rNext30 == NoReg) { - rNext30 = allocateRegNotConflictingWith(1ULL << rTop47); + rNext30 = allocateRegNotConflictingWith(((rTop47 < 0) ? (((usqInt)(1)) >> (-rTop47)) : (1ULL << rTop47))); } assert(!(((rTop47 == NoReg) || (rNext30 == NoReg)))); @@ -40543,14 +40590,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg29 = (rNext31 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask31 = 1ULL << reg29; + topRegistersMask31 = ((reg29 < 0) ? (((usqInt)(1)) >> (-reg29)) : (1ULL << reg29)); } } if (rTop48 == NoReg) { rTop48 = allocateRegNotConflictingWith(topRegistersMask31); } if (rNext31 == NoReg) { - rNext31 = allocateRegNotConflictingWith(1ULL << rTop48); + rNext31 = allocateRegNotConflictingWith(((rTop48 < 0) ? (((usqInt)(1)) >> (-rTop48)) : (1ULL << rTop48))); } assert(!(((rTop48 == NoReg) || (rNext31 == NoReg)))); @@ -40579,14 +40626,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg30 = (rNext32 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask32 = 1ULL << reg30; + topRegistersMask32 = ((reg30 < 0) ? (((usqInt)(1)) >> (-reg30)) : (1ULL << reg30)); } } if (rTop49 == NoReg) { rTop49 = allocateRegNotConflictingWith(topRegistersMask32); } if (rNext32 == NoReg) { - rNext32 = allocateRegNotConflictingWith(1ULL << rTop49); + rNext32 = allocateRegNotConflictingWith(((rTop49 < 0) ? (((usqInt)(1)) >> (-rTop49)) : (1ULL << rTop49))); } assert(!(((rTop49 == NoReg) || (rNext32 == NoReg)))); @@ -40616,14 +40663,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg31 = (rNext33 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask33 = 1ULL << reg31; + topRegistersMask33 = ((reg31 < 0) ? (((usqInt)(1)) >> (-reg31)) : (1ULL << reg31)); } } if (rTop50 == NoReg) { rTop50 = allocateRegNotConflictingWith(topRegistersMask33); } if (rNext33 == NoReg) { - rNext33 = allocateRegNotConflictingWith(1ULL << rTop50); + rNext33 = allocateRegNotConflictingWith(((rTop50 < 0) ? (((usqInt)(1)) >> (-rTop50)) : (1ULL << rTop50))); } assert(!(((rTop50 == NoReg) || (rNext33 == NoReg)))); @@ -40653,14 +40700,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg32 = (rNext110 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask34 = 1ULL << reg32; + topRegistersMask34 = ((reg32 < 0) ? (((usqInt)(1)) >> (-reg32)) : (1ULL << reg32)); } } if (rTop115 == NoReg) { rTop115 = allocateRegNotConflictingWith(topRegistersMask34); } if (rNext110 == NoReg) { - rNext110 = allocateRegNotConflictingWith(1ULL << rTop115); + rNext110 = allocateRegNotConflictingWith(((rTop115 < 0) ? (((usqInt)(1)) >> (-rTop115)) : (1ULL << rTop115))); } assert(!(((rTop115 == NoReg) || (rNext110 == NoReg)))); @@ -40766,7 +40813,7 @@ genLowcodeUnaryInlinePrimitive5(sqInt prim) if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult1 = allocateRegNotConflictingWith(1ULL << rTop1); + rResult1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); assert(!(((rTop1 == NoReg) || (rResult1 == NoReg)))); value = rTop1; @@ -41176,14 +41223,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } } if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(topRegistersMask); } if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1ULL << rTop); + rNext = allocateRegNotConflictingWith(((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1ULL << rTop))); } assert(!(((rTop == NoReg) || (rNext == NoReg)))); @@ -41213,14 +41260,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg1 = (rNext1 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask1 = 1ULL << reg1; + topRegistersMask1 = ((reg1 < 0) ? (((usqInt)(1)) >> (-reg1)) : (1ULL << reg1)); } } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask1); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -41303,14 +41350,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg3 = (rNext4 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask3 = 1ULL << reg3; + topRegistersMask3 = ((reg3 < 0) ? (((usqInt)(1)) >> (-reg3)) : (1ULL << reg3)); } } if (rTop5 == NoReg) { rTop5 = allocateRegNotConflictingWith(topRegistersMask3); } if (rNext4 == NoReg) { - rNext4 = allocateRegNotConflictingWith(1ULL << rTop5); + rNext4 = allocateRegNotConflictingWith(((rTop5 < 0) ? (((usqInt)(1)) >> (-rTop5)) : (1ULL << rTop5))); } assert(!(((rTop5 == NoReg) || (rNext4 == NoReg)))); @@ -41340,14 +41387,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg4 = (rNext11 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask4 = 1ULL << reg4; + topRegistersMask4 = ((reg4 < 0) ? (((usqInt)(1)) >> (-reg4)) : (1ULL << reg4)); } } if (rTop12 == NoReg) { rTop12 = allocateRegNotConflictingWith(topRegistersMask4); } if (rNext11 == NoReg) { - rNext11 = allocateRegNotConflictingWith(1ULL << rTop12); + rNext11 = allocateRegNotConflictingWith(((rTop12 < 0) ? (((usqInt)(1)) >> (-rTop12)) : (1ULL << rTop12))); } assert(!(((rTop12 == NoReg) || (rNext11 == NoReg)))); @@ -41376,14 +41423,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg5 = (rNext6 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask5 = 1ULL << reg5; + topRegistersMask5 = ((reg5 < 0) ? (((usqInt)(1)) >> (-reg5)) : (1ULL << reg5)); } } if (rTop7 == NoReg) { rTop7 = allocateRegNotConflictingWith(topRegistersMask5); } if (rNext6 == NoReg) { - rNext6 = allocateRegNotConflictingWith(1ULL << rTop7); + rNext6 = allocateRegNotConflictingWith(((rTop7 < 0) ? (((usqInt)(1)) >> (-rTop7)) : (1ULL << rTop7))); } assert(!(((rTop7 == NoReg) || (rNext6 == NoReg)))); @@ -41413,14 +41460,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg6 = (rNext7 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask6 = 1ULL << reg6; + topRegistersMask6 = ((reg6 < 0) ? (((usqInt)(1)) >> (-reg6)) : (1ULL << reg6)); } } if (rTop8 == NoReg) { rTop8 = allocateRegNotConflictingWith(topRegistersMask6); } if (rNext7 == NoReg) { - rNext7 = allocateRegNotConflictingWith(1ULL << rTop8); + rNext7 = allocateRegNotConflictingWith(((rTop8 < 0) ? (((usqInt)(1)) >> (-rTop8)) : (1ULL << rTop8))); } assert(!(((rTop8 == NoReg) || (rNext7 == NoReg)))); @@ -41584,18 +41631,18 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) nextRegisterMask2 = 0; if (rNext8 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask2 = 1ULL << rNext8; + nextRegisterMask2 = ((rNext8 < 0) ? (((usqInt)(1)) >> (-rNext8)) : (1ULL << rNext8)); } if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1ULL << rNextNext2); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNext2)) : (1ULL << rNextNext2))); } rTop9 = allocateRegNotConflictingWith(nextRegisterMask2); } if (rNext8 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask2 = 1ULL << rTop9; + nextRegisterMask2 = ((rTop9 < 0) ? (((usqInt)(1)) >> (-rTop9)) : (1ULL << rTop9)); if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1ULL << rNextNext2); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNext2)) : (1ULL << rNextNext2))); } rNext8 = allocateRegNotConflictingWith(nextRegisterMask2); } @@ -41636,14 +41683,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg7 = (rNext9 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask7 = 1ULL << reg7; + topRegistersMask7 = ((reg7 < 0) ? (((usqInt)(1)) >> (-reg7)) : (1ULL << reg7)); } } if (rTop10 == NoReg) { rTop10 = allocateRegNotConflictingWith(topRegistersMask7); } if (rNext9 == NoReg) { - rNext9 = allocateRegNotConflictingWith(1ULL << rTop10); + rNext9 = allocateRegNotConflictingWith(((rTop10 < 0) ? (((usqInt)(1)) >> (-rTop10)) : (1ULL << rTop10))); } assert(!(((rTop10 == NoReg) || (rNext9 == NoReg)))); @@ -41672,14 +41719,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg8 = (rNext10 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask8 = 1ULL << reg8; + topRegistersMask8 = ((reg8 < 0) ? (((usqInt)(1)) >> (-reg8)) : (1ULL << reg8)); } } if (rTop13 == NoReg) { rTop13 = allocateRegNotConflictingWith(topRegistersMask8); } if (rNext10 == NoReg) { - rNext10 = allocateRegNotConflictingWith(1ULL << rTop13); + rNext10 = allocateRegNotConflictingWith(((rTop13 < 0) ? (((usqInt)(1)) >> (-rTop13)) : (1ULL << rTop13))); } assert(!(((rTop13 == NoReg) || (rNext10 == NoReg)))); @@ -41707,7 +41754,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (frTop == NoReg) { frTop = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); } - frResult = allocateFloatRegNotConflictingWith(1ULL << frTop); + frResult = allocateFloatRegNotConflictingWith(((frTop < 0) ? (((usqInt)(1)) >> (-frTop)) : (1ULL << frTop))); assert(!(((frTop == NoReg) || (frResult == NoReg)))); value3 = frTop; @@ -41732,7 +41779,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (frTop1 == NoReg) { frTop1 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); } - frResult1 = allocateFloatRegNotConflictingWith(1ULL << frTop1); + frResult1 = allocateFloatRegNotConflictingWith(((frTop1 < 0) ? (((usqInt)(1)) >> (-frTop1)) : (1ULL << frTop1))); assert(!(((frTop1 == NoReg) || (frResult1 == NoReg)))); value4 = frTop1; @@ -41755,7 +41802,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (rTop14 == NoReg) { rTop14 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult3 = allocateRegNotConflictingWith(1ULL << rTop14); + rResult3 = allocateRegNotConflictingWith(((rTop14 < 0) ? (((usqInt)(1)) >> (-rTop14)) : (1ULL << rTop14))); assert(!(((rTop14 == NoReg) || (rResult3 == NoReg)))); value5 = rTop14; @@ -41779,7 +41826,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (rTop16 == NoReg) { rTop16 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult11 = allocateRegNotConflictingWith(1ULL << rTop16); + rResult11 = allocateRegNotConflictingWith(((rTop16 < 0) ? (((usqInt)(1)) >> (-rTop16)) : (1ULL << rTop16))); assert(!(((rTop16 == NoReg) || (rResult11 == NoReg)))); value6 = rTop16; @@ -41802,7 +41849,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (rTop17 == NoReg) { rTop17 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult5 = allocateRegNotConflictingWith(1ULL << rTop17); + rResult5 = allocateRegNotConflictingWith(((rTop17 < 0) ? (((usqInt)(1)) >> (-rTop17)) : (1ULL << rTop17))); assert(!(((rTop17 == NoReg) || (rResult5 == NoReg)))); pointerValue = rTop17; @@ -41853,24 +41900,24 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) nextRegisterMask3 = 0; if (rNext13 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask3 = 1ULL << rNext13; + nextRegisterMask3 = ((rNext13 < 0) ? (((usqInt)(1)) >> (-rNext13)) : (1ULL << rNext13)); } if (rNextNext3 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1ULL << rNextNext3); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNext3)) : (1ULL << rNextNext3))); } if (rNextNextNext2 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1ULL << rNextNextNext2); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNextNext2)) : (1ULL << rNextNextNext2))); } rTop18 = allocateRegNotConflictingWith(nextRegisterMask3); } if (rNext13 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask3 = 1ULL << rTop18; + nextRegisterMask3 = ((rTop18 < 0) ? (((usqInt)(1)) >> (-rTop18)) : (1ULL << rTop18)); if (rNextNext3 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1ULL << rNextNext3); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNext3)) : (1ULL << rNextNext3))); } if (rNextNextNext2 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1ULL << rNextNextNext2); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNextNext2)) : (1ULL << rNextNextNext2))); } rNext13 = allocateRegNotConflictingWith(nextRegisterMask3); } @@ -41878,7 +41925,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) /* begin registerMaskFor:and: */ nextRegisterMask3 = (1ULL << rTop18) | (1ULL << rNext13); if (rNextNextNext2 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1ULL << rNextNextNext2); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNextNext2)) : (1ULL << rNextNextNext2))); } rNextNext3 = allocateRegNotConflictingWith(nextRegisterMask3); } @@ -41951,24 +41998,24 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) nextRegisterMask4 = 0; if (rNext14 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask4 = 1ULL << rNext14; + nextRegisterMask4 = ((rNext14 < 0) ? (((usqInt)(1)) >> (-rNext14)) : (1ULL << rNext14)); } if (rNextNext4 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1ULL << rNextNext4); + nextRegisterMask4 = nextRegisterMask4 | (((rNextNext4 < 0) ? (((usqInt)(1)) >> (-rNextNext4)) : (1ULL << rNextNext4))); } if (rNextNextNext3 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1ULL << rNextNextNext3); + nextRegisterMask4 = nextRegisterMask4 | (((rNextNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNextNext3)) : (1ULL << rNextNextNext3))); } rTop19 = allocateRegNotConflictingWith(nextRegisterMask4); } if (rNext14 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask4 = 1ULL << rTop19; + nextRegisterMask4 = ((rTop19 < 0) ? (((usqInt)(1)) >> (-rTop19)) : (1ULL << rTop19)); if (rNextNext4 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1ULL << rNextNext4); + nextRegisterMask4 = nextRegisterMask4 | (((rNextNext4 < 0) ? (((usqInt)(1)) >> (-rNextNext4)) : (1ULL << rNextNext4))); } if (rNextNextNext3 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1ULL << rNextNextNext3); + nextRegisterMask4 = nextRegisterMask4 | (((rNextNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNextNext3)) : (1ULL << rNextNextNext3))); } rNext14 = allocateRegNotConflictingWith(nextRegisterMask4); } @@ -41976,7 +42023,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) /* begin registerMaskFor:and: */ nextRegisterMask4 = (1ULL << rTop19) | (1ULL << rNext14); if (rNextNextNext3 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1ULL << rNextNextNext3); + nextRegisterMask4 = nextRegisterMask4 | (((rNextNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNextNext3)) : (1ULL << rNextNextNext3))); } rNextNext4 = allocateRegNotConflictingWith(nextRegisterMask4); } @@ -42026,13 +42073,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg10 = (rNext15 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask10 = 1ULL << reg10; + topRegistersMask10 = ((reg10 < 0) ? (((usqInt)(1)) >> (-reg10)) : (1ULL << reg10)); } if (rTop20 == NoReg) { rTop20 = allocateFloatRegNotConflictingWith(topRegistersMask10); } if (rNext15 == NoReg) { - rNext15 = allocateFloatRegNotConflictingWith(1ULL << rTop20); + rNext15 = allocateFloatRegNotConflictingWith(((rTop20 < 0) ? (((usqInt)(1)) >> (-rTop20)) : (1ULL << rTop20))); } assert(!(((rTop20 == NoReg) || (rNext15 == NoReg)))); @@ -42057,13 +42104,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg11 = (rNext16 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask11 = 1ULL << reg11; + topRegistersMask11 = ((reg11 < 0) ? (((usqInt)(1)) >> (-reg11)) : (1ULL << reg11)); } if (rTop21 == NoReg) { rTop21 = allocateFloatRegNotConflictingWith(topRegistersMask11); } if (rNext16 == NoReg) { - rNext16 = allocateFloatRegNotConflictingWith(1ULL << rTop21); + rNext16 = allocateFloatRegNotConflictingWith(((rTop21 < 0) ? (((usqInt)(1)) >> (-rTop21)) : (1ULL << rTop21))); } assert(!(((rTop21 == NoReg) || (rNext16 == NoReg)))); @@ -42089,13 +42136,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg12 = (frNext = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask12 = 1ULL << reg12; + topRegistersMask12 = ((reg12 < 0) ? (((usqInt)(1)) >> (-reg12)) : (1ULL << reg12)); } if (frTop2 == NoReg) { frTop2 = allocateFloatRegNotConflictingWith(topRegistersMask12); } if (frNext == NoReg) { - frNext = allocateFloatRegNotConflictingWith(1ULL << frTop2); + frNext = allocateFloatRegNotConflictingWith(((frTop2 < 0) ? (((usqInt)(1)) >> (-frTop2)) : (1ULL << frTop2))); } rResult7 = allocateRegNotConflictingWith(0); assert(!(((frTop2 == NoReg) @@ -42141,13 +42188,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg13 = (frNext1 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask13 = 1ULL << reg13; + topRegistersMask13 = ((reg13 < 0) ? (((usqInt)(1)) >> (-reg13)) : (1ULL << reg13)); } if (frTop3 == NoReg) { frTop3 = allocateFloatRegNotConflictingWith(topRegistersMask13); } if (frNext1 == NoReg) { - frNext1 = allocateFloatRegNotConflictingWith(1ULL << frTop3); + frNext1 = allocateFloatRegNotConflictingWith(((frTop3 < 0) ? (((usqInt)(1)) >> (-frTop3)) : (1ULL << frTop3))); } rResult8 = allocateRegNotConflictingWith(0); assert(!(((frTop3 == NoReg) @@ -42193,13 +42240,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg14 = (frNext2 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask14 = 1ULL << reg14; + topRegistersMask14 = ((reg14 < 0) ? (((usqInt)(1)) >> (-reg14)) : (1ULL << reg14)); } if (frTop4 == NoReg) { frTop4 = allocateFloatRegNotConflictingWith(topRegistersMask14); } if (frNext2 == NoReg) { - frNext2 = allocateFloatRegNotConflictingWith(1ULL << frTop4); + frNext2 = allocateFloatRegNotConflictingWith(((frTop4 < 0) ? (((usqInt)(1)) >> (-frTop4)) : (1ULL << frTop4))); } rResult9 = allocateRegNotConflictingWith(0); assert(!(((frTop4 == NoReg) @@ -42245,13 +42292,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg15 = (frNext3 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask15 = 1ULL << reg15; + topRegistersMask15 = ((reg15 < 0) ? (((usqInt)(1)) >> (-reg15)) : (1ULL << reg15)); } if (frTop5 == NoReg) { frTop5 = allocateFloatRegNotConflictingWith(topRegistersMask15); } if (frNext3 == NoReg) { - frNext3 = allocateFloatRegNotConflictingWith(1ULL << frTop5); + frNext3 = allocateFloatRegNotConflictingWith(((frTop5 < 0) ? (((usqInt)(1)) >> (-frTop5)) : (1ULL << frTop5))); } rResult10 = allocateRegNotConflictingWith(0); assert(!(((frTop5 == NoReg) @@ -42297,13 +42344,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg16 = (frNext4 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask16 = 1ULL << reg16; + topRegistersMask16 = ((reg16 < 0) ? (((usqInt)(1)) >> (-reg16)) : (1ULL << reg16)); } if (frTop6 == NoReg) { frTop6 = allocateFloatRegNotConflictingWith(topRegistersMask16); } if (frNext4 == NoReg) { - frNext4 = allocateFloatRegNotConflictingWith(1ULL << frTop6); + frNext4 = allocateFloatRegNotConflictingWith(((frTop6 < 0) ? (((usqInt)(1)) >> (-frTop6)) : (1ULL << frTop6))); } rResult12 = allocateRegNotConflictingWith(0); assert(!(((frTop6 == NoReg) @@ -42348,13 +42395,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg17 = (rNext17 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask17 = 1ULL << reg17; + topRegistersMask17 = ((reg17 < 0) ? (((usqInt)(1)) >> (-reg17)) : (1ULL << reg17)); } if (rTop22 == NoReg) { rTop22 = allocateFloatRegNotConflictingWith(topRegistersMask17); } if (rNext17 == NoReg) { - rNext17 = allocateFloatRegNotConflictingWith(1ULL << rTop22); + rNext17 = allocateFloatRegNotConflictingWith(((rTop22 < 0) ? (((usqInt)(1)) >> (-rTop22)) : (1ULL << rTop22))); } assert(!(((rTop22 == NoReg) || (rNext17 == NoReg)))); @@ -42381,7 +42428,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (frTop7 == NoReg) { frTop7 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); } - frResult2 = allocateFloatRegNotConflictingWith(1ULL << frTop7); + frResult2 = allocateFloatRegNotConflictingWith(((frTop7 < 0) ? (((usqInt)(1)) >> (-frTop7)) : (1ULL << frTop7))); assert(!(((frTop7 == NoReg) || (frResult2 == NoReg)))); value12 = frTop7; @@ -42406,13 +42453,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg18 = (frNext5 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask18 = 1ULL << reg18; + topRegistersMask18 = ((reg18 < 0) ? (((usqInt)(1)) >> (-reg18)) : (1ULL << reg18)); } if (frTop8 == NoReg) { frTop8 = allocateFloatRegNotConflictingWith(topRegistersMask18); } if (frNext5 == NoReg) { - frNext5 = allocateFloatRegNotConflictingWith(1ULL << frTop8); + frNext5 = allocateFloatRegNotConflictingWith(((frTop8 < 0) ? (((usqInt)(1)) >> (-frTop8)) : (1ULL << frTop8))); } rResult13 = allocateRegNotConflictingWith(0); assert(!(((frTop8 == NoReg) @@ -42476,13 +42523,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg19 = (rNext18 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask20 = 1ULL << reg19; + topRegistersMask20 = ((reg19 < 0) ? (((usqInt)(1)) >> (-reg19)) : (1ULL << reg19)); } if (rTop23 == NoReg) { rTop23 = allocateFloatRegNotConflictingWith(topRegistersMask20); } if (rNext18 == NoReg) { - rNext18 = allocateFloatRegNotConflictingWith(1ULL << rTop23); + rNext18 = allocateFloatRegNotConflictingWith(((rTop23 < 0) ? (((usqInt)(1)) >> (-rTop23)) : (1ULL << rTop23))); } assert(!(((rTop23 == NoReg) || (rNext18 == NoReg)))); @@ -42618,13 +42665,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg20 = (rNext19 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask22 = 1ULL << reg20; + topRegistersMask22 = ((reg20 < 0) ? (((usqInt)(1)) >> (-reg20)) : (1ULL << reg20)); } if (rTop24 == NoReg) { rTop24 = allocateFloatRegNotConflictingWith(topRegistersMask22); } if (rNext19 == NoReg) { - rNext19 = allocateFloatRegNotConflictingWith(1ULL << rTop24); + rNext19 = allocateFloatRegNotConflictingWith(((rTop24 < 0) ? (((usqInt)(1)) >> (-rTop24)) : (1ULL << rTop24))); } assert(!(((rTop24 == NoReg) || (rNext19 == NoReg)))); @@ -42649,13 +42696,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg21 = (rNext20 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask23 = 1ULL << reg21; + topRegistersMask23 = ((reg21 < 0) ? (((usqInt)(1)) >> (-reg21)) : (1ULL << reg21)); } if (rTop25 == NoReg) { rTop25 = allocateFloatRegNotConflictingWith(topRegistersMask23); } if (rNext20 == NoReg) { - rNext20 = allocateFloatRegNotConflictingWith(1ULL << rTop25); + rNext20 = allocateFloatRegNotConflictingWith(((rTop25 < 0) ? (((usqInt)(1)) >> (-rTop25)) : (1ULL << rTop25))); } assert(!(((rTop25 == NoReg) || (rNext20 == NoReg)))); @@ -42681,13 +42728,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg22 = (frNext6 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask24 = 1ULL << reg22; + topRegistersMask24 = ((reg22 < 0) ? (((usqInt)(1)) >> (-reg22)) : (1ULL << reg22)); } if (frTop15 == NoReg) { frTop15 = allocateFloatRegNotConflictingWith(topRegistersMask24); } if (frNext6 == NoReg) { - frNext6 = allocateFloatRegNotConflictingWith(1ULL << frTop15); + frNext6 = allocateFloatRegNotConflictingWith(((frTop15 < 0) ? (((usqInt)(1)) >> (-frTop15)) : (1ULL << frTop15))); } rResult18 = allocateRegNotConflictingWith(0); assert(!(((frTop15 == NoReg) @@ -42733,13 +42780,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg23 = (frNext7 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask25 = 1ULL << reg23; + topRegistersMask25 = ((reg23 < 0) ? (((usqInt)(1)) >> (-reg23)) : (1ULL << reg23)); } if (frTop16 == NoReg) { frTop16 = allocateFloatRegNotConflictingWith(topRegistersMask25); } if (frNext7 == NoReg) { - frNext7 = allocateFloatRegNotConflictingWith(1ULL << frTop16); + frNext7 = allocateFloatRegNotConflictingWith(((frTop16 < 0) ? (((usqInt)(1)) >> (-frTop16)) : (1ULL << frTop16))); } rResult19 = allocateRegNotConflictingWith(0); assert(!(((frTop16 == NoReg) @@ -42785,13 +42832,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg24 = (frNext8 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask26 = 1ULL << reg24; + topRegistersMask26 = ((reg24 < 0) ? (((usqInt)(1)) >> (-reg24)) : (1ULL << reg24)); } if (frTop17 == NoReg) { frTop17 = allocateFloatRegNotConflictingWith(topRegistersMask26); } if (frNext8 == NoReg) { - frNext8 = allocateFloatRegNotConflictingWith(1ULL << frTop17); + frNext8 = allocateFloatRegNotConflictingWith(((frTop17 < 0) ? (((usqInt)(1)) >> (-frTop17)) : (1ULL << frTop17))); } rResult20 = allocateRegNotConflictingWith(0); assert(!(((frTop17 == NoReg) @@ -42837,13 +42884,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg25 = (frNext9 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask27 = 1ULL << reg25; + topRegistersMask27 = ((reg25 < 0) ? (((usqInt)(1)) >> (-reg25)) : (1ULL << reg25)); } if (frTop18 == NoReg) { frTop18 = allocateFloatRegNotConflictingWith(topRegistersMask27); } if (frNext9 == NoReg) { - frNext9 = allocateFloatRegNotConflictingWith(1ULL << frTop18); + frNext9 = allocateFloatRegNotConflictingWith(((frTop18 < 0) ? (((usqInt)(1)) >> (-frTop18)) : (1ULL << frTop18))); } rResult22 = allocateRegNotConflictingWith(0); assert(!(((frTop18 == NoReg) @@ -42889,13 +42936,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg26 = (frNext10 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask28 = 1ULL << reg26; + topRegistersMask28 = ((reg26 < 0) ? (((usqInt)(1)) >> (-reg26)) : (1ULL << reg26)); } if (frTop19 == NoReg) { frTop19 = allocateFloatRegNotConflictingWith(topRegistersMask28); } if (frNext10 == NoReg) { - frNext10 = allocateFloatRegNotConflictingWith(1ULL << frTop19); + frNext10 = allocateFloatRegNotConflictingWith(((frTop19 < 0) ? (((usqInt)(1)) >> (-frTop19)) : (1ULL << frTop19))); } rResult23 = allocateRegNotConflictingWith(0); assert(!(((frTop19 == NoReg) @@ -42940,13 +42987,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg27 = (rNext21 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask29 = 1ULL << reg27; + topRegistersMask29 = ((reg27 < 0) ? (((usqInt)(1)) >> (-reg27)) : (1ULL << reg27)); } if (rTop26 == NoReg) { rTop26 = allocateFloatRegNotConflictingWith(topRegistersMask29); } if (rNext21 == NoReg) { - rNext21 = allocateFloatRegNotConflictingWith(1ULL << rTop26); + rNext21 = allocateFloatRegNotConflictingWith(((rTop26 < 0) ? (((usqInt)(1)) >> (-rTop26)) : (1ULL << rTop26))); } assert(!(((rTop26 == NoReg) || (rNext21 == NoReg)))); @@ -42973,7 +43020,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (frTop20 == NoReg) { frTop20 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); } - frResult3 = allocateFloatRegNotConflictingWith(1ULL << frTop20); + frResult3 = allocateFloatRegNotConflictingWith(((frTop20 < 0) ? (((usqInt)(1)) >> (-frTop20)) : (1ULL << frTop20))); assert(!(((frTop20 == NoReg) || (frResult3 == NoReg)))); value24 = frTop20; @@ -42998,13 +43045,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg28 = (frNext11 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask30 = 1ULL << reg28; + topRegistersMask30 = ((reg28 < 0) ? (((usqInt)(1)) >> (-reg28)) : (1ULL << reg28)); } if (frTop21 == NoReg) { frTop21 = allocateFloatRegNotConflictingWith(topRegistersMask30); } if (frNext11 == NoReg) { - frNext11 = allocateFloatRegNotConflictingWith(1ULL << frTop21); + frNext11 = allocateFloatRegNotConflictingWith(((frTop21 < 0) ? (((usqInt)(1)) >> (-frTop21)) : (1ULL << frTop21))); } rResult24 = allocateRegNotConflictingWith(0); assert(!(((frTop21 == NoReg) @@ -43068,13 +43115,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg29 = (rNext22 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask32 = 1ULL << reg29; + topRegistersMask32 = ((reg29 < 0) ? (((usqInt)(1)) >> (-reg29)) : (1ULL << reg29)); } if (rTop27 == NoReg) { rTop27 = allocateFloatRegNotConflictingWith(topRegistersMask32); } if (rNext22 == NoReg) { - rNext22 = allocateFloatRegNotConflictingWith(1ULL << rTop27); + rNext22 = allocateFloatRegNotConflictingWith(((rTop27 < 0) ? (((usqInt)(1)) >> (-rTop27)) : (1ULL << rTop27))); } assert(!(((rTop27 == NoReg) || (rNext22 == NoReg)))); @@ -43591,11 +43638,11 @@ genPushMaybeContextReceiverVariable(sqInt slotIndex) AbstractInstruction *jmpSingle; /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ensureReceiverResultRegContainsSelf(); /* begin genPushMaybeContextSlotIndex: */ assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ voidReceiverResultRegContainsSelf(); @@ -43655,7 +43702,7 @@ genPushNewArrayBytecode(void) } else { /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << SendNumArgsReg)) | ((1U << ReceiverResultReg))), simStackPtr, simNativeStackPtr); } size = byte1 & 0x7F; if (!popValues) { @@ -43731,7 +43778,7 @@ genPushRemoteTempLongBytecode(void) (anInstruction->dependent = locateLiteralsize(offset, BytesPerOop)); } /* begin availableRegOrNoneNotConflictingWith: */ - regMask = 1ULL << tempVectReg; + regMask = ((tempVectReg < 0) ? (((usqInt)(1)) >> (-tempVectReg)) : (1ULL << tempVectReg)); remoteTempReg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); if (remoteTempReg == NoReg) { remoteTempReg = tempVectReg; @@ -44110,11 +44157,11 @@ genSpecialSelectorClass(void) || (topReg == ClassReg)) { /* begin ssAllocateRequiredReg:and: */ requiredReg1 = (topReg = SendNumArgsReg); - ssAllocateRequiredRegMaskupThroughupThroughNative((1ULL << requiredReg1) | (1U << ClassReg), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((((requiredReg1 < 0) ? (((usqInt)(1)) >> (-requiredReg1)) : (1ULL << requiredReg1))) | ((1U << ClassReg)), simStackPtr, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr, simNativeStackPtr); } ssPush(1); popToReg(ssTop(), topReg); @@ -44354,7 +44401,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean association = getLiteral(litVarIndex); voidReceiverResultRegContainsSelf(); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin genMoveConstant:R: */ if (shouldAnnotateObjectReference(association)) { annotateobjRef(gMoveCwR(association, ReceiverResultReg), association); @@ -44370,7 +44417,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean # if IMMUTABILITY if (needsImmCheck) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -44385,7 +44432,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -44449,7 +44496,7 @@ genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqI # endif // IMMUTABILITY ssPop(1); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ClassReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ssPush(1); genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); @@ -44498,7 +44545,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea # if IMMUTABILITY if (needsImmCheck1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -44513,7 +44560,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck1, 1); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck1); } @@ -44537,7 +44584,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt assert(needsFrame); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); /* begin MoveMw:r:R: */ offset = frameOffsetOfTemporary(remoteTempIndex); @@ -44550,7 +44597,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt # if IMMUTABILITY # endif - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -44745,13 +44792,13 @@ genVanillaInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -45066,12 +45113,12 @@ liveRegisters(void) } else { /* begin registerMaskFor: */ - regsSet = 1U << ReceiverResultReg; + regsSet = (1U << ReceiverResultReg); if ((methodOrBlockNumArgs <= 2 /* numRegArgs */) && (methodOrBlockNumArgs > 0)) { - regsSet = regsSet | (1U << Arg0Reg); + regsSet = regsSet | ((1U << Arg0Reg)); if (methodOrBlockNumArgs > 1) { - regsSet = regsSet | (1U << Arg1Reg); + regsSet = regsSet | ((1U << Arg1Reg)); } } } @@ -45180,13 +45227,13 @@ marshallSendArguments(sqInt numArgs) if (numArgs > 0) { if (numArgs > 1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 2, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 2, simNativeStackPtr); /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg1Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg1Reg), simStackPtr - 1, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 1, simNativeStackPtr); } } if (numArgs > 1) { @@ -45766,7 +45813,7 @@ ssAllocateRequiredFloatRegMaskupThroughupThroughNative(sqInt requiredRegsMask, s static void NoDbgRegParms ssAllocateRequiredFloatReg(sqInt requiredReg) { - ssAllocateRequiredFloatRegMaskupThroughupThroughNative(1ULL << requiredReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredFloatRegMaskupThroughupThroughNative(((requiredReg < 0) ? (((usqInt)(1)) >> (-requiredReg)) : (1ULL << requiredReg)), simStackPtr, simNativeStackPtr); } /* StackToRegisterMappingCogit>>#ssAllocateRequiredRegMask:upThrough:upThroughNative: */ diff --git a/spurlowcode64src/vm/cogitX64SysV.c b/spurlowcode64src/vm/cogitX64SysV.c index 6b2cd22220..c4eef7207f 100644 --- a/spurlowcode64src/vm/cogitX64SysV.c +++ b/spurlowcode64src/vm/cogitX64SysV.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + CCodeGenerator VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + StackToRegisterMappingCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 " __DATE__ ; +static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__cogitBuildInfo = __buildInfo; @@ -55,7 +55,7 @@ char *__cogitBuildInfo = __buildInfo; #define ArithmeticShiftRightRR 92 #define BadRegisterSet 1 #define BlockCreationBytecodeSize 4 -#define BSR 167 +#define BSR 169 #define BytecodeSetHasDirectedSuperSend 1 #define CArg0Reg 7 #define CArg1Reg 6 @@ -65,11 +65,11 @@ char *__cogitBuildInfo = __buildInfo; #define CallerSavedRegisterMask 0x2C6 #define CallFull 7 #define CallR 8 -#define CDQ 159 +#define CDQ 161 #if !defined(CheckRememberedInTrampoline) /* Allow this to be overridden on the compiler command line */ # define CheckRememberedInTrampoline 0 #endif -#define CLD 163 +#define CLD 165 #define ClassArray 7 #define ClassArrayCompactIndex 51 #define ClassBlockClosureCompactIndex 37 @@ -94,7 +94,7 @@ char *__cogitBuildInfo = __buildInfo; #define CMMaxUsageCount 7 #define CMMethod 2 #define CMOpenPIC 5 -#define CMPXCHGRMr 172 +#define CMPXCHGRMr 174 #define CmpC32R 113 #define CmpCqR 105 #define CmpCwR 112 @@ -109,7 +109,7 @@ char *__cogitBuildInfo = __buildInfo; #define ConvertRRs 150 #define ConvertRsR 149 #define ConvertRsRd 147 -#define CPUID 158 +#define CPUID 160 #define Debug DEBUGVM #define DisplacementMask 0x1F #define DisplacementX2N 0 @@ -153,11 +153,11 @@ char *__cogitBuildInfo = __buildInfo; #define HashMultiplyConstant 1664525 #define HashMultiplyMask 0xFFFFFFF #define HeaderIndex 0 -#define IDIVR 160 +#define IDIVR 162 #if !defined(IMMUTABILITY) /* Allow this to be overridden on the compiler command line */ # define IMMUTABILITY 1 #endif -#define IMULRR 161 +#define IMULRR 163 #define InFullBlock 2 #define InstanceSpecificationIndex 2 #define InstructionPointerIndex 1 @@ -208,11 +208,11 @@ char *__cogitBuildInfo = __buildInfo; #define Label 1 #define LargeContextSlots 62 #define LastJump 42 -#define LFENCE 168 +#define LFENCE 170 #undef LinkReg #define Literal 2 #define LiteralStart 1 -#define LOCK 171 +#define LOCK 173 #define LoadEffectiveAddressMwrR 88 #define LogicalShiftLeftCqR 95 #define LogicalShiftLeftCqRR 129 @@ -236,11 +236,11 @@ char *__cogitBuildInfo = __buildInfo; #define MethodCacheSelector 1 #define MethodIndex 3 #define MethodTooBig -4 -#define MFENCE 169 +#define MFENCE 171 #define MFMethodFlagHasContextFlag 1 #define MFMethodFlagIsBlockFlag 2 -#define MOVSB 165 -#define MOVSQ 166 +#define MOVSB 167 +#define MOVSQ 168 #define ModReg 3 #define ModRegInd 0 #define ModRegRegDisp32 2 @@ -259,10 +259,12 @@ char *__cogitBuildInfo = __buildInfo; #define MoveMbrR 65 #define MoveMs8rR 55 #define MoveMwrR 50 +#define MovePerfCnt64RL 159 +#define MovePerfCnt64RRL 158 #define MoveRA32 47 #define MoveRAb 49 #define MoveRAw 46 -#define MoveRAwNoVBR 174 +#define MoveRAwNoVBR 176 #define MoveRdM64r 76 #define MoveRdR 73 #define MoveRdRd 74 @@ -333,7 +335,7 @@ char *__cogitBuildInfo = __buildInfo; #define RCX 1 #define RDI 7 #define RDX 2 -#define REP 164 +#define REP 166 #define ReceiverIndex 5 #define ReceiverResultReg 2 #define RetN 9 @@ -342,12 +344,12 @@ char *__cogitBuildInfo = __buildInfo; #define RotateRightCqR 98 #define RSI 6 #define RSP 4 -#define SETE 173 +#define SETE 175 #define SelectorCannotInterpret 34 #define SelectorDoesNotUnderstand 20 #define SenderIndex 0 #define SendNumArgsReg 9 -#define SFENCE 170 +#define SFENCE 172 #define ShouldNotJIT -8 #define SIB1 0 #define SIB4 2 @@ -398,7 +400,7 @@ char *__cogitBuildInfo = __buildInfo; #define UnimplementedPrimitive -7 #define ValueIndex 1 #define VarBaseReg 3 -#define XCHGRR 162 +#define XCHGRR 164 #define XMM0L 0 #define XMM1L 1 #define XMM2L 2 @@ -549,7 +551,7 @@ static sqInt NoDbgRegParms concretizeAt(AbstractInstruction * self_in_concretize static sqInt NoDbgRegParms genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer); static sqInt NoDbgRegParms genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers); static sqInt NoDbgRegParms genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers); -static sqInt NoDbgRegParms genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg); +static sqInt NoDbgRegParms genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg); static sqInt NoDbgRegParms genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers); static void NoDbgRegParms genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister); static void NoDbgRegParms genWriteCSecondResultIntoReg(AbstractInstruction * self_in_genWriteCSecondResultIntoReg, sqInt abstractRegister); @@ -744,6 +746,8 @@ extern void linkSendAtintooffsetreceiver(sqInt callSiteReturnAddress, CogMethod static BytecodeDescriptor * loadBytesAndGetDescriptor(void); static void NoDbgRegParms loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc); static AbstractInstruction * NoDbgRegParms gMoveCwR(sqInt wordConstant, sqInt reg); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters); static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg); static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC); @@ -1111,6 +1115,7 @@ static sqInt NoDbgRegParms computeShiftRRSize(AbstractInstruction * self_in_comp static sqInt NoDbgRegParms computeSizeOfPushCw(AbstractInstruction * self_in_computeSizeOfPushCw); static sqInt NoDbgRegParms concretizeArithCqRWithROraxOpcode(AbstractInstruction * self_in_concretizeArithCqRWithROraxOpcode, sqInt regOpcode, sqInt raxOpcode); static sqInt NoDbgRegParms concretizeFill32(AbstractInstruction * self_in_concretizeFill32); +static sqInt NoDbgRegParms concretizeMovePerfCnt64RL(AbstractInstruction * self_in_concretizeMovePerfCnt64RL); static sqInt NoDbgRegParms concretizeMoveRX32rR(AbstractInstruction * self_in_concretizeMoveRX32rR); static sqInt NoDbgRegParms concretizeMoveX32rRR(AbstractInstruction * self_in_concretizeMoveX32rRR); static sqInt NoDbgRegParms concretizeOpRR(AbstractInstruction * self_in_concretizeOpRR, sqInt x64opcode); @@ -1260,6 +1265,7 @@ static sqInt genStoreAndPopReceiverVariableBytecode(void); static sqInt genStoreAndPopRemoteTempLongBytecode(void); static sqInt genStoreAndPopTemporaryVariableBytecode(void); static sqInt genStoreRemoteTempLongBytecode(void); +static void genTakeProfileSample(void); static sqInt genUnconditionalTrapBytecode(void); static void NoDbgRegParms loadNativeArgumentAddressto(sqInt baseOffset, sqInt reg); static void NoDbgRegParms loadNativeFramePointerInto(sqInt reg); @@ -2857,28 +2863,28 @@ addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *an static sqInt NoDbgRegParms availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << DPFPReg0)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg0))) != 0))) { return DPFPReg0; } - if (!(((liveRegsMask & (1U << DPFPReg1)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg1))) != 0))) { return DPFPReg1; } - if (!(((liveRegsMask & (1U << DPFPReg2)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg2))) != 0))) { return DPFPReg2; } - if (!(((liveRegsMask & (1U << DPFPReg3)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg3))) != 0))) { return DPFPReg3; } - if (!(((liveRegsMask & (1U << DPFPReg4)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg4))) != 0))) { return DPFPReg4; } - if (!(((liveRegsMask & (1U << DPFPReg5)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg5))) != 0))) { return DPFPReg5; } - if (!(((liveRegsMask & (1U << DPFPReg6)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg6))) != 0))) { return DPFPReg6; } - if (!(((liveRegsMask & (1U << DPFPReg7)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg7))) != 0))) { return DPFPReg7; } return NoReg; @@ -2993,9 +2999,9 @@ genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers) used immediately afterwards. */ - /* CogAbstractInstruction>>#genLoadStackPointersForFastPrimCall: */ + /* CogAbstractInstruction>>#genLoadStackPointersForPrimCall: */ static sqInt NoDbgRegParms -genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg) +genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg) { AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; @@ -5796,7 +5802,7 @@ compileCallFornumArgsargargargargfloatResultRegregsToSave(void *aRoutine, sqInt regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1ULL << resultRegOrNone)) - (1ULL << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ regMaskCopy = ((usqInt)regsToSave); @@ -5908,7 +5914,7 @@ compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numAr regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1ULL << resultRegOrNone)) - (1ULL << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ regMaskCopy = ((usqInt)regsToSave); @@ -6018,7 +6024,7 @@ compileCallFornumArgsargargargargresultRegresultRegregsToSave(void *aRoutine, sq regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1ULL << resultRegOrNone)) - (1ULL << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ regMaskCopy = ((usqInt)regsToSave); @@ -6149,7 +6155,7 @@ compileCallFornumArgsfloatArgfloatArgfloatArgfloatArgresultRegregsToSave(void *a regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1ULL << resultRegOrNone)) - (1ULL << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ regMaskCopy = ((usqInt)regsToSave); @@ -7886,7 +7892,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) startAddress = methodZoneBase; callerSavedReg = 0; pushedVarBaseReg = 0; - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { /* VarBaseReg is not caller-saved; must save and restore it, either by using an available caller-saved reg or push/pop. */ @@ -7919,7 +7925,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) /* begin checkLiteral:forInstruction: */ cStackPointerAddress(); anInstruction3 = genoperandoperand(MoveRAw, TempReg, cStackPointerAddress()); - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { if (pushedVarBaseReg) { gNativePopR(VarBaseReg); } @@ -9489,6 +9495,22 @@ gMoveCwR(sqInt wordConstant, sqInt reg) return anInstruction; } + /* Cogit>>#MovePerfCnt64R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters) +{ + assert(BytesPerWord == 8); + return genoperandoperand(MovePerfCnt64RL, destReg, liveRegisters); +} + + /* Cogit>>#MovePerfCnt64R:R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters) +{ + assert(BytesPerWord == 4); + return genoperandoperandoperand(MovePerfCnt64RRL, destRegLo, destRegHi, liveRegisters); +} + /* Answer the address of the null byte at the end of the method map. */ @@ -11012,11 +11034,14 @@ recordRunTimeObjectReferences(void) } } + +/* N.B. (self registerMaskFor: NoReg) = 0 */ + /* Cogit>>#registerMaskFor: */ static sqInt NoDbgRegParms registerMaskFor(sqInt reg) { - return 1ULL << reg; + return ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } /* Cogit>>#registerMaskFor:and: */ @@ -18330,7 +18355,7 @@ generateObjectRepresentationTrampolines(void) } # endif // IMMUTABILITY ceNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceNewHash", 1, ReceiverResultReg, null, null, null, /* begin emptyRegisterMask */ 0, 1, ReceiverResultReg, 0); - ceInlineNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceInlineNewHash", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, ReceiverResultReg, 0); + ceInlineNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceInlineNewHash", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))), 1, ReceiverResultReg, 0); /* begin genStoreCheckTrampoline */ if (CheckRememberedInTrampoline) { zeroOpcodeIndex(); @@ -18341,7 +18366,7 @@ generateObjectRepresentationTrampolines(void) genoperand(RetN, 0); jmpTarget(jumpSC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); } - ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))), 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), CheckRememberedInTrampoline); ceStoreCheckContextReceiverTrampoline = genStoreCheckContextReceiverTrampoline(); @@ -20478,7 +20503,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jumpRC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg)); jmpTarget(jumpImmutable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); @@ -20494,7 +20519,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* Store check */ jumpImmutable1 = genJumpImmutablescratchReg(ReceiverResultReg, SendNumArgsReg); - compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), 0 /* emptyRegisterMask */); genLoadStackPointers(backEnd()); @@ -21052,7 +21077,7 @@ registerMask(SimStackEntry * self_in_registerMask) || (((self_in_registerMask->type)) == SSRegister) ? (/* begin registerMaskFor: */ (reg = (self_in_registerMask->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : 0); } @@ -21065,7 +21090,7 @@ registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone) return (((self_in_registerMaskOrNone->type)) == SSRegister ? (/* begin registerMaskFor: */ (reg = (self_in_registerMaskOrNone->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : 0); } @@ -21263,7 +21288,7 @@ nativeFloatRegisterMask(CogSimStackNativeEntry * self_in_nativeFloatRegisterMask || (((self_in_nativeFloatRegisterMask->type)) == SSRegisterDoubleFloat) ? (/* begin registerMaskFor: */ (reg = (self_in_nativeFloatRegisterMask->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : 0); } @@ -21469,9 +21494,9 @@ nativeRegisterMask(CogSimStackNativeEntry * self_in_nativeRegisterMask) || (((self_in_nativeRegisterMask->type)) == SSRegisterDoubleFloat) ? (/* begin registerMaskFor: */ (reg = (self_in_nativeRegisterMask->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : (((self_in_nativeRegisterMask->type)) == SSRegisterPair - ? (1ULL << ((self_in_nativeRegisterMask->registerr))) | (1ULL << ((self_in_nativeRegisterMask->registerSecond))) + ? (((((self_in_nativeRegisterMask->registerr)) < 0) ? (((usqInt)(1)) >> (-((self_in_nativeRegisterMask->registerr)))) : (1ULL << ((self_in_nativeRegisterMask->registerr))))) | (((((self_in_nativeRegisterMask->registerSecond)) < 0) ? (((usqInt)(1)) >> (-((self_in_nativeRegisterMask->registerSecond)))) : (1ULL << ((self_in_nativeRegisterMask->registerSecond))))) : 0)); } @@ -21613,37 +21638,37 @@ isMergeFixup(BytecodeFixup * self_in_isMergeFixup) static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << Extra5Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra5Reg))) != 0))) { return Extra5Reg; } - if (!(((liveRegsMask & (1U << Extra4Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra4Reg))) != 0))) { return Extra4Reg; } - if (!(((liveRegsMask & (1U << Extra3Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra3Reg))) != 0))) { return Extra3Reg; } - if (!(((liveRegsMask & (1U << Extra2Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra2Reg))) != 0))) { return Extra2Reg; } - if (!(((liveRegsMask & (1U << Extra1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra1Reg))) != 0))) { return Extra1Reg; } - if (!(((liveRegsMask & (1U << Extra0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra0Reg))) != 0))) { return Extra0Reg; } - if (!(((liveRegsMask & (1U << Arg1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg1Reg))) != 0))) { return Arg1Reg; } - if (!(((liveRegsMask & (1U << Arg0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg0Reg))) != 0))) { return Arg0Reg; } - if (!(((liveRegsMask & (1U << SendNumArgsReg)) != 0))) { + if (!(((liveRegsMask & ((1U << SendNumArgsReg))) != 0))) { return SendNumArgsReg; } - if (!(((liveRegsMask & (1U << ClassReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ClassReg))) != 0))) { return ClassReg; } - if (!(((liveRegsMask & (1U << ReceiverResultReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ReceiverResultReg))) != 0))) { return ReceiverResultReg; } return NoReg; @@ -22222,6 +22247,11 @@ computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize) ? 1 : 0)); + case MovePerfCnt64RL: + + /* it is easier to calculate the right value by concretizing. We concretize twice, but so what? */ + return concretizeMovePerfCnt64RL(self_in_computeMaximumSize); + default: error("Case not found and no otherwise clause"); } @@ -22313,6 +22343,65 @@ concretizeFill32(AbstractInstruction * self_in_concretizeFill32) return 4; } + +/* Generate code for + 0x0: 50 pushq %rax + 0x1: 52 pushq %rdx + 0x2: 0f 31 rdtsc + 0x4: 48 c1 e2 20 shlq $0x20, %rdx + 0x8: 48 09 d0 orq %rdx, %rax + 0xb: 48 89 f8 movq %rdi, %rax + 0xe: 5a popq %rdx + 0xf: 58 popq %rax + et al */ + + /* CogX64Compiler>>#concretizeMovePerfCnt64RL */ +static sqInt NoDbgRegParms +concretizeMovePerfCnt64RL(AbstractInstruction * self_in_concretizeMovePerfCnt64RL) +{ + usqInt liveRegisters; + sqInt offset; + usqInt reg; + + reg = ((self_in_concretizeMovePerfCnt64RL->operands))[0]; + liveRegisters = ((self_in_concretizeMovePerfCnt64RL->operands))[1]; + offset = 0; + if (((liveRegisters & ((1U << RAX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[0] = 80; + offset += 1; + } + if (((liveRegisters & ((1U << RDX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 82; + offset += 1; + } + assert(!((reg == RDX))); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 15; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 1] = 49; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 2] = (rexRxb(self_in_concretizeMovePerfCnt64RL, 0, 0, RDX)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 3] = 193; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 4] = (modRMRO(self_in_concretizeMovePerfCnt64RL, ModReg, RDX, 4)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 5] = 32; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 6] = (rexRxb(self_in_concretizeMovePerfCnt64RL, RDX, 0, RAX)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 7] = 11; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 8] = (modRMRO(self_in_concretizeMovePerfCnt64RL, ModReg, RAX, RDX)); + offset += 9; + if (reg != RAX) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[11] = (rexRxb(self_in_concretizeMovePerfCnt64RL, reg, 0, RAX)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[12] = 137; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[13] = (modRMRO(self_in_concretizeMovePerfCnt64RL, ModReg, RAX, reg)); + offset += 3; + } + if (((liveRegisters & ((1U << RDX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 90; + offset += 1; + } + if (((liveRegisters & ((1U << RAX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 88; + offset += 1; + } + return offset; +} + /* CogX64Compiler>>#concretizeMoveRX32rR */ static sqInt NoDbgRegParms concretizeMoveRX32rR(AbstractInstruction * self_in_concretizeMoveRX32rR) @@ -25715,6 +25804,9 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) ((self_in_dispatchConcretize->machineCode))[skip28 + 1] = (modRMRO(self_in_dispatchConcretize, ModReg, srcReg28, destReg29)); return skip28 + 2; + case MovePerfCnt64RL: + return concretizeMovePerfCnt64RL(self_in_dispatchConcretize); + default: error("Case not found and no otherwise clause"); } @@ -26343,8 +26435,8 @@ genPushRegisterArgsForNumArgsscratchReg(AbstractInstruction * self_in_genPushReg /* This is a no-op on x64 SysV since the ABI passes up to 6 args in registers and trampolines currently observe a limit of 4. - But the WIN64 ABI allways reserve shadow space for saving up to 4 - parameter registers (even if less than 4 args). + But the WIN64 ABI always reserve shadow space for saving up to 4 parameter + registers (even if less than 4 args). */ /* CogX64Compiler>>#genRemoveNArgsFromStack: */ @@ -26366,7 +26458,7 @@ genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask) assert(!((((regMask & (registerMaskForand(RSP, RBP))) != 0)))); for (reg = RAX; reg <= R15; reg += 1) { - if (((regMask & (1ULL << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0)) { /* begin PopR: */ genoperand(PopR, reg); } @@ -26388,7 +26480,7 @@ genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask) assert(((R15 - RAX) + 1) == 16); assert(!((((regMask & (registerMaskForand(RSP, RBP))) != 0)))); for (reg = R15; reg >= RAX; reg += -1) { - if (((regMask & (1ULL << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0)) { /* begin PushR: */ genoperand(PushR, reg); } @@ -27220,53 +27312,42 @@ compileInterpreterPrimitive(void) static sqInt NoDbgRegParms compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) { - sqInt address2; + AbstractInstruction *anInstruction; + AbstractInstruction *anInstruction1; AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction12; + AbstractInstruction *anInstruction11; AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction15; + AbstractInstruction *anInstruction14; + AbstractInstruction *anInstruction16; + AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction18; AbstractInstruction *anInstruction19; AbstractInstruction *anInstruction2; + AbstractInstruction *anInstruction20; AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction24; - AbstractInstruction *anInstruction25; + AbstractInstruction *anInstruction22; AbstractInstruction *anInstruction26; AbstractInstruction *anInstruction27; + AbstractInstruction *anInstruction28; AbstractInstruction *anInstruction29; AbstractInstruction *anInstruction3; + AbstractInstruction *anInstruction30; AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction33; - AbstractInstruction *anInstruction34; - AbstractInstruction *anInstruction35; - AbstractInstruction *anInstruction36; - AbstractInstruction *anInstruction37; - AbstractInstruction *anInstruction38; - AbstractInstruction *anInstruction39; AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction40; AbstractInstruction *anInstruction41; - AbstractInstruction *anInstruction5; AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; AbstractInstruction *anInstruction8; - AbstractInstruction * continuePostSampleNonPrim; - AbstractInstruction * continuePostSamplePrim; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; - AbstractInstruction * jmpSampleNonPrim; - AbstractInstruction * jmpSamplePrim; + AbstractInstruction * jumpToTakeSample; + sqInt liveRegisters; sqInt offset; sqInt offset1; sqInt offset2; - sqInt operand1; - sqInt operand3; sqInt reg; sqInt retpc; - continuePostSampleNonPrim = ((AbstractInstruction *) 0); - continuePostSamplePrim = ((AbstractInstruction *) 0); - jmpSampleNonPrim = ((AbstractInstruction *) 0); - jmpSamplePrim = ((AbstractInstruction *) 0); + jumpToTakeSample = ((AbstractInstruction *) 0); assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); genExternalizePointersForPrimitiveCall(); /* begin genLoadCStackPointersForPrimCall */ @@ -27276,41 +27357,28 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) else { genLoadCStackPointer(backEnd); } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick if so */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction2 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpSampleNonPrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSampleNonPrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } if (recordPrimTraceForMethod(methodObj)) { genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction37 = genoperandoperand(MoveCqR, 0, TempReg); + anInstruction18 = genoperandoperand(MoveCqR, 0, TempReg); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction38 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); + anInstruction19 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); + anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); } /* begin checkLiteral:forInstruction: */ argumentCountAddress(); - anInstruction39 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); + anInstruction20 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { /* begin checkLiteral:forInstruction: */ ((sqInt)primitiveRoutine); - anInstruction5 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); + anInstruction1 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); /* begin checkLiteral:forInstruction: */ primitiveFunctionPointerAddress(); - anInstruction6 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); + anInstruction2 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); } if (((flags & (PrimCallNeedsNewMethod + PrimCallMayEndureCodeCompaction)) != 0)) { @@ -27322,26 +27390,25 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) /* begin MoveMw:r:R: */ offset = offsetof(CogMethod, methodObject); /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); + anInstruction3 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); /* begin checkLiteral:forInstruction: */ newMethodAddress(); - anInstruction8 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); + anInstruction4 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); } /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction40 = genoperand(PrefetchAw, primFailCodeAddress()); + anInstruction22 = genoperand(PrefetchAw, primFailCodeAddress()); if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - /* Sideways call the C primitive routine so that we return through cePrimReturnEnterCogCode. */ /* On Spur ceActivateFailingPrimitiveMethod: would like to retry if forwarders are found. So insist on PrimCallNeedsPrimitiveFunction being set too. */ assert(((flags & PrimCallNeedsPrimitiveFunction) != 0)); /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l32; + goto l20; assert(0 <= 4); if (null < NoReg) { /* begin MoveCq:R: */ - anInstruction12 = genoperandoperand(MoveCqR, -2 - null, CArg0Reg); + anInstruction11 = genoperandoperand(MoveCqR, -2 - null, CArg0Reg); } else { if (null != CArg0Reg) { @@ -27379,109 +27446,88 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) genoperandoperand(MoveRR, null, CArg3Reg); } } - l32: /* end genMarshallNArgs:arg:arg:arg:arg: */; + l20: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin genSubstituteReturnAddress: */ retpc = (((flags & PrimCallCollectsProfileSamples) != 0) ? cePrimReturnEnterCogCodeProfiling : cePrimReturnEnterCogCode); /* begin checkLiteral:forInstruction: */ - anInstruction13 = genoperand(PushCw, retpc); + anInstruction8 = genoperand(PushCw, retpc); /* begin gen:literal: */ - anInstruction10 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); - jmp = (jmpSamplePrim = (continuePostSamplePrim = null)); + anInstruction6 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); + return 0; } - else { - - /* Call the C primitive routine. */ - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l49; - assert(0 <= 4); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg0Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg1Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg2Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg3Reg); - l49: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin gen:literal: */ - anInstruction15 = genoperand(CallFull, ((sqInt)primitiveRoutine)); - /* begin genRemoveNArgsFromStack: */ - assert(0 <= 4); - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction18 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpSamplePrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSamplePrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - maybeCompileRetryOnPrimitiveFail(primitiveIndex); - /* begin MoveAw:R: */ - address2 = instructionPointerAddress(); - reg = ClassReg; - /* begin checkLiteral:forInstruction: */ - anInstruction24 = genoperandoperand(MoveAwR, address2, reg); - genLoadStackPointers(backEnd); + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + goto l43; + assert(0 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg0Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg1Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg2Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg3Reg); + l43: /* end genMarshallNArgs:arg:arg:arg:arg: */; + /* begin gen:literal: */ + anInstruction10 = genoperand(CallFull, ((sqInt)primitiveRoutine)); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 4); + maybeCompileRetryOnPrimitiveFail(primitiveIndex); + genLoadStackPointersForPrimCall(backEnd, ClassReg); + /* begin checkLiteral:forInstruction: */ + instructionPointerAddress(); + anInstruction13 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); + /* begin checkQuickConstant:forInstruction: */ + anInstruction14 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + /* begin checkLiteral:forInstruction: */ + primFailCodeAddress(); + anInstruction26 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + flag("ask concrete code gen if move sets condition codes?"); + /* begin checkQuickConstant:forInstruction: */ + anInstruction27 = genoperandoperand(CmpCqR, 0, TempReg); + /* begin JumpNonZero: */ + jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + /* begin preferredRegisterForMovePerfCnt64RL */ + reg = RAX; + gMovePerfCnt64RL(reg, liveRegisters); /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction25 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - /* begin PushR: */ - genoperand(PushR, ClassReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction26 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset1 = BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction27 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, BytesPerWord); + nextProfileTickAddress(); + anInstruction30 = genoperandoperand(MoveAwR, nextProfileTickAddress(), Arg1Reg); + /* begin CmpR:R: */ + assert(!((reg == SPReg))); + genoperandoperand(CmpRR, reg, Arg1Reg); + /* begin JumpGreaterOrEqual: */ + jumpToTakeSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l57; + l57: /* end genCheckForProfileTimerTick: */; } + /* begin MoveMw:r:R: */ + offset1 = BytesPerWord; + /* begin checkQuickConstant:forInstruction: */ + anInstruction28 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); + continueAfterProfileSample = anInstruction28; + /* begin RetN: */ + genoperand(RetN, BytesPerWord); if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* The sample is collected by cePrimReturnEnterCogCode for external calls */ - if (!(jmpSamplePrim == null)) { - - /* Call ceCheckProfileTick: to record sample and then continue. */ - jmpTarget(jmpSamplePrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin gen:literal: */ - operand1 = ((usqIntptr_t)ceCheckProfileTick); - /* begin checkLiteral:forInstruction: */ - anInstruction29 = genoperand(CallFull, operand1); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSamplePrim)); - } - jmpTarget(jmpSampleNonPrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction34 = genoperandoperand(MoveCqR, 0, TempReg); - /* begin checkLiteral:forInstruction: */ - newMethodAddress(); - anInstruction35 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); - /* begin gen:literal: */ - operand3 = ((usqIntptr_t)ceCheckProfileTick); + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); /* begin checkLiteral:forInstruction: */ - anInstruction33 = genoperand(CallFull, operand3); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSampleNonPrim)); - } - if (!(jmp == null)) { - - /* Jump to restore of receiver reg and proceed to frame build for failure. */ - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin MoveMw:r:R: */ - offset2 = BytesPerWord * (methodOrBlockNumArgs + (1)); + instructionPointerAddress(); + anInstruction16 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction36 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); + anInstruction17 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + /* begin Jump: */ + genoperand(Jump, ((sqInt)continueAfterProfileSample)); } + jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + /* begin MoveMw:r:R: */ + offset2 = BytesPerWord * (methodOrBlockNumArgs + (1)); + /* begin checkQuickConstant:forInstruction: */ + anInstruction29 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); return 0; } @@ -27511,7 +27557,7 @@ compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)) if ((methodOrBlockNumArgs > 2 /* numRegArgs */) || (methodOrBlockNumArgs == 0)) { /* begin registerMaskFor: */ - liveRegsMask = 1U << ReceiverResultReg; + liveRegsMask = (1U << ReceiverResultReg); } else { if (methodOrBlockNumArgs > 1) { @@ -27597,51 +27643,57 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags AbstractInstruction *anInstruction11; AbstractInstruction *anInstruction12; AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; AbstractInstruction *anInstruction16; AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction18; AbstractInstruction *anInstruction19; AbstractInstruction *anInstruction2; AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; AbstractInstruction *anInstruction22; AbstractInstruction *anInstruction23; + AbstractInstruction *anInstruction27; + AbstractInstruction *anInstruction28; + AbstractInstruction *anInstruction29; + AbstractInstruction *anInstruction30; AbstractInstruction *anInstruction4; AbstractInstruction *anInstruction5; AbstractInstruction *anInstruction6; AbstractInstruction *anInstruction8; AbstractInstruction *anInstruction9; sqInt calleeSavedRegisterMask; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; + AbstractInstruction * jumpToTakeSample; + sqInt liveRegisters; sqInt offset; sqInt offset1; sqInt operand1; + sqInt reg; sqInt retpcOffset; AbstractInstruction * retry; AbstractInstruction * skip; sqInt spRegSaveRegister; + jumpToTakeSample = ((AbstractInstruction *) 0); assert(((flags & PrimCallOnSmalltalkStack) != 0)); assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); if (recordFastCCallPrimTraceForMethod(methodObj)) { genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction18 = genoperandoperand(MoveCqR, 0, TempReg); + anInstruction20 = genoperandoperand(MoveCqR, 0, TempReg); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction19 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); + anInstruction22 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); } /* begin checkLiteral:forInstruction: */ argumentCountAddress(); - anInstruction20 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); + anInstruction23 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); genExternalizeStackPointerForFastPrimitiveCall(); - calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | (1U << ClassReg)) - (1U << ClassReg)); + calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | ((1U << ClassReg))) - ((1U << ClassReg))); spRegSaveRegister = NoReg; /* begin Label */ retry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); @@ -27650,22 +27702,54 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags } else { } + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + goto l53; + assert(0 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg0Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg1Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg2Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg3Reg); + l53: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin gen:literal: */ - anInstruction2 = genoperand(CallFull, primitiveRoutine); + anInstruction2 = genoperand(CallFull, ((sqInt)primitiveRoutine)); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 4); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction21 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + anInstruction27 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); if (spRegSaveRegister != NoReg) { /* begin MoveR:R: */ genoperandoperand(MoveRR, spRegSaveRegister, SPReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperand(CmpCqR, 0, TempReg); + anInstruction28 = genoperandoperand(CmpCqR, 0, TempReg); /* begin JumpNonZero: */ jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + /* begin preferredRegisterForMovePerfCnt64RL */ + reg = RAX; + gMovePerfCnt64RL(reg, liveRegisters); + /* begin checkLiteral:forInstruction: */ + nextProfileTickAddress(); + anInstruction30 = genoperandoperand(MoveAwR, nextProfileTickAddress(), Arg1Reg); + /* begin CmpR:R: */ + assert(!((reg == SPReg))); + genoperandoperand(CmpRR, reg, Arg1Reg); + /* begin JumpGreaterOrEqual: */ + jumpToTakeSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l66; + l66: /* end genCheckForProfileTimerTick: */; + } /* begin checkLiteral:forInstruction: */ stackPointerAddress(); - anInstruction23 = genoperandoperand(MoveAwR, stackPointerAddress(), TempReg); + anInstruction29 = genoperandoperand(MoveAwR, stackPointerAddress(), TempReg); + continueAfterProfileSample = anInstruction29; /* The original retpc is (argumentCount + 1) words below stackPointer. */ retpcOffset = -((methodOrBlockNumArgs + 1) * BytesPerWord); @@ -27679,6 +27763,12 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags anInstruction6 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, TempReg); /* begin RetN: */ genoperand(RetN, 0); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); + /* begin Jump: */ + genoperand(Jump, ((sqInt)continueAfterProfileSample)); + } jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); if ((accessorDepthForExternalPrimitiveMethod(methodObj)) >= 0) { @@ -27709,20 +27799,32 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags else { genLoadCStackPointer(backEnd); } + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + goto l36; + assert(0 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg0Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg1Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg2Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg3Reg); + l36: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin gen:literal: */ operand1 = ((usqIntptr_t)checkForAndFollowForwardedPrimitiveState); /* begin checkLiteral:forInstruction: */ anInstruction8 = genoperand(CallFull, operand1); - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(CmpCqR, 0, ABIResultReg); + anInstruction16 = genoperandoperand(CmpCqR, 0, ABIResultReg); /* begin JumpZero: */ skip = genConditionalBranchoperand(JumpZero, ((sqInt)0)); /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperand(MoveCqR, 0, TempReg); + anInstruction17 = genoperandoperand(MoveCqR, 0, TempReg); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction16 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); + anInstruction18 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); /* begin Jump: */ genoperand(Jump, ((sqInt)retry)); jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); @@ -27731,14 +27833,14 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags /* must reload SPReg to undo any alignment change, */ if (((flags & PrimCallOnSmalltalkStackAlign2x) != 0)) { - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); } } - if (((ABICallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((ABICallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* begin MoveMw:r:R: */ offset1 = (methodOrBlockNumArgs + (1)) * BytesPerWord; /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); + anInstruction19 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); } return 0; } @@ -28760,23 +28862,24 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) { sqInt address1; AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction10; + AbstractInstruction *anInstruction11; AbstractInstruction *anInstruction12; AbstractInstruction *anInstruction13; AbstractInstruction *anInstruction14; AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction18; + AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; + AbstractInstruction *anInstruction7; AbstractInstruction *anInstruction8; AbstractInstruction *anInstruction9; sqInt callTarget; AbstractInstruction *continuePostSample; AbstractInstruction *jmpFail; AbstractInstruction *jmpSample; + sqInt liveRegisters; sqInt quickConstant; sqInt reg; + sqInt reg1; continuePostSample = ((AbstractInstruction *) 0); jmpSample = ((AbstractInstruction *) 0); @@ -28785,56 +28888,63 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) quickConstant = varBaseAddress(); /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - if (profiling) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick: if so. - N.B. nextProfileTick is 64-bits so 32-bit systems need to test both halves. */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction3 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpSample = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction13 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + anInstruction12 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); flag("ask concrete code gen if move sets condition codes?"); /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(CmpCqR, 0, TempReg); + anInstruction13 = genoperandoperand(CmpCqR, 0, TempReg); /* begin JumpNonZero: */ jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (profiling + && (1)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + /* begin preferredRegisterForMovePerfCnt64RL */ + reg = RAX; + gMovePerfCnt64RL(reg, liveRegisters); + /* begin checkLiteral:forInstruction: */ + nextProfileTickAddress(); + anInstruction3 = genoperandoperand(MoveAwR, nextProfileTickAddress(), Arg1Reg); + /* begin CmpR:R: */ + assert(!((reg == SPReg))); + genoperandoperand(CmpRR, reg, Arg1Reg); + /* begin JumpGreaterOrEqual: */ + jmpSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l18; + l18: /* end genCheckForProfileTimerTick: */; + /* begin Label */ + continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); + } /* begin checkLiteral:forInstruction: */ instructionPointerAddress(); - anInstruction8 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); + anInstruction7 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); + anInstruction8 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + anInstruction9 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jmpFail, checkLiteralforInstruction(newMethodAddress(), genoperandoperand(MoveAwR, newMethodAddress(), SendNumArgsReg))); /* begin checkLiteral:forInstruction: */ cStackPointerAddress(); - anInstruction15 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); + anInstruction14 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); compileCallFornumArgsargargargargresultRegregsToSave(ceActivateFailingPrimitiveMethod, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); /* begin MoveAw:R: */ address1 = instructionPointerAddress(); - reg = ClassReg; + reg1 = ClassReg; /* begin checkLiteral:forInstruction: */ - anInstruction16 = genoperandoperand(MoveAwR, address1, reg); + anInstruction15 = genoperandoperand(MoveAwR, address1, reg1); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveMwrR, BytesPerWord, SPReg, ReceiverResultReg); + anInstruction11 = genoperandoperandoperand(MoveMwrR, BytesPerWord, SPReg, ReceiverResultReg); /* begin PushR: */ genoperand(PushR, ClassReg); /* begin RetN: */ genoperand(RetN, BytesPerWord); - if (profiling) { + if (profiling + && (1)) { /* Call ceCheckProfileTick: to record sample and then continue. newMethod should be up-to-date. Need to save and restore the link reg around this call. */ @@ -28843,7 +28953,7 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) /* begin CallFullRT: */ callTarget = (usqIntptr_t)ceCheckProfileTick; /* begin checkLiteral:forInstruction: */ - anInstruction18 = genoperand(CallFull, callTarget); + anInstruction17 = genoperand(CallFull, callTarget); /* begin Jump: */ genoperand(Jump, ((sqInt)continuePostSample)); } @@ -29198,6 +29308,61 @@ genStoreRemoteTempLongBytecode(void) && (shouldAnnotateObjectReference(((ssTop())->constant))))); } + /* SimpleStackBasedCogit>>#genTakeProfileSample */ +static void +genTakeProfileSample(void) +{ + AbstractInstruction *anInstruction1; + AbstractInstruction *anInstruction2; + AbstractInstruction *anInstruction3; + AbstractInstruction *anInstruction4; + sqInt operand1; + + addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + assert(1 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, ClassReg, CArg0Reg); + goto l12; + if (null < NoReg) { + /* begin MoveCq:R: */ + anInstruction2 = genoperandoperand(MoveCqR, -2 - null, CArg1Reg); + } + else { + if (null != CArg1Reg) { + /* begin MoveR:R: */ + genoperandoperand(MoveRR, null, CArg1Reg); + } + } + if (null < NoReg) { + /* begin MoveCq:R: */ + anInstruction3 = genoperandoperand(MoveCqR, -2 - null, CArg2Reg); + } + else { + if (null != CArg2Reg) { + /* begin MoveR:R: */ + genoperandoperand(MoveRR, null, CArg2Reg); + } + } + if (null < NoReg) { + /* begin MoveCq:R: */ + anInstruction4 = genoperandoperand(MoveCqR, -2 - null, CArg3Reg); + } + else { + if (null != CArg3Reg) { + /* begin MoveR:R: */ + genoperandoperand(MoveRR, null, CArg3Reg); + } + } + l12: /* end genMarshallNArgs:arg:arg:arg:arg: */; + /* begin gen:literal: */ + operand1 = ((usqIntptr_t)ceTakeProfileSample); + /* begin checkLiteral:forInstruction: */ + anInstruction1 = genoperand(CallFull, operand1); + /* begin genRemoveNArgsFromStack: */ + assert(1 <= 4); + } + /* SistaV1: * 217 Trap */ @@ -29586,7 +29751,7 @@ primitiveGeneratorOrNil(void) static sqInt NoDbgRegParms registerisInMask(sqInt reg, sqInt mask) { - return ((mask & (1ULL << reg)) != 0); + return ((mask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0); } /* SimpleStackBasedCogit>>#v3:Block:Code:Size: */ @@ -29966,7 +30131,7 @@ anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n) sqInt regMask; /* begin registerMaskFor: */ - regMask = 1ULL << reg; + regMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { if ((((registerMask(simStackAt(i))) & regMask) != 0)) { return 1; @@ -31068,7 +31233,7 @@ ensureReceiverResultRegContainsSelf(void) if (needsFrame) { if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin putSelfInReceiverResultReg */ storeToReg(simSelf(), ReceiverResultReg); ((simSelf())->liveRegister = ReceiverResultReg); @@ -31202,7 +31367,7 @@ freeAnyFloatRegNotConflictingWith(sqInt regMask) desc = simNativeStackAt(index); if ((((desc->type)) == SSRegisterSingleFloat) || (((desc->type)) == SSRegisterDoubleFloat)) { - if (!(((regMask & (1ULL << ((desc->registerr)))) != 0))) { + if (!(((regMask & (((((desc->registerr)) < 0) ? (((usqInt)(1)) >> (-((desc->registerr)))) : (1ULL << ((desc->registerr)))))) != 0))) { reg = (desc->registerr); } } @@ -31232,7 +31397,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) && (index < simStackPtr)) { desc = simStackAt(index); if (((desc->type)) == SSRegister) { - if (!(((regMask & (1ULL << ((desc->registerr)))) != 0))) { + if (!(((regMask & (((((desc->registerr)) < 0) ? (((usqInt)(1)) >> (-((desc->registerr)))) : (1ULL << ((desc->registerr)))))) != 0))) { reg = (desc->registerr); } } @@ -31240,7 +31405,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) } assert(!((reg == NoReg))); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1ULL << reg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)), simStackPtr, simNativeStackPtr); return reg; } @@ -31800,13 +31965,13 @@ genForwardersInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -32428,7 +32593,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop19 == NoReg) { rOopTop19 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult10 = allocateRegNotConflictingWith(1ULL << rOopTop19); + rResult10 = allocateRegNotConflictingWith(((rOopTop19 < 0) ? (((usqInt)(1)) >> (-rOopTop19)) : (1ULL << rOopTop19))); assert(!(((rOopTop19 == NoReg) || (rResult10 == NoReg)))); object17 = rOopTop19; @@ -32524,7 +32689,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop2 == NoReg) { rOopTop2 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult = allocateRegNotConflictingWith(1ULL << rOopTop2); + rResult = allocateRegNotConflictingWith(((rOopTop2 < 0) ? (((usqInt)(1)) >> (-rOopTop2)) : (1ULL << rOopTop2))); assert(!(((rOopTop2 == NoReg) || (rResult == NoReg)))); object2 = rOopTop2; @@ -32555,7 +32720,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop3 == NoReg) { rOopTop3 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult1 = allocateRegNotConflictingWith(1ULL << rOopTop3); + rResult1 = allocateRegNotConflictingWith(((rOopTop3 < 0) ? (((usqInt)(1)) >> (-rOopTop3)) : (1ULL << rOopTop3))); assert(!(((rOopTop3 == NoReg) || (rResult1 == NoReg)))); object3 = rOopTop3; @@ -32586,7 +32751,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop4 == NoReg) { rOopTop4 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult2 = allocateRegNotConflictingWith(1ULL << rOopTop4); + rResult2 = allocateRegNotConflictingWith(((rOopTop4 < 0) ? (((usqInt)(1)) >> (-rOopTop4)) : (1ULL << rOopTop4))); assert(!(((rOopTop4 == NoReg) || (rResult2 == NoReg)))); object4 = rOopTop4; @@ -32617,7 +32782,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop5 == NoReg) { rOopTop5 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult3 = allocateRegNotConflictingWith(1ULL << rOopTop5); + rResult3 = allocateRegNotConflictingWith(((rOopTop5 < 0) ? (((usqInt)(1)) >> (-rOopTop5)) : (1ULL << rOopTop5))); assert(!(((rOopTop5 == NoReg) || (rResult3 == NoReg)))); object5 = rOopTop5; @@ -32648,7 +32813,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop6 == NoReg) { rOopTop6 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult4 = allocateRegNotConflictingWith(1ULL << rOopTop6); + rResult4 = allocateRegNotConflictingWith(((rOopTop6 < 0) ? (((usqInt)(1)) >> (-rOopTop6)) : (1ULL << rOopTop6))); assert(!(((rOopTop6 == NoReg) || (rResult4 == NoReg)))); object6 = rOopTop6; @@ -32679,7 +32844,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop7 == NoReg) { rOopTop7 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult5 = allocateRegNotConflictingWith(1ULL << rOopTop7); + rResult5 = allocateRegNotConflictingWith(((rOopTop7 < 0) ? (((usqInt)(1)) >> (-rOopTop7)) : (1ULL << rOopTop7))); assert(!(((rOopTop7 == NoReg) || (rResult5 == NoReg)))); object7 = rOopTop7; @@ -32710,7 +32875,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop8 == NoReg) { rOopTop8 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult6 = allocateRegNotConflictingWith(1ULL << rOopTop8); + rResult6 = allocateRegNotConflictingWith(((rOopTop8 < 0) ? (((usqInt)(1)) >> (-rOopTop8)) : (1ULL << rOopTop8))); assert(!(((rOopTop8 == NoReg) || (rResult6 == NoReg)))); object8 = rOopTop8; @@ -32770,7 +32935,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop11 == NoReg) { rOopTop11 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult11 = allocateRegNotConflictingWith(1ULL << rOopTop11); + rResult11 = allocateRegNotConflictingWith(((rOopTop11 < 0) ? (((usqInt)(1)) >> (-rOopTop11)) : (1ULL << rOopTop11))); assert(!(((rOopTop11 == NoReg) || (rResult11 == NoReg)))); object10 = rOopTop11; @@ -32831,7 +32996,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop14 == NoReg) { rOopTop14 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult12 = allocateRegNotConflictingWith(1ULL << rOopTop14); + rResult12 = allocateRegNotConflictingWith(((rOopTop14 < 0) ? (((usqInt)(1)) >> (-rOopTop14)) : (1ULL << rOopTop14))); assert(!(((rOopTop14 == NoReg) || (rResult12 == NoReg)))); object12 = rOopTop14; @@ -32986,7 +33151,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop110 == NoReg) { rOopTop110 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult13 = allocateRegNotConflictingWith(1ULL << rOopTop110); + rResult13 = allocateRegNotConflictingWith(((rOopTop110 < 0) ? (((usqInt)(1)) >> (-rOopTop110)) : (1ULL << rOopTop110))); assert(!(((rOopTop110 == NoReg) || (rResult13 == NoReg)))); object21 = rOopTop110; @@ -33055,7 +33220,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop16 == NoReg) { rOopTop16 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult9 = allocateRegNotConflictingWith(1ULL << rOopTop16); + rResult9 = allocateRegNotConflictingWith(((rOopTop16 < 0) ? (((usqInt)(1)) >> (-rOopTop16)) : (1ULL << rOopTop16))); assert(!(((rOopTop16 == NoReg) || (rResult9 == NoReg)))); object14 = rOopTop16; @@ -33086,7 +33251,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop24 == NoReg) { rOopTop24 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult15 = allocateRegNotConflictingWith(1ULL << rOopTop24); + rResult15 = allocateRegNotConflictingWith(((rOopTop24 < 0) ? (((usqInt)(1)) >> (-rOopTop24)) : (1ULL << rOopTop24))); assert(!(((rOopTop24 == NoReg) || (rResult15 == NoReg)))); object22 = rOopTop24; @@ -33129,7 +33294,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop111 == NoReg) { rOopTop111 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult16 = allocateRegNotConflictingWith(1ULL << rOopTop111); + rResult16 = allocateRegNotConflictingWith(((rOopTop111 < 0) ? (((usqInt)(1)) >> (-rOopTop111)) : (1ULL << rOopTop111))); assert(!(((rOopTop111 == NoReg) || (rResult16 == NoReg)))); object23 = rOopTop111; @@ -33280,7 +33445,7 @@ genLowcodeNullaryInlinePrimitive(sqInt prim) if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult = allocateRegNotConflictingWith(1ULL << rTop); + rResult = allocateRegNotConflictingWith(((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1ULL << rTop))); assert(!(((rTop == NoReg) || (rResult == NoReg)))); value = rTop; @@ -33315,7 +33480,7 @@ genLowcodeNullaryInlinePrimitive(sqInt prim) if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult1 = allocateRegNotConflictingWith(1ULL << rTop1); + rResult1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); assert(!(((rTop1 == NoReg) || (rResult1 == NoReg)))); value1 = rTop1; @@ -33561,7 +33726,7 @@ genLowcodeNullaryInlinePrimitive(sqInt prim) if (rTop12 == NoReg) { rTop12 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult11 = allocateRegNotConflictingWith(1ULL << rTop12); + rResult11 = allocateRegNotConflictingWith(((rTop12 < 0) ? (((usqInt)(1)) >> (-rTop12)) : (1ULL << rTop12))); assert(!(((rTop12 == NoReg) || (rResult11 == NoReg)))); value6 = rTop12; @@ -33672,14 +33837,14 @@ genLowcodeTrinaryInlinePrimitive(sqInt prim) l4: ; if (rOopNext != NoReg) { /* begin registerMaskFor: */ - oopTopRegisterMask = 1ULL << rOopNext; + oopTopRegisterMask = ((rOopNext < 0) ? (((usqInt)(1)) >> (-rOopNext)) : (1ULL << rOopNext)); } } if (rOopTop == NoReg) { rOopTop = allocateRegNotConflictingWith(oopTopRegisterMask); } if (rOopNext == NoReg) { - rOopNext = allocateRegNotConflictingWith(1ULL << rOopTop); + rOopNext = allocateRegNotConflictingWith(((rOopTop < 0) ? (((usqInt)(1)) >> (-rOopTop)) : (1ULL << rOopTop))); } rResult = allocateRegNotConflictingWith((1ULL << rOopTop) | (1ULL << rOopNext)); assert(!(((rOopTop == NoReg) @@ -33741,14 +33906,14 @@ genLowcodeTrinaryInlinePrimitive(sqInt prim) l18: ; if (rOopNext1 != NoReg) { /* begin registerMaskFor: */ - oopTopRegisterMask1 = 1ULL << rOopNext1; + oopTopRegisterMask1 = ((rOopNext1 < 0) ? (((usqInt)(1)) >> (-rOopNext1)) : (1ULL << rOopNext1)); } } if (rOopTop1 == NoReg) { rOopTop1 = allocateRegNotConflictingWith(oopTopRegisterMask1); } if (rOopNext1 == NoReg) { - rOopNext1 = allocateRegNotConflictingWith(1ULL << rOopTop1); + rOopNext1 = allocateRegNotConflictingWith(((rOopTop1 < 0) ? (((usqInt)(1)) >> (-rOopTop1)) : (1ULL << rOopTop1))); } assert(!(((rOopTop1 == NoReg) || (rOopNext1 == NoReg)))); @@ -33809,14 +33974,14 @@ genLowcodeTrinaryInlinePrimitive(sqInt prim) l23: ; if (rOopNext2 != NoReg) { /* begin registerMaskFor: */ - oopTopRegisterMask2 = 1ULL << rOopNext2; + oopTopRegisterMask2 = ((rOopNext2 < 0) ? (((usqInt)(1)) >> (-rOopNext2)) : (1ULL << rOopNext2)); } } if (rOopTop2 == NoReg) { rOopTop2 = allocateRegNotConflictingWith(oopTopRegisterMask2); } if (rOopNext2 == NoReg) { - rOopNext2 = allocateRegNotConflictingWith(1ULL << rOopTop2); + rOopNext2 = allocateRegNotConflictingWith(((rOopTop2 < 0) ? (((usqInt)(1)) >> (-rOopTop2)) : (1ULL << rOopTop2))); } assert(!(((rOopTop2 == NoReg) || (rOopNext2 == NoReg)))); @@ -33837,17 +34002,17 @@ genLowcodeTrinaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { rTop = nativeRegisterOrNone(ssNativeTop()); /* begin registerMaskFor: */ - oopTopRegisterMask3 = 1ULL << rTop; + oopTopRegisterMask3 = ((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1ULL << rTop)); } if ((registerOrNone(ssTop())) != NoReg) { rOopTop3 = registerOrNone(ssTop()); /* begin registerMaskFor: */ - topRegisterMask = 1ULL << rOopTop3; + topRegisterMask = ((rOopTop3 < 0) ? (((usqInt)(1)) >> (-rOopTop3)) : (1ULL << rOopTop3)); } if ((registerOrNone(ssValue(1))) != NoReg) { rOopNext3 = registerOrNone(ssValue(1)); - topRegisterMask = topRegisterMask | (1ULL << rOopNext3); - oopTopRegisterMask3 = oopTopRegisterMask3 | (1ULL << rOopNext3); + topRegisterMask = topRegisterMask | (((rOopNext3 < 0) ? (((usqInt)(1)) >> (-rOopNext3)) : (1ULL << rOopNext3))); + oopTopRegisterMask3 = oopTopRegisterMask3 | (((rOopNext3 < 0) ? (((usqInt)(1)) >> (-rOopNext3)) : (1ULL << rOopNext3))); } if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(topRegisterMask); @@ -34363,13 +34528,13 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((registerOrNone(ssTop())) != NoReg) { rOopTop1 = registerOrNone(ssTop()); /* begin registerMaskFor: */ - topRegisterMask1 = 1ULL << rOopTop1; + topRegisterMask1 = ((rOopTop1 < 0) ? (((usqInt)(1)) >> (-rOopTop1)) : (1ULL << rOopTop1)); } if (rTop31 == NoReg) { rTop31 = allocateRegNotConflictingWith(topRegisterMask1); } if (rOopTop1 == NoReg) { - rOopTop1 = allocateRegNotConflictingWith(1ULL << rTop31); + rOopTop1 = allocateRegNotConflictingWith(((rTop31 < 0) ? (((usqInt)(1)) >> (-rTop31)) : (1ULL << rTop31))); } rOopResult = allocateRegNotConflictingWith((1ULL << rTop31) | (1ULL << rOopTop1)); assert(!(((rTop31 == NoReg) @@ -34419,7 +34584,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if (rOopTop2 == NoReg) { rOopTop2 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult35 = allocateRegNotConflictingWith(1ULL << rOopTop2); + rResult35 = allocateRegNotConflictingWith(((rOopTop2 < 0) ? (((usqInt)(1)) >> (-rOopTop2)) : (1ULL << rOopTop2))); assert(!(((rOopTop2 == NoReg) || (rResult35 == NoReg)))); classOop1 = rOopTop2; @@ -34493,14 +34658,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask1 = 1ULL << reg; + topRegistersMask1 = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } } if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(topRegistersMask1); } if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1ULL << rTop); + rNext = allocateRegNotConflictingWith(((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1ULL << rTop))); } assert(!(((rTop == NoReg) || (rNext == NoReg)))); @@ -34540,14 +34705,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg1 = (rNext1 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask2 = 1ULL << reg1; + topRegistersMask2 = ((reg1 < 0) ? (((usqInt)(1)) >> (-reg1)) : (1ULL << reg1)); } } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask2); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -34587,14 +34752,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg2 = (rNext2 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask3 = 1ULL << reg2; + topRegistersMask3 = ((reg2 < 0) ? (((usqInt)(1)) >> (-reg2)) : (1ULL << reg2)); } } if (rTop2 == NoReg) { rTop2 = allocateRegNotConflictingWith(topRegistersMask3); } if (rNext2 == NoReg) { - rNext2 = allocateRegNotConflictingWith(1ULL << rTop2); + rNext2 = allocateRegNotConflictingWith(((rTop2 < 0) ? (((usqInt)(1)) >> (-rTop2)) : (1ULL << rTop2))); } assert(!(((rTop2 == NoReg) || (rNext2 == NoReg)))); @@ -34634,14 +34799,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg3 = (rNext3 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask4 = 1ULL << reg3; + topRegistersMask4 = ((reg3 < 0) ? (((usqInt)(1)) >> (-reg3)) : (1ULL << reg3)); } } if (rTop3 == NoReg) { rTop3 = allocateRegNotConflictingWith(topRegistersMask4); } if (rNext3 == NoReg) { - rNext3 = allocateRegNotConflictingWith(1ULL << rTop3); + rNext3 = allocateRegNotConflictingWith(((rTop3 < 0) ? (((usqInt)(1)) >> (-rTop3)) : (1ULL << rTop3))); } assert(!(((rTop3 == NoReg) || (rNext3 == NoReg)))); @@ -34681,14 +34846,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg4 = (rNext4 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask5 = 1ULL << reg4; + topRegistersMask5 = ((reg4 < 0) ? (((usqInt)(1)) >> (-reg4)) : (1ULL << reg4)); } } if (rTop4 == NoReg) { rTop4 = allocateRegNotConflictingWith(topRegistersMask5); } if (rNext4 == NoReg) { - rNext4 = allocateRegNotConflictingWith(1ULL << rTop4); + rNext4 = allocateRegNotConflictingWith(((rTop4 < 0) ? (((usqInt)(1)) >> (-rTop4)) : (1ULL << rTop4))); } assert(!(((rTop4 == NoReg) || (rNext4 == NoReg)))); @@ -34728,14 +34893,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg5 = (rNext5 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask6 = 1ULL << reg5; + topRegistersMask6 = ((reg5 < 0) ? (((usqInt)(1)) >> (-reg5)) : (1ULL << reg5)); } } if (rTop5 == NoReg) { rTop5 = allocateRegNotConflictingWith(topRegistersMask6); } if (rNext5 == NoReg) { - rNext5 = allocateRegNotConflictingWith(1ULL << rTop5); + rNext5 = allocateRegNotConflictingWith(((rTop5 < 0) ? (((usqInt)(1)) >> (-rTop5)) : (1ULL << rTop5))); } assert(!(((rTop5 == NoReg) || (rNext5 == NoReg)))); @@ -34836,14 +35001,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg6 = (rNext11 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask7 = 1ULL << reg6; + topRegistersMask7 = ((reg6 < 0) ? (((usqInt)(1)) >> (-reg6)) : (1ULL << reg6)); } } if (rTop11 == NoReg) { rTop11 = allocateRegNotConflictingWith(topRegistersMask7); } if (rNext11 == NoReg) { - rNext11 = allocateRegNotConflictingWith(1ULL << rTop11); + rNext11 = allocateRegNotConflictingWith(((rTop11 < 0) ? (((usqInt)(1)) >> (-rTop11)) : (1ULL << rTop11))); } assert(!(((rTop11 == NoReg) || (rNext11 == NoReg)))); @@ -34884,14 +35049,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg7 = (rNext7 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask8 = 1ULL << reg7; + topRegistersMask8 = ((reg7 < 0) ? (((usqInt)(1)) >> (-reg7)) : (1ULL << reg7)); } } if (rTop10 == NoReg) { rTop10 = allocateRegNotConflictingWith(topRegistersMask8); } if (rNext7 == NoReg) { - rNext7 = allocateRegNotConflictingWith(1ULL << rTop10); + rNext7 = allocateRegNotConflictingWith(((rTop10 < 0) ? (((usqInt)(1)) >> (-rTop10)) : (1ULL << rTop10))); } assert(!(((rTop10 == NoReg) || (rNext7 == NoReg)))); @@ -34922,14 +35087,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg8 = (rNext8 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask9 = 1ULL << reg8; + topRegistersMask9 = ((reg8 < 0) ? (((usqInt)(1)) >> (-reg8)) : (1ULL << reg8)); } } if (rTop12 == NoReg) { rTop12 = allocateRegNotConflictingWith(topRegistersMask9); } if (rNext8 == NoReg) { - rNext8 = allocateRegNotConflictingWith(1ULL << rTop12); + rNext8 = allocateRegNotConflictingWith(((rTop12 < 0) ? (((usqInt)(1)) >> (-rTop12)) : (1ULL << rTop12))); } assert(!(((rTop12 == NoReg) || (rNext8 == NoReg)))); @@ -34960,14 +35125,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg9 = (rNext9 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask10 = 1ULL << reg9; + topRegistersMask10 = ((reg9 < 0) ? (((usqInt)(1)) >> (-reg9)) : (1ULL << reg9)); } } if (rTop13 == NoReg) { rTop13 = allocateRegNotConflictingWith(topRegistersMask10); } if (rNext9 == NoReg) { - rNext9 = allocateRegNotConflictingWith(1ULL << rTop13); + rNext9 = allocateRegNotConflictingWith(((rTop13 < 0) ? (((usqInt)(1)) >> (-rTop13)) : (1ULL << rTop13))); } assert(!(((rTop13 == NoReg) || (rNext9 == NoReg)))); @@ -34998,14 +35163,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg10 = (rNext10 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask11 = 1ULL << reg10; + topRegistersMask11 = ((reg10 < 0) ? (((usqInt)(1)) >> (-reg10)) : (1ULL << reg10)); } } if (rTop14 == NoReg) { rTop14 = allocateRegNotConflictingWith(topRegistersMask11); } if (rNext10 == NoReg) { - rNext10 = allocateRegNotConflictingWith(1ULL << rTop14); + rNext10 = allocateRegNotConflictingWith(((rTop14 < 0) ? (((usqInt)(1)) >> (-rTop14)) : (1ULL << rTop14))); } assert(!(((rTop14 == NoReg) || (rNext10 == NoReg)))); @@ -35036,14 +35201,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg11 = (rNext13 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask12 = 1ULL << reg11; + topRegistersMask12 = ((reg11 < 0) ? (((usqInt)(1)) >> (-reg11)) : (1ULL << reg11)); } } if (rTop16 == NoReg) { rTop16 = allocateRegNotConflictingWith(topRegistersMask12); } if (rNext13 == NoReg) { - rNext13 = allocateRegNotConflictingWith(1ULL << rTop16); + rNext13 = allocateRegNotConflictingWith(((rTop16 < 0) ? (((usqInt)(1)) >> (-rTop16)) : (1ULL << rTop16))); } assert(!(((rTop16 == NoReg) || (rNext13 == NoReg)))); @@ -35140,14 +35305,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg13 = (rNext15 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask14 = 1ULL << reg13; + topRegistersMask14 = ((reg13 < 0) ? (((usqInt)(1)) >> (-reg13)) : (1ULL << reg13)); } } if (rTop21 == NoReg) { rTop21 = allocateRegNotConflictingWith(topRegistersMask14); } if (rNext15 == NoReg) { - rNext15 = allocateRegNotConflictingWith(1ULL << rTop21); + rNext15 = allocateRegNotConflictingWith(((rTop21 < 0) ? (((usqInt)(1)) >> (-rTop21)) : (1ULL << rTop21))); } assert(!(((rTop21 == NoReg) || (rNext15 == NoReg)))); @@ -35177,14 +35342,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg14 = (rNext16 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask15 = 1ULL << reg14; + topRegistersMask15 = ((reg14 < 0) ? (((usqInt)(1)) >> (-reg14)) : (1ULL << reg14)); } } if (rTop22 == NoReg) { rTop22 = allocateRegNotConflictingWith(topRegistersMask15); } if (rNext16 == NoReg) { - rNext16 = allocateRegNotConflictingWith(1ULL << rTop22); + rNext16 = allocateRegNotConflictingWith(((rTop22 < 0) ? (((usqInt)(1)) >> (-rTop22)) : (1ULL << rTop22))); } assert(!(((rTop22 == NoReg) || (rNext16 == NoReg)))); @@ -35442,7 +35607,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if (rTop25 == NoReg) { rTop25 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult29 = allocateRegNotConflictingWith(1ULL << rTop25); + rResult29 = allocateRegNotConflictingWith(((rTop25 < 0) ? (((usqInt)(1)) >> (-rTop25)) : (1ULL << rTop25))); assert(!(((rTop25 == NoReg) || (rResult29 == NoReg)))); pointer4 = rTop25; @@ -35468,7 +35633,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if (rTop26 == NoReg) { rTop26 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult30 = allocateRegNotConflictingWith(1ULL << rTop26); + rResult30 = allocateRegNotConflictingWith(((rTop26 < 0) ? (((usqInt)(1)) >> (-rTop26)) : (1ULL << rTop26))); assert(!(((rTop26 == NoReg) || (rResult30 == NoReg)))); pointer5 = rTop26; @@ -35491,7 +35656,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if (rTop110 == NoReg) { rTop110 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult112 = allocateRegNotConflictingWith(1ULL << rTop110); + rResult112 = allocateRegNotConflictingWith(((rTop110 < 0) ? (((usqInt)(1)) >> (-rTop110)) : (1ULL << rTop110))); assert(!(((rTop110 == NoReg) || (rResult112 == NoReg)))); pointer6 = rTop110; @@ -35514,7 +35679,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if (rTop28 == NoReg) { rTop28 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult32 = allocateRegNotConflictingWith(1ULL << rTop28); + rResult32 = allocateRegNotConflictingWith(((rTop28 < 0) ? (((usqInt)(1)) >> (-rTop28)) : (1ULL << rTop28))); assert(!(((rTop28 == NoReg) || (rResult32 == NoReg)))); pointer7 = rTop28; @@ -35728,13 +35893,13 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((registerOrNone(ssTop())) != NoReg) { rOopTop = registerOrNone(ssTop()); /* begin registerMaskFor: */ - topRegisterMask = 1ULL << rOopTop; + topRegisterMask = ((rOopTop < 0) ? (((usqInt)(1)) >> (-rOopTop)) : (1ULL << rOopTop)); } if (rTop29 == NoReg) { rTop29 = allocateRegNotConflictingWith(topRegisterMask); } if (rOopTop == NoReg) { - rOopTop = allocateRegNotConflictingWith(1ULL << rTop29); + rOopTop = allocateRegNotConflictingWith(((rTop29 < 0) ? (((usqInt)(1)) >> (-rTop29)) : (1ULL << rTop29))); } assert(!(((rTop29 == NoReg) || (rOopTop == NoReg)))); @@ -35994,7 +36159,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult = allocateRegNotConflictingWith(1ULL << rTop); + rResult = allocateRegNotConflictingWith(((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1ULL << rTop))); assert(!(((rTop == NoReg) || (rResult == NoReg)))); pointer = rTop; @@ -36016,7 +36181,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult1 = allocateRegNotConflictingWith(1ULL << rTop1); + rResult1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); assert(!(((rTop1 == NoReg) || (rResult1 == NoReg)))); pointer1 = rTop1; @@ -36038,7 +36203,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop2 == NoReg) { rTop2 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult2 = allocateRegNotConflictingWith(1ULL << rTop2); + rResult2 = allocateRegNotConflictingWith(((rTop2 < 0) ? (((usqInt)(1)) >> (-rTop2)) : (1ULL << rTop2))); assert(!(((rTop2 == NoReg) || (rResult2 == NoReg)))); pointer2 = rTop2; @@ -36061,7 +36226,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop11 == NoReg) { rTop11 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult11 = allocateRegNotConflictingWith(1ULL << rTop11); + rResult11 = allocateRegNotConflictingWith(((rTop11 < 0) ? (((usqInt)(1)) >> (-rTop11)) : (1ULL << rTop11))); assert(!(((rTop11 == NoReg) || (rResult11 == NoReg)))); pointer3 = rTop11; @@ -36084,7 +36249,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop4 == NoReg) { rTop4 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult4 = allocateRegNotConflictingWith(1ULL << rTop4); + rResult4 = allocateRegNotConflictingWith(((rTop4 < 0) ? (((usqInt)(1)) >> (-rTop4)) : (1ULL << rTop4))); assert(!(((rTop4 == NoReg) || (rResult4 == NoReg)))); pointer4 = rTop4; @@ -36169,7 +36334,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop28 == NoReg) { rTop28 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult8 = allocateRegNotConflictingWith(1ULL << rTop28); + rResult8 = allocateRegNotConflictingWith(((rTop28 < 0) ? (((usqInt)(1)) >> (-rTop28)) : (1ULL << rTop28))); assert(!(((rTop28 == NoReg) || (rResult8 == NoReg)))); size1 = rTop28; @@ -36210,7 +36375,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop111 == NoReg) { rTop111 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult13 = allocateRegNotConflictingWith(1ULL << rTop111); + rResult13 = allocateRegNotConflictingWith(((rTop111 < 0) ? (((usqInt)(1)) >> (-rTop111)) : (1ULL << rTop111))); assert(!(((rTop111 == NoReg) || (rResult13 == NoReg)))); size2 = rTop111; @@ -36268,18 +36433,18 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) nextRegisterMask2 = 0; if (rNext13 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask2 = 1ULL << rNext13; + nextRegisterMask2 = ((rNext13 < 0) ? (((usqInt)(1)) >> (-rNext13)) : (1ULL << rNext13)); } if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1ULL << rNextNext2); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNext2)) : (1ULL << rNextNext2))); } rTop30 = allocateRegNotConflictingWith(nextRegisterMask2); } if (rNext13 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask2 = 1ULL << rTop30; + nextRegisterMask2 = ((rTop30 < 0) ? (((usqInt)(1)) >> (-rTop30)) : (1ULL << rTop30)); if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1ULL << rNextNext2); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNext2)) : (1ULL << rNextNext2))); } rNext13 = allocateRegNotConflictingWith(nextRegisterMask2); } @@ -36342,18 +36507,18 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) nextRegisterMask3 = 0; if (rNext14 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask3 = 1ULL << rNext14; + nextRegisterMask3 = ((rNext14 < 0) ? (((usqInt)(1)) >> (-rNext14)) : (1ULL << rNext14)); } if (rNextNext3 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1ULL << rNextNext3); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNext3)) : (1ULL << rNextNext3))); } rTop31 = allocateRegNotConflictingWith(nextRegisterMask3); } if (rNext14 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask3 = 1ULL << rTop31; + nextRegisterMask3 = ((rTop31 < 0) ? (((usqInt)(1)) >> (-rTop31)) : (1ULL << rTop31)); if (rNextNext3 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1ULL << rNextNext3); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNext3)) : (1ULL << rNextNext3))); } rNext14 = allocateRegNotConflictingWith(nextRegisterMask3); } @@ -36404,14 +36569,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg11 = (rNext15 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask13 = 1ULL << reg11; + topRegistersMask13 = ((reg11 < 0) ? (((usqInt)(1)) >> (-reg11)) : (1ULL << reg11)); } } if (rTop32 == NoReg) { rTop32 = allocateRegNotConflictingWith(topRegistersMask13); } if (rNext15 == NoReg) { - rNext15 = allocateRegNotConflictingWith(1ULL << rTop32); + rNext15 = allocateRegNotConflictingWith(((rTop32 < 0) ? (((usqInt)(1)) >> (-rTop32)) : (1ULL << rTop32))); } assert(!(((rTop32 == NoReg) || (rNext15 == NoReg)))); @@ -36498,14 +36663,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } } if (rTop5 == NoReg) { rTop5 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1ULL << rTop5); + rNext = allocateRegNotConflictingWith(((rTop5 < 0) ? (((usqInt)(1)) >> (-rTop5)) : (1ULL << rTop5))); } assert(!(((rTop5 == NoReg) || (rNext == NoReg)))); @@ -36535,14 +36700,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg1 = (rNext1 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask1 = 1ULL << reg1; + topRegistersMask1 = ((reg1 < 0) ? (((usqInt)(1)) >> (-reg1)) : (1ULL << reg1)); } } if (rTop6 == NoReg) { rTop6 = allocateRegNotConflictingWith(topRegistersMask1); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop6); + rNext1 = allocateRegNotConflictingWith(((rTop6 < 0) ? (((usqInt)(1)) >> (-rTop6)) : (1ULL << rTop6))); } assert(!(((rTop6 == NoReg) || (rNext1 == NoReg)))); @@ -36647,14 +36812,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg4 = (rNext4 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask4 = 1ULL << reg4; + topRegistersMask4 = ((reg4 < 0) ? (((usqInt)(1)) >> (-reg4)) : (1ULL << reg4)); } } if (rTop14 == NoReg) { rTop14 = allocateRegNotConflictingWith(topRegistersMask4); } if (rNext4 == NoReg) { - rNext4 = allocateRegNotConflictingWith(1ULL << rTop14); + rNext4 = allocateRegNotConflictingWith(((rTop14 < 0) ? (((usqInt)(1)) >> (-rTop14)) : (1ULL << rTop14))); } assert(!(((rTop14 == NoReg) || (rNext4 == NoReg)))); @@ -36687,14 +36852,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg5 = (rNext11 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask5 = 1ULL << reg5; + topRegistersMask5 = ((reg5 < 0) ? (((usqInt)(1)) >> (-reg5)) : (1ULL << reg5)); } } if (rTop16 == NoReg) { rTop16 = allocateRegNotConflictingWith(topRegistersMask5); } if (rNext11 == NoReg) { - rNext11 = allocateRegNotConflictingWith(1ULL << rTop16); + rNext11 = allocateRegNotConflictingWith(((rTop16 < 0) ? (((usqInt)(1)) >> (-rTop16)) : (1ULL << rTop16))); } assert(!(((rTop16 == NoReg) || (rNext11 == NoReg)))); @@ -36809,14 +36974,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg6 = (rNext6 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask6 = 1ULL << reg6; + topRegistersMask6 = ((reg6 < 0) ? (((usqInt)(1)) >> (-reg6)) : (1ULL << reg6)); } } if (rTop18 == NoReg) { rTop18 = allocateRegNotConflictingWith(topRegistersMask6); } if (rNext6 == NoReg) { - rNext6 = allocateRegNotConflictingWith(1ULL << rTop18); + rNext6 = allocateRegNotConflictingWith(((rTop18 < 0) ? (((usqInt)(1)) >> (-rTop18)) : (1ULL << rTop18))); } assert(!(((rTop18 == NoReg) || (rNext6 == NoReg)))); @@ -36846,14 +37011,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg7 = (rNext12 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask7 = 1ULL << reg7; + topRegistersMask7 = ((reg7 < 0) ? (((usqInt)(1)) >> (-reg7)) : (1ULL << reg7)); } } if (rTop19 == NoReg) { rTop19 = allocateRegNotConflictingWith(topRegistersMask7); } if (rNext12 == NoReg) { - rNext12 = allocateRegNotConflictingWith(1ULL << rTop19); + rNext12 = allocateRegNotConflictingWith(((rTop19 < 0) ? (((usqInt)(1)) >> (-rTop19)) : (1ULL << rTop19))); } assert(!(((rTop19 == NoReg) || (rNext12 == NoReg)))); @@ -36882,14 +37047,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg8 = (rNext8 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask8 = 1ULL << reg8; + topRegistersMask8 = ((reg8 < 0) ? (((usqInt)(1)) >> (-reg8)) : (1ULL << reg8)); } } if (rTop21 == NoReg) { rTop21 = allocateRegNotConflictingWith(topRegistersMask8); } if (rNext8 == NoReg) { - rNext8 = allocateRegNotConflictingWith(1ULL << rTop21); + rNext8 = allocateRegNotConflictingWith(((rTop21 < 0) ? (((usqInt)(1)) >> (-rTop21)) : (1ULL << rTop21))); } assert(!(((rTop21 == NoReg) || (rNext8 == NoReg)))); @@ -36929,14 +37094,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg9 = (rNext9 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask9 = 1ULL << reg9; + topRegistersMask9 = ((reg9 < 0) ? (((usqInt)(1)) >> (-reg9)) : (1ULL << reg9)); } } if (rTop22 == NoReg) { rTop22 = allocateRegNotConflictingWith(topRegistersMask9); } if (rNext9 == NoReg) { - rNext9 = allocateRegNotConflictingWith(1ULL << rTop22); + rNext9 = allocateRegNotConflictingWith(((rTop22 < 0) ? (((usqInt)(1)) >> (-rTop22)) : (1ULL << rTop22))); } assert(!(((rTop22 == NoReg) || (rNext9 == NoReg)))); @@ -36989,7 +37154,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop110 == NoReg) { rTop110 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult12 = allocateRegNotConflictingWith(1ULL << rTop110); + rResult12 = allocateRegNotConflictingWith(((rTop110 < 0) ? (((usqInt)(1)) >> (-rTop110)) : (1ULL << rTop110))); assert(!(((rTop110 == NoReg) || (rResult12 == NoReg)))); pointer6 = rTop110; @@ -37505,14 +37670,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } } if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(topRegistersMask); } if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1ULL << rTop); + rNext = allocateRegNotConflictingWith(((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1ULL << rTop))); } assert(!(((rTop == NoReg) || (rNext == NoReg)))); @@ -37541,14 +37706,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg1 = (rNext1 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask1 = 1ULL << reg1; + topRegistersMask1 = ((reg1 < 0) ? (((usqInt)(1)) >> (-reg1)) : (1ULL << reg1)); } } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask1); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -37578,14 +37743,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg2 = (rNext2 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask2 = 1ULL << reg2; + topRegistersMask2 = ((reg2 < 0) ? (((usqInt)(1)) >> (-reg2)) : (1ULL << reg2)); } } if (rTop2 == NoReg) { rTop2 = allocateRegNotConflictingWith(topRegistersMask2); } if (rNext2 == NoReg) { - rNext2 = allocateRegNotConflictingWith(1ULL << rTop2); + rNext2 = allocateRegNotConflictingWith(((rTop2 < 0) ? (((usqInt)(1)) >> (-rTop2)) : (1ULL << rTop2))); } assert(!(((rTop2 == NoReg) || (rNext2 == NoReg)))); @@ -37615,14 +37780,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg3 = (rNext3 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask3 = 1ULL << reg3; + topRegistersMask3 = ((reg3 < 0) ? (((usqInt)(1)) >> (-reg3)) : (1ULL << reg3)); } } if (rTop3 == NoReg) { rTop3 = allocateRegNotConflictingWith(topRegistersMask3); } if (rNext3 == NoReg) { - rNext3 = allocateRegNotConflictingWith(1ULL << rTop3); + rNext3 = allocateRegNotConflictingWith(((rTop3 < 0) ? (((usqInt)(1)) >> (-rTop3)) : (1ULL << rTop3))); } assert(!(((rTop3 == NoReg) || (rNext3 == NoReg)))); @@ -37710,7 +37875,7 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if (rTop12 == NoReg) { rTop12 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult11 = allocateRegNotConflictingWith(1ULL << rTop12); + rResult11 = allocateRegNotConflictingWith(((rTop12 < 0) ? (((usqInt)(1)) >> (-rTop12)) : (1ULL << rTop12))); assert(!(((rTop12 == NoReg) || (rResult11 == NoReg)))); value5 = rTop12; @@ -37735,7 +37900,7 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if (rTop13 == NoReg) { rTop13 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult12 = allocateRegNotConflictingWith(1ULL << rTop13); + rResult12 = allocateRegNotConflictingWith(((rTop13 < 0) ? (((usqInt)(1)) >> (-rTop13)) : (1ULL << rTop13))); assert(!(((rTop13 == NoReg) || (rResult12 == NoReg)))); value6 = rTop13; @@ -37820,14 +37985,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg6 = (rNext6 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask6 = 1ULL << reg6; + topRegistersMask6 = ((reg6 < 0) ? (((usqInt)(1)) >> (-reg6)) : (1ULL << reg6)); } } if (rTop14 == NoReg) { rTop14 = allocateRegNotConflictingWith(topRegistersMask6); } if (rNext6 == NoReg) { - rNext6 = allocateRegNotConflictingWith(1ULL << rTop14); + rNext6 = allocateRegNotConflictingWith(((rTop14 < 0) ? (((usqInt)(1)) >> (-rTop14)) : (1ULL << rTop14))); } assert(!(((rTop14 == NoReg) || (rNext6 == NoReg)))); @@ -37857,14 +38022,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg7 = (rNext7 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask7 = 1ULL << reg7; + topRegistersMask7 = ((reg7 < 0) ? (((usqInt)(1)) >> (-reg7)) : (1ULL << reg7)); } } if (rTop15 == NoReg) { rTop15 = allocateRegNotConflictingWith(topRegistersMask7); } if (rNext7 == NoReg) { - rNext7 = allocateRegNotConflictingWith(1ULL << rTop15); + rNext7 = allocateRegNotConflictingWith(((rTop15 < 0) ? (((usqInt)(1)) >> (-rTop15)) : (1ULL << rTop15))); } assert(!(((rTop15 == NoReg) || (rNext7 == NoReg)))); @@ -37893,14 +38058,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg8 = (rNext11 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask8 = 1ULL << reg8; + topRegistersMask8 = ((reg8 < 0) ? (((usqInt)(1)) >> (-reg8)) : (1ULL << reg8)); } } if (rTop16 == NoReg) { rTop16 = allocateRegNotConflictingWith(topRegistersMask8); } if (rNext11 == NoReg) { - rNext11 = allocateRegNotConflictingWith(1ULL << rTop16); + rNext11 = allocateRegNotConflictingWith(((rTop16 < 0) ? (((usqInt)(1)) >> (-rTop16)) : (1ULL << rTop16))); } assert(!(((rTop16 == NoReg) || (rNext11 == NoReg)))); @@ -37929,14 +38094,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg9 = (rNext9 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask9 = 1ULL << reg9; + topRegistersMask9 = ((reg9 < 0) ? (((usqInt)(1)) >> (-reg9)) : (1ULL << reg9)); } } if (rTop18 == NoReg) { rTop18 = allocateRegNotConflictingWith(topRegistersMask9); } if (rNext9 == NoReg) { - rNext9 = allocateRegNotConflictingWith(1ULL << rTop18); + rNext9 = allocateRegNotConflictingWith(((rTop18 < 0) ? (((usqInt)(1)) >> (-rTop18)) : (1ULL << rTop18))); } assert(!(((rTop18 == NoReg) || (rNext9 == NoReg)))); @@ -38119,14 +38284,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg11 = (rNext12 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask13 = 1ULL << reg11; + topRegistersMask13 = ((reg11 < 0) ? (((usqInt)(1)) >> (-reg11)) : (1ULL << reg11)); } } if (rTop24 == NoReg) { rTop24 = allocateRegNotConflictingWith(topRegistersMask13); } if (rNext12 == NoReg) { - rNext12 = allocateRegNotConflictingWith(1ULL << rTop24); + rNext12 = allocateRegNotConflictingWith(((rTop24 < 0) ? (((usqInt)(1)) >> (-rTop24)) : (1ULL << rTop24))); } assert(!(((rTop24 == NoReg) || (rNext12 == NoReg)))); @@ -38154,14 +38319,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg12 = (rNext13 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask14 = 1ULL << reg12; + topRegistersMask14 = ((reg12 < 0) ? (((usqInt)(1)) >> (-reg12)) : (1ULL << reg12)); } } if (rTop25 == NoReg) { rTop25 = allocateRegNotConflictingWith(topRegistersMask14); } if (rNext13 == NoReg) { - rNext13 = allocateRegNotConflictingWith(1ULL << rTop25); + rNext13 = allocateRegNotConflictingWith(((rTop25 < 0) ? (((usqInt)(1)) >> (-rTop25)) : (1ULL << rTop25))); } assert(!(((rTop25 == NoReg) || (rNext13 == NoReg)))); @@ -38191,14 +38356,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg13 = (rNext15 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask15 = 1ULL << reg13; + topRegistersMask15 = ((reg13 < 0) ? (((usqInt)(1)) >> (-reg13)) : (1ULL << reg13)); } } if (rTop111 == NoReg) { rTop111 = allocateRegNotConflictingWith(topRegistersMask15); } if (rNext15 == NoReg) { - rNext15 = allocateRegNotConflictingWith(1ULL << rTop111); + rNext15 = allocateRegNotConflictingWith(((rTop111 < 0) ? (((usqInt)(1)) >> (-rTop111)) : (1ULL << rTop111))); } assert(!(((rTop111 == NoReg) || (rNext15 == NoReg)))); @@ -38298,7 +38463,7 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if (rTop114 == NoReg) { rTop114 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult13 = allocateRegNotConflictingWith(1ULL << rTop114); + rResult13 = allocateRegNotConflictingWith(((rTop114 < 0) ? (((usqInt)(1)) >> (-rTop114)) : (1ULL << rTop114))); assert(!(((rTop114 == NoReg) || (rResult13 == NoReg)))); value21 = rTop114; @@ -38324,14 +38489,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg17 = (rNext19 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask19 = 1ULL << reg17; + topRegistersMask19 = ((reg17 < 0) ? (((usqInt)(1)) >> (-reg17)) : (1ULL << reg17)); } } if (rTop32 == NoReg) { rTop32 = allocateRegNotConflictingWith(topRegistersMask19); } if (rNext19 == NoReg) { - rNext19 = allocateRegNotConflictingWith(1ULL << rTop32); + rNext19 = allocateRegNotConflictingWith(((rTop32 < 0) ? (((usqInt)(1)) >> (-rTop32)) : (1ULL << rTop32))); } assert(!(((rTop32 == NoReg) || (rNext19 == NoReg)))); @@ -38360,14 +38525,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg18 = (rNext20 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask20 = 1ULL << reg18; + topRegistersMask20 = ((reg18 < 0) ? (((usqInt)(1)) >> (-reg18)) : (1ULL << reg18)); } } if (rTop33 == NoReg) { rTop33 = allocateRegNotConflictingWith(topRegistersMask20); } if (rNext20 == NoReg) { - rNext20 = allocateRegNotConflictingWith(1ULL << rTop33); + rNext20 = allocateRegNotConflictingWith(((rTop33 < 0) ? (((usqInt)(1)) >> (-rTop33)) : (1ULL << rTop33))); } assert(!(((rTop33 == NoReg) || (rNext20 == NoReg)))); @@ -38397,14 +38562,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg19 = (rNext21 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask21 = 1ULL << reg19; + topRegistersMask21 = ((reg19 < 0) ? (((usqInt)(1)) >> (-reg19)) : (1ULL << reg19)); } } if (rTop34 == NoReg) { rTop34 = allocateRegNotConflictingWith(topRegistersMask21); } if (rNext21 == NoReg) { - rNext21 = allocateRegNotConflictingWith(1ULL << rTop34); + rNext21 = allocateRegNotConflictingWith(((rTop34 < 0) ? (((usqInt)(1)) >> (-rTop34)) : (1ULL << rTop34))); } assert(!(((rTop34 == NoReg) || (rNext21 == NoReg)))); @@ -38444,14 +38609,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg20 = (rNext22 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask22 = 1ULL << reg20; + topRegistersMask22 = ((reg20 < 0) ? (((usqInt)(1)) >> (-reg20)) : (1ULL << reg20)); } } if (rTop35 == NoReg) { rTop35 = allocateRegNotConflictingWith(topRegistersMask22); } if (rNext22 == NoReg) { - rNext22 = allocateRegNotConflictingWith(1ULL << rTop35); + rNext22 = allocateRegNotConflictingWith(((rTop35 < 0) ? (((usqInt)(1)) >> (-rTop35)) : (1ULL << rTop35))); } assert(!(((rTop35 == NoReg) || (rNext22 == NoReg)))); @@ -38491,14 +38656,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg21 = (rNext23 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask23 = 1ULL << reg21; + topRegistersMask23 = ((reg21 < 0) ? (((usqInt)(1)) >> (-reg21)) : (1ULL << reg21)); } } if (rTop36 == NoReg) { rTop36 = allocateRegNotConflictingWith(topRegistersMask23); } if (rNext23 == NoReg) { - rNext23 = allocateRegNotConflictingWith(1ULL << rTop36); + rNext23 = allocateRegNotConflictingWith(((rTop36 < 0) ? (((usqInt)(1)) >> (-rTop36)) : (1ULL << rTop36))); } assert(!(((rTop36 == NoReg) || (rNext23 == NoReg)))); @@ -38538,14 +38703,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg22 = (rNext24 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask24 = 1ULL << reg22; + topRegistersMask24 = ((reg22 < 0) ? (((usqInt)(1)) >> (-reg22)) : (1ULL << reg22)); } } if (rTop37 == NoReg) { rTop37 = allocateRegNotConflictingWith(topRegistersMask24); } if (rNext24 == NoReg) { - rNext24 = allocateRegNotConflictingWith(1ULL << rTop37); + rNext24 = allocateRegNotConflictingWith(((rTop37 < 0) ? (((usqInt)(1)) >> (-rTop37)) : (1ULL << rTop37))); } assert(!(((rTop37 == NoReg) || (rNext24 == NoReg)))); @@ -38630,14 +38795,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg23 = (rNext25 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask25 = 1ULL << reg23; + topRegistersMask25 = ((reg23 < 0) ? (((usqInt)(1)) >> (-reg23)) : (1ULL << reg23)); } } if (rTop40 == NoReg) { rTop40 = allocateRegNotConflictingWith(topRegistersMask25); } if (rNext25 == NoReg) { - rNext25 = allocateRegNotConflictingWith(1ULL << rTop40); + rNext25 = allocateRegNotConflictingWith(((rTop40 < 0) ? (((usqInt)(1)) >> (-rTop40)) : (1ULL << rTop40))); } assert(!(((rTop40 == NoReg) || (rNext25 == NoReg)))); @@ -38668,14 +38833,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg24 = (rNext26 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask26 = 1ULL << reg24; + topRegistersMask26 = ((reg24 < 0) ? (((usqInt)(1)) >> (-reg24)) : (1ULL << reg24)); } } if (rTop41 == NoReg) { rTop41 = allocateRegNotConflictingWith(topRegistersMask26); } if (rNext26 == NoReg) { - rNext26 = allocateRegNotConflictingWith(1ULL << rTop41); + rNext26 = allocateRegNotConflictingWith(((rTop41 < 0) ? (((usqInt)(1)) >> (-rTop41)) : (1ULL << rTop41))); } assert(!(((rTop41 == NoReg) || (rNext26 == NoReg)))); @@ -38706,14 +38871,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg25 = (rNext27 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask27 = 1ULL << reg25; + topRegistersMask27 = ((reg25 < 0) ? (((usqInt)(1)) >> (-reg25)) : (1ULL << reg25)); } } if (rTop42 == NoReg) { rTop42 = allocateRegNotConflictingWith(topRegistersMask27); } if (rNext27 == NoReg) { - rNext27 = allocateRegNotConflictingWith(1ULL << rTop42); + rNext27 = allocateRegNotConflictingWith(((rTop42 < 0) ? (((usqInt)(1)) >> (-rTop42)) : (1ULL << rTop42))); } assert(!(((rTop42 == NoReg) || (rNext27 == NoReg)))); @@ -38744,14 +38909,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg26 = (rNext28 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask28 = 1ULL << reg26; + topRegistersMask28 = ((reg26 < 0) ? (((usqInt)(1)) >> (-reg26)) : (1ULL << reg26)); } } if (rTop43 == NoReg) { rTop43 = allocateRegNotConflictingWith(topRegistersMask28); } if (rNext28 == NoReg) { - rNext28 = allocateRegNotConflictingWith(1ULL << rTop43); + rNext28 = allocateRegNotConflictingWith(((rTop43 < 0) ? (((usqInt)(1)) >> (-rTop43)) : (1ULL << rTop43))); } assert(!(((rTop43 == NoReg) || (rNext28 == NoReg)))); @@ -38821,14 +38986,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg27 = (rNext29 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask29 = 1ULL << reg27; + topRegistersMask29 = ((reg27 < 0) ? (((usqInt)(1)) >> (-reg27)) : (1ULL << reg27)); } } if (rTop46 == NoReg) { rTop46 = allocateRegNotConflictingWith(topRegistersMask29); } if (rNext29 == NoReg) { - rNext29 = allocateRegNotConflictingWith(1ULL << rTop46); + rNext29 = allocateRegNotConflictingWith(((rTop46 < 0) ? (((usqInt)(1)) >> (-rTop46)) : (1ULL << rTop46))); } assert(!(((rTop46 == NoReg) || (rNext29 == NoReg)))); @@ -38858,14 +39023,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg28 = (rNext30 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask30 = 1ULL << reg28; + topRegistersMask30 = ((reg28 < 0) ? (((usqInt)(1)) >> (-reg28)) : (1ULL << reg28)); } } if (rTop47 == NoReg) { rTop47 = allocateRegNotConflictingWith(topRegistersMask30); } if (rNext30 == NoReg) { - rNext30 = allocateRegNotConflictingWith(1ULL << rTop47); + rNext30 = allocateRegNotConflictingWith(((rTop47 < 0) ? (((usqInt)(1)) >> (-rTop47)) : (1ULL << rTop47))); } assert(!(((rTop47 == NoReg) || (rNext30 == NoReg)))); @@ -38903,14 +39068,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg29 = (rNext31 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask31 = 1ULL << reg29; + topRegistersMask31 = ((reg29 < 0) ? (((usqInt)(1)) >> (-reg29)) : (1ULL << reg29)); } } if (rTop48 == NoReg) { rTop48 = allocateRegNotConflictingWith(topRegistersMask31); } if (rNext31 == NoReg) { - rNext31 = allocateRegNotConflictingWith(1ULL << rTop48); + rNext31 = allocateRegNotConflictingWith(((rTop48 < 0) ? (((usqInt)(1)) >> (-rTop48)) : (1ULL << rTop48))); } assert(!(((rTop48 == NoReg) || (rNext31 == NoReg)))); @@ -38939,14 +39104,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg30 = (rNext32 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask32 = 1ULL << reg30; + topRegistersMask32 = ((reg30 < 0) ? (((usqInt)(1)) >> (-reg30)) : (1ULL << reg30)); } } if (rTop49 == NoReg) { rTop49 = allocateRegNotConflictingWith(topRegistersMask32); } if (rNext32 == NoReg) { - rNext32 = allocateRegNotConflictingWith(1ULL << rTop49); + rNext32 = allocateRegNotConflictingWith(((rTop49 < 0) ? (((usqInt)(1)) >> (-rTop49)) : (1ULL << rTop49))); } assert(!(((rTop49 == NoReg) || (rNext32 == NoReg)))); @@ -38976,14 +39141,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg31 = (rNext33 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask33 = 1ULL << reg31; + topRegistersMask33 = ((reg31 < 0) ? (((usqInt)(1)) >> (-reg31)) : (1ULL << reg31)); } } if (rTop50 == NoReg) { rTop50 = allocateRegNotConflictingWith(topRegistersMask33); } if (rNext33 == NoReg) { - rNext33 = allocateRegNotConflictingWith(1ULL << rTop50); + rNext33 = allocateRegNotConflictingWith(((rTop50 < 0) ? (((usqInt)(1)) >> (-rTop50)) : (1ULL << rTop50))); } assert(!(((rTop50 == NoReg) || (rNext33 == NoReg)))); @@ -39013,14 +39178,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg32 = (rNext110 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask34 = 1ULL << reg32; + topRegistersMask34 = ((reg32 < 0) ? (((usqInt)(1)) >> (-reg32)) : (1ULL << reg32)); } } if (rTop115 == NoReg) { rTop115 = allocateRegNotConflictingWith(topRegistersMask34); } if (rNext110 == NoReg) { - rNext110 = allocateRegNotConflictingWith(1ULL << rTop115); + rNext110 = allocateRegNotConflictingWith(((rTop115 < 0) ? (((usqInt)(1)) >> (-rTop115)) : (1ULL << rTop115))); } assert(!(((rTop115 == NoReg) || (rNext110 == NoReg)))); @@ -39126,7 +39291,7 @@ genLowcodeUnaryInlinePrimitive5(sqInt prim) if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult1 = allocateRegNotConflictingWith(1ULL << rTop1); + rResult1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); assert(!(((rTop1 == NoReg) || (rResult1 == NoReg)))); value = rTop1; @@ -39536,14 +39701,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } } if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(topRegistersMask); } if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1ULL << rTop); + rNext = allocateRegNotConflictingWith(((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1ULL << rTop))); } assert(!(((rTop == NoReg) || (rNext == NoReg)))); @@ -39573,14 +39738,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg1 = (rNext1 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask1 = 1ULL << reg1; + topRegistersMask1 = ((reg1 < 0) ? (((usqInt)(1)) >> (-reg1)) : (1ULL << reg1)); } } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask1); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -39658,14 +39823,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg3 = (rNext4 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask3 = 1ULL << reg3; + topRegistersMask3 = ((reg3 < 0) ? (((usqInt)(1)) >> (-reg3)) : (1ULL << reg3)); } } if (rTop5 == NoReg) { rTop5 = allocateRegNotConflictingWith(topRegistersMask3); } if (rNext4 == NoReg) { - rNext4 = allocateRegNotConflictingWith(1ULL << rTop5); + rNext4 = allocateRegNotConflictingWith(((rTop5 < 0) ? (((usqInt)(1)) >> (-rTop5)) : (1ULL << rTop5))); } assert(!(((rTop5 == NoReg) || (rNext4 == NoReg)))); @@ -39695,14 +39860,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg4 = (rNext11 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask4 = 1ULL << reg4; + topRegistersMask4 = ((reg4 < 0) ? (((usqInt)(1)) >> (-reg4)) : (1ULL << reg4)); } } if (rTop12 == NoReg) { rTop12 = allocateRegNotConflictingWith(topRegistersMask4); } if (rNext11 == NoReg) { - rNext11 = allocateRegNotConflictingWith(1ULL << rTop12); + rNext11 = allocateRegNotConflictingWith(((rTop12 < 0) ? (((usqInt)(1)) >> (-rTop12)) : (1ULL << rTop12))); } assert(!(((rTop12 == NoReg) || (rNext11 == NoReg)))); @@ -39731,14 +39896,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg5 = (rNext6 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask5 = 1ULL << reg5; + topRegistersMask5 = ((reg5 < 0) ? (((usqInt)(1)) >> (-reg5)) : (1ULL << reg5)); } } if (rTop7 == NoReg) { rTop7 = allocateRegNotConflictingWith(topRegistersMask5); } if (rNext6 == NoReg) { - rNext6 = allocateRegNotConflictingWith(1ULL << rTop7); + rNext6 = allocateRegNotConflictingWith(((rTop7 < 0) ? (((usqInt)(1)) >> (-rTop7)) : (1ULL << rTop7))); } assert(!(((rTop7 == NoReg) || (rNext6 == NoReg)))); @@ -39768,14 +39933,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg6 = (rNext7 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask6 = 1ULL << reg6; + topRegistersMask6 = ((reg6 < 0) ? (((usqInt)(1)) >> (-reg6)) : (1ULL << reg6)); } } if (rTop8 == NoReg) { rTop8 = allocateRegNotConflictingWith(topRegistersMask6); } if (rNext7 == NoReg) { - rNext7 = allocateRegNotConflictingWith(1ULL << rTop8); + rNext7 = allocateRegNotConflictingWith(((rTop8 < 0) ? (((usqInt)(1)) >> (-rTop8)) : (1ULL << rTop8))); } assert(!(((rTop8 == NoReg) || (rNext7 == NoReg)))); @@ -39922,18 +40087,18 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) nextRegisterMask2 = 0; if (rNext8 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask2 = 1ULL << rNext8; + nextRegisterMask2 = ((rNext8 < 0) ? (((usqInt)(1)) >> (-rNext8)) : (1ULL << rNext8)); } if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1ULL << rNextNext2); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNext2)) : (1ULL << rNextNext2))); } rTop9 = allocateRegNotConflictingWith(nextRegisterMask2); } if (rNext8 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask2 = 1ULL << rTop9; + nextRegisterMask2 = ((rTop9 < 0) ? (((usqInt)(1)) >> (-rTop9)) : (1ULL << rTop9)); if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1ULL << rNextNext2); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNext2)) : (1ULL << rNextNext2))); } rNext8 = allocateRegNotConflictingWith(nextRegisterMask2); } @@ -39974,14 +40139,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg7 = (rNext9 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask7 = 1ULL << reg7; + topRegistersMask7 = ((reg7 < 0) ? (((usqInt)(1)) >> (-reg7)) : (1ULL << reg7)); } } if (rTop10 == NoReg) { rTop10 = allocateRegNotConflictingWith(topRegistersMask7); } if (rNext9 == NoReg) { - rNext9 = allocateRegNotConflictingWith(1ULL << rTop10); + rNext9 = allocateRegNotConflictingWith(((rTop10 < 0) ? (((usqInt)(1)) >> (-rTop10)) : (1ULL << rTop10))); } assert(!(((rTop10 == NoReg) || (rNext9 == NoReg)))); @@ -40010,14 +40175,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg8 = (rNext10 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask8 = 1ULL << reg8; + topRegistersMask8 = ((reg8 < 0) ? (((usqInt)(1)) >> (-reg8)) : (1ULL << reg8)); } } if (rTop13 == NoReg) { rTop13 = allocateRegNotConflictingWith(topRegistersMask8); } if (rNext10 == NoReg) { - rNext10 = allocateRegNotConflictingWith(1ULL << rTop13); + rNext10 = allocateRegNotConflictingWith(((rTop13 < 0) ? (((usqInt)(1)) >> (-rTop13)) : (1ULL << rTop13))); } assert(!(((rTop13 == NoReg) || (rNext10 == NoReg)))); @@ -40045,7 +40210,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (frTop == NoReg) { frTop = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); } - frResult = allocateFloatRegNotConflictingWith(1ULL << frTop); + frResult = allocateFloatRegNotConflictingWith(((frTop < 0) ? (((usqInt)(1)) >> (-frTop)) : (1ULL << frTop))); assert(!(((frTop == NoReg) || (frResult == NoReg)))); value3 = frTop; @@ -40070,7 +40235,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (frTop1 == NoReg) { frTop1 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); } - frResult1 = allocateFloatRegNotConflictingWith(1ULL << frTop1); + frResult1 = allocateFloatRegNotConflictingWith(((frTop1 < 0) ? (((usqInt)(1)) >> (-frTop1)) : (1ULL << frTop1))); assert(!(((frTop1 == NoReg) || (frResult1 == NoReg)))); value4 = frTop1; @@ -40093,7 +40258,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (rTop14 == NoReg) { rTop14 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult3 = allocateRegNotConflictingWith(1ULL << rTop14); + rResult3 = allocateRegNotConflictingWith(((rTop14 < 0) ? (((usqInt)(1)) >> (-rTop14)) : (1ULL << rTop14))); assert(!(((rTop14 == NoReg) || (rResult3 == NoReg)))); value5 = rTop14; @@ -40117,7 +40282,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (rTop16 == NoReg) { rTop16 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult11 = allocateRegNotConflictingWith(1ULL << rTop16); + rResult11 = allocateRegNotConflictingWith(((rTop16 < 0) ? (((usqInt)(1)) >> (-rTop16)) : (1ULL << rTop16))); assert(!(((rTop16 == NoReg) || (rResult11 == NoReg)))); value6 = rTop16; @@ -40140,7 +40305,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (rTop17 == NoReg) { rTop17 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult5 = allocateRegNotConflictingWith(1ULL << rTop17); + rResult5 = allocateRegNotConflictingWith(((rTop17 < 0) ? (((usqInt)(1)) >> (-rTop17)) : (1ULL << rTop17))); assert(!(((rTop17 == NoReg) || (rResult5 == NoReg)))); pointerValue = rTop17; @@ -40191,24 +40356,24 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) nextRegisterMask3 = 0; if (rNext13 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask3 = 1ULL << rNext13; + nextRegisterMask3 = ((rNext13 < 0) ? (((usqInt)(1)) >> (-rNext13)) : (1ULL << rNext13)); } if (rNextNext3 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1ULL << rNextNext3); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNext3)) : (1ULL << rNextNext3))); } if (rNextNextNext2 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1ULL << rNextNextNext2); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNextNext2)) : (1ULL << rNextNextNext2))); } rTop18 = allocateRegNotConflictingWith(nextRegisterMask3); } if (rNext13 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask3 = 1ULL << rTop18; + nextRegisterMask3 = ((rTop18 < 0) ? (((usqInt)(1)) >> (-rTop18)) : (1ULL << rTop18)); if (rNextNext3 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1ULL << rNextNext3); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNext3)) : (1ULL << rNextNext3))); } if (rNextNextNext2 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1ULL << rNextNextNext2); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNextNext2)) : (1ULL << rNextNextNext2))); } rNext13 = allocateRegNotConflictingWith(nextRegisterMask3); } @@ -40216,7 +40381,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) /* begin registerMaskFor:and: */ nextRegisterMask3 = (1ULL << rTop18) | (1ULL << rNext13); if (rNextNextNext2 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1ULL << rNextNextNext2); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNextNext2)) : (1ULL << rNextNextNext2))); } rNextNext3 = allocateRegNotConflictingWith(nextRegisterMask3); } @@ -40289,24 +40454,24 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) nextRegisterMask4 = 0; if (rNext14 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask4 = 1ULL << rNext14; + nextRegisterMask4 = ((rNext14 < 0) ? (((usqInt)(1)) >> (-rNext14)) : (1ULL << rNext14)); } if (rNextNext4 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1ULL << rNextNext4); + nextRegisterMask4 = nextRegisterMask4 | (((rNextNext4 < 0) ? (((usqInt)(1)) >> (-rNextNext4)) : (1ULL << rNextNext4))); } if (rNextNextNext3 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1ULL << rNextNextNext3); + nextRegisterMask4 = nextRegisterMask4 | (((rNextNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNextNext3)) : (1ULL << rNextNextNext3))); } rTop19 = allocateRegNotConflictingWith(nextRegisterMask4); } if (rNext14 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask4 = 1ULL << rTop19; + nextRegisterMask4 = ((rTop19 < 0) ? (((usqInt)(1)) >> (-rTop19)) : (1ULL << rTop19)); if (rNextNext4 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1ULL << rNextNext4); + nextRegisterMask4 = nextRegisterMask4 | (((rNextNext4 < 0) ? (((usqInt)(1)) >> (-rNextNext4)) : (1ULL << rNextNext4))); } if (rNextNextNext3 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1ULL << rNextNextNext3); + nextRegisterMask4 = nextRegisterMask4 | (((rNextNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNextNext3)) : (1ULL << rNextNextNext3))); } rNext14 = allocateRegNotConflictingWith(nextRegisterMask4); } @@ -40314,7 +40479,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) /* begin registerMaskFor:and: */ nextRegisterMask4 = (1ULL << rTop19) | (1ULL << rNext14); if (rNextNextNext3 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1ULL << rNextNextNext3); + nextRegisterMask4 = nextRegisterMask4 | (((rNextNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNextNext3)) : (1ULL << rNextNextNext3))); } rNextNext4 = allocateRegNotConflictingWith(nextRegisterMask4); } @@ -40364,13 +40529,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg10 = (rNext15 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask10 = 1ULL << reg10; + topRegistersMask10 = ((reg10 < 0) ? (((usqInt)(1)) >> (-reg10)) : (1ULL << reg10)); } if (rTop20 == NoReg) { rTop20 = allocateFloatRegNotConflictingWith(topRegistersMask10); } if (rNext15 == NoReg) { - rNext15 = allocateFloatRegNotConflictingWith(1ULL << rTop20); + rNext15 = allocateFloatRegNotConflictingWith(((rTop20 < 0) ? (((usqInt)(1)) >> (-rTop20)) : (1ULL << rTop20))); } assert(!(((rTop20 == NoReg) || (rNext15 == NoReg)))); @@ -40395,13 +40560,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg11 = (rNext16 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask11 = 1ULL << reg11; + topRegistersMask11 = ((reg11 < 0) ? (((usqInt)(1)) >> (-reg11)) : (1ULL << reg11)); } if (rTop21 == NoReg) { rTop21 = allocateFloatRegNotConflictingWith(topRegistersMask11); } if (rNext16 == NoReg) { - rNext16 = allocateFloatRegNotConflictingWith(1ULL << rTop21); + rNext16 = allocateFloatRegNotConflictingWith(((rTop21 < 0) ? (((usqInt)(1)) >> (-rTop21)) : (1ULL << rTop21))); } assert(!(((rTop21 == NoReg) || (rNext16 == NoReg)))); @@ -40427,13 +40592,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg12 = (frNext = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask12 = 1ULL << reg12; + topRegistersMask12 = ((reg12 < 0) ? (((usqInt)(1)) >> (-reg12)) : (1ULL << reg12)); } if (frTop2 == NoReg) { frTop2 = allocateFloatRegNotConflictingWith(topRegistersMask12); } if (frNext == NoReg) { - frNext = allocateFloatRegNotConflictingWith(1ULL << frTop2); + frNext = allocateFloatRegNotConflictingWith(((frTop2 < 0) ? (((usqInt)(1)) >> (-frTop2)) : (1ULL << frTop2))); } rResult7 = allocateRegNotConflictingWith(0); assert(!(((frTop2 == NoReg) @@ -40473,13 +40638,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg13 = (frNext1 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask13 = 1ULL << reg13; + topRegistersMask13 = ((reg13 < 0) ? (((usqInt)(1)) >> (-reg13)) : (1ULL << reg13)); } if (frTop3 == NoReg) { frTop3 = allocateFloatRegNotConflictingWith(topRegistersMask13); } if (frNext1 == NoReg) { - frNext1 = allocateFloatRegNotConflictingWith(1ULL << frTop3); + frNext1 = allocateFloatRegNotConflictingWith(((frTop3 < 0) ? (((usqInt)(1)) >> (-frTop3)) : (1ULL << frTop3))); } rResult8 = allocateRegNotConflictingWith(0); assert(!(((frTop3 == NoReg) @@ -40519,13 +40684,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg14 = (frNext2 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask14 = 1ULL << reg14; + topRegistersMask14 = ((reg14 < 0) ? (((usqInt)(1)) >> (-reg14)) : (1ULL << reg14)); } if (frTop4 == NoReg) { frTop4 = allocateFloatRegNotConflictingWith(topRegistersMask14); } if (frNext2 == NoReg) { - frNext2 = allocateFloatRegNotConflictingWith(1ULL << frTop4); + frNext2 = allocateFloatRegNotConflictingWith(((frTop4 < 0) ? (((usqInt)(1)) >> (-frTop4)) : (1ULL << frTop4))); } rResult9 = allocateRegNotConflictingWith(0); assert(!(((frTop4 == NoReg) @@ -40565,13 +40730,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg15 = (frNext3 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask15 = 1ULL << reg15; + topRegistersMask15 = ((reg15 < 0) ? (((usqInt)(1)) >> (-reg15)) : (1ULL << reg15)); } if (frTop5 == NoReg) { frTop5 = allocateFloatRegNotConflictingWith(topRegistersMask15); } if (frNext3 == NoReg) { - frNext3 = allocateFloatRegNotConflictingWith(1ULL << frTop5); + frNext3 = allocateFloatRegNotConflictingWith(((frTop5 < 0) ? (((usqInt)(1)) >> (-frTop5)) : (1ULL << frTop5))); } rResult10 = allocateRegNotConflictingWith(0); assert(!(((frTop5 == NoReg) @@ -40611,13 +40776,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg16 = (frNext4 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask16 = 1ULL << reg16; + topRegistersMask16 = ((reg16 < 0) ? (((usqInt)(1)) >> (-reg16)) : (1ULL << reg16)); } if (frTop6 == NoReg) { frTop6 = allocateFloatRegNotConflictingWith(topRegistersMask16); } if (frNext4 == NoReg) { - frNext4 = allocateFloatRegNotConflictingWith(1ULL << frTop6); + frNext4 = allocateFloatRegNotConflictingWith(((frTop6 < 0) ? (((usqInt)(1)) >> (-frTop6)) : (1ULL << frTop6))); } rResult12 = allocateRegNotConflictingWith(0); assert(!(((frTop6 == NoReg) @@ -40656,13 +40821,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg17 = (rNext17 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask17 = 1ULL << reg17; + topRegistersMask17 = ((reg17 < 0) ? (((usqInt)(1)) >> (-reg17)) : (1ULL << reg17)); } if (rTop22 == NoReg) { rTop22 = allocateFloatRegNotConflictingWith(topRegistersMask17); } if (rNext17 == NoReg) { - rNext17 = allocateFloatRegNotConflictingWith(1ULL << rTop22); + rNext17 = allocateFloatRegNotConflictingWith(((rTop22 < 0) ? (((usqInt)(1)) >> (-rTop22)) : (1ULL << rTop22))); } assert(!(((rTop22 == NoReg) || (rNext17 == NoReg)))); @@ -40689,7 +40854,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (frTop7 == NoReg) { frTop7 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); } - frResult2 = allocateFloatRegNotConflictingWith(1ULL << frTop7); + frResult2 = allocateFloatRegNotConflictingWith(((frTop7 < 0) ? (((usqInt)(1)) >> (-frTop7)) : (1ULL << frTop7))); assert(!(((frTop7 == NoReg) || (frResult2 == NoReg)))); value12 = frTop7; @@ -40714,13 +40879,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg18 = (frNext5 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask18 = 1ULL << reg18; + topRegistersMask18 = ((reg18 < 0) ? (((usqInt)(1)) >> (-reg18)) : (1ULL << reg18)); } if (frTop8 == NoReg) { frTop8 = allocateFloatRegNotConflictingWith(topRegistersMask18); } if (frNext5 == NoReg) { - frNext5 = allocateFloatRegNotConflictingWith(1ULL << frTop8); + frNext5 = allocateFloatRegNotConflictingWith(((frTop8 < 0) ? (((usqInt)(1)) >> (-frTop8)) : (1ULL << frTop8))); } rResult13 = allocateRegNotConflictingWith(0); assert(!(((frTop8 == NoReg) @@ -40778,13 +40943,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg19 = (rNext18 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask20 = 1ULL << reg19; + topRegistersMask20 = ((reg19 < 0) ? (((usqInt)(1)) >> (-reg19)) : (1ULL << reg19)); } if (rTop23 == NoReg) { rTop23 = allocateFloatRegNotConflictingWith(topRegistersMask20); } if (rNext18 == NoReg) { - rNext18 = allocateFloatRegNotConflictingWith(1ULL << rTop23); + rNext18 = allocateFloatRegNotConflictingWith(((rTop23 < 0) ? (((usqInt)(1)) >> (-rTop23)) : (1ULL << rTop23))); } assert(!(((rTop23 == NoReg) || (rNext18 == NoReg)))); @@ -40920,13 +41085,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg20 = (rNext19 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask22 = 1ULL << reg20; + topRegistersMask22 = ((reg20 < 0) ? (((usqInt)(1)) >> (-reg20)) : (1ULL << reg20)); } if (rTop24 == NoReg) { rTop24 = allocateFloatRegNotConflictingWith(topRegistersMask22); } if (rNext19 == NoReg) { - rNext19 = allocateFloatRegNotConflictingWith(1ULL << rTop24); + rNext19 = allocateFloatRegNotConflictingWith(((rTop24 < 0) ? (((usqInt)(1)) >> (-rTop24)) : (1ULL << rTop24))); } assert(!(((rTop24 == NoReg) || (rNext19 == NoReg)))); @@ -40951,13 +41116,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg21 = (rNext20 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask23 = 1ULL << reg21; + topRegistersMask23 = ((reg21 < 0) ? (((usqInt)(1)) >> (-reg21)) : (1ULL << reg21)); } if (rTop25 == NoReg) { rTop25 = allocateFloatRegNotConflictingWith(topRegistersMask23); } if (rNext20 == NoReg) { - rNext20 = allocateFloatRegNotConflictingWith(1ULL << rTop25); + rNext20 = allocateFloatRegNotConflictingWith(((rTop25 < 0) ? (((usqInt)(1)) >> (-rTop25)) : (1ULL << rTop25))); } assert(!(((rTop25 == NoReg) || (rNext20 == NoReg)))); @@ -40983,13 +41148,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg22 = (frNext6 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask24 = 1ULL << reg22; + topRegistersMask24 = ((reg22 < 0) ? (((usqInt)(1)) >> (-reg22)) : (1ULL << reg22)); } if (frTop15 == NoReg) { frTop15 = allocateFloatRegNotConflictingWith(topRegistersMask24); } if (frNext6 == NoReg) { - frNext6 = allocateFloatRegNotConflictingWith(1ULL << frTop15); + frNext6 = allocateFloatRegNotConflictingWith(((frTop15 < 0) ? (((usqInt)(1)) >> (-frTop15)) : (1ULL << frTop15))); } rResult18 = allocateRegNotConflictingWith(0); assert(!(((frTop15 == NoReg) @@ -41029,13 +41194,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg23 = (frNext7 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask25 = 1ULL << reg23; + topRegistersMask25 = ((reg23 < 0) ? (((usqInt)(1)) >> (-reg23)) : (1ULL << reg23)); } if (frTop16 == NoReg) { frTop16 = allocateFloatRegNotConflictingWith(topRegistersMask25); } if (frNext7 == NoReg) { - frNext7 = allocateFloatRegNotConflictingWith(1ULL << frTop16); + frNext7 = allocateFloatRegNotConflictingWith(((frTop16 < 0) ? (((usqInt)(1)) >> (-frTop16)) : (1ULL << frTop16))); } rResult19 = allocateRegNotConflictingWith(0); assert(!(((frTop16 == NoReg) @@ -41075,13 +41240,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg24 = (frNext8 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask26 = 1ULL << reg24; + topRegistersMask26 = ((reg24 < 0) ? (((usqInt)(1)) >> (-reg24)) : (1ULL << reg24)); } if (frTop17 == NoReg) { frTop17 = allocateFloatRegNotConflictingWith(topRegistersMask26); } if (frNext8 == NoReg) { - frNext8 = allocateFloatRegNotConflictingWith(1ULL << frTop17); + frNext8 = allocateFloatRegNotConflictingWith(((frTop17 < 0) ? (((usqInt)(1)) >> (-frTop17)) : (1ULL << frTop17))); } rResult20 = allocateRegNotConflictingWith(0); assert(!(((frTop17 == NoReg) @@ -41121,13 +41286,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg25 = (frNext9 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask27 = 1ULL << reg25; + topRegistersMask27 = ((reg25 < 0) ? (((usqInt)(1)) >> (-reg25)) : (1ULL << reg25)); } if (frTop18 == NoReg) { frTop18 = allocateFloatRegNotConflictingWith(topRegistersMask27); } if (frNext9 == NoReg) { - frNext9 = allocateFloatRegNotConflictingWith(1ULL << frTop18); + frNext9 = allocateFloatRegNotConflictingWith(((frTop18 < 0) ? (((usqInt)(1)) >> (-frTop18)) : (1ULL << frTop18))); } rResult22 = allocateRegNotConflictingWith(0); assert(!(((frTop18 == NoReg) @@ -41167,13 +41332,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg26 = (frNext10 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask28 = 1ULL << reg26; + topRegistersMask28 = ((reg26 < 0) ? (((usqInt)(1)) >> (-reg26)) : (1ULL << reg26)); } if (frTop19 == NoReg) { frTop19 = allocateFloatRegNotConflictingWith(topRegistersMask28); } if (frNext10 == NoReg) { - frNext10 = allocateFloatRegNotConflictingWith(1ULL << frTop19); + frNext10 = allocateFloatRegNotConflictingWith(((frTop19 < 0) ? (((usqInt)(1)) >> (-frTop19)) : (1ULL << frTop19))); } rResult23 = allocateRegNotConflictingWith(0); assert(!(((frTop19 == NoReg) @@ -41212,13 +41377,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg27 = (rNext21 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask29 = 1ULL << reg27; + topRegistersMask29 = ((reg27 < 0) ? (((usqInt)(1)) >> (-reg27)) : (1ULL << reg27)); } if (rTop26 == NoReg) { rTop26 = allocateFloatRegNotConflictingWith(topRegistersMask29); } if (rNext21 == NoReg) { - rNext21 = allocateFloatRegNotConflictingWith(1ULL << rTop26); + rNext21 = allocateFloatRegNotConflictingWith(((rTop26 < 0) ? (((usqInt)(1)) >> (-rTop26)) : (1ULL << rTop26))); } assert(!(((rTop26 == NoReg) || (rNext21 == NoReg)))); @@ -41245,7 +41410,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (frTop20 == NoReg) { frTop20 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); } - frResult3 = allocateFloatRegNotConflictingWith(1ULL << frTop20); + frResult3 = allocateFloatRegNotConflictingWith(((frTop20 < 0) ? (((usqInt)(1)) >> (-frTop20)) : (1ULL << frTop20))); assert(!(((frTop20 == NoReg) || (frResult3 == NoReg)))); value24 = frTop20; @@ -41270,13 +41435,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg28 = (frNext11 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask30 = 1ULL << reg28; + topRegistersMask30 = ((reg28 < 0) ? (((usqInt)(1)) >> (-reg28)) : (1ULL << reg28)); } if (frTop21 == NoReg) { frTop21 = allocateFloatRegNotConflictingWith(topRegistersMask30); } if (frNext11 == NoReg) { - frNext11 = allocateFloatRegNotConflictingWith(1ULL << frTop21); + frNext11 = allocateFloatRegNotConflictingWith(((frTop21 < 0) ? (((usqInt)(1)) >> (-frTop21)) : (1ULL << frTop21))); } rResult24 = allocateRegNotConflictingWith(0); assert(!(((frTop21 == NoReg) @@ -41334,13 +41499,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg29 = (rNext22 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask32 = 1ULL << reg29; + topRegistersMask32 = ((reg29 < 0) ? (((usqInt)(1)) >> (-reg29)) : (1ULL << reg29)); } if (rTop27 == NoReg) { rTop27 = allocateFloatRegNotConflictingWith(topRegistersMask32); } if (rNext22 == NoReg) { - rNext22 = allocateFloatRegNotConflictingWith(1ULL << rTop27); + rNext22 = allocateFloatRegNotConflictingWith(((rTop27 < 0) ? (((usqInt)(1)) >> (-rTop27)) : (1ULL << rTop27))); } assert(!(((rTop27 == NoReg) || (rNext22 == NoReg)))); @@ -41808,11 +41973,11 @@ genPushMaybeContextReceiverVariable(sqInt slotIndex) AbstractInstruction *jmpSingle; /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ensureReceiverResultRegContainsSelf(); /* begin genPushMaybeContextSlotIndex: */ assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ voidReceiverResultRegContainsSelf(); @@ -41866,7 +42031,7 @@ genPushNewArrayBytecode(void) } else { /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << SendNumArgsReg)) | ((1U << ReceiverResultReg))), simStackPtr, simNativeStackPtr); } size = byte1 & 0x7F; if (!popValues) { @@ -41939,7 +42104,7 @@ genPushRemoteTempLongBytecode(void) /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperandoperand(MoveMwrR, offset, FPReg, tempVectReg); /* begin availableRegOrNoneNotConflictingWith: */ - regMask = 1ULL << tempVectReg; + regMask = ((tempVectReg < 0) ? (((usqInt)(1)) >> (-tempVectReg)) : (1ULL << tempVectReg)); remoteTempReg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); if (remoteTempReg == NoReg) { remoteTempReg = tempVectReg; @@ -42290,11 +42455,11 @@ genSpecialSelectorClass(void) || (topReg == ClassReg)) { /* begin ssAllocateRequiredReg:and: */ requiredReg1 = (topReg = SendNumArgsReg); - ssAllocateRequiredRegMaskupThroughupThroughNative((1ULL << requiredReg1) | (1U << ClassReg), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((((requiredReg1 < 0) ? (((usqInt)(1)) >> (-requiredReg1)) : (1ULL << requiredReg1))) | ((1U << ClassReg)), simStackPtr, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr, simNativeStackPtr); } ssPush(1); popToReg(ssTop(), topReg); @@ -42528,7 +42693,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean association = getLiteral(litVarIndex); voidReceiverResultRegContainsSelf(); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin genMoveConstant:R: */ if (shouldAnnotateObjectReference(association)) { annotateobjRef(checkLiteralforInstruction(association, genoperandoperand(MoveCwR, association, ReceiverResultReg)), association); @@ -42541,7 +42706,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean # if IMMUTABILITY if (needsImmCheck) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -42556,7 +42721,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -42617,7 +42782,7 @@ genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqI # endif // IMMUTABILITY ssPop(1); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ClassReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ssPush(1); genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); @@ -42663,7 +42828,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea # if IMMUTABILITY if (needsImmCheck1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -42678,7 +42843,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck1, 1); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck1); } @@ -42702,7 +42867,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt assert(needsFrame); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); /* begin MoveMw:r:R: */ offset = frameOffsetOfTemporary(remoteTempIndex); @@ -42712,7 +42877,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt # if IMMUTABILITY # endif - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -42902,13 +43067,13 @@ genVanillaInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -43207,12 +43372,12 @@ liveRegisters(void) } else { /* begin registerMaskFor: */ - regsSet = 1U << ReceiverResultReg; + regsSet = (1U << ReceiverResultReg); if ((methodOrBlockNumArgs <= 2 /* numRegArgs */) && (methodOrBlockNumArgs > 0)) { - regsSet = regsSet | (1U << Arg0Reg); + regsSet = regsSet | ((1U << Arg0Reg)); if (methodOrBlockNumArgs > 1) { - regsSet = regsSet | (1U << Arg1Reg); + regsSet = regsSet | ((1U << Arg1Reg)); } } } @@ -43321,13 +43486,13 @@ marshallSendArguments(sqInt numArgs) if (numArgs > 0) { if (numArgs > 1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 2, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 2, simNativeStackPtr); /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg1Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg1Reg), simStackPtr - 1, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 1, simNativeStackPtr); } } if (numArgs > 1) { @@ -43907,7 +44072,7 @@ ssAllocateRequiredFloatRegMaskupThroughupThroughNative(sqInt requiredRegsMask, s static void NoDbgRegParms ssAllocateRequiredFloatReg(sqInt requiredReg) { - ssAllocateRequiredFloatRegMaskupThroughupThroughNative(1ULL << requiredReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredFloatRegMaskupThroughupThroughNative(((requiredReg < 0) ? (((usqInt)(1)) >> (-requiredReg)) : (1ULL << requiredReg)), simStackPtr, simNativeStackPtr); } /* StackToRegisterMappingCogit>>#ssAllocateRequiredRegMask:upThrough:upThroughNative: */ diff --git a/spurlowcode64src/vm/cogitX64WIN64.c b/spurlowcode64src/vm/cogitX64WIN64.c index 63886f4d85..8eea9b4394 100644 --- a/spurlowcode64src/vm/cogitX64WIN64.c +++ b/spurlowcode64src/vm/cogitX64WIN64.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + CCodeGenerator VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + StackToRegisterMappingCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 " __DATE__ ; +static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__cogitBuildInfo = __buildInfo; @@ -55,7 +55,7 @@ char *__cogitBuildInfo = __buildInfo; #define ArithmeticShiftRightRR 92 #define BadRegisterSet 1 #define BlockCreationBytecodeSize 4 -#define BSR 167 +#define BSR 169 #define BytecodeSetHasDirectedSuperSend 1 #define CArg0Reg 1 #define CArg1Reg 2 @@ -65,11 +65,11 @@ char *__cogitBuildInfo = __buildInfo; #define CallerSavedRegisterMask 0x706 #define CallFull 7 #define CallR 8 -#define CDQ 159 +#define CDQ 161 #if !defined(CheckRememberedInTrampoline) /* Allow this to be overridden on the compiler command line */ # define CheckRememberedInTrampoline 0 #endif -#define CLD 163 +#define CLD 165 #define ClassArray 7 #define ClassArrayCompactIndex 51 #define ClassBlockClosureCompactIndex 37 @@ -94,7 +94,7 @@ char *__cogitBuildInfo = __buildInfo; #define CMMaxUsageCount 7 #define CMMethod 2 #define CMOpenPIC 5 -#define CMPXCHGRMr 172 +#define CMPXCHGRMr 174 #define CmpC32R 113 #define CmpCqR 105 #define CmpCwR 112 @@ -109,7 +109,7 @@ char *__cogitBuildInfo = __buildInfo; #define ConvertRRs 150 #define ConvertRsR 149 #define ConvertRsRd 147 -#define CPUID 158 +#define CPUID 160 #define Debug DEBUGVM #define DisplacementMask 0x1F #define DisplacementX2N 0 @@ -153,11 +153,11 @@ char *__cogitBuildInfo = __buildInfo; #define HashMultiplyConstant 1664525 #define HashMultiplyMask 0xFFFFFFF #define HeaderIndex 0 -#define IDIVR 160 +#define IDIVR 162 #if !defined(IMMUTABILITY) /* Allow this to be overridden on the compiler command line */ # define IMMUTABILITY 1 #endif -#define IMULRR 161 +#define IMULRR 163 #define InFullBlock 2 #define InstanceSpecificationIndex 2 #define InstructionPointerIndex 1 @@ -208,11 +208,11 @@ char *__cogitBuildInfo = __buildInfo; #define Label 1 #define LargeContextSlots 62 #define LastJump 42 -#define LFENCE 168 +#define LFENCE 170 #undef LinkReg #define Literal 2 #define LiteralStart 1 -#define LOCK 171 +#define LOCK 173 #define LoadEffectiveAddressMwrR 88 #define LogicalShiftLeftCqR 95 #define LogicalShiftLeftCqRR 129 @@ -236,11 +236,11 @@ char *__cogitBuildInfo = __buildInfo; #define MethodCacheSelector 1 #define MethodIndex 3 #define MethodTooBig -4 -#define MFENCE 169 +#define MFENCE 171 #define MFMethodFlagHasContextFlag 1 #define MFMethodFlagIsBlockFlag 2 -#define MOVSB 165 -#define MOVSQ 166 +#define MOVSB 167 +#define MOVSQ 168 #define ModReg 3 #define ModRegInd 0 #define ModRegRegDisp32 2 @@ -259,10 +259,12 @@ char *__cogitBuildInfo = __buildInfo; #define MoveMbrR 65 #define MoveMs8rR 55 #define MoveMwrR 50 +#define MovePerfCnt64RL 159 +#define MovePerfCnt64RRL 158 #define MoveRA32 47 #define MoveRAb 49 #define MoveRAw 46 -#define MoveRAwNoVBR 174 +#define MoveRAwNoVBR 176 #define MoveRdM64r 76 #define MoveRdR 73 #define MoveRdRd 74 @@ -333,7 +335,7 @@ char *__cogitBuildInfo = __buildInfo; #define RCX 1 #define RDI 7 #define RDX 2 -#define REP 164 +#define REP 166 #define ReceiverIndex 5 #define ReceiverResultReg 9 #define RetN 9 @@ -342,12 +344,12 @@ char *__cogitBuildInfo = __buildInfo; #define RotateRightCqR 98 #define RSI 6 #define RSP 4 -#define SETE 173 +#define SETE 175 #define SelectorCannotInterpret 34 #define SelectorDoesNotUnderstand 20 #define SenderIndex 0 #define SendNumArgsReg 10 -#define SFENCE 170 +#define SFENCE 172 #define ShouldNotJIT -8 #define SIB1 0 #define SIB4 2 @@ -398,7 +400,7 @@ char *__cogitBuildInfo = __buildInfo; #define UnimplementedPrimitive -7 #define ValueIndex 1 #define VarBaseReg 3 -#define XCHGRR 162 +#define XCHGRR 164 #define XMM0L 0 #define XMM1L 1 #define XMM2L 2 @@ -549,7 +551,7 @@ static sqInt NoDbgRegParms concretizeAt(AbstractInstruction * self_in_concretize static sqInt NoDbgRegParms genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer); static sqInt NoDbgRegParms genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers); static sqInt NoDbgRegParms genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers); -static sqInt NoDbgRegParms genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg); +static sqInt NoDbgRegParms genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg); static sqInt NoDbgRegParms genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers); static void NoDbgRegParms genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister); static void NoDbgRegParms genWriteCSecondResultIntoReg(AbstractInstruction * self_in_genWriteCSecondResultIntoReg, sqInt abstractRegister); @@ -744,6 +746,8 @@ extern void linkSendAtintooffsetreceiver(sqInt callSiteReturnAddress, CogMethod static BytecodeDescriptor * loadBytesAndGetDescriptor(void); static void NoDbgRegParms loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc); static AbstractInstruction * NoDbgRegParms gMoveCwR(sqInt wordConstant, sqInt reg); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters); static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg); static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC); @@ -1111,6 +1115,7 @@ static sqInt NoDbgRegParms computeShiftRRSize(AbstractInstruction * self_in_comp static sqInt NoDbgRegParms computeSizeOfPushCw(AbstractInstruction * self_in_computeSizeOfPushCw); static sqInt NoDbgRegParms concretizeArithCqRWithROraxOpcode(AbstractInstruction * self_in_concretizeArithCqRWithROraxOpcode, sqInt regOpcode, sqInt raxOpcode); static sqInt NoDbgRegParms concretizeFill32(AbstractInstruction * self_in_concretizeFill32); +static sqInt NoDbgRegParms concretizeMovePerfCnt64RL(AbstractInstruction * self_in_concretizeMovePerfCnt64RL); static sqInt NoDbgRegParms concretizeMoveRX32rR(AbstractInstruction * self_in_concretizeMoveRX32rR); static sqInt NoDbgRegParms concretizeMoveX32rRR(AbstractInstruction * self_in_concretizeMoveX32rRR); static sqInt NoDbgRegParms concretizeOpRR(AbstractInstruction * self_in_concretizeOpRR, sqInt x64opcode); @@ -1260,6 +1265,7 @@ static sqInt genStoreAndPopReceiverVariableBytecode(void); static sqInt genStoreAndPopRemoteTempLongBytecode(void); static sqInt genStoreAndPopTemporaryVariableBytecode(void); static sqInt genStoreRemoteTempLongBytecode(void); +static void genTakeProfileSample(void); static sqInt genUnconditionalTrapBytecode(void); static void NoDbgRegParms loadNativeArgumentAddressto(sqInt baseOffset, sqInt reg); static void NoDbgRegParms loadNativeFramePointerInto(sqInt reg); @@ -2857,28 +2863,28 @@ addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *an static sqInt NoDbgRegParms availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << DPFPReg0)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg0))) != 0))) { return DPFPReg0; } - if (!(((liveRegsMask & (1U << DPFPReg1)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg1))) != 0))) { return DPFPReg1; } - if (!(((liveRegsMask & (1U << DPFPReg2)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg2))) != 0))) { return DPFPReg2; } - if (!(((liveRegsMask & (1U << DPFPReg3)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg3))) != 0))) { return DPFPReg3; } - if (!(((liveRegsMask & (1U << DPFPReg4)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg4))) != 0))) { return DPFPReg4; } - if (!(((liveRegsMask & (1U << DPFPReg5)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg5))) != 0))) { return DPFPReg5; } - if (!(((liveRegsMask & (1U << DPFPReg6)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg6))) != 0))) { return DPFPReg6; } - if (!(((liveRegsMask & (1U << DPFPReg7)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg7))) != 0))) { return DPFPReg7; } return NoReg; @@ -2993,9 +2999,9 @@ genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers) used immediately afterwards. */ - /* CogAbstractInstruction>>#genLoadStackPointersForFastPrimCall: */ + /* CogAbstractInstruction>>#genLoadStackPointersForPrimCall: */ static sqInt NoDbgRegParms -genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg) +genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg) { AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; @@ -5798,7 +5804,7 @@ compileCallFornumArgsargargargargfloatResultRegregsToSave(void *aRoutine, sqInt regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1ULL << resultRegOrNone)) - (1ULL << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ regMaskCopy = ((usqInt)regsToSave); @@ -5918,7 +5924,7 @@ compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numAr regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1ULL << resultRegOrNone)) - (1ULL << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ regMaskCopy = ((usqInt)regsToSave); @@ -6036,7 +6042,7 @@ compileCallFornumArgsargargargargresultRegresultRegregsToSave(void *aRoutine, sq regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1ULL << resultRegOrNone)) - (1ULL << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ regMaskCopy = ((usqInt)regsToSave); @@ -6175,7 +6181,7 @@ compileCallFornumArgsfloatArgfloatArgfloatArgfloatArgresultRegregsToSave(void *a regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1ULL << resultRegOrNone)) - (1ULL << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ regMaskCopy = ((usqInt)regsToSave); @@ -7918,7 +7924,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) startAddress = methodZoneBase; callerSavedReg = 0; pushedVarBaseReg = 0; - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { /* VarBaseReg is not caller-saved; must save and restore it, either by using an available caller-saved reg or push/pop. */ @@ -7951,7 +7957,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) /* begin checkLiteral:forInstruction: */ cStackPointerAddress(); anInstruction3 = genoperandoperand(MoveRAw, TempReg, cStackPointerAddress()); - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { if (pushedVarBaseReg) { gNativePopR(VarBaseReg); } @@ -9531,6 +9537,22 @@ gMoveCwR(sqInt wordConstant, sqInt reg) return anInstruction; } + /* Cogit>>#MovePerfCnt64R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters) +{ + assert(BytesPerWord == 8); + return genoperandoperand(MovePerfCnt64RL, destReg, liveRegisters); +} + + /* Cogit>>#MovePerfCnt64R:R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters) +{ + assert(BytesPerWord == 4); + return genoperandoperandoperand(MovePerfCnt64RRL, destRegLo, destRegHi, liveRegisters); +} + /* Answer the address of the null byte at the end of the method map. */ @@ -11054,11 +11076,14 @@ recordRunTimeObjectReferences(void) } } + +/* N.B. (self registerMaskFor: NoReg) = 0 */ + /* Cogit>>#registerMaskFor: */ static sqInt NoDbgRegParms registerMaskFor(sqInt reg) { - return 1ULL << reg; + return ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } /* Cogit>>#registerMaskFor:and: */ @@ -18372,7 +18397,7 @@ generateObjectRepresentationTrampolines(void) } # endif // IMMUTABILITY ceNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceNewHash", 1, ReceiverResultReg, null, null, null, /* begin emptyRegisterMask */ 0, 1, ReceiverResultReg, 0); - ceInlineNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceInlineNewHash", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, ReceiverResultReg, 0); + ceInlineNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceInlineNewHash", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))), 1, ReceiverResultReg, 0); /* begin genStoreCheckTrampoline */ if (CheckRememberedInTrampoline) { zeroOpcodeIndex(); @@ -18383,7 +18408,7 @@ generateObjectRepresentationTrampolines(void) genoperand(RetN, 0); jmpTarget(jumpSC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); } - ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))), 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), CheckRememberedInTrampoline); ceStoreCheckContextReceiverTrampoline = genStoreCheckContextReceiverTrampoline(); @@ -20520,7 +20545,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jumpRC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg)); jmpTarget(jumpImmutable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); @@ -20536,7 +20561,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* Store check */ jumpImmutable1 = genJumpImmutablescratchReg(ReceiverResultReg, SendNumArgsReg); - compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), 0 /* emptyRegisterMask */); genLoadStackPointers(backEnd()); @@ -21094,7 +21119,7 @@ registerMask(SimStackEntry * self_in_registerMask) || (((self_in_registerMask->type)) == SSRegister) ? (/* begin registerMaskFor: */ (reg = (self_in_registerMask->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : 0); } @@ -21107,7 +21132,7 @@ registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone) return (((self_in_registerMaskOrNone->type)) == SSRegister ? (/* begin registerMaskFor: */ (reg = (self_in_registerMaskOrNone->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : 0); } @@ -21305,7 +21330,7 @@ nativeFloatRegisterMask(CogSimStackNativeEntry * self_in_nativeFloatRegisterMask || (((self_in_nativeFloatRegisterMask->type)) == SSRegisterDoubleFloat) ? (/* begin registerMaskFor: */ (reg = (self_in_nativeFloatRegisterMask->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : 0); } @@ -21511,9 +21536,9 @@ nativeRegisterMask(CogSimStackNativeEntry * self_in_nativeRegisterMask) || (((self_in_nativeRegisterMask->type)) == SSRegisterDoubleFloat) ? (/* begin registerMaskFor: */ (reg = (self_in_nativeRegisterMask->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : (((self_in_nativeRegisterMask->type)) == SSRegisterPair - ? (1ULL << ((self_in_nativeRegisterMask->registerr))) | (1ULL << ((self_in_nativeRegisterMask->registerSecond))) + ? (((((self_in_nativeRegisterMask->registerr)) < 0) ? (((usqInt)(1)) >> (-((self_in_nativeRegisterMask->registerr)))) : (1ULL << ((self_in_nativeRegisterMask->registerr))))) | (((((self_in_nativeRegisterMask->registerSecond)) < 0) ? (((usqInt)(1)) >> (-((self_in_nativeRegisterMask->registerSecond)))) : (1ULL << ((self_in_nativeRegisterMask->registerSecond))))) : 0)); } @@ -21655,37 +21680,37 @@ isMergeFixup(BytecodeFixup * self_in_isMergeFixup) static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << Extra5Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra5Reg))) != 0))) { return Extra5Reg; } - if (!(((liveRegsMask & (1U << Extra4Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra4Reg))) != 0))) { return Extra4Reg; } - if (!(((liveRegsMask & (1U << Extra3Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra3Reg))) != 0))) { return Extra3Reg; } - if (!(((liveRegsMask & (1U << Extra2Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra2Reg))) != 0))) { return Extra2Reg; } - if (!(((liveRegsMask & (1U << Extra1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra1Reg))) != 0))) { return Extra1Reg; } - if (!(((liveRegsMask & (1U << Extra0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra0Reg))) != 0))) { return Extra0Reg; } - if (!(((liveRegsMask & (1U << Arg1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg1Reg))) != 0))) { return Arg1Reg; } - if (!(((liveRegsMask & (1U << Arg0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg0Reg))) != 0))) { return Arg0Reg; } - if (!(((liveRegsMask & (1U << SendNumArgsReg)) != 0))) { + if (!(((liveRegsMask & ((1U << SendNumArgsReg))) != 0))) { return SendNumArgsReg; } - if (!(((liveRegsMask & (1U << ClassReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ClassReg))) != 0))) { return ClassReg; } - if (!(((liveRegsMask & (1U << ReceiverResultReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ReceiverResultReg))) != 0))) { return ReceiverResultReg; } return NoReg; @@ -22264,6 +22289,11 @@ computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize) ? 1 : 0)); + case MovePerfCnt64RL: + + /* it is easier to calculate the right value by concretizing. We concretize twice, but so what? */ + return concretizeMovePerfCnt64RL(self_in_computeMaximumSize); + default: error("Case not found and no otherwise clause"); } @@ -22355,6 +22385,65 @@ concretizeFill32(AbstractInstruction * self_in_concretizeFill32) return 4; } + +/* Generate code for + 0x0: 50 pushq %rax + 0x1: 52 pushq %rdx + 0x2: 0f 31 rdtsc + 0x4: 48 c1 e2 20 shlq $0x20, %rdx + 0x8: 48 09 d0 orq %rdx, %rax + 0xb: 48 89 f8 movq %rdi, %rax + 0xe: 5a popq %rdx + 0xf: 58 popq %rax + et al */ + + /* CogX64Compiler>>#concretizeMovePerfCnt64RL */ +static sqInt NoDbgRegParms +concretizeMovePerfCnt64RL(AbstractInstruction * self_in_concretizeMovePerfCnt64RL) +{ + usqInt liveRegisters; + sqInt offset; + usqInt reg; + + reg = ((self_in_concretizeMovePerfCnt64RL->operands))[0]; + liveRegisters = ((self_in_concretizeMovePerfCnt64RL->operands))[1]; + offset = 0; + if (((liveRegisters & ((1U << RAX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[0] = 80; + offset += 1; + } + if (((liveRegisters & ((1U << RDX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 82; + offset += 1; + } + assert(!((reg == RDX))); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 15; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 1] = 49; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 2] = (rexRxb(self_in_concretizeMovePerfCnt64RL, 0, 0, RDX)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 3] = 193; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 4] = (modRMRO(self_in_concretizeMovePerfCnt64RL, ModReg, RDX, 4)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 5] = 32; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 6] = (rexRxb(self_in_concretizeMovePerfCnt64RL, RDX, 0, RAX)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 7] = 11; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 8] = (modRMRO(self_in_concretizeMovePerfCnt64RL, ModReg, RAX, RDX)); + offset += 9; + if (reg != RAX) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[11] = (rexRxb(self_in_concretizeMovePerfCnt64RL, reg, 0, RAX)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[12] = 137; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[13] = (modRMRO(self_in_concretizeMovePerfCnt64RL, ModReg, RAX, reg)); + offset += 3; + } + if (((liveRegisters & ((1U << RDX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 90; + offset += 1; + } + if (((liveRegisters & ((1U << RAX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 88; + offset += 1; + } + return offset; +} + /* CogX64Compiler>>#concretizeMoveRX32rR */ static sqInt NoDbgRegParms concretizeMoveRX32rR(AbstractInstruction * self_in_concretizeMoveRX32rR) @@ -25757,6 +25846,9 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) ((self_in_dispatchConcretize->machineCode))[skip28 + 1] = (modRMRO(self_in_dispatchConcretize, ModReg, srcReg28, destReg29)); return skip28 + 2; + case MovePerfCnt64RL: + return concretizeMovePerfCnt64RL(self_in_dispatchConcretize); + default: error("Case not found and no otherwise clause"); } @@ -26385,8 +26477,8 @@ genPushRegisterArgsForNumArgsscratchReg(AbstractInstruction * self_in_genPushReg /* This is a no-op on x64 SysV since the ABI passes up to 6 args in registers and trampolines currently observe a limit of 4. - But the WIN64 ABI allways reserve shadow space for saving up to 4 - parameter registers (even if less than 4 args). + But the WIN64 ABI always reserve shadow space for saving up to 4 parameter + registers (even if less than 4 args). */ /* CogX64Compiler>>#genRemoveNArgsFromStack: */ @@ -26412,7 +26504,7 @@ genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask) assert(!((((regMask & (registerMaskForand(RSP, RBP))) != 0)))); for (reg = RAX; reg <= R15; reg += 1) { - if (((regMask & (1ULL << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0)) { /* begin PopR: */ genoperand(PopR, reg); } @@ -26434,7 +26526,7 @@ genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask) assert(((R15 - RAX) + 1) == 16); assert(!((((regMask & (registerMaskForand(RSP, RBP))) != 0)))); for (reg = R15; reg >= RAX; reg += -1) { - if (((regMask & (1ULL << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0)) { /* begin PushR: */ genoperand(PushR, reg); } @@ -27266,56 +27358,45 @@ compileInterpreterPrimitive(void) static sqInt NoDbgRegParms compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) { - sqInt address2; + AbstractInstruction *anInstruction; + AbstractInstruction *anInstruction1; AbstractInstruction *anInstruction10; AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction15; + AbstractInstruction *anInstruction14; + AbstractInstruction *anInstruction16; + AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction18; AbstractInstruction *anInstruction19; AbstractInstruction *anInstruction2; AbstractInstruction *anInstruction20; AbstractInstruction *anInstruction21; + AbstractInstruction *anInstruction22; AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction24; AbstractInstruction *anInstruction25; AbstractInstruction *anInstruction26; AbstractInstruction *anInstruction27; + AbstractInstruction *anInstruction28; AbstractInstruction *anInstruction29; AbstractInstruction *anInstruction3; + AbstractInstruction *anInstruction30; AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction33; - AbstractInstruction *anInstruction34; - AbstractInstruction *anInstruction35; - AbstractInstruction *anInstruction36; - AbstractInstruction *anInstruction37; - AbstractInstruction *anInstruction38; - AbstractInstruction *anInstruction39; AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction40; AbstractInstruction *anInstruction41; - AbstractInstruction *anInstruction5; AbstractInstruction *anInstruction6; AbstractInstruction *anInstruction7; AbstractInstruction *anInstruction8; - AbstractInstruction * continuePostSampleNonPrim; - AbstractInstruction * continuePostSamplePrim; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; - AbstractInstruction * jmpSampleNonPrim; - AbstractInstruction * jmpSamplePrim; + AbstractInstruction * jumpToTakeSample; + sqInt liveRegisters; sqInt offset; sqInt offset1; sqInt offset2; - sqInt operand1; - sqInt operand3; sqInt reg; sqInt retpc; - continuePostSampleNonPrim = ((AbstractInstruction *) 0); - continuePostSamplePrim = ((AbstractInstruction *) 0); - jmpSampleNonPrim = ((AbstractInstruction *) 0); - jmpSamplePrim = ((AbstractInstruction *) 0); + jumpToTakeSample = ((AbstractInstruction *) 0); assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); genExternalizePointersForPrimitiveCall(); /* begin genLoadCStackPointersForPrimCall */ @@ -27325,41 +27406,28 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) else { genLoadCStackPointer(backEnd); } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick if so */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction2 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpSampleNonPrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSampleNonPrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } if (recordPrimTraceForMethod(methodObj)) { genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction37 = genoperandoperand(MoveCqR, 0, TempReg); + anInstruction18 = genoperandoperand(MoveCqR, 0, TempReg); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction38 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); + anInstruction19 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); + anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); } /* begin checkLiteral:forInstruction: */ argumentCountAddress(); - anInstruction39 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); + anInstruction20 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { /* begin checkLiteral:forInstruction: */ ((sqInt)primitiveRoutine); - anInstruction5 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); + anInstruction1 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); /* begin checkLiteral:forInstruction: */ primitiveFunctionPointerAddress(); - anInstruction6 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); + anInstruction2 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); } if (((flags & (PrimCallNeedsNewMethod + PrimCallMayEndureCodeCompaction)) != 0)) { @@ -27371,17 +27439,16 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) /* begin MoveMw:r:R: */ offset = offsetof(CogMethod, methodObject); /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); + anInstruction3 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); /* begin checkLiteral:forInstruction: */ newMethodAddress(); - anInstruction8 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); + anInstruction4 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); } /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction40 = genoperand(PrefetchAw, primFailCodeAddress()); + anInstruction22 = genoperand(PrefetchAw, primFailCodeAddress()); if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - /* Sideways call the C primitive routine so that we return through cePrimReturnEnterCogCode. */ /* On Spur ceActivateFailingPrimitiveMethod: would like to retry if forwarders are found. So insist on PrimCallNeedsPrimitiveFunction being set too. */ assert(((flags & PrimCallNeedsPrimitiveFunction) != 0)); @@ -27389,12 +27456,12 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) /* WIN64 ABI allways reserve shadow space on the stack for callee to save up to 4 register parameters */ /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperand(SubCqR, 32, RSP); - goto l32; + anInstruction7 = genoperandoperand(SubCqR, 32, RSP); + goto l20; assert(0 <= 4); if (null < NoReg) { /* begin MoveCq:R: */ - anInstruction12 = genoperandoperand(MoveCqR, -2 - null, CArg0Reg); + anInstruction11 = genoperandoperand(MoveCqR, -2 - null, CArg0Reg); } else { if (null != CArg0Reg) { @@ -27432,115 +27499,94 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) genoperandoperand(MoveRR, null, CArg3Reg); } } - l32: /* end genMarshallNArgs:arg:arg:arg:arg: */; + l20: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin genSubstituteReturnAddress: */ retpc = (((flags & PrimCallCollectsProfileSamples) != 0) ? cePrimReturnEnterCogCodeProfiling : cePrimReturnEnterCogCode); /* begin checkLiteral:forInstruction: */ - anInstruction13 = genoperand(PushCw, retpc); + anInstruction8 = genoperand(PushCw, retpc); /* begin gen:literal: */ - anInstruction10 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); - jmp = (jmpSamplePrim = (continuePostSamplePrim = null)); + anInstruction6 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); + return 0; } - else { - - /* Call the C primitive routine. */ - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - - /* WIN64 ABI allways reserve shadow space on the stack for callee to save up to 4 register parameters */ - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperand(SubCqR, 32, RSP); - goto l49; - assert(0 <= 4); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg0Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg1Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg2Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg3Reg); - l49: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin gen:literal: */ - anInstruction15 = genoperand(CallFull, ((sqInt)primitiveRoutine)); - /* begin genRemoveNArgsFromStack: */ - assert(0 <= 4); - /* begin checkQuickConstant:forInstruction: */ - anInstruction23 = genoperandoperand(AddCqR, 32, RSP); - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction18 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpSamplePrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSamplePrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - maybeCompileRetryOnPrimitiveFail(primitiveIndex); - /* begin MoveAw:R: */ - address2 = instructionPointerAddress(); - reg = ClassReg; - /* begin checkLiteral:forInstruction: */ - anInstruction24 = genoperandoperand(MoveAwR, address2, reg); - genLoadStackPointers(backEnd); + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + + /* WIN64 ABI allways reserve shadow space on the stack for callee to save up to 4 register parameters */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction23 = genoperandoperand(SubCqR, 32, RSP); + goto l43; + assert(0 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg0Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg1Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg2Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg3Reg); + l43: /* end genMarshallNArgs:arg:arg:arg:arg: */; + /* begin gen:literal: */ + anInstruction10 = genoperand(CallFull, ((sqInt)primitiveRoutine)); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 4); + /* begin checkQuickConstant:forInstruction: */ + anInstruction25 = genoperandoperand(AddCqR, 32, RSP); + maybeCompileRetryOnPrimitiveFail(primitiveIndex); + genLoadStackPointersForPrimCall(backEnd, ClassReg); + /* begin checkLiteral:forInstruction: */ + instructionPointerAddress(); + anInstruction13 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); + /* begin checkQuickConstant:forInstruction: */ + anInstruction14 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + /* begin checkLiteral:forInstruction: */ + primFailCodeAddress(); + anInstruction26 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + flag("ask concrete code gen if move sets condition codes?"); + /* begin checkQuickConstant:forInstruction: */ + anInstruction27 = genoperandoperand(CmpCqR, 0, TempReg); + /* begin JumpNonZero: */ + jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + /* begin preferredRegisterForMovePerfCnt64RL */ + reg = RAX; + gMovePerfCnt64RL(reg, liveRegisters); /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction25 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - /* begin PushR: */ - genoperand(PushR, ClassReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction26 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset1 = BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction27 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, BytesPerWord); + nextProfileTickAddress(); + anInstruction30 = genoperandoperand(MoveAwR, nextProfileTickAddress(), Arg1Reg); + /* begin CmpR:R: */ + assert(!((reg == SPReg))); + genoperandoperand(CmpRR, reg, Arg1Reg); + /* begin JumpGreaterOrEqual: */ + jumpToTakeSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l57; + l57: /* end genCheckForProfileTimerTick: */; } + /* begin MoveMw:r:R: */ + offset1 = BytesPerWord; + /* begin checkQuickConstant:forInstruction: */ + anInstruction28 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); + continueAfterProfileSample = anInstruction28; + /* begin RetN: */ + genoperand(RetN, BytesPerWord); if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* The sample is collected by cePrimReturnEnterCogCode for external calls */ - if (!(jmpSamplePrim == null)) { - - /* Call ceCheckProfileTick: to record sample and then continue. */ - jmpTarget(jmpSamplePrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin gen:literal: */ - operand1 = ((usqIntptr_t)ceCheckProfileTick); - /* begin checkLiteral:forInstruction: */ - anInstruction29 = genoperand(CallFull, operand1); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSamplePrim)); - } - jmpTarget(jmpSampleNonPrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction34 = genoperandoperand(MoveCqR, 0, TempReg); + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); /* begin checkLiteral:forInstruction: */ - newMethodAddress(); - anInstruction35 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); - /* begin gen:literal: */ - operand3 = ((usqIntptr_t)ceCheckProfileTick); - /* begin checkLiteral:forInstruction: */ - anInstruction33 = genoperand(CallFull, operand3); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSampleNonPrim)); - } - if (!(jmp == null)) { - - /* Jump to restore of receiver reg and proceed to frame build for failure. */ - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin MoveMw:r:R: */ - offset2 = BytesPerWord * (methodOrBlockNumArgs + (1)); + instructionPointerAddress(); + anInstruction16 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction36 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); + anInstruction17 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + /* begin Jump: */ + genoperand(Jump, ((sqInt)continueAfterProfileSample)); } + jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + /* begin MoveMw:r:R: */ + offset2 = BytesPerWord * (methodOrBlockNumArgs + (1)); + /* begin checkQuickConstant:forInstruction: */ + anInstruction29 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); return 0; } @@ -27572,7 +27618,7 @@ compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)) if ((methodOrBlockNumArgs > 2 /* numRegArgs */) || (methodOrBlockNumArgs == 0)) { /* begin registerMaskFor: */ - liveRegsMask = 1U << ReceiverResultReg; + liveRegsMask = (1U << ReceiverResultReg); } else { if (methodOrBlockNumArgs > 1) { @@ -27665,50 +27711,59 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags AbstractInstruction *anInstruction12; AbstractInstruction *anInstruction13; AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; AbstractInstruction *anInstruction16; AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction18; AbstractInstruction *anInstruction19; AbstractInstruction *anInstruction2; AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; AbstractInstruction *anInstruction22; AbstractInstruction *anInstruction23; + AbstractInstruction *anInstruction24; + AbstractInstruction *anInstruction26; + AbstractInstruction *anInstruction27; + AbstractInstruction *anInstruction28; + AbstractInstruction *anInstruction29; + AbstractInstruction *anInstruction30; AbstractInstruction *anInstruction4; AbstractInstruction *anInstruction5; AbstractInstruction *anInstruction6; AbstractInstruction *anInstruction8; AbstractInstruction *anInstruction9; sqInt calleeSavedRegisterMask; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; + AbstractInstruction * jumpToTakeSample; + sqInt liveRegisters; sqInt offset; sqInt offset1; sqInt operand1; + sqInt reg; sqInt retpcOffset; AbstractInstruction * retry; AbstractInstruction * skip; sqInt spRegSaveRegister; + jumpToTakeSample = ((AbstractInstruction *) 0); assert(((flags & PrimCallOnSmalltalkStack) != 0)); assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); if (recordFastCCallPrimTraceForMethod(methodObj)) { genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction18 = genoperandoperand(MoveCqR, 0, TempReg); + anInstruction20 = genoperandoperand(MoveCqR, 0, TempReg); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction19 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); + anInstruction22 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); } /* begin checkLiteral:forInstruction: */ argumentCountAddress(); - anInstruction20 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); + anInstruction23 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); genExternalizeStackPointerForFastPrimitiveCall(); - calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | (1U << ClassReg)) - (1U << ClassReg)); + calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | ((1U << ClassReg))) - ((1U << ClassReg))); spRegSaveRegister = NoReg; /* begin Label */ retry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); @@ -27717,22 +27772,60 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags } else { } + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + + /* WIN64 ABI allways reserve shadow space on the stack for callee to save up to 4 register parameters */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction24 = genoperandoperand(SubCqR, 32, RSP); + goto l53; + assert(0 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg0Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg1Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg2Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg3Reg); + l53: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin gen:literal: */ - anInstruction2 = genoperand(CallFull, primitiveRoutine); + anInstruction2 = genoperand(CallFull, ((sqInt)primitiveRoutine)); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 4); + /* begin checkQuickConstant:forInstruction: */ + anInstruction26 = genoperandoperand(AddCqR, 32, RSP); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction21 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + anInstruction27 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); if (spRegSaveRegister != NoReg) { /* begin MoveR:R: */ genoperandoperand(MoveRR, spRegSaveRegister, SPReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperand(CmpCqR, 0, TempReg); + anInstruction28 = genoperandoperand(CmpCqR, 0, TempReg); /* begin JumpNonZero: */ jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + /* begin preferredRegisterForMovePerfCnt64RL */ + reg = RAX; + gMovePerfCnt64RL(reg, liveRegisters); + /* begin checkLiteral:forInstruction: */ + nextProfileTickAddress(); + anInstruction30 = genoperandoperand(MoveAwR, nextProfileTickAddress(), Arg1Reg); + /* begin CmpR:R: */ + assert(!((reg == SPReg))); + genoperandoperand(CmpRR, reg, Arg1Reg); + /* begin JumpGreaterOrEqual: */ + jumpToTakeSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l66; + l66: /* end genCheckForProfileTimerTick: */; + } /* begin checkLiteral:forInstruction: */ stackPointerAddress(); - anInstruction23 = genoperandoperand(MoveAwR, stackPointerAddress(), TempReg); + anInstruction29 = genoperandoperand(MoveAwR, stackPointerAddress(), TempReg); + continueAfterProfileSample = anInstruction29; /* The original retpc is (argumentCount + 1) words below stackPointer. */ retpcOffset = -((methodOrBlockNumArgs + 1) * BytesPerWord); @@ -27746,6 +27839,12 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags anInstruction6 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, TempReg); /* begin RetN: */ genoperand(RetN, 0); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); + /* begin Jump: */ + genoperand(Jump, ((sqInt)continueAfterProfileSample)); + } jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); if ((accessorDepthForExternalPrimitiveMethod(methodObj)) >= 0) { @@ -27776,20 +27875,36 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags else { genLoadCStackPointer(backEnd); } + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + + /* WIN64 ABI allways reserve shadow space on the stack for callee to save up to 4 register parameters */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction14 = genoperandoperand(SubCqR, 32, RSP); + goto l36; + assert(0 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg0Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg1Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg2Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg3Reg); + l36: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin gen:literal: */ operand1 = ((usqIntptr_t)checkForAndFollowForwardedPrimitiveState); /* begin checkLiteral:forInstruction: */ anInstruction8 = genoperand(CallFull, operand1); - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(CmpCqR, 0, ABIResultReg); + anInstruction16 = genoperandoperand(CmpCqR, 0, ABIResultReg); /* begin JumpZero: */ skip = genConditionalBranchoperand(JumpZero, ((sqInt)0)); /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperand(MoveCqR, 0, TempReg); + anInstruction17 = genoperandoperand(MoveCqR, 0, TempReg); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction16 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); + anInstruction18 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); /* begin Jump: */ genoperand(Jump, ((sqInt)retry)); jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); @@ -27798,14 +27913,14 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags /* must reload SPReg to undo any alignment change, */ if (((flags & PrimCallOnSmalltalkStackAlign2x) != 0)) { - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); } } - if (((ABICallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((ABICallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* begin MoveMw:r:R: */ offset1 = (methodOrBlockNumArgs + (1)) * BytesPerWord; /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); + anInstruction19 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); } return 0; } @@ -28827,23 +28942,24 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) { sqInt address1; AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction10; + AbstractInstruction *anInstruction11; AbstractInstruction *anInstruction12; AbstractInstruction *anInstruction13; AbstractInstruction *anInstruction14; AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction18; + AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; + AbstractInstruction *anInstruction7; AbstractInstruction *anInstruction8; AbstractInstruction *anInstruction9; sqInt callTarget; AbstractInstruction *continuePostSample; AbstractInstruction *jmpFail; AbstractInstruction *jmpSample; + sqInt liveRegisters; sqInt quickConstant; sqInt reg; + sqInt reg1; continuePostSample = ((AbstractInstruction *) 0); jmpSample = ((AbstractInstruction *) 0); @@ -28852,56 +28968,63 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) quickConstant = varBaseAddress(); /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - if (profiling) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick: if so. - N.B. nextProfileTick is 64-bits so 32-bit systems need to test both halves. */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction3 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpSample = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction13 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + anInstruction12 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); flag("ask concrete code gen if move sets condition codes?"); /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(CmpCqR, 0, TempReg); + anInstruction13 = genoperandoperand(CmpCqR, 0, TempReg); /* begin JumpNonZero: */ jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (profiling + && (1)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + /* begin preferredRegisterForMovePerfCnt64RL */ + reg = RAX; + gMovePerfCnt64RL(reg, liveRegisters); + /* begin checkLiteral:forInstruction: */ + nextProfileTickAddress(); + anInstruction3 = genoperandoperand(MoveAwR, nextProfileTickAddress(), Arg1Reg); + /* begin CmpR:R: */ + assert(!((reg == SPReg))); + genoperandoperand(CmpRR, reg, Arg1Reg); + /* begin JumpGreaterOrEqual: */ + jmpSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l18; + l18: /* end genCheckForProfileTimerTick: */; + /* begin Label */ + continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); + } /* begin checkLiteral:forInstruction: */ instructionPointerAddress(); - anInstruction8 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); + anInstruction7 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); + anInstruction8 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + anInstruction9 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jmpFail, checkLiteralforInstruction(newMethodAddress(), genoperandoperand(MoveAwR, newMethodAddress(), SendNumArgsReg))); /* begin checkLiteral:forInstruction: */ cStackPointerAddress(); - anInstruction15 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); + anInstruction14 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); compileCallFornumArgsargargargargresultRegregsToSave(ceActivateFailingPrimitiveMethod, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); /* begin MoveAw:R: */ address1 = instructionPointerAddress(); - reg = ClassReg; + reg1 = ClassReg; /* begin checkLiteral:forInstruction: */ - anInstruction16 = genoperandoperand(MoveAwR, address1, reg); + anInstruction15 = genoperandoperand(MoveAwR, address1, reg1); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveMwrR, BytesPerWord, SPReg, ReceiverResultReg); + anInstruction11 = genoperandoperandoperand(MoveMwrR, BytesPerWord, SPReg, ReceiverResultReg); /* begin PushR: */ genoperand(PushR, ClassReg); /* begin RetN: */ genoperand(RetN, BytesPerWord); - if (profiling) { + if (profiling + && (1)) { /* Call ceCheckProfileTick: to record sample and then continue. newMethod should be up-to-date. Need to save and restore the link reg around this call. */ @@ -28910,7 +29033,7 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) /* begin CallFullRT: */ callTarget = (usqIntptr_t)ceCheckProfileTick; /* begin checkLiteral:forInstruction: */ - anInstruction18 = genoperand(CallFull, callTarget); + anInstruction17 = genoperand(CallFull, callTarget); /* begin Jump: */ genoperand(Jump, ((sqInt)continuePostSample)); } @@ -29265,6 +29388,69 @@ genStoreRemoteTempLongBytecode(void) && (shouldAnnotateObjectReference(((ssTop())->constant))))); } + /* SimpleStackBasedCogit>>#genTakeProfileSample */ +static void +genTakeProfileSample(void) +{ + AbstractInstruction *anInstruction1; + AbstractInstruction *anInstruction2; + AbstractInstruction *anInstruction3; + AbstractInstruction *anInstruction4; + AbstractInstruction *anInstruction5; + AbstractInstruction *anInstruction6; + sqInt operand1; + + addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + + /* WIN64 ABI allways reserve shadow space on the stack for callee to save up to 4 register parameters */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction5 = genoperandoperand(SubCqR, 32, RSP); + assert(1 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, ClassReg, CArg0Reg); + goto l12; + if (null < NoReg) { + /* begin MoveCq:R: */ + anInstruction2 = genoperandoperand(MoveCqR, -2 - null, CArg1Reg); + } + else { + if (null != CArg1Reg) { + /* begin MoveR:R: */ + genoperandoperand(MoveRR, null, CArg1Reg); + } + } + if (null < NoReg) { + /* begin MoveCq:R: */ + anInstruction3 = genoperandoperand(MoveCqR, -2 - null, CArg2Reg); + } + else { + if (null != CArg2Reg) { + /* begin MoveR:R: */ + genoperandoperand(MoveRR, null, CArg2Reg); + } + } + if (null < NoReg) { + /* begin MoveCq:R: */ + anInstruction4 = genoperandoperand(MoveCqR, -2 - null, CArg3Reg); + } + else { + if (null != CArg3Reg) { + /* begin MoveR:R: */ + genoperandoperand(MoveRR, null, CArg3Reg); + } + } + l12: /* end genMarshallNArgs:arg:arg:arg:arg: */; + /* begin gen:literal: */ + operand1 = ((usqIntptr_t)ceTakeProfileSample); + /* begin checkLiteral:forInstruction: */ + anInstruction1 = genoperand(CallFull, operand1); + /* begin genRemoveNArgsFromStack: */ + assert(1 <= 4); + /* begin checkQuickConstant:forInstruction: */ + anInstruction6 = genoperandoperand(AddCqR, 32, RSP); + } + /* SistaV1: * 217 Trap */ @@ -29653,7 +29839,7 @@ primitiveGeneratorOrNil(void) static sqInt NoDbgRegParms registerisInMask(sqInt reg, sqInt mask) { - return ((mask & (1ULL << reg)) != 0); + return ((mask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0); } /* SimpleStackBasedCogit>>#v3:Block:Code:Size: */ @@ -30033,7 +30219,7 @@ anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n) sqInt regMask; /* begin registerMaskFor: */ - regMask = 1ULL << reg; + regMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { if ((((registerMask(simStackAt(i))) & regMask) != 0)) { return 1; @@ -31135,7 +31321,7 @@ ensureReceiverResultRegContainsSelf(void) if (needsFrame) { if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin putSelfInReceiverResultReg */ storeToReg(simSelf(), ReceiverResultReg); ((simSelf())->liveRegister = ReceiverResultReg); @@ -31269,7 +31455,7 @@ freeAnyFloatRegNotConflictingWith(sqInt regMask) desc = simNativeStackAt(index); if ((((desc->type)) == SSRegisterSingleFloat) || (((desc->type)) == SSRegisterDoubleFloat)) { - if (!(((regMask & (1ULL << ((desc->registerr)))) != 0))) { + if (!(((regMask & (((((desc->registerr)) < 0) ? (((usqInt)(1)) >> (-((desc->registerr)))) : (1ULL << ((desc->registerr)))))) != 0))) { reg = (desc->registerr); } } @@ -31299,7 +31485,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) && (index < simStackPtr)) { desc = simStackAt(index); if (((desc->type)) == SSRegister) { - if (!(((regMask & (1ULL << ((desc->registerr)))) != 0))) { + if (!(((regMask & (((((desc->registerr)) < 0) ? (((usqInt)(1)) >> (-((desc->registerr)))) : (1ULL << ((desc->registerr)))))) != 0))) { reg = (desc->registerr); } } @@ -31307,7 +31493,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) } assert(!((reg == NoReg))); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1ULL << reg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)), simStackPtr, simNativeStackPtr); return reg; } @@ -31867,13 +32053,13 @@ genForwardersInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -32495,7 +32681,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop19 == NoReg) { rOopTop19 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult10 = allocateRegNotConflictingWith(1ULL << rOopTop19); + rResult10 = allocateRegNotConflictingWith(((rOopTop19 < 0) ? (((usqInt)(1)) >> (-rOopTop19)) : (1ULL << rOopTop19))); assert(!(((rOopTop19 == NoReg) || (rResult10 == NoReg)))); object17 = rOopTop19; @@ -32591,7 +32777,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop2 == NoReg) { rOopTop2 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult = allocateRegNotConflictingWith(1ULL << rOopTop2); + rResult = allocateRegNotConflictingWith(((rOopTop2 < 0) ? (((usqInt)(1)) >> (-rOopTop2)) : (1ULL << rOopTop2))); assert(!(((rOopTop2 == NoReg) || (rResult == NoReg)))); object2 = rOopTop2; @@ -32622,7 +32808,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop3 == NoReg) { rOopTop3 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult1 = allocateRegNotConflictingWith(1ULL << rOopTop3); + rResult1 = allocateRegNotConflictingWith(((rOopTop3 < 0) ? (((usqInt)(1)) >> (-rOopTop3)) : (1ULL << rOopTop3))); assert(!(((rOopTop3 == NoReg) || (rResult1 == NoReg)))); object3 = rOopTop3; @@ -32653,7 +32839,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop4 == NoReg) { rOopTop4 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult2 = allocateRegNotConflictingWith(1ULL << rOopTop4); + rResult2 = allocateRegNotConflictingWith(((rOopTop4 < 0) ? (((usqInt)(1)) >> (-rOopTop4)) : (1ULL << rOopTop4))); assert(!(((rOopTop4 == NoReg) || (rResult2 == NoReg)))); object4 = rOopTop4; @@ -32684,7 +32870,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop5 == NoReg) { rOopTop5 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult3 = allocateRegNotConflictingWith(1ULL << rOopTop5); + rResult3 = allocateRegNotConflictingWith(((rOopTop5 < 0) ? (((usqInt)(1)) >> (-rOopTop5)) : (1ULL << rOopTop5))); assert(!(((rOopTop5 == NoReg) || (rResult3 == NoReg)))); object5 = rOopTop5; @@ -32715,7 +32901,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop6 == NoReg) { rOopTop6 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult4 = allocateRegNotConflictingWith(1ULL << rOopTop6); + rResult4 = allocateRegNotConflictingWith(((rOopTop6 < 0) ? (((usqInt)(1)) >> (-rOopTop6)) : (1ULL << rOopTop6))); assert(!(((rOopTop6 == NoReg) || (rResult4 == NoReg)))); object6 = rOopTop6; @@ -32746,7 +32932,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop7 == NoReg) { rOopTop7 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult5 = allocateRegNotConflictingWith(1ULL << rOopTop7); + rResult5 = allocateRegNotConflictingWith(((rOopTop7 < 0) ? (((usqInt)(1)) >> (-rOopTop7)) : (1ULL << rOopTop7))); assert(!(((rOopTop7 == NoReg) || (rResult5 == NoReg)))); object7 = rOopTop7; @@ -32777,7 +32963,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop8 == NoReg) { rOopTop8 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult6 = allocateRegNotConflictingWith(1ULL << rOopTop8); + rResult6 = allocateRegNotConflictingWith(((rOopTop8 < 0) ? (((usqInt)(1)) >> (-rOopTop8)) : (1ULL << rOopTop8))); assert(!(((rOopTop8 == NoReg) || (rResult6 == NoReg)))); object8 = rOopTop8; @@ -32837,7 +33023,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop11 == NoReg) { rOopTop11 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult11 = allocateRegNotConflictingWith(1ULL << rOopTop11); + rResult11 = allocateRegNotConflictingWith(((rOopTop11 < 0) ? (((usqInt)(1)) >> (-rOopTop11)) : (1ULL << rOopTop11))); assert(!(((rOopTop11 == NoReg) || (rResult11 == NoReg)))); object10 = rOopTop11; @@ -32898,7 +33084,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop14 == NoReg) { rOopTop14 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult12 = allocateRegNotConflictingWith(1ULL << rOopTop14); + rResult12 = allocateRegNotConflictingWith(((rOopTop14 < 0) ? (((usqInt)(1)) >> (-rOopTop14)) : (1ULL << rOopTop14))); assert(!(((rOopTop14 == NoReg) || (rResult12 == NoReg)))); object12 = rOopTop14; @@ -33053,7 +33239,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop110 == NoReg) { rOopTop110 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult13 = allocateRegNotConflictingWith(1ULL << rOopTop110); + rResult13 = allocateRegNotConflictingWith(((rOopTop110 < 0) ? (((usqInt)(1)) >> (-rOopTop110)) : (1ULL << rOopTop110))); assert(!(((rOopTop110 == NoReg) || (rResult13 == NoReg)))); object21 = rOopTop110; @@ -33122,7 +33308,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop16 == NoReg) { rOopTop16 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult9 = allocateRegNotConflictingWith(1ULL << rOopTop16); + rResult9 = allocateRegNotConflictingWith(((rOopTop16 < 0) ? (((usqInt)(1)) >> (-rOopTop16)) : (1ULL << rOopTop16))); assert(!(((rOopTop16 == NoReg) || (rResult9 == NoReg)))); object14 = rOopTop16; @@ -33153,7 +33339,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop24 == NoReg) { rOopTop24 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult15 = allocateRegNotConflictingWith(1ULL << rOopTop24); + rResult15 = allocateRegNotConflictingWith(((rOopTop24 < 0) ? (((usqInt)(1)) >> (-rOopTop24)) : (1ULL << rOopTop24))); assert(!(((rOopTop24 == NoReg) || (rResult15 == NoReg)))); object22 = rOopTop24; @@ -33196,7 +33382,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop111 == NoReg) { rOopTop111 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult16 = allocateRegNotConflictingWith(1ULL << rOopTop111); + rResult16 = allocateRegNotConflictingWith(((rOopTop111 < 0) ? (((usqInt)(1)) >> (-rOopTop111)) : (1ULL << rOopTop111))); assert(!(((rOopTop111 == NoReg) || (rResult16 == NoReg)))); object23 = rOopTop111; @@ -33347,7 +33533,7 @@ genLowcodeNullaryInlinePrimitive(sqInt prim) if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult = allocateRegNotConflictingWith(1ULL << rTop); + rResult = allocateRegNotConflictingWith(((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1ULL << rTop))); assert(!(((rTop == NoReg) || (rResult == NoReg)))); value = rTop; @@ -33382,7 +33568,7 @@ genLowcodeNullaryInlinePrimitive(sqInt prim) if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult1 = allocateRegNotConflictingWith(1ULL << rTop1); + rResult1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); assert(!(((rTop1 == NoReg) || (rResult1 == NoReg)))); value1 = rTop1; @@ -33628,7 +33814,7 @@ genLowcodeNullaryInlinePrimitive(sqInt prim) if (rTop12 == NoReg) { rTop12 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult11 = allocateRegNotConflictingWith(1ULL << rTop12); + rResult11 = allocateRegNotConflictingWith(((rTop12 < 0) ? (((usqInt)(1)) >> (-rTop12)) : (1ULL << rTop12))); assert(!(((rTop12 == NoReg) || (rResult11 == NoReg)))); value6 = rTop12; @@ -33739,14 +33925,14 @@ genLowcodeTrinaryInlinePrimitive(sqInt prim) l4: ; if (rOopNext != NoReg) { /* begin registerMaskFor: */ - oopTopRegisterMask = 1ULL << rOopNext; + oopTopRegisterMask = ((rOopNext < 0) ? (((usqInt)(1)) >> (-rOopNext)) : (1ULL << rOopNext)); } } if (rOopTop == NoReg) { rOopTop = allocateRegNotConflictingWith(oopTopRegisterMask); } if (rOopNext == NoReg) { - rOopNext = allocateRegNotConflictingWith(1ULL << rOopTop); + rOopNext = allocateRegNotConflictingWith(((rOopTop < 0) ? (((usqInt)(1)) >> (-rOopTop)) : (1ULL << rOopTop))); } rResult = allocateRegNotConflictingWith((1ULL << rOopTop) | (1ULL << rOopNext)); assert(!(((rOopTop == NoReg) @@ -33808,14 +33994,14 @@ genLowcodeTrinaryInlinePrimitive(sqInt prim) l18: ; if (rOopNext1 != NoReg) { /* begin registerMaskFor: */ - oopTopRegisterMask1 = 1ULL << rOopNext1; + oopTopRegisterMask1 = ((rOopNext1 < 0) ? (((usqInt)(1)) >> (-rOopNext1)) : (1ULL << rOopNext1)); } } if (rOopTop1 == NoReg) { rOopTop1 = allocateRegNotConflictingWith(oopTopRegisterMask1); } if (rOopNext1 == NoReg) { - rOopNext1 = allocateRegNotConflictingWith(1ULL << rOopTop1); + rOopNext1 = allocateRegNotConflictingWith(((rOopTop1 < 0) ? (((usqInt)(1)) >> (-rOopTop1)) : (1ULL << rOopTop1))); } assert(!(((rOopTop1 == NoReg) || (rOopNext1 == NoReg)))); @@ -33876,14 +34062,14 @@ genLowcodeTrinaryInlinePrimitive(sqInt prim) l23: ; if (rOopNext2 != NoReg) { /* begin registerMaskFor: */ - oopTopRegisterMask2 = 1ULL << rOopNext2; + oopTopRegisterMask2 = ((rOopNext2 < 0) ? (((usqInt)(1)) >> (-rOopNext2)) : (1ULL << rOopNext2)); } } if (rOopTop2 == NoReg) { rOopTop2 = allocateRegNotConflictingWith(oopTopRegisterMask2); } if (rOopNext2 == NoReg) { - rOopNext2 = allocateRegNotConflictingWith(1ULL << rOopTop2); + rOopNext2 = allocateRegNotConflictingWith(((rOopTop2 < 0) ? (((usqInt)(1)) >> (-rOopTop2)) : (1ULL << rOopTop2))); } assert(!(((rOopTop2 == NoReg) || (rOopNext2 == NoReg)))); @@ -33904,17 +34090,17 @@ genLowcodeTrinaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { rTop = nativeRegisterOrNone(ssNativeTop()); /* begin registerMaskFor: */ - oopTopRegisterMask3 = 1ULL << rTop; + oopTopRegisterMask3 = ((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1ULL << rTop)); } if ((registerOrNone(ssTop())) != NoReg) { rOopTop3 = registerOrNone(ssTop()); /* begin registerMaskFor: */ - topRegisterMask = 1ULL << rOopTop3; + topRegisterMask = ((rOopTop3 < 0) ? (((usqInt)(1)) >> (-rOopTop3)) : (1ULL << rOopTop3)); } if ((registerOrNone(ssValue(1))) != NoReg) { rOopNext3 = registerOrNone(ssValue(1)); - topRegisterMask = topRegisterMask | (1ULL << rOopNext3); - oopTopRegisterMask3 = oopTopRegisterMask3 | (1ULL << rOopNext3); + topRegisterMask = topRegisterMask | (((rOopNext3 < 0) ? (((usqInt)(1)) >> (-rOopNext3)) : (1ULL << rOopNext3))); + oopTopRegisterMask3 = oopTopRegisterMask3 | (((rOopNext3 < 0) ? (((usqInt)(1)) >> (-rOopNext3)) : (1ULL << rOopNext3))); } if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(topRegisterMask); @@ -34430,13 +34616,13 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((registerOrNone(ssTop())) != NoReg) { rOopTop1 = registerOrNone(ssTop()); /* begin registerMaskFor: */ - topRegisterMask1 = 1ULL << rOopTop1; + topRegisterMask1 = ((rOopTop1 < 0) ? (((usqInt)(1)) >> (-rOopTop1)) : (1ULL << rOopTop1)); } if (rTop31 == NoReg) { rTop31 = allocateRegNotConflictingWith(topRegisterMask1); } if (rOopTop1 == NoReg) { - rOopTop1 = allocateRegNotConflictingWith(1ULL << rTop31); + rOopTop1 = allocateRegNotConflictingWith(((rTop31 < 0) ? (((usqInt)(1)) >> (-rTop31)) : (1ULL << rTop31))); } rOopResult = allocateRegNotConflictingWith((1ULL << rTop31) | (1ULL << rOopTop1)); assert(!(((rTop31 == NoReg) @@ -34486,7 +34672,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if (rOopTop2 == NoReg) { rOopTop2 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult35 = allocateRegNotConflictingWith(1ULL << rOopTop2); + rResult35 = allocateRegNotConflictingWith(((rOopTop2 < 0) ? (((usqInt)(1)) >> (-rOopTop2)) : (1ULL << rOopTop2))); assert(!(((rOopTop2 == NoReg) || (rResult35 == NoReg)))); classOop1 = rOopTop2; @@ -34560,14 +34746,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask1 = 1ULL << reg; + topRegistersMask1 = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } } if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(topRegistersMask1); } if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1ULL << rTop); + rNext = allocateRegNotConflictingWith(((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1ULL << rTop))); } assert(!(((rTop == NoReg) || (rNext == NoReg)))); @@ -34607,14 +34793,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg1 = (rNext1 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask2 = 1ULL << reg1; + topRegistersMask2 = ((reg1 < 0) ? (((usqInt)(1)) >> (-reg1)) : (1ULL << reg1)); } } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask2); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -34654,14 +34840,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg2 = (rNext2 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask3 = 1ULL << reg2; + topRegistersMask3 = ((reg2 < 0) ? (((usqInt)(1)) >> (-reg2)) : (1ULL << reg2)); } } if (rTop2 == NoReg) { rTop2 = allocateRegNotConflictingWith(topRegistersMask3); } if (rNext2 == NoReg) { - rNext2 = allocateRegNotConflictingWith(1ULL << rTop2); + rNext2 = allocateRegNotConflictingWith(((rTop2 < 0) ? (((usqInt)(1)) >> (-rTop2)) : (1ULL << rTop2))); } assert(!(((rTop2 == NoReg) || (rNext2 == NoReg)))); @@ -34701,14 +34887,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg3 = (rNext3 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask4 = 1ULL << reg3; + topRegistersMask4 = ((reg3 < 0) ? (((usqInt)(1)) >> (-reg3)) : (1ULL << reg3)); } } if (rTop3 == NoReg) { rTop3 = allocateRegNotConflictingWith(topRegistersMask4); } if (rNext3 == NoReg) { - rNext3 = allocateRegNotConflictingWith(1ULL << rTop3); + rNext3 = allocateRegNotConflictingWith(((rTop3 < 0) ? (((usqInt)(1)) >> (-rTop3)) : (1ULL << rTop3))); } assert(!(((rTop3 == NoReg) || (rNext3 == NoReg)))); @@ -34748,14 +34934,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg4 = (rNext4 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask5 = 1ULL << reg4; + topRegistersMask5 = ((reg4 < 0) ? (((usqInt)(1)) >> (-reg4)) : (1ULL << reg4)); } } if (rTop4 == NoReg) { rTop4 = allocateRegNotConflictingWith(topRegistersMask5); } if (rNext4 == NoReg) { - rNext4 = allocateRegNotConflictingWith(1ULL << rTop4); + rNext4 = allocateRegNotConflictingWith(((rTop4 < 0) ? (((usqInt)(1)) >> (-rTop4)) : (1ULL << rTop4))); } assert(!(((rTop4 == NoReg) || (rNext4 == NoReg)))); @@ -34795,14 +34981,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg5 = (rNext5 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask6 = 1ULL << reg5; + topRegistersMask6 = ((reg5 < 0) ? (((usqInt)(1)) >> (-reg5)) : (1ULL << reg5)); } } if (rTop5 == NoReg) { rTop5 = allocateRegNotConflictingWith(topRegistersMask6); } if (rNext5 == NoReg) { - rNext5 = allocateRegNotConflictingWith(1ULL << rTop5); + rNext5 = allocateRegNotConflictingWith(((rTop5 < 0) ? (((usqInt)(1)) >> (-rTop5)) : (1ULL << rTop5))); } assert(!(((rTop5 == NoReg) || (rNext5 == NoReg)))); @@ -34903,14 +35089,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg6 = (rNext11 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask7 = 1ULL << reg6; + topRegistersMask7 = ((reg6 < 0) ? (((usqInt)(1)) >> (-reg6)) : (1ULL << reg6)); } } if (rTop11 == NoReg) { rTop11 = allocateRegNotConflictingWith(topRegistersMask7); } if (rNext11 == NoReg) { - rNext11 = allocateRegNotConflictingWith(1ULL << rTop11); + rNext11 = allocateRegNotConflictingWith(((rTop11 < 0) ? (((usqInt)(1)) >> (-rTop11)) : (1ULL << rTop11))); } assert(!(((rTop11 == NoReg) || (rNext11 == NoReg)))); @@ -34951,14 +35137,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg7 = (rNext7 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask8 = 1ULL << reg7; + topRegistersMask8 = ((reg7 < 0) ? (((usqInt)(1)) >> (-reg7)) : (1ULL << reg7)); } } if (rTop10 == NoReg) { rTop10 = allocateRegNotConflictingWith(topRegistersMask8); } if (rNext7 == NoReg) { - rNext7 = allocateRegNotConflictingWith(1ULL << rTop10); + rNext7 = allocateRegNotConflictingWith(((rTop10 < 0) ? (((usqInt)(1)) >> (-rTop10)) : (1ULL << rTop10))); } assert(!(((rTop10 == NoReg) || (rNext7 == NoReg)))); @@ -34989,14 +35175,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg8 = (rNext8 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask9 = 1ULL << reg8; + topRegistersMask9 = ((reg8 < 0) ? (((usqInt)(1)) >> (-reg8)) : (1ULL << reg8)); } } if (rTop12 == NoReg) { rTop12 = allocateRegNotConflictingWith(topRegistersMask9); } if (rNext8 == NoReg) { - rNext8 = allocateRegNotConflictingWith(1ULL << rTop12); + rNext8 = allocateRegNotConflictingWith(((rTop12 < 0) ? (((usqInt)(1)) >> (-rTop12)) : (1ULL << rTop12))); } assert(!(((rTop12 == NoReg) || (rNext8 == NoReg)))); @@ -35027,14 +35213,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg9 = (rNext9 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask10 = 1ULL << reg9; + topRegistersMask10 = ((reg9 < 0) ? (((usqInt)(1)) >> (-reg9)) : (1ULL << reg9)); } } if (rTop13 == NoReg) { rTop13 = allocateRegNotConflictingWith(topRegistersMask10); } if (rNext9 == NoReg) { - rNext9 = allocateRegNotConflictingWith(1ULL << rTop13); + rNext9 = allocateRegNotConflictingWith(((rTop13 < 0) ? (((usqInt)(1)) >> (-rTop13)) : (1ULL << rTop13))); } assert(!(((rTop13 == NoReg) || (rNext9 == NoReg)))); @@ -35065,14 +35251,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg10 = (rNext10 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask11 = 1ULL << reg10; + topRegistersMask11 = ((reg10 < 0) ? (((usqInt)(1)) >> (-reg10)) : (1ULL << reg10)); } } if (rTop14 == NoReg) { rTop14 = allocateRegNotConflictingWith(topRegistersMask11); } if (rNext10 == NoReg) { - rNext10 = allocateRegNotConflictingWith(1ULL << rTop14); + rNext10 = allocateRegNotConflictingWith(((rTop14 < 0) ? (((usqInt)(1)) >> (-rTop14)) : (1ULL << rTop14))); } assert(!(((rTop14 == NoReg) || (rNext10 == NoReg)))); @@ -35103,14 +35289,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg11 = (rNext13 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask12 = 1ULL << reg11; + topRegistersMask12 = ((reg11 < 0) ? (((usqInt)(1)) >> (-reg11)) : (1ULL << reg11)); } } if (rTop16 == NoReg) { rTop16 = allocateRegNotConflictingWith(topRegistersMask12); } if (rNext13 == NoReg) { - rNext13 = allocateRegNotConflictingWith(1ULL << rTop16); + rNext13 = allocateRegNotConflictingWith(((rTop16 < 0) ? (((usqInt)(1)) >> (-rTop16)) : (1ULL << rTop16))); } assert(!(((rTop16 == NoReg) || (rNext13 == NoReg)))); @@ -35207,14 +35393,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg13 = (rNext15 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask14 = 1ULL << reg13; + topRegistersMask14 = ((reg13 < 0) ? (((usqInt)(1)) >> (-reg13)) : (1ULL << reg13)); } } if (rTop21 == NoReg) { rTop21 = allocateRegNotConflictingWith(topRegistersMask14); } if (rNext15 == NoReg) { - rNext15 = allocateRegNotConflictingWith(1ULL << rTop21); + rNext15 = allocateRegNotConflictingWith(((rTop21 < 0) ? (((usqInt)(1)) >> (-rTop21)) : (1ULL << rTop21))); } assert(!(((rTop21 == NoReg) || (rNext15 == NoReg)))); @@ -35244,14 +35430,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg14 = (rNext16 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask15 = 1ULL << reg14; + topRegistersMask15 = ((reg14 < 0) ? (((usqInt)(1)) >> (-reg14)) : (1ULL << reg14)); } } if (rTop22 == NoReg) { rTop22 = allocateRegNotConflictingWith(topRegistersMask15); } if (rNext16 == NoReg) { - rNext16 = allocateRegNotConflictingWith(1ULL << rTop22); + rNext16 = allocateRegNotConflictingWith(((rTop22 < 0) ? (((usqInt)(1)) >> (-rTop22)) : (1ULL << rTop22))); } assert(!(((rTop22 == NoReg) || (rNext16 == NoReg)))); @@ -35509,7 +35695,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if (rTop25 == NoReg) { rTop25 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult29 = allocateRegNotConflictingWith(1ULL << rTop25); + rResult29 = allocateRegNotConflictingWith(((rTop25 < 0) ? (((usqInt)(1)) >> (-rTop25)) : (1ULL << rTop25))); assert(!(((rTop25 == NoReg) || (rResult29 == NoReg)))); pointer4 = rTop25; @@ -35535,7 +35721,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if (rTop26 == NoReg) { rTop26 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult30 = allocateRegNotConflictingWith(1ULL << rTop26); + rResult30 = allocateRegNotConflictingWith(((rTop26 < 0) ? (((usqInt)(1)) >> (-rTop26)) : (1ULL << rTop26))); assert(!(((rTop26 == NoReg) || (rResult30 == NoReg)))); pointer5 = rTop26; @@ -35558,7 +35744,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if (rTop110 == NoReg) { rTop110 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult112 = allocateRegNotConflictingWith(1ULL << rTop110); + rResult112 = allocateRegNotConflictingWith(((rTop110 < 0) ? (((usqInt)(1)) >> (-rTop110)) : (1ULL << rTop110))); assert(!(((rTop110 == NoReg) || (rResult112 == NoReg)))); pointer6 = rTop110; @@ -35581,7 +35767,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if (rTop28 == NoReg) { rTop28 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult32 = allocateRegNotConflictingWith(1ULL << rTop28); + rResult32 = allocateRegNotConflictingWith(((rTop28 < 0) ? (((usqInt)(1)) >> (-rTop28)) : (1ULL << rTop28))); assert(!(((rTop28 == NoReg) || (rResult32 == NoReg)))); pointer7 = rTop28; @@ -35795,13 +35981,13 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((registerOrNone(ssTop())) != NoReg) { rOopTop = registerOrNone(ssTop()); /* begin registerMaskFor: */ - topRegisterMask = 1ULL << rOopTop; + topRegisterMask = ((rOopTop < 0) ? (((usqInt)(1)) >> (-rOopTop)) : (1ULL << rOopTop)); } if (rTop29 == NoReg) { rTop29 = allocateRegNotConflictingWith(topRegisterMask); } if (rOopTop == NoReg) { - rOopTop = allocateRegNotConflictingWith(1ULL << rTop29); + rOopTop = allocateRegNotConflictingWith(((rTop29 < 0) ? (((usqInt)(1)) >> (-rTop29)) : (1ULL << rTop29))); } assert(!(((rTop29 == NoReg) || (rOopTop == NoReg)))); @@ -36061,7 +36247,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult = allocateRegNotConflictingWith(1ULL << rTop); + rResult = allocateRegNotConflictingWith(((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1ULL << rTop))); assert(!(((rTop == NoReg) || (rResult == NoReg)))); pointer = rTop; @@ -36083,7 +36269,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult1 = allocateRegNotConflictingWith(1ULL << rTop1); + rResult1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); assert(!(((rTop1 == NoReg) || (rResult1 == NoReg)))); pointer1 = rTop1; @@ -36105,7 +36291,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop2 == NoReg) { rTop2 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult2 = allocateRegNotConflictingWith(1ULL << rTop2); + rResult2 = allocateRegNotConflictingWith(((rTop2 < 0) ? (((usqInt)(1)) >> (-rTop2)) : (1ULL << rTop2))); assert(!(((rTop2 == NoReg) || (rResult2 == NoReg)))); pointer2 = rTop2; @@ -36128,7 +36314,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop11 == NoReg) { rTop11 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult11 = allocateRegNotConflictingWith(1ULL << rTop11); + rResult11 = allocateRegNotConflictingWith(((rTop11 < 0) ? (((usqInt)(1)) >> (-rTop11)) : (1ULL << rTop11))); assert(!(((rTop11 == NoReg) || (rResult11 == NoReg)))); pointer3 = rTop11; @@ -36151,7 +36337,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop4 == NoReg) { rTop4 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult4 = allocateRegNotConflictingWith(1ULL << rTop4); + rResult4 = allocateRegNotConflictingWith(((rTop4 < 0) ? (((usqInt)(1)) >> (-rTop4)) : (1ULL << rTop4))); assert(!(((rTop4 == NoReg) || (rResult4 == NoReg)))); pointer4 = rTop4; @@ -36236,7 +36422,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop28 == NoReg) { rTop28 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult8 = allocateRegNotConflictingWith(1ULL << rTop28); + rResult8 = allocateRegNotConflictingWith(((rTop28 < 0) ? (((usqInt)(1)) >> (-rTop28)) : (1ULL << rTop28))); assert(!(((rTop28 == NoReg) || (rResult8 == NoReg)))); size1 = rTop28; @@ -36277,7 +36463,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop111 == NoReg) { rTop111 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult13 = allocateRegNotConflictingWith(1ULL << rTop111); + rResult13 = allocateRegNotConflictingWith(((rTop111 < 0) ? (((usqInt)(1)) >> (-rTop111)) : (1ULL << rTop111))); assert(!(((rTop111 == NoReg) || (rResult13 == NoReg)))); size2 = rTop111; @@ -36335,18 +36521,18 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) nextRegisterMask2 = 0; if (rNext13 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask2 = 1ULL << rNext13; + nextRegisterMask2 = ((rNext13 < 0) ? (((usqInt)(1)) >> (-rNext13)) : (1ULL << rNext13)); } if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1ULL << rNextNext2); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNext2)) : (1ULL << rNextNext2))); } rTop30 = allocateRegNotConflictingWith(nextRegisterMask2); } if (rNext13 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask2 = 1ULL << rTop30; + nextRegisterMask2 = ((rTop30 < 0) ? (((usqInt)(1)) >> (-rTop30)) : (1ULL << rTop30)); if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1ULL << rNextNext2); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNext2)) : (1ULL << rNextNext2))); } rNext13 = allocateRegNotConflictingWith(nextRegisterMask2); } @@ -36409,18 +36595,18 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) nextRegisterMask3 = 0; if (rNext14 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask3 = 1ULL << rNext14; + nextRegisterMask3 = ((rNext14 < 0) ? (((usqInt)(1)) >> (-rNext14)) : (1ULL << rNext14)); } if (rNextNext3 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1ULL << rNextNext3); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNext3)) : (1ULL << rNextNext3))); } rTop31 = allocateRegNotConflictingWith(nextRegisterMask3); } if (rNext14 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask3 = 1ULL << rTop31; + nextRegisterMask3 = ((rTop31 < 0) ? (((usqInt)(1)) >> (-rTop31)) : (1ULL << rTop31)); if (rNextNext3 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1ULL << rNextNext3); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNext3)) : (1ULL << rNextNext3))); } rNext14 = allocateRegNotConflictingWith(nextRegisterMask3); } @@ -36471,14 +36657,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg11 = (rNext15 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask13 = 1ULL << reg11; + topRegistersMask13 = ((reg11 < 0) ? (((usqInt)(1)) >> (-reg11)) : (1ULL << reg11)); } } if (rTop32 == NoReg) { rTop32 = allocateRegNotConflictingWith(topRegistersMask13); } if (rNext15 == NoReg) { - rNext15 = allocateRegNotConflictingWith(1ULL << rTop32); + rNext15 = allocateRegNotConflictingWith(((rTop32 < 0) ? (((usqInt)(1)) >> (-rTop32)) : (1ULL << rTop32))); } assert(!(((rTop32 == NoReg) || (rNext15 == NoReg)))); @@ -36565,14 +36751,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } } if (rTop5 == NoReg) { rTop5 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1ULL << rTop5); + rNext = allocateRegNotConflictingWith(((rTop5 < 0) ? (((usqInt)(1)) >> (-rTop5)) : (1ULL << rTop5))); } assert(!(((rTop5 == NoReg) || (rNext == NoReg)))); @@ -36602,14 +36788,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg1 = (rNext1 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask1 = 1ULL << reg1; + topRegistersMask1 = ((reg1 < 0) ? (((usqInt)(1)) >> (-reg1)) : (1ULL << reg1)); } } if (rTop6 == NoReg) { rTop6 = allocateRegNotConflictingWith(topRegistersMask1); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop6); + rNext1 = allocateRegNotConflictingWith(((rTop6 < 0) ? (((usqInt)(1)) >> (-rTop6)) : (1ULL << rTop6))); } assert(!(((rTop6 == NoReg) || (rNext1 == NoReg)))); @@ -36714,14 +36900,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg4 = (rNext4 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask4 = 1ULL << reg4; + topRegistersMask4 = ((reg4 < 0) ? (((usqInt)(1)) >> (-reg4)) : (1ULL << reg4)); } } if (rTop14 == NoReg) { rTop14 = allocateRegNotConflictingWith(topRegistersMask4); } if (rNext4 == NoReg) { - rNext4 = allocateRegNotConflictingWith(1ULL << rTop14); + rNext4 = allocateRegNotConflictingWith(((rTop14 < 0) ? (((usqInt)(1)) >> (-rTop14)) : (1ULL << rTop14))); } assert(!(((rTop14 == NoReg) || (rNext4 == NoReg)))); @@ -36754,14 +36940,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg5 = (rNext11 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask5 = 1ULL << reg5; + topRegistersMask5 = ((reg5 < 0) ? (((usqInt)(1)) >> (-reg5)) : (1ULL << reg5)); } } if (rTop16 == NoReg) { rTop16 = allocateRegNotConflictingWith(topRegistersMask5); } if (rNext11 == NoReg) { - rNext11 = allocateRegNotConflictingWith(1ULL << rTop16); + rNext11 = allocateRegNotConflictingWith(((rTop16 < 0) ? (((usqInt)(1)) >> (-rTop16)) : (1ULL << rTop16))); } assert(!(((rTop16 == NoReg) || (rNext11 == NoReg)))); @@ -36876,14 +37062,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg6 = (rNext6 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask6 = 1ULL << reg6; + topRegistersMask6 = ((reg6 < 0) ? (((usqInt)(1)) >> (-reg6)) : (1ULL << reg6)); } } if (rTop18 == NoReg) { rTop18 = allocateRegNotConflictingWith(topRegistersMask6); } if (rNext6 == NoReg) { - rNext6 = allocateRegNotConflictingWith(1ULL << rTop18); + rNext6 = allocateRegNotConflictingWith(((rTop18 < 0) ? (((usqInt)(1)) >> (-rTop18)) : (1ULL << rTop18))); } assert(!(((rTop18 == NoReg) || (rNext6 == NoReg)))); @@ -36913,14 +37099,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg7 = (rNext12 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask7 = 1ULL << reg7; + topRegistersMask7 = ((reg7 < 0) ? (((usqInt)(1)) >> (-reg7)) : (1ULL << reg7)); } } if (rTop19 == NoReg) { rTop19 = allocateRegNotConflictingWith(topRegistersMask7); } if (rNext12 == NoReg) { - rNext12 = allocateRegNotConflictingWith(1ULL << rTop19); + rNext12 = allocateRegNotConflictingWith(((rTop19 < 0) ? (((usqInt)(1)) >> (-rTop19)) : (1ULL << rTop19))); } assert(!(((rTop19 == NoReg) || (rNext12 == NoReg)))); @@ -36949,14 +37135,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg8 = (rNext8 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask8 = 1ULL << reg8; + topRegistersMask8 = ((reg8 < 0) ? (((usqInt)(1)) >> (-reg8)) : (1ULL << reg8)); } } if (rTop21 == NoReg) { rTop21 = allocateRegNotConflictingWith(topRegistersMask8); } if (rNext8 == NoReg) { - rNext8 = allocateRegNotConflictingWith(1ULL << rTop21); + rNext8 = allocateRegNotConflictingWith(((rTop21 < 0) ? (((usqInt)(1)) >> (-rTop21)) : (1ULL << rTop21))); } assert(!(((rTop21 == NoReg) || (rNext8 == NoReg)))); @@ -36996,14 +37182,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg9 = (rNext9 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask9 = 1ULL << reg9; + topRegistersMask9 = ((reg9 < 0) ? (((usqInt)(1)) >> (-reg9)) : (1ULL << reg9)); } } if (rTop22 == NoReg) { rTop22 = allocateRegNotConflictingWith(topRegistersMask9); } if (rNext9 == NoReg) { - rNext9 = allocateRegNotConflictingWith(1ULL << rTop22); + rNext9 = allocateRegNotConflictingWith(((rTop22 < 0) ? (((usqInt)(1)) >> (-rTop22)) : (1ULL << rTop22))); } assert(!(((rTop22 == NoReg) || (rNext9 == NoReg)))); @@ -37056,7 +37242,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop110 == NoReg) { rTop110 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult12 = allocateRegNotConflictingWith(1ULL << rTop110); + rResult12 = allocateRegNotConflictingWith(((rTop110 < 0) ? (((usqInt)(1)) >> (-rTop110)) : (1ULL << rTop110))); assert(!(((rTop110 == NoReg) || (rResult12 == NoReg)))); pointer6 = rTop110; @@ -37572,14 +37758,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } } if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(topRegistersMask); } if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1ULL << rTop); + rNext = allocateRegNotConflictingWith(((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1ULL << rTop))); } assert(!(((rTop == NoReg) || (rNext == NoReg)))); @@ -37608,14 +37794,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg1 = (rNext1 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask1 = 1ULL << reg1; + topRegistersMask1 = ((reg1 < 0) ? (((usqInt)(1)) >> (-reg1)) : (1ULL << reg1)); } } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask1); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -37645,14 +37831,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg2 = (rNext2 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask2 = 1ULL << reg2; + topRegistersMask2 = ((reg2 < 0) ? (((usqInt)(1)) >> (-reg2)) : (1ULL << reg2)); } } if (rTop2 == NoReg) { rTop2 = allocateRegNotConflictingWith(topRegistersMask2); } if (rNext2 == NoReg) { - rNext2 = allocateRegNotConflictingWith(1ULL << rTop2); + rNext2 = allocateRegNotConflictingWith(((rTop2 < 0) ? (((usqInt)(1)) >> (-rTop2)) : (1ULL << rTop2))); } assert(!(((rTop2 == NoReg) || (rNext2 == NoReg)))); @@ -37682,14 +37868,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg3 = (rNext3 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask3 = 1ULL << reg3; + topRegistersMask3 = ((reg3 < 0) ? (((usqInt)(1)) >> (-reg3)) : (1ULL << reg3)); } } if (rTop3 == NoReg) { rTop3 = allocateRegNotConflictingWith(topRegistersMask3); } if (rNext3 == NoReg) { - rNext3 = allocateRegNotConflictingWith(1ULL << rTop3); + rNext3 = allocateRegNotConflictingWith(((rTop3 < 0) ? (((usqInt)(1)) >> (-rTop3)) : (1ULL << rTop3))); } assert(!(((rTop3 == NoReg) || (rNext3 == NoReg)))); @@ -37777,7 +37963,7 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if (rTop12 == NoReg) { rTop12 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult11 = allocateRegNotConflictingWith(1ULL << rTop12); + rResult11 = allocateRegNotConflictingWith(((rTop12 < 0) ? (((usqInt)(1)) >> (-rTop12)) : (1ULL << rTop12))); assert(!(((rTop12 == NoReg) || (rResult11 == NoReg)))); value5 = rTop12; @@ -37802,7 +37988,7 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if (rTop13 == NoReg) { rTop13 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult12 = allocateRegNotConflictingWith(1ULL << rTop13); + rResult12 = allocateRegNotConflictingWith(((rTop13 < 0) ? (((usqInt)(1)) >> (-rTop13)) : (1ULL << rTop13))); assert(!(((rTop13 == NoReg) || (rResult12 == NoReg)))); value6 = rTop13; @@ -37887,14 +38073,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg6 = (rNext6 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask6 = 1ULL << reg6; + topRegistersMask6 = ((reg6 < 0) ? (((usqInt)(1)) >> (-reg6)) : (1ULL << reg6)); } } if (rTop14 == NoReg) { rTop14 = allocateRegNotConflictingWith(topRegistersMask6); } if (rNext6 == NoReg) { - rNext6 = allocateRegNotConflictingWith(1ULL << rTop14); + rNext6 = allocateRegNotConflictingWith(((rTop14 < 0) ? (((usqInt)(1)) >> (-rTop14)) : (1ULL << rTop14))); } assert(!(((rTop14 == NoReg) || (rNext6 == NoReg)))); @@ -37924,14 +38110,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg7 = (rNext7 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask7 = 1ULL << reg7; + topRegistersMask7 = ((reg7 < 0) ? (((usqInt)(1)) >> (-reg7)) : (1ULL << reg7)); } } if (rTop15 == NoReg) { rTop15 = allocateRegNotConflictingWith(topRegistersMask7); } if (rNext7 == NoReg) { - rNext7 = allocateRegNotConflictingWith(1ULL << rTop15); + rNext7 = allocateRegNotConflictingWith(((rTop15 < 0) ? (((usqInt)(1)) >> (-rTop15)) : (1ULL << rTop15))); } assert(!(((rTop15 == NoReg) || (rNext7 == NoReg)))); @@ -37960,14 +38146,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg8 = (rNext11 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask8 = 1ULL << reg8; + topRegistersMask8 = ((reg8 < 0) ? (((usqInt)(1)) >> (-reg8)) : (1ULL << reg8)); } } if (rTop16 == NoReg) { rTop16 = allocateRegNotConflictingWith(topRegistersMask8); } if (rNext11 == NoReg) { - rNext11 = allocateRegNotConflictingWith(1ULL << rTop16); + rNext11 = allocateRegNotConflictingWith(((rTop16 < 0) ? (((usqInt)(1)) >> (-rTop16)) : (1ULL << rTop16))); } assert(!(((rTop16 == NoReg) || (rNext11 == NoReg)))); @@ -37996,14 +38182,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg9 = (rNext9 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask9 = 1ULL << reg9; + topRegistersMask9 = ((reg9 < 0) ? (((usqInt)(1)) >> (-reg9)) : (1ULL << reg9)); } } if (rTop18 == NoReg) { rTop18 = allocateRegNotConflictingWith(topRegistersMask9); } if (rNext9 == NoReg) { - rNext9 = allocateRegNotConflictingWith(1ULL << rTop18); + rNext9 = allocateRegNotConflictingWith(((rTop18 < 0) ? (((usqInt)(1)) >> (-rTop18)) : (1ULL << rTop18))); } assert(!(((rTop18 == NoReg) || (rNext9 == NoReg)))); @@ -38186,14 +38372,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg11 = (rNext12 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask13 = 1ULL << reg11; + topRegistersMask13 = ((reg11 < 0) ? (((usqInt)(1)) >> (-reg11)) : (1ULL << reg11)); } } if (rTop24 == NoReg) { rTop24 = allocateRegNotConflictingWith(topRegistersMask13); } if (rNext12 == NoReg) { - rNext12 = allocateRegNotConflictingWith(1ULL << rTop24); + rNext12 = allocateRegNotConflictingWith(((rTop24 < 0) ? (((usqInt)(1)) >> (-rTop24)) : (1ULL << rTop24))); } assert(!(((rTop24 == NoReg) || (rNext12 == NoReg)))); @@ -38221,14 +38407,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg12 = (rNext13 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask14 = 1ULL << reg12; + topRegistersMask14 = ((reg12 < 0) ? (((usqInt)(1)) >> (-reg12)) : (1ULL << reg12)); } } if (rTop25 == NoReg) { rTop25 = allocateRegNotConflictingWith(topRegistersMask14); } if (rNext13 == NoReg) { - rNext13 = allocateRegNotConflictingWith(1ULL << rTop25); + rNext13 = allocateRegNotConflictingWith(((rTop25 < 0) ? (((usqInt)(1)) >> (-rTop25)) : (1ULL << rTop25))); } assert(!(((rTop25 == NoReg) || (rNext13 == NoReg)))); @@ -38258,14 +38444,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg13 = (rNext15 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask15 = 1ULL << reg13; + topRegistersMask15 = ((reg13 < 0) ? (((usqInt)(1)) >> (-reg13)) : (1ULL << reg13)); } } if (rTop111 == NoReg) { rTop111 = allocateRegNotConflictingWith(topRegistersMask15); } if (rNext15 == NoReg) { - rNext15 = allocateRegNotConflictingWith(1ULL << rTop111); + rNext15 = allocateRegNotConflictingWith(((rTop111 < 0) ? (((usqInt)(1)) >> (-rTop111)) : (1ULL << rTop111))); } assert(!(((rTop111 == NoReg) || (rNext15 == NoReg)))); @@ -38365,7 +38551,7 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if (rTop114 == NoReg) { rTop114 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult13 = allocateRegNotConflictingWith(1ULL << rTop114); + rResult13 = allocateRegNotConflictingWith(((rTop114 < 0) ? (((usqInt)(1)) >> (-rTop114)) : (1ULL << rTop114))); assert(!(((rTop114 == NoReg) || (rResult13 == NoReg)))); value21 = rTop114; @@ -38391,14 +38577,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg17 = (rNext19 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask19 = 1ULL << reg17; + topRegistersMask19 = ((reg17 < 0) ? (((usqInt)(1)) >> (-reg17)) : (1ULL << reg17)); } } if (rTop32 == NoReg) { rTop32 = allocateRegNotConflictingWith(topRegistersMask19); } if (rNext19 == NoReg) { - rNext19 = allocateRegNotConflictingWith(1ULL << rTop32); + rNext19 = allocateRegNotConflictingWith(((rTop32 < 0) ? (((usqInt)(1)) >> (-rTop32)) : (1ULL << rTop32))); } assert(!(((rTop32 == NoReg) || (rNext19 == NoReg)))); @@ -38427,14 +38613,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg18 = (rNext20 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask20 = 1ULL << reg18; + topRegistersMask20 = ((reg18 < 0) ? (((usqInt)(1)) >> (-reg18)) : (1ULL << reg18)); } } if (rTop33 == NoReg) { rTop33 = allocateRegNotConflictingWith(topRegistersMask20); } if (rNext20 == NoReg) { - rNext20 = allocateRegNotConflictingWith(1ULL << rTop33); + rNext20 = allocateRegNotConflictingWith(((rTop33 < 0) ? (((usqInt)(1)) >> (-rTop33)) : (1ULL << rTop33))); } assert(!(((rTop33 == NoReg) || (rNext20 == NoReg)))); @@ -38464,14 +38650,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg19 = (rNext21 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask21 = 1ULL << reg19; + topRegistersMask21 = ((reg19 < 0) ? (((usqInt)(1)) >> (-reg19)) : (1ULL << reg19)); } } if (rTop34 == NoReg) { rTop34 = allocateRegNotConflictingWith(topRegistersMask21); } if (rNext21 == NoReg) { - rNext21 = allocateRegNotConflictingWith(1ULL << rTop34); + rNext21 = allocateRegNotConflictingWith(((rTop34 < 0) ? (((usqInt)(1)) >> (-rTop34)) : (1ULL << rTop34))); } assert(!(((rTop34 == NoReg) || (rNext21 == NoReg)))); @@ -38511,14 +38697,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg20 = (rNext22 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask22 = 1ULL << reg20; + topRegistersMask22 = ((reg20 < 0) ? (((usqInt)(1)) >> (-reg20)) : (1ULL << reg20)); } } if (rTop35 == NoReg) { rTop35 = allocateRegNotConflictingWith(topRegistersMask22); } if (rNext22 == NoReg) { - rNext22 = allocateRegNotConflictingWith(1ULL << rTop35); + rNext22 = allocateRegNotConflictingWith(((rTop35 < 0) ? (((usqInt)(1)) >> (-rTop35)) : (1ULL << rTop35))); } assert(!(((rTop35 == NoReg) || (rNext22 == NoReg)))); @@ -38558,14 +38744,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg21 = (rNext23 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask23 = 1ULL << reg21; + topRegistersMask23 = ((reg21 < 0) ? (((usqInt)(1)) >> (-reg21)) : (1ULL << reg21)); } } if (rTop36 == NoReg) { rTop36 = allocateRegNotConflictingWith(topRegistersMask23); } if (rNext23 == NoReg) { - rNext23 = allocateRegNotConflictingWith(1ULL << rTop36); + rNext23 = allocateRegNotConflictingWith(((rTop36 < 0) ? (((usqInt)(1)) >> (-rTop36)) : (1ULL << rTop36))); } assert(!(((rTop36 == NoReg) || (rNext23 == NoReg)))); @@ -38605,14 +38791,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg22 = (rNext24 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask24 = 1ULL << reg22; + topRegistersMask24 = ((reg22 < 0) ? (((usqInt)(1)) >> (-reg22)) : (1ULL << reg22)); } } if (rTop37 == NoReg) { rTop37 = allocateRegNotConflictingWith(topRegistersMask24); } if (rNext24 == NoReg) { - rNext24 = allocateRegNotConflictingWith(1ULL << rTop37); + rNext24 = allocateRegNotConflictingWith(((rTop37 < 0) ? (((usqInt)(1)) >> (-rTop37)) : (1ULL << rTop37))); } assert(!(((rTop37 == NoReg) || (rNext24 == NoReg)))); @@ -38697,14 +38883,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg23 = (rNext25 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask25 = 1ULL << reg23; + topRegistersMask25 = ((reg23 < 0) ? (((usqInt)(1)) >> (-reg23)) : (1ULL << reg23)); } } if (rTop40 == NoReg) { rTop40 = allocateRegNotConflictingWith(topRegistersMask25); } if (rNext25 == NoReg) { - rNext25 = allocateRegNotConflictingWith(1ULL << rTop40); + rNext25 = allocateRegNotConflictingWith(((rTop40 < 0) ? (((usqInt)(1)) >> (-rTop40)) : (1ULL << rTop40))); } assert(!(((rTop40 == NoReg) || (rNext25 == NoReg)))); @@ -38735,14 +38921,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg24 = (rNext26 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask26 = 1ULL << reg24; + topRegistersMask26 = ((reg24 < 0) ? (((usqInt)(1)) >> (-reg24)) : (1ULL << reg24)); } } if (rTop41 == NoReg) { rTop41 = allocateRegNotConflictingWith(topRegistersMask26); } if (rNext26 == NoReg) { - rNext26 = allocateRegNotConflictingWith(1ULL << rTop41); + rNext26 = allocateRegNotConflictingWith(((rTop41 < 0) ? (((usqInt)(1)) >> (-rTop41)) : (1ULL << rTop41))); } assert(!(((rTop41 == NoReg) || (rNext26 == NoReg)))); @@ -38773,14 +38959,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg25 = (rNext27 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask27 = 1ULL << reg25; + topRegistersMask27 = ((reg25 < 0) ? (((usqInt)(1)) >> (-reg25)) : (1ULL << reg25)); } } if (rTop42 == NoReg) { rTop42 = allocateRegNotConflictingWith(topRegistersMask27); } if (rNext27 == NoReg) { - rNext27 = allocateRegNotConflictingWith(1ULL << rTop42); + rNext27 = allocateRegNotConflictingWith(((rTop42 < 0) ? (((usqInt)(1)) >> (-rTop42)) : (1ULL << rTop42))); } assert(!(((rTop42 == NoReg) || (rNext27 == NoReg)))); @@ -38811,14 +38997,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg26 = (rNext28 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask28 = 1ULL << reg26; + topRegistersMask28 = ((reg26 < 0) ? (((usqInt)(1)) >> (-reg26)) : (1ULL << reg26)); } } if (rTop43 == NoReg) { rTop43 = allocateRegNotConflictingWith(topRegistersMask28); } if (rNext28 == NoReg) { - rNext28 = allocateRegNotConflictingWith(1ULL << rTop43); + rNext28 = allocateRegNotConflictingWith(((rTop43 < 0) ? (((usqInt)(1)) >> (-rTop43)) : (1ULL << rTop43))); } assert(!(((rTop43 == NoReg) || (rNext28 == NoReg)))); @@ -38888,14 +39074,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg27 = (rNext29 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask29 = 1ULL << reg27; + topRegistersMask29 = ((reg27 < 0) ? (((usqInt)(1)) >> (-reg27)) : (1ULL << reg27)); } } if (rTop46 == NoReg) { rTop46 = allocateRegNotConflictingWith(topRegistersMask29); } if (rNext29 == NoReg) { - rNext29 = allocateRegNotConflictingWith(1ULL << rTop46); + rNext29 = allocateRegNotConflictingWith(((rTop46 < 0) ? (((usqInt)(1)) >> (-rTop46)) : (1ULL << rTop46))); } assert(!(((rTop46 == NoReg) || (rNext29 == NoReg)))); @@ -38925,14 +39111,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg28 = (rNext30 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask30 = 1ULL << reg28; + topRegistersMask30 = ((reg28 < 0) ? (((usqInt)(1)) >> (-reg28)) : (1ULL << reg28)); } } if (rTop47 == NoReg) { rTop47 = allocateRegNotConflictingWith(topRegistersMask30); } if (rNext30 == NoReg) { - rNext30 = allocateRegNotConflictingWith(1ULL << rTop47); + rNext30 = allocateRegNotConflictingWith(((rTop47 < 0) ? (((usqInt)(1)) >> (-rTop47)) : (1ULL << rTop47))); } assert(!(((rTop47 == NoReg) || (rNext30 == NoReg)))); @@ -38970,14 +39156,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg29 = (rNext31 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask31 = 1ULL << reg29; + topRegistersMask31 = ((reg29 < 0) ? (((usqInt)(1)) >> (-reg29)) : (1ULL << reg29)); } } if (rTop48 == NoReg) { rTop48 = allocateRegNotConflictingWith(topRegistersMask31); } if (rNext31 == NoReg) { - rNext31 = allocateRegNotConflictingWith(1ULL << rTop48); + rNext31 = allocateRegNotConflictingWith(((rTop48 < 0) ? (((usqInt)(1)) >> (-rTop48)) : (1ULL << rTop48))); } assert(!(((rTop48 == NoReg) || (rNext31 == NoReg)))); @@ -39006,14 +39192,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg30 = (rNext32 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask32 = 1ULL << reg30; + topRegistersMask32 = ((reg30 < 0) ? (((usqInt)(1)) >> (-reg30)) : (1ULL << reg30)); } } if (rTop49 == NoReg) { rTop49 = allocateRegNotConflictingWith(topRegistersMask32); } if (rNext32 == NoReg) { - rNext32 = allocateRegNotConflictingWith(1ULL << rTop49); + rNext32 = allocateRegNotConflictingWith(((rTop49 < 0) ? (((usqInt)(1)) >> (-rTop49)) : (1ULL << rTop49))); } assert(!(((rTop49 == NoReg) || (rNext32 == NoReg)))); @@ -39043,14 +39229,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg31 = (rNext33 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask33 = 1ULL << reg31; + topRegistersMask33 = ((reg31 < 0) ? (((usqInt)(1)) >> (-reg31)) : (1ULL << reg31)); } } if (rTop50 == NoReg) { rTop50 = allocateRegNotConflictingWith(topRegistersMask33); } if (rNext33 == NoReg) { - rNext33 = allocateRegNotConflictingWith(1ULL << rTop50); + rNext33 = allocateRegNotConflictingWith(((rTop50 < 0) ? (((usqInt)(1)) >> (-rTop50)) : (1ULL << rTop50))); } assert(!(((rTop50 == NoReg) || (rNext33 == NoReg)))); @@ -39080,14 +39266,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg32 = (rNext110 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask34 = 1ULL << reg32; + topRegistersMask34 = ((reg32 < 0) ? (((usqInt)(1)) >> (-reg32)) : (1ULL << reg32)); } } if (rTop115 == NoReg) { rTop115 = allocateRegNotConflictingWith(topRegistersMask34); } if (rNext110 == NoReg) { - rNext110 = allocateRegNotConflictingWith(1ULL << rTop115); + rNext110 = allocateRegNotConflictingWith(((rTop115 < 0) ? (((usqInt)(1)) >> (-rTop115)) : (1ULL << rTop115))); } assert(!(((rTop115 == NoReg) || (rNext110 == NoReg)))); @@ -39193,7 +39379,7 @@ genLowcodeUnaryInlinePrimitive5(sqInt prim) if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult1 = allocateRegNotConflictingWith(1ULL << rTop1); + rResult1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); assert(!(((rTop1 == NoReg) || (rResult1 == NoReg)))); value = rTop1; @@ -39603,14 +39789,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } } if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(topRegistersMask); } if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1ULL << rTop); + rNext = allocateRegNotConflictingWith(((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1ULL << rTop))); } assert(!(((rTop == NoReg) || (rNext == NoReg)))); @@ -39640,14 +39826,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg1 = (rNext1 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask1 = 1ULL << reg1; + topRegistersMask1 = ((reg1 < 0) ? (((usqInt)(1)) >> (-reg1)) : (1ULL << reg1)); } } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask1); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -39725,14 +39911,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg3 = (rNext4 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask3 = 1ULL << reg3; + topRegistersMask3 = ((reg3 < 0) ? (((usqInt)(1)) >> (-reg3)) : (1ULL << reg3)); } } if (rTop5 == NoReg) { rTop5 = allocateRegNotConflictingWith(topRegistersMask3); } if (rNext4 == NoReg) { - rNext4 = allocateRegNotConflictingWith(1ULL << rTop5); + rNext4 = allocateRegNotConflictingWith(((rTop5 < 0) ? (((usqInt)(1)) >> (-rTop5)) : (1ULL << rTop5))); } assert(!(((rTop5 == NoReg) || (rNext4 == NoReg)))); @@ -39762,14 +39948,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg4 = (rNext11 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask4 = 1ULL << reg4; + topRegistersMask4 = ((reg4 < 0) ? (((usqInt)(1)) >> (-reg4)) : (1ULL << reg4)); } } if (rTop12 == NoReg) { rTop12 = allocateRegNotConflictingWith(topRegistersMask4); } if (rNext11 == NoReg) { - rNext11 = allocateRegNotConflictingWith(1ULL << rTop12); + rNext11 = allocateRegNotConflictingWith(((rTop12 < 0) ? (((usqInt)(1)) >> (-rTop12)) : (1ULL << rTop12))); } assert(!(((rTop12 == NoReg) || (rNext11 == NoReg)))); @@ -39798,14 +39984,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg5 = (rNext6 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask5 = 1ULL << reg5; + topRegistersMask5 = ((reg5 < 0) ? (((usqInt)(1)) >> (-reg5)) : (1ULL << reg5)); } } if (rTop7 == NoReg) { rTop7 = allocateRegNotConflictingWith(topRegistersMask5); } if (rNext6 == NoReg) { - rNext6 = allocateRegNotConflictingWith(1ULL << rTop7); + rNext6 = allocateRegNotConflictingWith(((rTop7 < 0) ? (((usqInt)(1)) >> (-rTop7)) : (1ULL << rTop7))); } assert(!(((rTop7 == NoReg) || (rNext6 == NoReg)))); @@ -39835,14 +40021,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg6 = (rNext7 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask6 = 1ULL << reg6; + topRegistersMask6 = ((reg6 < 0) ? (((usqInt)(1)) >> (-reg6)) : (1ULL << reg6)); } } if (rTop8 == NoReg) { rTop8 = allocateRegNotConflictingWith(topRegistersMask6); } if (rNext7 == NoReg) { - rNext7 = allocateRegNotConflictingWith(1ULL << rTop8); + rNext7 = allocateRegNotConflictingWith(((rTop8 < 0) ? (((usqInt)(1)) >> (-rTop8)) : (1ULL << rTop8))); } assert(!(((rTop8 == NoReg) || (rNext7 == NoReg)))); @@ -39989,18 +40175,18 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) nextRegisterMask2 = 0; if (rNext8 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask2 = 1ULL << rNext8; + nextRegisterMask2 = ((rNext8 < 0) ? (((usqInt)(1)) >> (-rNext8)) : (1ULL << rNext8)); } if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1ULL << rNextNext2); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNext2)) : (1ULL << rNextNext2))); } rTop9 = allocateRegNotConflictingWith(nextRegisterMask2); } if (rNext8 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask2 = 1ULL << rTop9; + nextRegisterMask2 = ((rTop9 < 0) ? (((usqInt)(1)) >> (-rTop9)) : (1ULL << rTop9)); if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1ULL << rNextNext2); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNext2)) : (1ULL << rNextNext2))); } rNext8 = allocateRegNotConflictingWith(nextRegisterMask2); } @@ -40041,14 +40227,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg7 = (rNext9 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask7 = 1ULL << reg7; + topRegistersMask7 = ((reg7 < 0) ? (((usqInt)(1)) >> (-reg7)) : (1ULL << reg7)); } } if (rTop10 == NoReg) { rTop10 = allocateRegNotConflictingWith(topRegistersMask7); } if (rNext9 == NoReg) { - rNext9 = allocateRegNotConflictingWith(1ULL << rTop10); + rNext9 = allocateRegNotConflictingWith(((rTop10 < 0) ? (((usqInt)(1)) >> (-rTop10)) : (1ULL << rTop10))); } assert(!(((rTop10 == NoReg) || (rNext9 == NoReg)))); @@ -40077,14 +40263,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg8 = (rNext10 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask8 = 1ULL << reg8; + topRegistersMask8 = ((reg8 < 0) ? (((usqInt)(1)) >> (-reg8)) : (1ULL << reg8)); } } if (rTop13 == NoReg) { rTop13 = allocateRegNotConflictingWith(topRegistersMask8); } if (rNext10 == NoReg) { - rNext10 = allocateRegNotConflictingWith(1ULL << rTop13); + rNext10 = allocateRegNotConflictingWith(((rTop13 < 0) ? (((usqInt)(1)) >> (-rTop13)) : (1ULL << rTop13))); } assert(!(((rTop13 == NoReg) || (rNext10 == NoReg)))); @@ -40112,7 +40298,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (frTop == NoReg) { frTop = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); } - frResult = allocateFloatRegNotConflictingWith(1ULL << frTop); + frResult = allocateFloatRegNotConflictingWith(((frTop < 0) ? (((usqInt)(1)) >> (-frTop)) : (1ULL << frTop))); assert(!(((frTop == NoReg) || (frResult == NoReg)))); value3 = frTop; @@ -40137,7 +40323,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (frTop1 == NoReg) { frTop1 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); } - frResult1 = allocateFloatRegNotConflictingWith(1ULL << frTop1); + frResult1 = allocateFloatRegNotConflictingWith(((frTop1 < 0) ? (((usqInt)(1)) >> (-frTop1)) : (1ULL << frTop1))); assert(!(((frTop1 == NoReg) || (frResult1 == NoReg)))); value4 = frTop1; @@ -40160,7 +40346,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (rTop14 == NoReg) { rTop14 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult3 = allocateRegNotConflictingWith(1ULL << rTop14); + rResult3 = allocateRegNotConflictingWith(((rTop14 < 0) ? (((usqInt)(1)) >> (-rTop14)) : (1ULL << rTop14))); assert(!(((rTop14 == NoReg) || (rResult3 == NoReg)))); value5 = rTop14; @@ -40184,7 +40370,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (rTop16 == NoReg) { rTop16 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult11 = allocateRegNotConflictingWith(1ULL << rTop16); + rResult11 = allocateRegNotConflictingWith(((rTop16 < 0) ? (((usqInt)(1)) >> (-rTop16)) : (1ULL << rTop16))); assert(!(((rTop16 == NoReg) || (rResult11 == NoReg)))); value6 = rTop16; @@ -40207,7 +40393,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (rTop17 == NoReg) { rTop17 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult5 = allocateRegNotConflictingWith(1ULL << rTop17); + rResult5 = allocateRegNotConflictingWith(((rTop17 < 0) ? (((usqInt)(1)) >> (-rTop17)) : (1ULL << rTop17))); assert(!(((rTop17 == NoReg) || (rResult5 == NoReg)))); pointerValue = rTop17; @@ -40258,24 +40444,24 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) nextRegisterMask3 = 0; if (rNext13 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask3 = 1ULL << rNext13; + nextRegisterMask3 = ((rNext13 < 0) ? (((usqInt)(1)) >> (-rNext13)) : (1ULL << rNext13)); } if (rNextNext3 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1ULL << rNextNext3); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNext3)) : (1ULL << rNextNext3))); } if (rNextNextNext2 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1ULL << rNextNextNext2); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNextNext2)) : (1ULL << rNextNextNext2))); } rTop18 = allocateRegNotConflictingWith(nextRegisterMask3); } if (rNext13 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask3 = 1ULL << rTop18; + nextRegisterMask3 = ((rTop18 < 0) ? (((usqInt)(1)) >> (-rTop18)) : (1ULL << rTop18)); if (rNextNext3 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1ULL << rNextNext3); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNext3)) : (1ULL << rNextNext3))); } if (rNextNextNext2 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1ULL << rNextNextNext2); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNextNext2)) : (1ULL << rNextNextNext2))); } rNext13 = allocateRegNotConflictingWith(nextRegisterMask3); } @@ -40283,7 +40469,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) /* begin registerMaskFor:and: */ nextRegisterMask3 = (1ULL << rTop18) | (1ULL << rNext13); if (rNextNextNext2 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1ULL << rNextNextNext2); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNextNext2)) : (1ULL << rNextNextNext2))); } rNextNext3 = allocateRegNotConflictingWith(nextRegisterMask3); } @@ -40356,24 +40542,24 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) nextRegisterMask4 = 0; if (rNext14 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask4 = 1ULL << rNext14; + nextRegisterMask4 = ((rNext14 < 0) ? (((usqInt)(1)) >> (-rNext14)) : (1ULL << rNext14)); } if (rNextNext4 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1ULL << rNextNext4); + nextRegisterMask4 = nextRegisterMask4 | (((rNextNext4 < 0) ? (((usqInt)(1)) >> (-rNextNext4)) : (1ULL << rNextNext4))); } if (rNextNextNext3 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1ULL << rNextNextNext3); + nextRegisterMask4 = nextRegisterMask4 | (((rNextNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNextNext3)) : (1ULL << rNextNextNext3))); } rTop19 = allocateRegNotConflictingWith(nextRegisterMask4); } if (rNext14 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask4 = 1ULL << rTop19; + nextRegisterMask4 = ((rTop19 < 0) ? (((usqInt)(1)) >> (-rTop19)) : (1ULL << rTop19)); if (rNextNext4 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1ULL << rNextNext4); + nextRegisterMask4 = nextRegisterMask4 | (((rNextNext4 < 0) ? (((usqInt)(1)) >> (-rNextNext4)) : (1ULL << rNextNext4))); } if (rNextNextNext3 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1ULL << rNextNextNext3); + nextRegisterMask4 = nextRegisterMask4 | (((rNextNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNextNext3)) : (1ULL << rNextNextNext3))); } rNext14 = allocateRegNotConflictingWith(nextRegisterMask4); } @@ -40381,7 +40567,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) /* begin registerMaskFor:and: */ nextRegisterMask4 = (1ULL << rTop19) | (1ULL << rNext14); if (rNextNextNext3 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1ULL << rNextNextNext3); + nextRegisterMask4 = nextRegisterMask4 | (((rNextNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNextNext3)) : (1ULL << rNextNextNext3))); } rNextNext4 = allocateRegNotConflictingWith(nextRegisterMask4); } @@ -40431,13 +40617,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg10 = (rNext15 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask10 = 1ULL << reg10; + topRegistersMask10 = ((reg10 < 0) ? (((usqInt)(1)) >> (-reg10)) : (1ULL << reg10)); } if (rTop20 == NoReg) { rTop20 = allocateFloatRegNotConflictingWith(topRegistersMask10); } if (rNext15 == NoReg) { - rNext15 = allocateFloatRegNotConflictingWith(1ULL << rTop20); + rNext15 = allocateFloatRegNotConflictingWith(((rTop20 < 0) ? (((usqInt)(1)) >> (-rTop20)) : (1ULL << rTop20))); } assert(!(((rTop20 == NoReg) || (rNext15 == NoReg)))); @@ -40462,13 +40648,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg11 = (rNext16 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask11 = 1ULL << reg11; + topRegistersMask11 = ((reg11 < 0) ? (((usqInt)(1)) >> (-reg11)) : (1ULL << reg11)); } if (rTop21 == NoReg) { rTop21 = allocateFloatRegNotConflictingWith(topRegistersMask11); } if (rNext16 == NoReg) { - rNext16 = allocateFloatRegNotConflictingWith(1ULL << rTop21); + rNext16 = allocateFloatRegNotConflictingWith(((rTop21 < 0) ? (((usqInt)(1)) >> (-rTop21)) : (1ULL << rTop21))); } assert(!(((rTop21 == NoReg) || (rNext16 == NoReg)))); @@ -40494,13 +40680,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg12 = (frNext = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask12 = 1ULL << reg12; + topRegistersMask12 = ((reg12 < 0) ? (((usqInt)(1)) >> (-reg12)) : (1ULL << reg12)); } if (frTop2 == NoReg) { frTop2 = allocateFloatRegNotConflictingWith(topRegistersMask12); } if (frNext == NoReg) { - frNext = allocateFloatRegNotConflictingWith(1ULL << frTop2); + frNext = allocateFloatRegNotConflictingWith(((frTop2 < 0) ? (((usqInt)(1)) >> (-frTop2)) : (1ULL << frTop2))); } rResult7 = allocateRegNotConflictingWith(0); assert(!(((frTop2 == NoReg) @@ -40540,13 +40726,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg13 = (frNext1 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask13 = 1ULL << reg13; + topRegistersMask13 = ((reg13 < 0) ? (((usqInt)(1)) >> (-reg13)) : (1ULL << reg13)); } if (frTop3 == NoReg) { frTop3 = allocateFloatRegNotConflictingWith(topRegistersMask13); } if (frNext1 == NoReg) { - frNext1 = allocateFloatRegNotConflictingWith(1ULL << frTop3); + frNext1 = allocateFloatRegNotConflictingWith(((frTop3 < 0) ? (((usqInt)(1)) >> (-frTop3)) : (1ULL << frTop3))); } rResult8 = allocateRegNotConflictingWith(0); assert(!(((frTop3 == NoReg) @@ -40586,13 +40772,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg14 = (frNext2 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask14 = 1ULL << reg14; + topRegistersMask14 = ((reg14 < 0) ? (((usqInt)(1)) >> (-reg14)) : (1ULL << reg14)); } if (frTop4 == NoReg) { frTop4 = allocateFloatRegNotConflictingWith(topRegistersMask14); } if (frNext2 == NoReg) { - frNext2 = allocateFloatRegNotConflictingWith(1ULL << frTop4); + frNext2 = allocateFloatRegNotConflictingWith(((frTop4 < 0) ? (((usqInt)(1)) >> (-frTop4)) : (1ULL << frTop4))); } rResult9 = allocateRegNotConflictingWith(0); assert(!(((frTop4 == NoReg) @@ -40632,13 +40818,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg15 = (frNext3 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask15 = 1ULL << reg15; + topRegistersMask15 = ((reg15 < 0) ? (((usqInt)(1)) >> (-reg15)) : (1ULL << reg15)); } if (frTop5 == NoReg) { frTop5 = allocateFloatRegNotConflictingWith(topRegistersMask15); } if (frNext3 == NoReg) { - frNext3 = allocateFloatRegNotConflictingWith(1ULL << frTop5); + frNext3 = allocateFloatRegNotConflictingWith(((frTop5 < 0) ? (((usqInt)(1)) >> (-frTop5)) : (1ULL << frTop5))); } rResult10 = allocateRegNotConflictingWith(0); assert(!(((frTop5 == NoReg) @@ -40678,13 +40864,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg16 = (frNext4 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask16 = 1ULL << reg16; + topRegistersMask16 = ((reg16 < 0) ? (((usqInt)(1)) >> (-reg16)) : (1ULL << reg16)); } if (frTop6 == NoReg) { frTop6 = allocateFloatRegNotConflictingWith(topRegistersMask16); } if (frNext4 == NoReg) { - frNext4 = allocateFloatRegNotConflictingWith(1ULL << frTop6); + frNext4 = allocateFloatRegNotConflictingWith(((frTop6 < 0) ? (((usqInt)(1)) >> (-frTop6)) : (1ULL << frTop6))); } rResult12 = allocateRegNotConflictingWith(0); assert(!(((frTop6 == NoReg) @@ -40723,13 +40909,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg17 = (rNext17 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask17 = 1ULL << reg17; + topRegistersMask17 = ((reg17 < 0) ? (((usqInt)(1)) >> (-reg17)) : (1ULL << reg17)); } if (rTop22 == NoReg) { rTop22 = allocateFloatRegNotConflictingWith(topRegistersMask17); } if (rNext17 == NoReg) { - rNext17 = allocateFloatRegNotConflictingWith(1ULL << rTop22); + rNext17 = allocateFloatRegNotConflictingWith(((rTop22 < 0) ? (((usqInt)(1)) >> (-rTop22)) : (1ULL << rTop22))); } assert(!(((rTop22 == NoReg) || (rNext17 == NoReg)))); @@ -40756,7 +40942,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (frTop7 == NoReg) { frTop7 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); } - frResult2 = allocateFloatRegNotConflictingWith(1ULL << frTop7); + frResult2 = allocateFloatRegNotConflictingWith(((frTop7 < 0) ? (((usqInt)(1)) >> (-frTop7)) : (1ULL << frTop7))); assert(!(((frTop7 == NoReg) || (frResult2 == NoReg)))); value12 = frTop7; @@ -40781,13 +40967,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg18 = (frNext5 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask18 = 1ULL << reg18; + topRegistersMask18 = ((reg18 < 0) ? (((usqInt)(1)) >> (-reg18)) : (1ULL << reg18)); } if (frTop8 == NoReg) { frTop8 = allocateFloatRegNotConflictingWith(topRegistersMask18); } if (frNext5 == NoReg) { - frNext5 = allocateFloatRegNotConflictingWith(1ULL << frTop8); + frNext5 = allocateFloatRegNotConflictingWith(((frTop8 < 0) ? (((usqInt)(1)) >> (-frTop8)) : (1ULL << frTop8))); } rResult13 = allocateRegNotConflictingWith(0); assert(!(((frTop8 == NoReg) @@ -40845,13 +41031,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg19 = (rNext18 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask20 = 1ULL << reg19; + topRegistersMask20 = ((reg19 < 0) ? (((usqInt)(1)) >> (-reg19)) : (1ULL << reg19)); } if (rTop23 == NoReg) { rTop23 = allocateFloatRegNotConflictingWith(topRegistersMask20); } if (rNext18 == NoReg) { - rNext18 = allocateFloatRegNotConflictingWith(1ULL << rTop23); + rNext18 = allocateFloatRegNotConflictingWith(((rTop23 < 0) ? (((usqInt)(1)) >> (-rTop23)) : (1ULL << rTop23))); } assert(!(((rTop23 == NoReg) || (rNext18 == NoReg)))); @@ -40987,13 +41173,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg20 = (rNext19 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask22 = 1ULL << reg20; + topRegistersMask22 = ((reg20 < 0) ? (((usqInt)(1)) >> (-reg20)) : (1ULL << reg20)); } if (rTop24 == NoReg) { rTop24 = allocateFloatRegNotConflictingWith(topRegistersMask22); } if (rNext19 == NoReg) { - rNext19 = allocateFloatRegNotConflictingWith(1ULL << rTop24); + rNext19 = allocateFloatRegNotConflictingWith(((rTop24 < 0) ? (((usqInt)(1)) >> (-rTop24)) : (1ULL << rTop24))); } assert(!(((rTop24 == NoReg) || (rNext19 == NoReg)))); @@ -41018,13 +41204,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg21 = (rNext20 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask23 = 1ULL << reg21; + topRegistersMask23 = ((reg21 < 0) ? (((usqInt)(1)) >> (-reg21)) : (1ULL << reg21)); } if (rTop25 == NoReg) { rTop25 = allocateFloatRegNotConflictingWith(topRegistersMask23); } if (rNext20 == NoReg) { - rNext20 = allocateFloatRegNotConflictingWith(1ULL << rTop25); + rNext20 = allocateFloatRegNotConflictingWith(((rTop25 < 0) ? (((usqInt)(1)) >> (-rTop25)) : (1ULL << rTop25))); } assert(!(((rTop25 == NoReg) || (rNext20 == NoReg)))); @@ -41050,13 +41236,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg22 = (frNext6 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask24 = 1ULL << reg22; + topRegistersMask24 = ((reg22 < 0) ? (((usqInt)(1)) >> (-reg22)) : (1ULL << reg22)); } if (frTop15 == NoReg) { frTop15 = allocateFloatRegNotConflictingWith(topRegistersMask24); } if (frNext6 == NoReg) { - frNext6 = allocateFloatRegNotConflictingWith(1ULL << frTop15); + frNext6 = allocateFloatRegNotConflictingWith(((frTop15 < 0) ? (((usqInt)(1)) >> (-frTop15)) : (1ULL << frTop15))); } rResult18 = allocateRegNotConflictingWith(0); assert(!(((frTop15 == NoReg) @@ -41096,13 +41282,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg23 = (frNext7 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask25 = 1ULL << reg23; + topRegistersMask25 = ((reg23 < 0) ? (((usqInt)(1)) >> (-reg23)) : (1ULL << reg23)); } if (frTop16 == NoReg) { frTop16 = allocateFloatRegNotConflictingWith(topRegistersMask25); } if (frNext7 == NoReg) { - frNext7 = allocateFloatRegNotConflictingWith(1ULL << frTop16); + frNext7 = allocateFloatRegNotConflictingWith(((frTop16 < 0) ? (((usqInt)(1)) >> (-frTop16)) : (1ULL << frTop16))); } rResult19 = allocateRegNotConflictingWith(0); assert(!(((frTop16 == NoReg) @@ -41142,13 +41328,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg24 = (frNext8 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask26 = 1ULL << reg24; + topRegistersMask26 = ((reg24 < 0) ? (((usqInt)(1)) >> (-reg24)) : (1ULL << reg24)); } if (frTop17 == NoReg) { frTop17 = allocateFloatRegNotConflictingWith(topRegistersMask26); } if (frNext8 == NoReg) { - frNext8 = allocateFloatRegNotConflictingWith(1ULL << frTop17); + frNext8 = allocateFloatRegNotConflictingWith(((frTop17 < 0) ? (((usqInt)(1)) >> (-frTop17)) : (1ULL << frTop17))); } rResult20 = allocateRegNotConflictingWith(0); assert(!(((frTop17 == NoReg) @@ -41188,13 +41374,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg25 = (frNext9 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask27 = 1ULL << reg25; + topRegistersMask27 = ((reg25 < 0) ? (((usqInt)(1)) >> (-reg25)) : (1ULL << reg25)); } if (frTop18 == NoReg) { frTop18 = allocateFloatRegNotConflictingWith(topRegistersMask27); } if (frNext9 == NoReg) { - frNext9 = allocateFloatRegNotConflictingWith(1ULL << frTop18); + frNext9 = allocateFloatRegNotConflictingWith(((frTop18 < 0) ? (((usqInt)(1)) >> (-frTop18)) : (1ULL << frTop18))); } rResult22 = allocateRegNotConflictingWith(0); assert(!(((frTop18 == NoReg) @@ -41234,13 +41420,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg26 = (frNext10 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask28 = 1ULL << reg26; + topRegistersMask28 = ((reg26 < 0) ? (((usqInt)(1)) >> (-reg26)) : (1ULL << reg26)); } if (frTop19 == NoReg) { frTop19 = allocateFloatRegNotConflictingWith(topRegistersMask28); } if (frNext10 == NoReg) { - frNext10 = allocateFloatRegNotConflictingWith(1ULL << frTop19); + frNext10 = allocateFloatRegNotConflictingWith(((frTop19 < 0) ? (((usqInt)(1)) >> (-frTop19)) : (1ULL << frTop19))); } rResult23 = allocateRegNotConflictingWith(0); assert(!(((frTop19 == NoReg) @@ -41279,13 +41465,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg27 = (rNext21 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask29 = 1ULL << reg27; + topRegistersMask29 = ((reg27 < 0) ? (((usqInt)(1)) >> (-reg27)) : (1ULL << reg27)); } if (rTop26 == NoReg) { rTop26 = allocateFloatRegNotConflictingWith(topRegistersMask29); } if (rNext21 == NoReg) { - rNext21 = allocateFloatRegNotConflictingWith(1ULL << rTop26); + rNext21 = allocateFloatRegNotConflictingWith(((rTop26 < 0) ? (((usqInt)(1)) >> (-rTop26)) : (1ULL << rTop26))); } assert(!(((rTop26 == NoReg) || (rNext21 == NoReg)))); @@ -41312,7 +41498,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (frTop20 == NoReg) { frTop20 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); } - frResult3 = allocateFloatRegNotConflictingWith(1ULL << frTop20); + frResult3 = allocateFloatRegNotConflictingWith(((frTop20 < 0) ? (((usqInt)(1)) >> (-frTop20)) : (1ULL << frTop20))); assert(!(((frTop20 == NoReg) || (frResult3 == NoReg)))); value24 = frTop20; @@ -41337,13 +41523,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg28 = (frNext11 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask30 = 1ULL << reg28; + topRegistersMask30 = ((reg28 < 0) ? (((usqInt)(1)) >> (-reg28)) : (1ULL << reg28)); } if (frTop21 == NoReg) { frTop21 = allocateFloatRegNotConflictingWith(topRegistersMask30); } if (frNext11 == NoReg) { - frNext11 = allocateFloatRegNotConflictingWith(1ULL << frTop21); + frNext11 = allocateFloatRegNotConflictingWith(((frTop21 < 0) ? (((usqInt)(1)) >> (-frTop21)) : (1ULL << frTop21))); } rResult24 = allocateRegNotConflictingWith(0); assert(!(((frTop21 == NoReg) @@ -41401,13 +41587,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg29 = (rNext22 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask32 = 1ULL << reg29; + topRegistersMask32 = ((reg29 < 0) ? (((usqInt)(1)) >> (-reg29)) : (1ULL << reg29)); } if (rTop27 == NoReg) { rTop27 = allocateFloatRegNotConflictingWith(topRegistersMask32); } if (rNext22 == NoReg) { - rNext22 = allocateFloatRegNotConflictingWith(1ULL << rTop27); + rNext22 = allocateFloatRegNotConflictingWith(((rTop27 < 0) ? (((usqInt)(1)) >> (-rTop27)) : (1ULL << rTop27))); } assert(!(((rTop27 == NoReg) || (rNext22 == NoReg)))); @@ -41875,11 +42061,11 @@ genPushMaybeContextReceiverVariable(sqInt slotIndex) AbstractInstruction *jmpSingle; /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ensureReceiverResultRegContainsSelf(); /* begin genPushMaybeContextSlotIndex: */ assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ voidReceiverResultRegContainsSelf(); @@ -41933,7 +42119,7 @@ genPushNewArrayBytecode(void) } else { /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << SendNumArgsReg)) | ((1U << ReceiverResultReg))), simStackPtr, simNativeStackPtr); } size = byte1 & 0x7F; if (!popValues) { @@ -42006,7 +42192,7 @@ genPushRemoteTempLongBytecode(void) /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperandoperand(MoveMwrR, offset, FPReg, tempVectReg); /* begin availableRegOrNoneNotConflictingWith: */ - regMask = 1ULL << tempVectReg; + regMask = ((tempVectReg < 0) ? (((usqInt)(1)) >> (-tempVectReg)) : (1ULL << tempVectReg)); remoteTempReg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); if (remoteTempReg == NoReg) { remoteTempReg = tempVectReg; @@ -42357,11 +42543,11 @@ genSpecialSelectorClass(void) || (topReg == ClassReg)) { /* begin ssAllocateRequiredReg:and: */ requiredReg1 = (topReg = SendNumArgsReg); - ssAllocateRequiredRegMaskupThroughupThroughNative((1ULL << requiredReg1) | (1U << ClassReg), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((((requiredReg1 < 0) ? (((usqInt)(1)) >> (-requiredReg1)) : (1ULL << requiredReg1))) | ((1U << ClassReg)), simStackPtr, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr, simNativeStackPtr); } ssPush(1); popToReg(ssTop(), topReg); @@ -42595,7 +42781,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean association = getLiteral(litVarIndex); voidReceiverResultRegContainsSelf(); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin genMoveConstant:R: */ if (shouldAnnotateObjectReference(association)) { annotateobjRef(checkLiteralforInstruction(association, genoperandoperand(MoveCwR, association, ReceiverResultReg)), association); @@ -42608,7 +42794,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean # if IMMUTABILITY if (needsImmCheck) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -42623,7 +42809,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -42684,7 +42870,7 @@ genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqI # endif // IMMUTABILITY ssPop(1); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ClassReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ssPush(1); genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); @@ -42730,7 +42916,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea # if IMMUTABILITY if (needsImmCheck1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -42745,7 +42931,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck1, 1); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck1); } @@ -42769,7 +42955,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt assert(needsFrame); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); /* begin MoveMw:r:R: */ offset = frameOffsetOfTemporary(remoteTempIndex); @@ -42779,7 +42965,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt # if IMMUTABILITY # endif - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -42969,13 +43155,13 @@ genVanillaInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -43274,12 +43460,12 @@ liveRegisters(void) } else { /* begin registerMaskFor: */ - regsSet = 1U << ReceiverResultReg; + regsSet = (1U << ReceiverResultReg); if ((methodOrBlockNumArgs <= 2 /* numRegArgs */) && (methodOrBlockNumArgs > 0)) { - regsSet = regsSet | (1U << Arg0Reg); + regsSet = regsSet | ((1U << Arg0Reg)); if (methodOrBlockNumArgs > 1) { - regsSet = regsSet | (1U << Arg1Reg); + regsSet = regsSet | ((1U << Arg1Reg)); } } } @@ -43388,13 +43574,13 @@ marshallSendArguments(sqInt numArgs) if (numArgs > 0) { if (numArgs > 1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 2, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 2, simNativeStackPtr); /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg1Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg1Reg), simStackPtr - 1, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 1, simNativeStackPtr); } } if (numArgs > 1) { @@ -43974,7 +44160,7 @@ ssAllocateRequiredFloatRegMaskupThroughupThroughNative(sqInt requiredRegsMask, s static void NoDbgRegParms ssAllocateRequiredFloatReg(sqInt requiredReg) { - ssAllocateRequiredFloatRegMaskupThroughupThroughNative(1ULL << requiredReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredFloatRegMaskupThroughupThroughNative(((requiredReg < 0) ? (((usqInt)(1)) >> (-requiredReg)) : (1ULL << requiredReg)), simStackPtr, simNativeStackPtr); } /* StackToRegisterMappingCogit>>#ssAllocateRequiredRegMask:upThrough:upThroughNative: */ diff --git a/spurlowcode64src/vm/cointerp.c b/spurlowcode64src/vm/cointerp.c index 048a33e955..43a8d782cd 100644 --- a/spurlowcode64src/vm/cointerp.c +++ b/spurlowcode64src/vm/cointerp.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - CoInterpreter VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CoInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 " __DATE__ ; +static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -491,6 +491,7 @@ extern sqInt ceSendabovetonumArgs(sqInt selector, sqInt methodClass, sqInt rcvr, extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern sqInt ceSistaTrap(void); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethod); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); @@ -672,7 +673,6 @@ static void primitiveExitCriticalSection(void); static void primitiveFlushCacheByMethod(void); static void primitiveFlushCacheBySelector(void); extern usqInt primitiveFunctionPointerAddress(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); EXPORT(sqInt) primitiveMethodPCData(void); static void primitiveMethodXray(void); EXPORT(void) primitiveMinimumUnusedHeadroom(void); @@ -1218,7 +1218,6 @@ static sqInt NoDbgRegParms isPureBitsFormat(sqInt format); extern sqInt isReallyYoung(sqInt oop); static sqInt NoDbgRegParms isRemembered(sqInt objOop); static sqInt NoDbgRegParms isSegmentBridge(sqInt objOop); -static sqInt NoDbgRegParms isSemaphoreOop(sqInt anOop); extern sqInt isShorts(sqInt oop); extern sqInt isUnambiguouslyForwarder(sqInt objOop); extern sqInt isUnmarked(sqInt objOop); @@ -1448,7 +1447,6 @@ EXPORT(sqInt) callbackLeave(sqInt cbID); extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHeader); extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkForEventsMayContextSwitch(sqInt mayContextSwitch); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); @@ -1735,7 +1733,6 @@ static sqInt NoDbgRegParms updateDisplayLeftTopRightBottom(sqInt l, sqInt t, sqI static sqInt NoDbgRegParms validBCPCinMethod(sqInt thePC, usqInt aMethod); static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, char *fp); static sqInt validStackPageBaseFrames(void); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt wakeHighestPriority(void); static sqInt NeverInline writeImageFileIO(void); static usqInt NoDbgRegParms cloneContext(sqInt aContext); @@ -1758,7 +1755,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1835,15 +1831,14 @@ _iss usqInt lastMobileObject; _iss sqInt tempOop; _iss sqInt numClassTablePages; _iss sqInt lkupClass; -_iss sqInt futureSurvivorStart; _iss sqInt profileProcess; -_iss sqInt profileSemaphore; +_iss sqInt futureSurvivorStart; _iss sqInt mournQueue; _iss sqInt numRememberedEphemerons; +_iss sqInt profileMethod; _iss sqInt jmpDepth; _iss sqInt mobileStart; -_iss sqInt profileMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; +_iss sqInt profileSemaphore; _iss sqInt growHeadroom; _iss sqInt tenureThreshold; _iss sqInt lastCoggableInterpretedBlockMethod; @@ -1851,7 +1846,6 @@ _iss sqInt lastUncoggableInterpretedBlockMethod; _iss char * objStackInvalidBecause; _iss sqInt sweepIndex; _iss sqInt ephemeronList; -_iss sqInt longRunningPrimitiveCheckMethod; _iss sqInt tenureCriterion; _iss usqInt totalHeapSizeIncludingBridges; _iss sqInt becomeEffectsFlags; @@ -1875,19 +1869,15 @@ _iss sqInt gcMode; _iss sqInt highestRunnableProcessPriority; _iss sqInt metaclassNumSlots; _iss usqLong nextWakeupUsecs; -_iss usqLong statGCEndUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; _iss sqInt shrinkThreshold; -_iss usqLong statCheckForEvents; _iss sqInt statTenures; _iss sqInt weakList; _iss usqInt cogCodeSize; -_iss usqLong gcStartUsecs; _iss sqInt marking; _iss sqLong oldSpaceUsePriorToScavenge; _iss sqInt preemptionYields; _iss sqInt rememberedSetLimit; +_iss usqLong statGCEndUsecs; _iss sqInt statSurvivorCount; _iss sqInt thisClassIndex; _iss sqInt externalPrimitiveTableFirstFreeIndex; @@ -1902,6 +1892,7 @@ _iss sqInt statShrinkMemory; _iss sqInt biasForGC; _iss sqInt edenBytes; _iss sqInt fullScreenFlag; +_iss usqLong gcStartUsecs; _iss usqInt lastHash; _iss sqInt lastMethodCacheProbeWrite; _iss sqInt newFinalization; @@ -1916,10 +1907,10 @@ _iss sqInt freeSpaceCheckOopToIgnore; _iss usqInt heapSizeAtPreviousGC; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss sqInt methodDictLinearSearchLimit; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statCompactionUsecs; _iss usqLong statForceInterruptCheck; _iss usqLong statFullGCUsecs; @@ -1940,7 +1931,6 @@ _iss sqInt extraFramesToMoveOnOverflow; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; _iss sqInt inFFIFlags; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss sqInt refCountToShrinkRT; _iss sqInt signalLowSpace; @@ -1954,7 +1944,6 @@ _iss sqInt classByteArrayCompactIndex; _iss usqInt exceptionPC; _iss sqInt gcSemaphoreIndex; _iss usqLong gcSweepEndUsecs; -_iss usqLong longRunningPrimitiveGCUsecs; _iss sqInt overflowLimit; _iss StackPage * overflowedPage; _iss sqInt statCompactPassCount; @@ -1972,6 +1961,9 @@ _iss usqInt suspendedCallbacks[MaxJumpBuf + 1 /* 33 */]; _iss usqInt suspendedMethods[MaxJumpBuf + 1 /* 33 */]; _iss jmp_buf jmpBuf[MaxJumpBuf + 1 /* 33 */]; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; _iss sqInt preferredPinningSegment; _iss sqInt statCoalesces; _iss usqLong statFGCDeltaUsecs; @@ -2648,7 +2640,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Open Smalltalk Cog[Spur] VM [CoInterpreterPrimitives VMMaker.oscog-eem.3024]"; +const char *interpreterVersion = "Open Smalltalk Cog[Spur] VM [CoInterpreterPrimitives VMMaker.oscog-eem.3031]"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */; int displayWidth; int displayDepth; @@ -35100,6 +35092,27 @@ ceStackOverflow(sqInt contextSwitchIfNotNil) error("should not be reached"); } + +/* A primitive has succeeded and the nextProfileTick has been reached (all + done in machine code). + Now take a sample. c.f. checkProfileTick: */ + + /* CoInterpreter>>#ceTakeProfileSample: */ +void +ceTakeProfileSample(CogMethod *aCogMethod) +{ DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt objOop; + sqInt objOop1; + + /* begin fetchPointer:ofObject: */ + objOop1 = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(SchedulerAssociation) << (shiftForWord()))))); + objOop = longAt((objOop1 + BaseHeaderSize) + (((sqInt)((usqInt)(ValueIndex) << (shiftForWord()))))); + GIV(profileProcess) = longAt((objOop + BaseHeaderSize) + (((sqInt)((usqInt)(ActiveProcessIndex) << (shiftForWord()))))); + GIV(profileMethod) = (aCogMethod->methodObject); + forceInterruptCheck(); + GIV(nextProfileTick) = 0; +} + /* CoInterpreter>>#ceTraceBlockActivation */ void ceTraceBlockActivation(void) @@ -37096,24 +37109,6 @@ void forceInterruptCheckFromHeartbeat(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; sqLowLevelMFence(); if (GIV(deferSmash)) { GIV(deferredSmash) = 1; @@ -40065,7 +40060,7 @@ printFrameWithSP(char *theFP, char *theSP) usqInt index; sqInt methodField; usqInt numArgs; - sqInt numTemps; + usqInt numTemps; char *rcvrAddress; sqInt rcvrOrClosure; CogBlockMethod * self_in_cmHomeMethod; @@ -43428,56 +43423,6 @@ primitiveFunctionPointerAddress(void) return ((usqInt)((&primitiveFunctionPointer))); } - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* CoInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; - int flushState; - sqInt sema; - char *sp; - - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (sema == GIV(nilObj)) { - flushState = GIV(longRunningPrimitiveCheckSemaphore) != null; - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - flushState = GIV(longRunningPrimitiveCheckSemaphore) == null; - if (!(((!(sema & (tagMask())))) - && (((longAt(sema)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(ClassSemaphore) << (shiftForWord())))))))))) { - return (GIV(primFailCode) = PrimErrBadArgument); - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(longRunningPrimitiveCheckSemaphore) == null)) - || (((stackValue(0)) == GIV(longRunningPrimitiveCheckSemaphore)) - && (isSemaphoreOop(sema)))); - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - if (flushState) { - ceInvokeInterpret(); - } - return 0; -} - /* CoInterpreterPrimitives>>#primitiveMethodPCData */ EXPORT(sqInt) primitiveMethodPCData(void) @@ -43790,14 +43735,9 @@ primitiveObjectAtPut(void) EXPORT(sqInt) primitiveProfileSemaphore(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; int flushState; sqInt sema; - char *sp; - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); if (sema == GIV(nilObj)) { flushState = GIV(profileSemaphore) != GIV(nilObj); @@ -43809,28 +43749,21 @@ primitiveProfileSemaphore(void) return (GIV(primFailCode) = PrimErrBadArgument); } } + GIV(profileSemaphore) = sema; /* If we've switched profiling on or off we must void machine code (and machine code pcs in contexts) since we will start or stop testing the profile clock in machine code primitive invocations, and so generate slightly different code from here on in. */ - GIV(profileSemaphore) = sema; - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(profileSemaphore) == (nilObject()))) - || (((stackValue(0)) == GIV(profileSemaphore)) - && (isSemaphoreOop(sema)))); - } GIV(profileProcess) = (GIV(profileMethod) = GIV(nilObj)); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; if (flushState) { - ceInvokeInterpret(); + flushExternalPrimitives(); + } + else { + /* begin methodReturnReceiver */ + assert(!((failed()))); + /* begin pop: */ + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; } return 0; } @@ -52232,26 +52165,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -52976,7 +52911,7 @@ primitiveInvokeObjectAsMethod(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt i; sqInt lookupClassTag; - usqInt runArgs; + sqInt runArgs; sqInt runReceiver; char *sp; char *sp1; @@ -54892,15 +54827,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -54918,15 +54848,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -54950,39 +54875,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((((integerPointer) & 7) == 1)) { - deltaTicks = (integerPointer >> 3); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((((deltaTicks) & 7) == 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 3)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -70358,14 +70262,6 @@ isSegmentBridge(sqInt objOop) return ((longAt(objOop)) & (classIndexMask())) == (segmentBridgePun()); } - /* SpurMemoryManager>>#isSemaphoreOop: */ -static sqInt NoDbgRegParms -isSemaphoreOop(sqInt anOop) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - return ((!(anOop & (tagMask())))) - && (((longAt(anOop)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(ClassSemaphore) << (shiftForWord())))))))); -} - /* Answer if the argument contains only indexable 16-bit half words (no oops). See comment in formatOf: @@ -72645,8 +72541,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) sqInt referent; sqInt referent1; sqInt referent2; - sqInt referent3; - sqInt referent4; sqInt sizeOfUnusedEden; StackPage *thePage; @@ -72785,38 +72679,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - if ((!((longAt(GIV(longRunningPrimitiveCheckMethod))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckMethod))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((GIV(longRunningPrimitiveCheckMethod) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent3 & (tagMask())))) - && ((!((longAt(referent3)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((referent3 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckMethod) = referent3; - } - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - if ((!((longAt(GIV(longRunningPrimitiveCheckSemaphore))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckSemaphore))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((GIV(longRunningPrimitiveCheckSemaphore) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent4 & (tagMask())))) - && ((!((longAt(referent4)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((referent4 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckSemaphore) = referent4; - } - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -80329,7 +80191,7 @@ updatePointersInsavedFirstFieldPointer(sqInt obj, sqInt firstFieldPtr) assert((ReceiverIndex + ((sp >> 3))) < (lengthOf(obj))); contextSize = (sp >> 3); l6: /* end fetchStackPointerOf: */; - numPointerSlots = ((usqInt) (CtxtTempFrameStart + contextSize)); + numPointerSlots = CtxtTempFrameStart + contextSize; goto l10; } /* begin numSlotsOf: */ @@ -80359,7 +80221,7 @@ updatePointersInsavedFirstFieldPointer(sqInt obj, sqInt firstFieldPtr) /* begin literalCountOfMethodHeader: */ assert((((header) & 7) == 1)); numLiterals = ((header >> 3)) & AlternateHeaderNumLiteralsMask; - numPointerSlots = ((usqInt) (numLiterals + LiteralStart)); + numPointerSlots = numLiterals + LiteralStart; l10: /* end numPointerSlotsWhileCompactingOf:withFormat:savedFirstFieldPointer: */; if ((fmt <= 5 /* lastPointerFormat */) && (numPointerSlots > 0)) { @@ -81741,33 +81603,6 @@ checkAllAccessibleObjectsOkay(void) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -81858,9 +81693,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { /* begin signalLowSpace: */ GIV(signalLowSpace) = 0; @@ -84609,8 +84441,8 @@ static sqInt getErrorObjectFromPrimFailCode(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt classIndex; - sqInt clone; - sqInt errObj; + usqInt clone; + usqInt errObj; sqInt fieldIndex; sqInt i; usqInt newObj; @@ -86932,23 +86764,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i = 1; i <= GIV(jmpDepth); i += 1) { oop = GIV(suspendedCallbacks)[i]; @@ -91037,8 +90852,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -91067,18 +90882,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -94252,22 +94069,6 @@ validStackPageBaseFrames(void) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Return the highest priority process that is ready to run. To save time looking at many empty lists before finding a runnable process the VM maintains a variable holding the @@ -96778,74 +96579,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((addressCouldBeObj(lrpcm)) - && ((!(((longAt(lrpcm)) & (classIndexMask())) == (isFreeObjectClassIndexPun()))) - && (((((usqInt)((longAt(lrpcm)))) >> (formatShift())) & (formatMask())) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - assert(!(isForwarded(result))); - if ((assert(isNonImmediate(result)), - oopisGreaterThanOrEqualTo(result, GIV(oldSpaceStart)))) { - - /* most stores into young objects */ - if (((!(lrpcm & (tagMask())))) - && (oopisLessThan(lrpcm, GIV(newSpaceLimit)))) { - /* begin possibleRootStoreInto: */ - if (!(((((usqInt)((longAt(result)))) >> (rememberedBitShift())) & 1) != 0)) { - remember(result); - } - } - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 3) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 3) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -99318,15 +99051,13 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveGreaterOrEqualLargeIntegers\000\377\000", (void*)primitiveGreaterOrEqualLargeIntegers}, {(void*)_m, "primitiveGreaterThanLargeIntegers\000\377\000", (void*)primitiveGreaterThanLargeIntegers}, {(void*)_m, "primitiveHeartbeatFrequency\000\377\000", (void*)primitiveHeartbeatFrequency}, - {(void*)_m, "primitiveHighResClock\000\377\000", (void*)primitiveHighResClock}, + {(void*)_m, "primitiveHighResClock\000\377\001", (void*)primitiveHighResClock}, {(void*)_m, "primitiveImageFormatVersion\000\377\000", (void*)primitiveImageFormatVersion}, {(void*)_m, "primitiveInterruptChecksPerMSec\000\377\000", (void*)primitiveInterruptChecksPerMSec}, {(void*)_m, "primitiveIsBigEnder\000\377\000", (void*)primitiveIsBigEnder}, {(void*)_m, "primitiveIsWindowObscured\000\377\000", (void*)primitiveIsWindowObscured}, {(void*)_m, "primitiveLessOrEqualLargeIntegers\000\377\000", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers\000\377\000", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive\000\377\000", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore\000\000\000", (void*)primitiveLongRunningPrimitiveSemaphore}, {(void*)_m, "primitiveMethodPCData\000\000\000", (void*)primitiveMethodPCData}, {(void*)_m, "primitiveMillisecondClockMask\000\377\000", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveMinimumUnusedHeadroom\000\377\000", (void*)primitiveMinimumUnusedHeadroom}, @@ -99334,10 +99065,10 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveMultiplyLargeIntegers\000\000\000", (void*)primitiveMultiplyLargeIntegers}, {(void*)_m, "primitiveNotEqualLargeIntegers\000\377\000", (void*)primitiveNotEqualLargeIntegers}, {(void*)_m, "primitivePathToUsing\000\000\000", (void*)primitivePathToUsing}, - {(void*)_m, "primitiveProfilePrimitive\000\377\000", (void*)primitiveProfilePrimitive}, - {(void*)_m, "primitiveProfileSample\000\377\000", (void*)primitiveProfileSample}, + {(void*)_m, "primitiveProfilePrimitive\000\377\001", (void*)primitiveProfilePrimitive}, + {(void*)_m, "primitiveProfileSample\000\377\001", (void*)primitiveProfileSample}, {(void*)_m, "primitiveProfileSemaphore\000\000\000", (void*)primitiveProfileSemaphore}, - {(void*)_m, "primitiveProfileStart\000\000\000", (void*)primitiveProfileStart}, + {(void*)_m, "primitiveProfileStart\000\000\001", (void*)primitiveProfileStart}, {(void*)_m, "primitiveQuoLargeIntegers\000\000\000", (void*)primitiveQuoLargeIntegers}, {(void*)_m, "primitiveRemLargeIntegers\000\000\000", (void*)primitiveRemLargeIntegers}, {(void*)_m, "primitiveScreenDepth\000\377\000", (void*)primitiveScreenDepth}, diff --git a/spurlowcode64src/vm/cointerp.h b/spurlowcode64src/vm/cointerp.h index d71d10315b..921a9e29b3 100644 --- a/spurlowcode64src/vm/cointerp.h +++ b/spurlowcode64src/vm/cointerp.h @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ @@ -50,6 +50,7 @@ extern sqInt ceSendabovetonumArgs(sqInt selector, sqInt methodClass, sqInt rcvr, extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern sqInt ceSistaTrap(void); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethod); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); diff --git a/spurlowcode64src/vm/gcc3x-cointerp.c b/spurlowcode64src/vm/gcc3x-cointerp.c index 86052bbca8..be1c2e3872 100644 --- a/spurlowcode64src/vm/gcc3x-cointerp.c +++ b/spurlowcode64src/vm/gcc3x-cointerp.c @@ -2,11 +2,11 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - CoInterpreter VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CoInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 " __DATE__ ; +static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -494,6 +494,7 @@ extern sqInt ceSendabovetonumArgs(sqInt selector, sqInt methodClass, sqInt rcvr, extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern sqInt ceSistaTrap(void); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethod); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); @@ -675,7 +676,6 @@ static void primitiveExitCriticalSection(void); static void primitiveFlushCacheByMethod(void); static void primitiveFlushCacheBySelector(void); extern usqInt primitiveFunctionPointerAddress(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); EXPORT(sqInt) primitiveMethodPCData(void); static void primitiveMethodXray(void); EXPORT(void) primitiveMinimumUnusedHeadroom(void); @@ -1221,7 +1221,6 @@ static sqInt NoDbgRegParms isPureBitsFormat(sqInt format); extern sqInt isReallyYoung(sqInt oop); static sqInt NoDbgRegParms isRemembered(sqInt objOop); static sqInt NoDbgRegParms isSegmentBridge(sqInt objOop); -static sqInt NoDbgRegParms isSemaphoreOop(sqInt anOop); extern sqInt isShorts(sqInt oop); extern sqInt isUnambiguouslyForwarder(sqInt objOop); extern sqInt isUnmarked(sqInt objOop); @@ -1451,7 +1450,6 @@ EXPORT(sqInt) callbackLeave(sqInt cbID); extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHeader); extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkForEventsMayContextSwitch(sqInt mayContextSwitch); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); @@ -1738,7 +1736,6 @@ static sqInt NoDbgRegParms updateDisplayLeftTopRightBottom(sqInt l, sqInt t, sqI static sqInt NoDbgRegParms validBCPCinMethod(sqInt thePC, usqInt aMethod); static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, char *fp); static sqInt validStackPageBaseFrames(void); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt wakeHighestPriority(void); static sqInt NeverInline writeImageFileIO(void); static usqInt NoDbgRegParms cloneContext(sqInt aContext); @@ -1761,7 +1758,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1838,15 +1834,14 @@ _iss usqInt lastMobileObject; _iss sqInt tempOop; _iss sqInt numClassTablePages; _iss sqInt lkupClass; -_iss sqInt futureSurvivorStart; _iss sqInt profileProcess; -_iss sqInt profileSemaphore; +_iss sqInt futureSurvivorStart; _iss sqInt mournQueue; _iss sqInt numRememberedEphemerons; +_iss sqInt profileMethod; _iss sqInt jmpDepth; _iss sqInt mobileStart; -_iss sqInt profileMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; +_iss sqInt profileSemaphore; _iss sqInt growHeadroom; _iss sqInt tenureThreshold; _iss sqInt lastCoggableInterpretedBlockMethod; @@ -1854,7 +1849,6 @@ _iss sqInt lastUncoggableInterpretedBlockMethod; _iss char * objStackInvalidBecause; _iss sqInt sweepIndex; _iss sqInt ephemeronList; -_iss sqInt longRunningPrimitiveCheckMethod; _iss sqInt tenureCriterion; _iss usqInt totalHeapSizeIncludingBridges; _iss sqInt becomeEffectsFlags; @@ -1878,19 +1872,15 @@ _iss sqInt gcMode; _iss sqInt highestRunnableProcessPriority; _iss sqInt metaclassNumSlots; _iss usqLong nextWakeupUsecs; -_iss usqLong statGCEndUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; _iss sqInt shrinkThreshold; -_iss usqLong statCheckForEvents; _iss sqInt statTenures; _iss sqInt weakList; _iss usqInt cogCodeSize; -_iss usqLong gcStartUsecs; _iss sqInt marking; _iss sqLong oldSpaceUsePriorToScavenge; _iss sqInt preemptionYields; _iss sqInt rememberedSetLimit; +_iss usqLong statGCEndUsecs; _iss sqInt statSurvivorCount; _iss sqInt thisClassIndex; _iss sqInt externalPrimitiveTableFirstFreeIndex; @@ -1905,6 +1895,7 @@ _iss sqInt statShrinkMemory; _iss sqInt biasForGC; _iss sqInt edenBytes; _iss sqInt fullScreenFlag; +_iss usqLong gcStartUsecs; _iss usqInt lastHash; _iss sqInt lastMethodCacheProbeWrite; _iss sqInt newFinalization; @@ -1919,10 +1910,10 @@ _iss sqInt freeSpaceCheckOopToIgnore; _iss usqInt heapSizeAtPreviousGC; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss sqInt methodDictLinearSearchLimit; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statCompactionUsecs; _iss usqLong statForceInterruptCheck; _iss usqLong statFullGCUsecs; @@ -1943,7 +1934,6 @@ _iss sqInt extraFramesToMoveOnOverflow; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; _iss sqInt inFFIFlags; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss sqInt refCountToShrinkRT; _iss sqInt signalLowSpace; @@ -1957,7 +1947,6 @@ _iss sqInt classByteArrayCompactIndex; _iss usqInt exceptionPC; _iss sqInt gcSemaphoreIndex; _iss usqLong gcSweepEndUsecs; -_iss usqLong longRunningPrimitiveGCUsecs; _iss sqInt overflowLimit; _iss StackPage * overflowedPage; _iss sqInt statCompactPassCount; @@ -1975,6 +1964,9 @@ _iss usqInt suspendedCallbacks[MaxJumpBuf + 1 /* 33 */]; _iss usqInt suspendedMethods[MaxJumpBuf + 1 /* 33 */]; _iss jmp_buf jmpBuf[MaxJumpBuf + 1 /* 33 */]; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; _iss sqInt preferredPinningSegment; _iss sqInt statCoalesces; _iss usqLong statFGCDeltaUsecs; @@ -2651,7 +2643,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Open Smalltalk Cog[Spur] VM [CoInterpreterPrimitives VMMaker.oscog-eem.3024]"; +const char *interpreterVersion = "Open Smalltalk Cog[Spur] VM [CoInterpreterPrimitives VMMaker.oscog-eem.3031]"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */; int displayWidth; int displayDepth; @@ -35109,6 +35101,27 @@ ceStackOverflow(sqInt contextSwitchIfNotNil) error("should not be reached"); } + +/* A primitive has succeeded and the nextProfileTick has been reached (all + done in machine code). + Now take a sample. c.f. checkProfileTick: */ + + /* CoInterpreter>>#ceTakeProfileSample: */ +void +ceTakeProfileSample(CogMethod *aCogMethod) +{ DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt objOop; + sqInt objOop1; + + /* begin fetchPointer:ofObject: */ + objOop1 = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(SchedulerAssociation) << (shiftForWord()))))); + objOop = longAt((objOop1 + BaseHeaderSize) + (((sqInt)((usqInt)(ValueIndex) << (shiftForWord()))))); + GIV(profileProcess) = longAt((objOop + BaseHeaderSize) + (((sqInt)((usqInt)(ActiveProcessIndex) << (shiftForWord()))))); + GIV(profileMethod) = (aCogMethod->methodObject); + forceInterruptCheck(); + GIV(nextProfileTick) = 0; +} + /* CoInterpreter>>#ceTraceBlockActivation */ void ceTraceBlockActivation(void) @@ -37105,24 +37118,6 @@ void forceInterruptCheckFromHeartbeat(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; sqLowLevelMFence(); if (GIV(deferSmash)) { GIV(deferredSmash) = 1; @@ -40074,7 +40069,7 @@ printFrameWithSP(char *theFP, char *theSP) usqInt index; sqInt methodField; usqInt numArgs; - sqInt numTemps; + usqInt numTemps; char *rcvrAddress; sqInt rcvrOrClosure; CogBlockMethod * self_in_cmHomeMethod; @@ -43437,56 +43432,6 @@ primitiveFunctionPointerAddress(void) return ((usqInt)((&primitiveFunctionPointer))); } - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* CoInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; - int flushState; - sqInt sema; - char *sp; - - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (sema == GIV(nilObj)) { - flushState = GIV(longRunningPrimitiveCheckSemaphore) != null; - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - flushState = GIV(longRunningPrimitiveCheckSemaphore) == null; - if (!(((!(sema & (tagMask())))) - && (((longAt(sema)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(ClassSemaphore) << (shiftForWord())))))))))) { - return (GIV(primFailCode) = PrimErrBadArgument); - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(longRunningPrimitiveCheckSemaphore) == null)) - || (((stackValue(0)) == GIV(longRunningPrimitiveCheckSemaphore)) - && (isSemaphoreOop(sema)))); - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - if (flushState) { - ceInvokeInterpret(); - } - return 0; -} - /* CoInterpreterPrimitives>>#primitiveMethodPCData */ EXPORT(sqInt) primitiveMethodPCData(void) @@ -43799,14 +43744,9 @@ primitiveObjectAtPut(void) EXPORT(sqInt) primitiveProfileSemaphore(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; int flushState; sqInt sema; - char *sp; - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); if (sema == GIV(nilObj)) { flushState = GIV(profileSemaphore) != GIV(nilObj); @@ -43818,28 +43758,21 @@ primitiveProfileSemaphore(void) return (GIV(primFailCode) = PrimErrBadArgument); } } + GIV(profileSemaphore) = sema; /* If we've switched profiling on or off we must void machine code (and machine code pcs in contexts) since we will start or stop testing the profile clock in machine code primitive invocations, and so generate slightly different code from here on in. */ - GIV(profileSemaphore) = sema; - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(profileSemaphore) == (nilObject()))) - || (((stackValue(0)) == GIV(profileSemaphore)) - && (isSemaphoreOop(sema)))); - } GIV(profileProcess) = (GIV(profileMethod) = GIV(nilObj)); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; if (flushState) { - ceInvokeInterpret(); + flushExternalPrimitives(); + } + else { + /* begin methodReturnReceiver */ + assert(!((failed()))); + /* begin pop: */ + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; } return 0; } @@ -52241,26 +52174,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -52985,7 +52920,7 @@ primitiveInvokeObjectAsMethod(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt i; sqInt lookupClassTag; - usqInt runArgs; + sqInt runArgs; sqInt runReceiver; char *sp; char *sp1; @@ -54901,15 +54836,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -54927,15 +54857,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -54959,39 +54884,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((((integerPointer) & 7) == 1)) { - deltaTicks = (integerPointer >> 3); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((((deltaTicks) & 7) == 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 3)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -70367,14 +70271,6 @@ isSegmentBridge(sqInt objOop) return ((longAt(objOop)) & (classIndexMask())) == (segmentBridgePun()); } - /* SpurMemoryManager>>#isSemaphoreOop: */ -static sqInt NoDbgRegParms -isSemaphoreOop(sqInt anOop) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - return ((!(anOop & (tagMask())))) - && (((longAt(anOop)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(ClassSemaphore) << (shiftForWord())))))))); -} - /* Answer if the argument contains only indexable 16-bit half words (no oops). See comment in formatOf: @@ -72654,8 +72550,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) sqInt referent; sqInt referent1; sqInt referent2; - sqInt referent3; - sqInt referent4; sqInt sizeOfUnusedEden; StackPage *thePage; @@ -72794,38 +72688,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - if ((!((longAt(GIV(longRunningPrimitiveCheckMethod))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckMethod))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((GIV(longRunningPrimitiveCheckMethod) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent3 & (tagMask())))) - && ((!((longAt(referent3)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((referent3 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckMethod) = referent3; - } - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - if ((!((longAt(GIV(longRunningPrimitiveCheckSemaphore))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckSemaphore))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((GIV(longRunningPrimitiveCheckSemaphore) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent4 & (tagMask())))) - && ((!((longAt(referent4)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((referent4 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckSemaphore) = referent4; - } - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -80338,7 +80200,7 @@ updatePointersInsavedFirstFieldPointer(sqInt obj, sqInt firstFieldPtr) assert((ReceiverIndex + ((sp >> 3))) < (lengthOf(obj))); contextSize = (sp >> 3); l6: /* end fetchStackPointerOf: */; - numPointerSlots = ((usqInt) (CtxtTempFrameStart + contextSize)); + numPointerSlots = CtxtTempFrameStart + contextSize; goto l10; } /* begin numSlotsOf: */ @@ -80368,7 +80230,7 @@ updatePointersInsavedFirstFieldPointer(sqInt obj, sqInt firstFieldPtr) /* begin literalCountOfMethodHeader: */ assert((((header) & 7) == 1)); numLiterals = ((header >> 3)) & AlternateHeaderNumLiteralsMask; - numPointerSlots = ((usqInt) (numLiterals + LiteralStart)); + numPointerSlots = numLiterals + LiteralStart; l10: /* end numPointerSlotsWhileCompactingOf:withFormat:savedFirstFieldPointer: */; if ((fmt <= 5 /* lastPointerFormat */) && (numPointerSlots > 0)) { @@ -81750,33 +81612,6 @@ checkAllAccessibleObjectsOkay(void) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -81867,9 +81702,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { /* begin signalLowSpace: */ GIV(signalLowSpace) = 0; @@ -84618,8 +84450,8 @@ static sqInt getErrorObjectFromPrimFailCode(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt classIndex; - sqInt clone; - sqInt errObj; + usqInt clone; + usqInt errObj; sqInt fieldIndex; sqInt i; usqInt newObj; @@ -86941,23 +86773,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i = 1; i <= GIV(jmpDepth); i += 1) { oop = GIV(suspendedCallbacks)[i]; @@ -91046,8 +90861,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -91076,18 +90891,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -94261,22 +94078,6 @@ validStackPageBaseFrames(void) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Return the highest priority process that is ready to run. To save time looking at many empty lists before finding a runnable process the VM maintains a variable holding the @@ -96787,74 +96588,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((addressCouldBeObj(lrpcm)) - && ((!(((longAt(lrpcm)) & (classIndexMask())) == (isFreeObjectClassIndexPun()))) - && (((((usqInt)((longAt(lrpcm)))) >> (formatShift())) & (formatMask())) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - assert(!(isForwarded(result))); - if ((assert(isNonImmediate(result)), - oopisGreaterThanOrEqualTo(result, GIV(oldSpaceStart)))) { - - /* most stores into young objects */ - if (((!(lrpcm & (tagMask())))) - && (oopisLessThan(lrpcm, GIV(newSpaceLimit)))) { - /* begin possibleRootStoreInto: */ - if (!(((((usqInt)((longAt(result)))) >> (rememberedBitShift())) & 1) != 0)) { - remember(result); - } - } - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 3) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 3) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -99327,15 +99060,13 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveGreaterOrEqualLargeIntegers\000\377\000", (void*)primitiveGreaterOrEqualLargeIntegers}, {(void*)_m, "primitiveGreaterThanLargeIntegers\000\377\000", (void*)primitiveGreaterThanLargeIntegers}, {(void*)_m, "primitiveHeartbeatFrequency\000\377\000", (void*)primitiveHeartbeatFrequency}, - {(void*)_m, "primitiveHighResClock\000\377\000", (void*)primitiveHighResClock}, + {(void*)_m, "primitiveHighResClock\000\377\001", (void*)primitiveHighResClock}, {(void*)_m, "primitiveImageFormatVersion\000\377\000", (void*)primitiveImageFormatVersion}, {(void*)_m, "primitiveInterruptChecksPerMSec\000\377\000", (void*)primitiveInterruptChecksPerMSec}, {(void*)_m, "primitiveIsBigEnder\000\377\000", (void*)primitiveIsBigEnder}, {(void*)_m, "primitiveIsWindowObscured\000\377\000", (void*)primitiveIsWindowObscured}, {(void*)_m, "primitiveLessOrEqualLargeIntegers\000\377\000", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers\000\377\000", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive\000\377\000", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore\000\000\000", (void*)primitiveLongRunningPrimitiveSemaphore}, {(void*)_m, "primitiveMethodPCData\000\000\000", (void*)primitiveMethodPCData}, {(void*)_m, "primitiveMillisecondClockMask\000\377\000", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveMinimumUnusedHeadroom\000\377\000", (void*)primitiveMinimumUnusedHeadroom}, @@ -99343,10 +99074,10 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveMultiplyLargeIntegers\000\000\000", (void*)primitiveMultiplyLargeIntegers}, {(void*)_m, "primitiveNotEqualLargeIntegers\000\377\000", (void*)primitiveNotEqualLargeIntegers}, {(void*)_m, "primitivePathToUsing\000\000\000", (void*)primitivePathToUsing}, - {(void*)_m, "primitiveProfilePrimitive\000\377\000", (void*)primitiveProfilePrimitive}, - {(void*)_m, "primitiveProfileSample\000\377\000", (void*)primitiveProfileSample}, + {(void*)_m, "primitiveProfilePrimitive\000\377\001", (void*)primitiveProfilePrimitive}, + {(void*)_m, "primitiveProfileSample\000\377\001", (void*)primitiveProfileSample}, {(void*)_m, "primitiveProfileSemaphore\000\000\000", (void*)primitiveProfileSemaphore}, - {(void*)_m, "primitiveProfileStart\000\000\000", (void*)primitiveProfileStart}, + {(void*)_m, "primitiveProfileStart\000\000\001", (void*)primitiveProfileStart}, {(void*)_m, "primitiveQuoLargeIntegers\000\000\000", (void*)primitiveQuoLargeIntegers}, {(void*)_m, "primitiveRemLargeIntegers\000\000\000", (void*)primitiveRemLargeIntegers}, {(void*)_m, "primitiveScreenDepth\000\377\000", (void*)primitiveScreenDepth}, diff --git a/spurlowcodesrc/vm/cogit.c b/spurlowcodesrc/vm/cogit.c index 3a448a3c69..8d71e53f42 100644 --- a/spurlowcodesrc/vm/cogit.c +++ b/spurlowcodesrc/vm/cogit.c @@ -1,5 +1,5 @@ /* Automatically generated by - Cogit VMMaker.oscog-eem.2537 uuid: 0518f049-7c3c-4dfa-8e2d-04e2cf2eee40 + Cogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ #if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7__) || defined(__arm__) || defined(__arm32__) || defined(ARM32) || defined(_M_ARM) @@ -10,10 +10,6 @@ # include "cogitIA32.c" -#elif defined(__MIPSEL__) - -# include "cogitMIPSEL.c" - #else # error As yet no Cogit implementation appears to exist for your platform. # error Consider implementing it, starting by adding a subclass of CogAbstractInstruction. diff --git a/spurlowcodesrc/vm/cogit.h b/spurlowcodesrc/vm/cogit.h index 1959c1e7fe..a22e8c6922 100644 --- a/spurlowcodesrc/vm/cogit.h +++ b/spurlowcodesrc/vm/cogit.h @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + CCodeGenerator VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ diff --git a/spurlowcodesrc/vm/cogitARMv5.c b/spurlowcodesrc/vm/cogitARMv5.c index 44deb12715..5c511ceee9 100644 --- a/spurlowcodesrc/vm/cogitARMv5.c +++ b/spurlowcodesrc/vm/cogitARMv5.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + CCodeGenerator VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + StackToRegisterMappingCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 " __DATE__ ; +static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__cogitBuildInfo = __buildInfo; @@ -96,7 +96,7 @@ char *__cogitBuildInfo = __buildInfo; #define CMMaxUsageCount 7 #define CMMethod 2 #define CMOpenPIC 5 -#define CMPSMULL 165 +#define CMPSMULL 167 #define CmpC32R 113 #define CmpCqR 105 #define CmpCwR 112 @@ -258,6 +258,8 @@ char *__cogitBuildInfo = __buildInfo; #define MoveMwrR 50 #define MoveNotOpcode 15 #define MoveOpcode 13 +#define MovePerfCnt64RL 159 +#define MovePerfCnt64RRL 158 #define MoveRAb 49 #define MoveRAw 46 #define MoveRdM64r 76 @@ -274,7 +276,7 @@ char *__cogitBuildInfo = __buildInfo; #define MoveRXwrR 53 #define MoveXbrRR 67 #define MoveXwrRR 52 -#define MSR 159 +#define MSR 161 #define MULTIPLEBYTECODESETS 1 #define MulRdRd 134 #define MulRsRs 141 @@ -305,7 +307,7 @@ char *__cogitBuildInfo = __buildInfo; #define PC 15 #define PCReg 15 #define PL 5 -#define PopLDM 161 +#define PopLDM 163 #define PopR 80 #define PrefetchAw 87 #define PrimCallCollectsProfileSamples 8 @@ -322,7 +324,7 @@ char *__cogitBuildInfo = __buildInfo; #define PushCq 82 #define PushCw 83 #define PushR 81 -#define PushSTM 162 +#define PushSTM 164 #define ReceiverIndex 5 #define ReceiverResultReg 5 #define RetN 9 @@ -338,7 +340,7 @@ char *__cogitBuildInfo = __buildInfo; #define SignExtend8RR 151 #define SistaV1BytecodeSet 1 #define SistaVM 1 -#define SMULL 158 +#define SMULL 160 #define SmallContextSlots 22 #define SP 13 #define SPReg 13 @@ -530,7 +532,7 @@ static void NoDbgRegParms cloneLiteralFrom(AbstractInstruction * self_in_cloneLi static sqInt NoDbgRegParms genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer); static sqInt NoDbgRegParms genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers); static sqInt NoDbgRegParms genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers); -static sqInt NoDbgRegParms genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg); +static sqInt NoDbgRegParms genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg); static sqInt NoDbgRegParms genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers); static AbstractInstruction * NoDbgRegParms genSwapRRScratch(AbstractInstruction * self_in_genSwapRRScratch, sqInt regA, sqInt regB, sqInt regTmp); static void NoDbgRegParms genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister); @@ -823,6 +825,8 @@ static BytecodeDescriptor * loadBytesAndGetDescriptor(void); static void NoDbgRegParms loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc); static AbstractInstruction * NoDbgRegParms gMoveAwR(sqInt address, sqInt reg); static AbstractInstruction * NoDbgRegParms gMoveCwR(sqInt wordConstant, sqInt reg); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters); static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg); static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC); @@ -869,6 +873,7 @@ static void NoDbgRegParms recordGeneratedRunTimeaddress(char *aString, sqInt add extern sqInt recordPrimTraceFunc(void); static void recordRunTimeObjectReferences(void); static sqInt NoDbgRegParms registerMaskFor(sqInt reg); +static sqInt NoDbgRegParms registerMaskForand(sqInt reg1, sqInt reg2); static void NoDbgRegParms relocateCallsAndSelfReferencesInMethod(CogMethod *cogMethod); static void NoDbgRegParms relocateCallsInClosedPIC(CogMethod *cPIC); static sqInt NoDbgRegParms relocateIfCallOrMethodReferencemcpcdelta(sqInt annotation, char *mcpc, CogMethod *refDeltaArg); @@ -1275,6 +1280,7 @@ static sqInt genStoreAndPopReceiverVariableBytecode(void); static sqInt genStoreAndPopRemoteTempLongBytecode(void); static sqInt genStoreAndPopTemporaryVariableBytecode(void); static sqInt genStoreRemoteTempLongBytecode(void); +static void genTakeProfileSample(void); static sqInt genUnconditionalTrapBytecode(void); static void NoDbgRegParms loadNativeArgumentAddressto(sqInt baseOffset, sqInt reg); static void NoDbgRegParms loadNativeFramePointerInto(sqInt reg); @@ -2874,28 +2880,28 @@ addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *an static sqInt NoDbgRegParms availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << DPFPReg0)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg0))) != 0))) { return DPFPReg0; } - if (!(((liveRegsMask & (1U << DPFPReg1)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg1))) != 0))) { return DPFPReg1; } - if (!(((liveRegsMask & (1U << DPFPReg2)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg2))) != 0))) { return DPFPReg2; } - if (!(((liveRegsMask & (1U << DPFPReg3)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg3))) != 0))) { return DPFPReg3; } - if (!(((liveRegsMask & (1U << DPFPReg4)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg4))) != 0))) { return DPFPReg4; } - if (!(((liveRegsMask & (1U << DPFPReg5)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg5))) != 0))) { return DPFPReg5; } - if (!(((liveRegsMask & (1U << DPFPReg6)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg6))) != 0))) { return DPFPReg6; } - if (!(((liveRegsMask & (1U << DPFPReg7)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg7))) != 0))) { return DPFPReg7; } return NoReg; @@ -2995,11 +3001,11 @@ genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers) used immediately afterwards. */ - /* CogAbstractInstruction>>#genLoadStackPointersForFastPrimCall: */ + /* CogAbstractInstruction>>#genLoadStackPointersForPrimCall: */ static sqInt NoDbgRegParms -genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg) +genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg) { - genLoadStackPointers(self_in_genLoadStackPointersForFastPrimCall); + genLoadStackPointers(self_in_genLoadStackPointersForPrimCall); return 0; } @@ -3289,28 +3295,28 @@ andrnimmror(AbstractInstruction * self_in_andrnimmror, sqInt destReg, sqInt srcR static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << Extra0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra0Reg))) != 0))) { return Extra0Reg; } - if (!(((liveRegsMask & (1U << Extra1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra1Reg))) != 0))) { return Extra1Reg; } - if (!(((liveRegsMask & (1U << Extra2Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra2Reg))) != 0))) { return Extra2Reg; } - if (!(((liveRegsMask & (1U << Arg1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg1Reg))) != 0))) { return Arg1Reg; } - if (!(((liveRegsMask & (1U << Arg0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg0Reg))) != 0))) { return Arg0Reg; } - if (!(((liveRegsMask & (1U << SendNumArgsReg)) != 0))) { + if (!(((liveRegsMask & ((1U << SendNumArgsReg))) != 0))) { return SendNumArgsReg; } - if (!(((liveRegsMask & (1U << ClassReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ClassReg))) != 0))) { return ClassReg; } - if (!(((liveRegsMask & (1U << ReceiverResultReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ReceiverResultReg))) != 0))) { return ReceiverResultReg; } return NoReg; @@ -10417,7 +10423,7 @@ compileCallFornumArgsargargargargfloatResultRegregsToSave(void *aRoutine, sqInt regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1U << resultRegOrNone)) - (1U << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1U << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1U << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ regMaskCopy = ((usqInt)regsToSave); @@ -10485,7 +10491,7 @@ compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numAr regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1U << resultRegOrNone)) - (1U << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1U << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1U << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ regMaskCopy = ((usqInt)regsToSave); @@ -10551,7 +10557,7 @@ compileCallFornumArgsargargargargresultRegresultRegregsToSave(void *aRoutine, sq regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1U << resultRegOrNone)) - (1U << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1U << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1U << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ regMaskCopy = ((usqInt)regsToSave); @@ -10618,7 +10624,7 @@ compileCallFornumArgsfloatArgfloatArgfloatArgfloatArgresultRegregsToSave(void *a regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1U << resultRegOrNone)) - (1U << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1U << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1U << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ regMaskCopy = ((usqInt)regsToSave); @@ -12301,7 +12307,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) startAddress = methodZoneBase; callerSavedReg = 0; pushedVarBaseReg = 0; - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { /* VarBaseReg is not caller-saved; must save and restore it, either by using an available caller-saved reg or push/pop. */ @@ -12351,7 +12357,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) operandTwo2 = cStackPointerAddress(); checkLiteralforInstruction(operandTwo2, genoperandoperand(MoveRAw, NativeSPReg, operandTwo2)); } - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { if (pushedVarBaseReg) { gNativePopR(VarBaseReg); } @@ -13872,6 +13878,22 @@ gMoveCwR(sqInt wordConstant, sqInt reg) return checkLiteralforInstruction(wordConstant, genoperandoperand(MoveCwR, wordConstant, reg)); } + /* Cogit>>#MovePerfCnt64R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters) +{ + assert(0); + return genoperandoperand(MovePerfCnt64RL, destReg, liveRegisters); +} + + /* Cogit>>#MovePerfCnt64R:R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters) +{ + assert(0); + return genoperandoperandoperand(MovePerfCnt64RRL, destRegLo, destRegHi, liveRegisters); +} + /* Answer the address of the null byte at the end of the method map. */ @@ -15406,11 +15428,21 @@ recordRunTimeObjectReferences(void) } } + +/* N.B. (self registerMaskFor: NoReg) = 0 */ + /* Cogit>>#registerMaskFor: */ static sqInt NoDbgRegParms registerMaskFor(sqInt reg) { - return 1U << reg; + return ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); +} + + /* Cogit>>#registerMaskFor:and: */ +static sqInt NoDbgRegParms +registerMaskForand(sqInt reg1, sqInt reg2) +{ + return (1U << reg1) | (1U << reg2); } /* Cogit>>#relocateCallsAndSelfReferencesInMethod: */ @@ -23002,7 +23034,7 @@ generateObjectRepresentationTrampolines(void) } # endif // IMMUTABILITY ceNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceNewHash", 1, ReceiverResultReg, null, null, null, /* begin emptyRegisterMask */ 0, 1, ReceiverResultReg, 0); - ceInlineNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceInlineNewHash", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, ReceiverResultReg, 0); + ceInlineNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceInlineNewHash", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))), 1, ReceiverResultReg, 0); /* begin genStoreCheckTrampoline */ if (CheckRememberedInTrampoline) { zeroOpcodeIndex(); @@ -23013,7 +23045,7 @@ generateObjectRepresentationTrampolines(void) genoperand(RetN, 0); jmpTarget(jumpSC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); } - ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))), 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), CheckRememberedInTrampoline); ceStoreCheckContextReceiverTrampoline = genStoreCheckContextReceiverTrampoline(); @@ -25742,7 +25774,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jumpRC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg)); jmpTarget(jumpImmutable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); @@ -25758,7 +25790,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* Store check */ jumpImmutable1 = genJumpImmutablescratchReg(ReceiverResultReg, SendNumArgsReg); - compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), 0 /* emptyRegisterMask */); genLoadStackPointers(backEnd()); @@ -26903,7 +26935,7 @@ registerMask(SimStackEntry * self_in_registerMask) || (((self_in_registerMask->type)) == SSRegister) ? (/* begin registerMaskFor: */ (reg = (self_in_registerMask->registerr)), - 1U << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg))) : 0); } @@ -26916,7 +26948,7 @@ registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone) return (((self_in_registerMaskOrNone->type)) == SSRegister ? (/* begin registerMaskFor: */ (reg = (self_in_registerMaskOrNone->registerr)), - 1U << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg))) : 0); } @@ -27162,7 +27194,7 @@ nativeFloatRegisterMask(CogSimStackNativeEntry * self_in_nativeFloatRegisterMask || (((self_in_nativeFloatRegisterMask->type)) == SSRegisterDoubleFloat) ? (/* begin registerMaskFor: */ (reg = (self_in_nativeFloatRegisterMask->registerr)), - 1U << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg))) : 0); } @@ -27371,9 +27403,9 @@ nativeRegisterMask(CogSimStackNativeEntry * self_in_nativeRegisterMask) || (((self_in_nativeRegisterMask->type)) == SSRegisterDoubleFloat) ? (/* begin registerMaskFor: */ (reg = (self_in_nativeRegisterMask->registerr)), - 1U << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg))) : (((self_in_nativeRegisterMask->type)) == SSRegisterPair - ? (1U << ((self_in_nativeRegisterMask->registerr))) | (1U << ((self_in_nativeRegisterMask->registerSecond))) + ? (((((self_in_nativeRegisterMask->registerr)) < 0) ? (((usqInt)(1)) >> (-((self_in_nativeRegisterMask->registerr)))) : (1U << ((self_in_nativeRegisterMask->registerr))))) | (((((self_in_nativeRegisterMask->registerSecond)) < 0) ? (((usqInt)(1)) >> (-((self_in_nativeRegisterMask->registerSecond)))) : (1U << ((self_in_nativeRegisterMask->registerSecond))))) : 0)); } @@ -27849,40 +27881,24 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) { sqInt address; sqInt address1; - sqInt address10; - sqInt address11; - sqInt address12; - sqInt address13; - sqInt address3; - sqInt address4; - sqInt address5; + sqInt address2; sqInt address6; + sqInt address7; sqInt address8; sqInt address9; + AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; AbstractInstruction *anInstruction4; AbstractInstruction *anInstruction5; AbstractInstruction *anInstruction6; AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction * continuePostSampleNonPrim; - AbstractInstruction * continuePostSamplePrim; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; - AbstractInstruction * jmpSampleNonPrim; - AbstractInstruction * jmpSamplePrim; sqInt offset; sqInt offset1; sqInt offset2; - sqInt operand1; - sqInt operand3; - sqInt reg; sqInt retpc; - continuePostSampleNonPrim = ((AbstractInstruction *) 0); - continuePostSamplePrim = ((AbstractInstruction *) 0); - jmpSampleNonPrim = ((AbstractInstruction *) 0); - jmpSamplePrim = ((AbstractInstruction *) 0); assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); genExternalizePointersForPrimitiveCall(); /* begin genLoadCStackPointersForPrimCall */ @@ -27892,54 +27908,36 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) else { genLoadCStackPointer(backEnd); } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick if so */ - /* begin MoveAw:R: */ - address = nextProfileTickAddress(); - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address, genoperandoperand(MoveAwR, address, TempReg)); - /* begin MoveAw:R: */ - address1 = (nextProfileTickAddress()) + BytesPerWord; - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address1, genoperandoperand(MoveAwR, address1, ClassReg)); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSampleNonPrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSampleNonPrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } if (recordPrimTraceForMethod(methodObj)) { genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(MoveCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction8)) { - (anInstruction8->dependent = locateLiteral(0)); + anInstruction4 = genoperandoperand(MoveCqR, 0, TempReg); + if (usesOutOfLineLiteral(anInstruction4)) { + (anInstruction4->dependent = locateLiteral(0)); } /* begin MoveR:Aw: */ - address11 = primFailCodeAddress(); + address6 = primFailCodeAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address11, genoperandoperand(MoveRAw, TempReg, address11)); + checkLiteralforInstruction(address6, genoperandoperand(MoveRAw, TempReg, address6)); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); - if (usesOutOfLineLiteral(anInstruction1)) { - (anInstruction1->dependent = locateLiteral(methodOrBlockNumArgs)); + anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); + if (usesOutOfLineLiteral(anInstruction)) { + (anInstruction->dependent = locateLiteral(methodOrBlockNumArgs)); } } /* begin MoveR:Aw: */ - address12 = argumentCountAddress(); + address7 = argumentCountAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address12, genoperandoperand(MoveRAw, TempReg, address12)); + checkLiteralforInstruction(address7, genoperandoperand(MoveRAw, TempReg, address7)); if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { /* begin MoveCw:R: */ checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg)); /* begin MoveR:Aw: */ - address3 = primitiveFunctionPointerAddress(); + address = primitiveFunctionPointerAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address3, genoperandoperand(MoveRAw, TempReg, address3)); + checkLiteralforInstruction(address, genoperandoperand(MoveRAw, TempReg, address)); } if (((flags & (PrimCallNeedsNewMethod + PrimCallMayEndureCodeCompaction)) != 0)) { @@ -27951,22 +27949,21 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) /* begin MoveMw:r:R: */ offset = offsetof(CogMethod, methodObject); /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - if (usesOutOfLineLiteral(anInstruction2)) { - (anInstruction2->dependent = locateLiteral(offset)); + anInstruction1 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); + if (usesOutOfLineLiteral(anInstruction1)) { + (anInstruction1->dependent = locateLiteral(offset)); } /* begin MoveR:Aw: */ - address4 = newMethodAddress(); + address1 = newMethodAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address4, genoperandoperand(MoveRAw, TempReg, address4)); + checkLiteralforInstruction(address1, genoperandoperand(MoveRAw, TempReg, address1)); } /* begin PrefetchAw: */ - address13 = primFailCodeAddress(); + address8 = primFailCodeAddress(); /* begin gen:literal: */ - checkLiteralforInstruction(address13, genoperand(PrefetchAw, address13)); + checkLiteralforInstruction(address8, genoperand(PrefetchAw, address8)); if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - /* Sideways call the C primitive routine so that we return through cePrimReturnEnterCogCode. */ /* On Spur ceActivateFailingPrimitiveMethod: would like to retry if forwarders are found. So insist on PrimCallNeedsPrimitiveFunction being set too. */ assert(((flags & PrimCallNeedsPrimitiveFunction) != 0)); @@ -27979,103 +27976,48 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) checkLiteralforInstruction(retpc, genoperandoperand(MoveCwR, retpc, LR)); /* begin gen:literal: */ checkLiteralforInstruction(((sqInt)(((sqInt)primitiveRoutine))), genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine))))); - jmp = (jmpSamplePrim = (continuePostSamplePrim = null)); + return 0; } - else { - - /* Call the C primitive routine. */ - genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); - /* begin gen:literal: */ - checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperand(CallFull, ((sqInt)primitiveRoutine))); - /* begin genRemoveNArgsFromStack: */ - assert(0 <= 4); - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin MoveAw:R: */ - address5 = nextProfileTickAddress(); - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address5, genoperandoperand(MoveAwR, address5, TempReg)); - /* begin MoveAw:R: */ - address6 = (nextProfileTickAddress()) + BytesPerWord; - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address6, genoperandoperand(MoveAwR, address6, ClassReg)); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSamplePrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSamplePrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - maybeCompileRetryOnPrimitiveFail(primitiveIndex); - /* begin MoveAw:R: */ - address8 = instructionPointerAddress(); - reg = LinkReg; - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address8, genoperandoperand(MoveAwR, address8, reg)); - genLoadStackPointers(backEnd); - /* begin MoveAw:R: */ - address9 = primFailCodeAddress(); - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address9, genoperandoperand(MoveAwR, address9, TempReg)); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction4)) { - (anInstruction4->dependent = locateLiteral(0)); - } - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset1 = 0; - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); - if (usesOutOfLineLiteral(anInstruction5)) { - (anInstruction5->dependent = locateLiteral(offset1)); - } - /* begin RetN: */ - genoperand(RetN, BytesPerWord); + genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); + /* begin gen:literal: */ + checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperand(CallFull, ((sqInt)primitiveRoutine))); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 4); + maybeCompileRetryOnPrimitiveFail(primitiveIndex); + genLoadStackPointersForPrimCall(backEnd, ClassReg); + /* begin MoveAw:R: */ + address2 = instructionPointerAddress(); + /* begin gen:literal:operand: */ + checkLiteralforInstruction(address2, genoperandoperand(MoveAwR, address2, LinkReg)); + /* begin MoveAw:R: */ + address9 = primFailCodeAddress(); + /* begin gen:literal:operand: */ + checkLiteralforInstruction(address9, genoperandoperand(MoveAwR, address9, TempReg)); + flag("ask concrete code gen if move sets condition codes?"); + /* begin checkQuickConstant:forInstruction: */ + anInstruction5 = genoperandoperand(CmpCqR, 0, TempReg); + if (usesOutOfLineLiteral(anInstruction5)) { + (anInstruction5->dependent = locateLiteral(0)); } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* The sample is collected by cePrimReturnEnterCogCode for external calls */ - if (!(jmpSamplePrim == null)) { - - /* Call ceCheckProfileTick: to record sample and then continue. */ - jmpTarget(jmpSamplePrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin gen:literal: */ - operand1 = ((usqIntptr_t)ceCheckProfileTick); - checkLiteralforInstruction(operand1, genoperand(CallFull, operand1)); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSamplePrim)); - } - jmpTarget(jmpSampleNonPrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(MoveCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction6)) { - (anInstruction6->dependent = locateLiteral(0)); - } - /* begin MoveR:Aw: */ - address10 = newMethodAddress(); - /* begin gen:operand:literal: */ - checkLiteralforInstruction(address10, genoperandoperand(MoveRAw, TempReg, address10)); - /* begin gen:literal: */ - operand3 = ((usqIntptr_t)ceCheckProfileTick); - checkLiteralforInstruction(operand3, genoperand(CallFull, operand3)); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSampleNonPrim)); + /* begin JumpNonZero: */ + jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + /* begin MoveMw:r:R: */ + offset1 = 0; + /* begin checkQuickConstant:forInstruction: */ + anInstruction6 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); + if (usesOutOfLineLiteral(anInstruction6)) { + (anInstruction6->dependent = locateLiteral(offset1)); } - if (!(jmp == null)) { - - /* Jump to restore of receiver reg and proceed to frame build for failure. */ - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin MoveMw:r:R: */ - offset2 = BytesPerWord * (methodOrBlockNumArgs + (0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); - if (usesOutOfLineLiteral(anInstruction7)) { - (anInstruction7->dependent = locateLiteral(offset2)); - } + continueAfterProfileSample = anInstruction6; + /* begin RetN: */ + genoperand(RetN, BytesPerWord); + jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + /* begin MoveMw:r:R: */ + offset2 = BytesPerWord * (methodOrBlockNumArgs + (0)); + /* begin checkQuickConstant:forInstruction: */ + anInstruction7 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); + if (usesOutOfLineLiteral(anInstruction7)) { + (anInstruction7->dependent = locateLiteral(offset2)); } return 0; } @@ -28105,7 +28047,7 @@ compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)) if ((methodOrBlockNumArgs > 2 /* numRegArgs */) || (methodOrBlockNumArgs == 0)) { /* begin registerMaskFor: */ - liveRegsMask = 1U << ReceiverResultReg; + liveRegsMask = (1U << ReceiverResultReg); } else { if (methodOrBlockNumArgs > 1) { @@ -28197,6 +28139,7 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags AbstractInstruction *anInstruction8; AbstractInstruction *anInstruction9; sqInt calleeSavedRegisterMask; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; sqInt linkRegSaveRegister; sqInt offset; @@ -28233,12 +28176,12 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags /* begin gen:operand:literal: */ checkLiteralforInstruction(address5, genoperandoperand(MoveRAw, TempReg, address5)); genExternalizeStackPointerForFastPrimitiveCall(); - calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | (1U << ClassReg)) - (1U << ClassReg)); + calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | ((1U << ClassReg))) - ((1U << ClassReg))); linkRegSaveRegister = availableRegisterOrNoneIn(calleeSavedRegisterMask); assert(!((linkRegSaveRegister == NoReg))); /* begin MoveR:R: */ genoperandoperand(MoveRR, LinkReg, linkRegSaveRegister); - calleeSavedRegisterMask = ((calleeSavedRegisterMask | (1U << linkRegSaveRegister)) - (1U << linkRegSaveRegister)); + calleeSavedRegisterMask = ((calleeSavedRegisterMask | (((linkRegSaveRegister < 0) ? (((usqInt)(1)) >> (-linkRegSaveRegister)) : (1U << linkRegSaveRegister)))) - (((linkRegSaveRegister < 0) ? (((usqInt)(1)) >> (-linkRegSaveRegister)) : (1U << linkRegSaveRegister)))); spRegSaveRegister = NoReg; /* begin Label */ retry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); @@ -28247,8 +28190,11 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags } else { } + genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); /* begin gen:literal: */ - checkLiteralforInstruction(primitiveRoutine, genoperand(CallFull, primitiveRoutine)); + checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperand(CallFull, ((sqInt)primitiveRoutine))); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 4); /* begin MoveAw:R: */ address6 = primFailCodeAddress(); /* begin gen:literal:operand: */ @@ -28267,7 +28213,7 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags /* begin MoveAw:R: */ address7 = stackPointerAddress(); /* begin gen:literal:operand: */ - checkLiteralforInstruction(address7, genoperandoperand(MoveAwR, address7, TempReg)); + continueAfterProfileSample = checkLiteralforInstruction(address7, genoperandoperand(MoveAwR, address7, TempReg)); /* begin checkQuickConstant:forInstruction: */ anInstruction1 = genoperandoperandoperand(MoveMwrR, 0, TempReg, ReceiverResultReg); if (usesOutOfLineLiteral(anInstruction1)) { @@ -28313,10 +28259,11 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags else { genLoadCStackPointer(backEnd); } + genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); /* begin gen:literal: */ operand1 = ((usqIntptr_t)checkForAndFollowForwardedPrimitiveState); checkLiteralforInstruction(operand1, genoperand(CallFull, operand1)); - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); /* begin checkQuickConstant:forInstruction: */ anInstruction6 = genoperandoperand(CmpCqR, 0, ABIResultReg); if (usesOutOfLineLiteral(anInstruction6)) { @@ -28341,12 +28288,12 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags /* must reload SPReg to undo any alignment change, */ if (((flags & PrimCallOnSmalltalkStackAlign2x) != 0)) { - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); } } /* begin MoveR:R: */ genoperandoperand(MoveRR, linkRegSaveRegister, LinkReg); - if (((ABICallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((ABICallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* begin MoveMw:r:R: */ offset1 = (methodOrBlockNumArgs + (0)) * BytesPerWord; /* begin checkQuickConstant:forInstruction: */ @@ -29423,24 +29370,16 @@ static void NoDbgRegParms genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) { sqInt address; - sqInt address1; sqInt address3; - sqInt address6; - sqInt address7; - sqInt address8; + sqInt address4; + sqInt address5; AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction7; - sqInt callTarget; - AbstractInstruction *continuePostSample; - AbstractInstruction * inst; + AbstractInstruction *anInstruction4; + AbstractInstruction *anInstruction6; AbstractInstruction *jmpFail; - AbstractInstruction *jmpSample; sqInt quickConstant; sqInt reg; - continuePostSample = ((AbstractInstruction *) 0); - jmpSample = ((AbstractInstruction *) 0); zeroOpcodeIndex(); /* begin MoveCq:R: */ quickConstant = varBaseAddress(); @@ -29449,34 +29388,15 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) if (usesOutOfLineLiteral(anInstruction)) { (anInstruction->dependent = locateLiteral(quickConstant)); } - if (profiling) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick: if so. - N.B. nextProfileTick is 64-bits so 32-bit systems need to test both halves. */ - /* begin MoveAw:R: */ - address = nextProfileTickAddress(); - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address, genoperandoperand(MoveAwR, address, TempReg)); - /* begin MoveAw:R: */ - address1 = (nextProfileTickAddress()) + BytesPerWord; - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address1, genoperandoperand(MoveAwR, address1, ClassReg)); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSample = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } /* begin MoveAw:R: */ - address6 = primFailCodeAddress(); + address3 = primFailCodeAddress(); /* begin gen:literal:operand: */ - checkLiteralforInstruction(address6, genoperandoperand(MoveAwR, address6, TempReg)); + checkLiteralforInstruction(address3, genoperandoperand(MoveAwR, address3, TempReg)); flag("ask concrete code gen if move sets condition codes?"); /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(CmpCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction7)) { - (anInstruction7->dependent = locateLiteral(0)); + anInstruction6 = genoperandoperand(CmpCqR, 0, TempReg); + if (usesOutOfLineLiteral(anInstruction6)) { + (anInstruction6->dependent = locateLiteral(0)); } /* begin JumpNonZero: */ jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); @@ -29484,44 +29404,29 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) /* begin PopR: */ genoperand(PopR, ReceiverResultReg); /* begin MoveAw:R: */ - address3 = instructionPointerAddress(); + address = instructionPointerAddress(); /* begin gen:literal:operand: */ - checkLiteralforInstruction(address3, genoperandoperand(MoveAwR, address3, PCReg)); + checkLiteralforInstruction(address, genoperandoperand(MoveAwR, address, PCReg)); jmpTarget(jmpFail, gMoveAwR(newMethodAddress(), SendNumArgsReg)); /* begin MoveAw:R: */ - address7 = cStackPointerAddress(); + address4 = cStackPointerAddress(); /* begin gen:literal:operand: */ - checkLiteralforInstruction(address7, genoperandoperand(MoveAwR, address7, SPReg)); + checkLiteralforInstruction(address4, genoperandoperand(MoveAwR, address4, SPReg)); compileCallFornumArgsargargargargresultRegregsToSave(ceActivateFailingPrimitiveMethod, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); /* begin MoveAw:R: */ - address8 = instructionPointerAddress(); + address5 = instructionPointerAddress(); reg = LinkReg; /* begin gen:literal:operand: */ - checkLiteralforInstruction(address8, genoperandoperand(MoveAwR, address8, reg)); + checkLiteralforInstruction(address5, genoperandoperand(MoveAwR, address5, reg)); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); - if (usesOutOfLineLiteral(anInstruction5)) { - (anInstruction5->dependent = locateLiteral(0)); + anInstruction4 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); + if (usesOutOfLineLiteral(anInstruction4)) { + (anInstruction4->dependent = locateLiteral(0)); } /* begin RetN: */ genoperand(RetN, BytesPerWord); - if (profiling) { - - /* Call ceCheckProfileTick: to record sample and then continue. newMethod - should be up-to-date. Need to save and restore the link reg around this call. */ - jmpTarget(jmpSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - /* begin CallFullRT: */ - callTarget = (usqIntptr_t)ceCheckProfileTick; - /* begin gen:literal: */ - checkLiteralforInstruction(callTarget, genoperand(CallFull, callTarget)); - genoperand(PopR, LinkReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSample)); } -} /* SimpleStackBasedCogit>>#genPushConstantFalseBytecode */ static sqInt @@ -29887,6 +29792,21 @@ genStoreRemoteTempLongBytecode(void) && (shouldAnnotateObjectReference(((ssTop())->constant))))); } + /* SimpleStackBasedCogit>>#genTakeProfileSample */ +static void +genTakeProfileSample(void) +{ + sqInt operand1; + + addDependent(methodLabel, annotateAbsolutePCRef(gMoveCwR(((sqInt)methodLabel), ClassReg))); + genMarshallNArgsargargargarg(backEnd, 1, ClassReg, null, null, null); + /* begin gen:literal: */ + operand1 = ((usqIntptr_t)ceTakeProfileSample); + checkLiteralforInstruction(operand1, genoperand(CallFull, operand1)); + /* begin genRemoveNArgsFromStack: */ + assert(1 <= 4); + } + /* SistaV1: * 217 Trap */ @@ -30289,7 +30209,7 @@ primitiveGeneratorOrNil(void) static sqInt NoDbgRegParms registerisInMask(sqInt reg, sqInt mask) { - return ((mask & (1U << reg)) != 0); + return ((mask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)))) != 0); } /* SimpleStackBasedCogit>>#v3:Block:Code:Size: */ @@ -30679,7 +30599,7 @@ anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n) sqInt regMask; /* begin registerMaskFor: */ - regMask = 1U << reg; + regMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { if ((((registerMask(simStackAt(i))) & regMask) != 0)) { return 1; @@ -31849,7 +31769,7 @@ ensureReceiverResultRegContainsSelf(void) if (needsFrame) { if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin putSelfInReceiverResultReg */ storeToReg(simSelf(), ReceiverResultReg); ((simSelf())->liveRegister = ReceiverResultReg); @@ -31983,7 +31903,7 @@ freeAnyFloatRegNotConflictingWith(sqInt regMask) desc = simNativeStackAt(index); if ((((desc->type)) == SSRegisterSingleFloat) || (((desc->type)) == SSRegisterDoubleFloat)) { - if (!(((regMask & (1U << ((desc->registerr)))) != 0))) { + if (!(((regMask & (((((desc->registerr)) < 0) ? (((usqInt)(1)) >> (-((desc->registerr)))) : (1U << ((desc->registerr)))))) != 0))) { reg = (desc->registerr); } } @@ -32013,7 +31933,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) && (index < simStackPtr)) { desc = simStackAt(index); if (((desc->type)) == SSRegister) { - if (!(((regMask & (1U << ((desc->registerr)))) != 0))) { + if (!(((regMask & (((((desc->registerr)) < 0) ? (((usqInt)(1)) >> (-((desc->registerr)))) : (1U << ((desc->registerr)))))) != 0))) { reg = (desc->registerr); } } @@ -32021,7 +31941,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) } assert(!((reg == NoReg))); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << reg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)), simStackPtr, simNativeStackPtr); return reg; } @@ -32580,13 +32500,13 @@ genForwardersInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -33252,7 +33172,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop19 == NoReg) { rOopTop19 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult10 = allocateRegNotConflictingWith(1U << rOopTop19); + rResult10 = allocateRegNotConflictingWith(((rOopTop19 < 0) ? (((usqInt)(1)) >> (-rOopTop19)) : (1U << rOopTop19))); assert(!(((rOopTop19 == NoReg) || (rResult10 == NoReg)))); object17 = rOopTop19; @@ -33348,7 +33268,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop2 == NoReg) { rOopTop2 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult = allocateRegNotConflictingWith(1U << rOopTop2); + rResult = allocateRegNotConflictingWith(((rOopTop2 < 0) ? (((usqInt)(1)) >> (-rOopTop2)) : (1U << rOopTop2))); assert(!(((rOopTop2 == NoReg) || (rResult == NoReg)))); object2 = rOopTop2; @@ -33379,7 +33299,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop3 == NoReg) { rOopTop3 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult1 = allocateRegNotConflictingWith(1U << rOopTop3); + rResult1 = allocateRegNotConflictingWith(((rOopTop3 < 0) ? (((usqInt)(1)) >> (-rOopTop3)) : (1U << rOopTop3))); assert(!(((rOopTop3 == NoReg) || (rResult1 == NoReg)))); object3 = rOopTop3; @@ -33410,7 +33330,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop4 == NoReg) { rOopTop4 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult2 = allocateRegNotConflictingWith(1U << rOopTop4); + rResult2 = allocateRegNotConflictingWith(((rOopTop4 < 0) ? (((usqInt)(1)) >> (-rOopTop4)) : (1U << rOopTop4))); assert(!(((rOopTop4 == NoReg) || (rResult2 == NoReg)))); object4 = rOopTop4; @@ -33441,7 +33361,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop5 == NoReg) { rOopTop5 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult3 = allocateRegNotConflictingWith(1U << rOopTop5); + rResult3 = allocateRegNotConflictingWith(((rOopTop5 < 0) ? (((usqInt)(1)) >> (-rOopTop5)) : (1U << rOopTop5))); assert(!(((rOopTop5 == NoReg) || (rResult3 == NoReg)))); object5 = rOopTop5; @@ -33472,7 +33392,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop6 == NoReg) { rOopTop6 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult4 = allocateRegNotConflictingWith(1U << rOopTop6); + rResult4 = allocateRegNotConflictingWith(((rOopTop6 < 0) ? (((usqInt)(1)) >> (-rOopTop6)) : (1U << rOopTop6))); assert(!(((rOopTop6 == NoReg) || (rResult4 == NoReg)))); object6 = rOopTop6; @@ -33503,7 +33423,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop7 == NoReg) { rOopTop7 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult5 = allocateRegNotConflictingWith(1U << rOopTop7); + rResult5 = allocateRegNotConflictingWith(((rOopTop7 < 0) ? (((usqInt)(1)) >> (-rOopTop7)) : (1U << rOopTop7))); assert(!(((rOopTop7 == NoReg) || (rResult5 == NoReg)))); object7 = rOopTop7; @@ -33534,7 +33454,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop8 == NoReg) { rOopTop8 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult6 = allocateRegNotConflictingWith(1U << rOopTop8); + rResult6 = allocateRegNotConflictingWith(((rOopTop8 < 0) ? (((usqInt)(1)) >> (-rOopTop8)) : (1U << rOopTop8))); assert(!(((rOopTop8 == NoReg) || (rResult6 == NoReg)))); object8 = rOopTop8; @@ -33594,7 +33514,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop10 == NoReg) { rOopTop10 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult7 = allocateRegNotConflictingWith(1U << rOopTop10); + rResult7 = allocateRegNotConflictingWith(((rOopTop10 < 0) ? (((usqInt)(1)) >> (-rOopTop10)) : (1U << rOopTop10))); rResult21 = allocateRegNotConflictingWith((1U << rOopTop10) | (1U << rResult7)); assert(!(((rOopTop10 == NoReg) || (rResult7 == NoReg)))); @@ -33662,7 +33582,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop13 == NoReg) { rOopTop13 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult8 = allocateRegNotConflictingWith(1U << rOopTop13); + rResult8 = allocateRegNotConflictingWith(((rOopTop13 < 0) ? (((usqInt)(1)) >> (-rOopTop13)) : (1U << rOopTop13))); rResult22 = allocateRegNotConflictingWith((1U << rOopTop13) | (1U << rResult8)); assert(!(((rOopTop13 == NoReg) || (rResult8 == NoReg)))); @@ -33824,7 +33744,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop23 == NoReg) { rOopTop23 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult14 = allocateRegNotConflictingWith(1U << rOopTop23); + rResult14 = allocateRegNotConflictingWith(((rOopTop23 < 0) ? (((usqInt)(1)) >> (-rOopTop23)) : (1U << rOopTop23))); rResult23 = allocateRegNotConflictingWith((1U << rOopTop23) | (1U << rResult14)); assert(!(((rOopTop23 == NoReg) || (rResult14 == NoReg)))); @@ -33895,7 +33815,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop16 == NoReg) { rOopTop16 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult9 = allocateRegNotConflictingWith(1U << rOopTop16); + rResult9 = allocateRegNotConflictingWith(((rOopTop16 < 0) ? (((usqInt)(1)) >> (-rOopTop16)) : (1U << rOopTop16))); assert(!(((rOopTop16 == NoReg) || (rResult9 == NoReg)))); object14 = rOopTop16; @@ -33926,7 +33846,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop24 == NoReg) { rOopTop24 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult15 = allocateRegNotConflictingWith(1U << rOopTop24); + rResult15 = allocateRegNotConflictingWith(((rOopTop24 < 0) ? (((usqInt)(1)) >> (-rOopTop24)) : (1U << rOopTop24))); assert(!(((rOopTop24 == NoReg) || (rResult15 == NoReg)))); object22 = rOopTop24; @@ -33969,7 +33889,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop25 == NoReg) { rOopTop25 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult17 = allocateRegNotConflictingWith(1U << rOopTop25); + rResult17 = allocateRegNotConflictingWith(((rOopTop25 < 0) ? (((usqInt)(1)) >> (-rOopTop25)) : (1U << rOopTop25))); rResult24 = allocateRegNotConflictingWith((1U << rOopTop25) | (1U << rResult17)); assert(!(((rOopTop25 == NoReg) || (rResult17 == NoReg)))); @@ -34133,7 +34053,7 @@ genLowcodeNullaryInlinePrimitive(sqInt prim) if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult = allocateRegNotConflictingWith(1U << rTop); + rResult = allocateRegNotConflictingWith(((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1U << rTop))); assert(!(((rTop == NoReg) || (rResult == NoReg)))); value = rTop; @@ -34176,14 +34096,14 @@ genLowcodeNullaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } } if (rTop2 == NoReg) { rTop2 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1U << rTop2); + rNext = allocateRegNotConflictingWith(((rTop2 < 0) ? (((usqInt)(1)) >> (-rTop2)) : (1U << rTop2))); } assert(!(((rTop2 == NoReg) || (rNext == NoReg)))); @@ -34319,14 +34239,14 @@ genLowcodeNullaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg1 = (rNext1 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask1 = 1U << reg1; + topRegistersMask1 = ((reg1 < 0) ? (((usqInt)(1)) >> (-reg1)) : (1U << reg1)); } } if (rTop4 == NoReg) { rTop4 = allocateRegNotConflictingWith(topRegistersMask1); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop4); + rNext1 = allocateRegNotConflictingWith(((rTop4 < 0) ? (((usqInt)(1)) >> (-rTop4)) : (1U << rTop4))); } assert(!(((rTop4 == NoReg) || (rNext1 == NoReg)))); @@ -34454,14 +34374,14 @@ genLowcodeNullaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg2 = (rNext2 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask2 = 1U << reg2; + topRegistersMask2 = ((reg2 < 0) ? (((usqInt)(1)) >> (-reg2)) : (1U << reg2)); } } if (rTop9 == NoReg) { rTop9 = allocateRegNotConflictingWith(topRegistersMask2); } if (rNext2 == NoReg) { - rNext2 = allocateRegNotConflictingWith(1U << rTop9); + rNext2 = allocateRegNotConflictingWith(((rTop9 < 0) ? (((usqInt)(1)) >> (-rTop9)) : (1U << rTop9))); } assert(!(((rTop9 == NoReg) || (rNext2 == NoReg)))); @@ -34576,14 +34496,14 @@ genLowcodeTrinaryInlinePrimitive(sqInt prim) l4: ; if (rOopNext != NoReg) { /* begin registerMaskFor: */ - oopTopRegisterMask = 1U << rOopNext; + oopTopRegisterMask = ((rOopNext < 0) ? (((usqInt)(1)) >> (-rOopNext)) : (1U << rOopNext)); } } if (rOopTop == NoReg) { rOopTop = allocateRegNotConflictingWith(oopTopRegisterMask); } if (rOopNext == NoReg) { - rOopNext = allocateRegNotConflictingWith(1U << rOopTop); + rOopNext = allocateRegNotConflictingWith(((rOopTop < 0) ? (((usqInt)(1)) >> (-rOopTop)) : (1U << rOopTop))); } rResult = allocateRegNotConflictingWith((1U << rOopTop) | (1U << rOopNext)); assert(!(((rOopTop == NoReg) @@ -34651,14 +34571,14 @@ genLowcodeTrinaryInlinePrimitive(sqInt prim) l18: ; if (rOopNext1 != NoReg) { /* begin registerMaskFor: */ - oopTopRegisterMask1 = 1U << rOopNext1; + oopTopRegisterMask1 = ((rOopNext1 < 0) ? (((usqInt)(1)) >> (-rOopNext1)) : (1U << rOopNext1)); } } if (rOopTop1 == NoReg) { rOopTop1 = allocateRegNotConflictingWith(oopTopRegisterMask1); } if (rOopNext1 == NoReg) { - rOopNext1 = allocateRegNotConflictingWith(1U << rOopTop1); + rOopNext1 = allocateRegNotConflictingWith(((rOopTop1 < 0) ? (((usqInt)(1)) >> (-rOopTop1)) : (1U << rOopTop1))); } assert(!(((rOopTop1 == NoReg) || (rOopNext1 == NoReg)))); @@ -34725,14 +34645,14 @@ genLowcodeTrinaryInlinePrimitive(sqInt prim) l23: ; if (rOopNext2 != NoReg) { /* begin registerMaskFor: */ - oopTopRegisterMask2 = 1U << rOopNext2; + oopTopRegisterMask2 = ((rOopNext2 < 0) ? (((usqInt)(1)) >> (-rOopNext2)) : (1U << rOopNext2)); } } if (rOopTop2 == NoReg) { rOopTop2 = allocateRegNotConflictingWith(oopTopRegisterMask2); } if (rOopNext2 == NoReg) { - rOopNext2 = allocateRegNotConflictingWith(1U << rOopTop2); + rOopNext2 = allocateRegNotConflictingWith(((rOopTop2 < 0) ? (((usqInt)(1)) >> (-rOopTop2)) : (1U << rOopTop2))); } assert(!(((rOopTop2 == NoReg) || (rOopNext2 == NoReg)))); @@ -34753,17 +34673,17 @@ genLowcodeTrinaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { rTop = nativeRegisterOrNone(ssNativeTop()); /* begin registerMaskFor: */ - oopTopRegisterMask3 = 1U << rTop; + oopTopRegisterMask3 = ((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1U << rTop)); } if ((registerOrNone(ssTop())) != NoReg) { rOopTop3 = registerOrNone(ssTop()); /* begin registerMaskFor: */ - topRegisterMask = 1U << rOopTop3; + topRegisterMask = ((rOopTop3 < 0) ? (((usqInt)(1)) >> (-rOopTop3)) : (1U << rOopTop3)); } if ((registerOrNone(ssValue(1))) != NoReg) { rOopNext3 = registerOrNone(ssValue(1)); - topRegisterMask = topRegisterMask | (1U << rOopNext3); - oopTopRegisterMask3 = oopTopRegisterMask3 | (1U << rOopNext3); + topRegisterMask = topRegisterMask | (((rOopNext3 < 0) ? (((usqInt)(1)) >> (-rOopNext3)) : (1U << rOopNext3))); + oopTopRegisterMask3 = oopTopRegisterMask3 | (((rOopNext3 < 0) ? (((usqInt)(1)) >> (-rOopNext3)) : (1U << rOopNext3))); } if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(topRegisterMask); @@ -35316,13 +35236,13 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((registerOrNone(ssTop())) != NoReg) { rOopTop1 = registerOrNone(ssTop()); /* begin registerMaskFor: */ - topRegisterMask1 = 1U << rOopTop1; + topRegisterMask1 = ((rOopTop1 < 0) ? (((usqInt)(1)) >> (-rOopTop1)) : (1U << rOopTop1)); } if (rTop31 == NoReg) { rTop31 = allocateRegNotConflictingWith(topRegisterMask1); } if (rOopTop1 == NoReg) { - rOopTop1 = allocateRegNotConflictingWith(1U << rTop31); + rOopTop1 = allocateRegNotConflictingWith(((rTop31 < 0) ? (((usqInt)(1)) >> (-rTop31)) : (1U << rTop31))); } rOopResult = allocateRegNotConflictingWith((1U << rTop31) | (1U << rOopTop1)); assert(!(((rTop31 == NoReg) @@ -35372,7 +35292,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if (rOopTop2 == NoReg) { rOopTop2 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult35 = allocateRegNotConflictingWith(1U << rOopTop2); + rResult35 = allocateRegNotConflictingWith(((rOopTop2 < 0) ? (((usqInt)(1)) >> (-rOopTop2)) : (1U << rOopTop2))); assert(!(((rOopTop2 == NoReg) || (rResult35 == NoReg)))); classOop1 = rOopTop2; @@ -35446,14 +35366,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask1 = 1U << reg; + topRegistersMask1 = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } } if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(topRegistersMask1); } if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1U << rTop); + rNext = allocateRegNotConflictingWith(((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1U << rTop))); } assert(!(((rTop == NoReg) || (rNext == NoReg)))); @@ -35499,14 +35419,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg1 = (rNext1 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask2 = 1U << reg1; + topRegistersMask2 = ((reg1 < 0) ? (((usqInt)(1)) >> (-reg1)) : (1U << reg1)); } } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask2); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -35552,14 +35472,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg2 = (rNext2 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask3 = 1U << reg2; + topRegistersMask3 = ((reg2 < 0) ? (((usqInt)(1)) >> (-reg2)) : (1U << reg2)); } } if (rTop2 == NoReg) { rTop2 = allocateRegNotConflictingWith(topRegistersMask3); } if (rNext2 == NoReg) { - rNext2 = allocateRegNotConflictingWith(1U << rTop2); + rNext2 = allocateRegNotConflictingWith(((rTop2 < 0) ? (((usqInt)(1)) >> (-rTop2)) : (1U << rTop2))); } assert(!(((rTop2 == NoReg) || (rNext2 == NoReg)))); @@ -35605,14 +35525,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg3 = (rNext3 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask4 = 1U << reg3; + topRegistersMask4 = ((reg3 < 0) ? (((usqInt)(1)) >> (-reg3)) : (1U << reg3)); } } if (rTop3 == NoReg) { rTop3 = allocateRegNotConflictingWith(topRegistersMask4); } if (rNext3 == NoReg) { - rNext3 = allocateRegNotConflictingWith(1U << rTop3); + rNext3 = allocateRegNotConflictingWith(((rTop3 < 0) ? (((usqInt)(1)) >> (-rTop3)) : (1U << rTop3))); } assert(!(((rTop3 == NoReg) || (rNext3 == NoReg)))); @@ -35658,14 +35578,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg4 = (rNext4 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask5 = 1U << reg4; + topRegistersMask5 = ((reg4 < 0) ? (((usqInt)(1)) >> (-reg4)) : (1U << reg4)); } } if (rTop4 == NoReg) { rTop4 = allocateRegNotConflictingWith(topRegistersMask5); } if (rNext4 == NoReg) { - rNext4 = allocateRegNotConflictingWith(1U << rTop4); + rNext4 = allocateRegNotConflictingWith(((rTop4 < 0) ? (((usqInt)(1)) >> (-rTop4)) : (1U << rTop4))); } assert(!(((rTop4 == NoReg) || (rNext4 == NoReg)))); @@ -35711,14 +35631,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg5 = (rNext5 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask6 = 1U << reg5; + topRegistersMask6 = ((reg5 < 0) ? (((usqInt)(1)) >> (-reg5)) : (1U << reg5)); } } if (rTop5 == NoReg) { rTop5 = allocateRegNotConflictingWith(topRegistersMask6); } if (rNext5 == NoReg) { - rNext5 = allocateRegNotConflictingWith(1U << rTop5); + rNext5 = allocateRegNotConflictingWith(((rTop5 < 0) ? (((usqInt)(1)) >> (-rTop5)) : (1U << rTop5))); } assert(!(((rTop5 == NoReg) || (rNext5 == NoReg)))); @@ -35849,24 +35769,24 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) nextRegisterMask = 0; if (rNext6 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask = 1U << rNext6; + nextRegisterMask = ((rNext6 < 0) ? (((usqInt)(1)) >> (-rNext6)) : (1U << rNext6)); } if (rNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNext < 0) ? (((usqInt)(1)) >> (-rNextNext)) : (1U << rNextNext))); } if (rNextNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNextNext < 0) ? (((usqInt)(1)) >> (-rNextNextNext)) : (1U << rNextNextNext))); } rTop9 = allocateRegNotConflictingWith(nextRegisterMask); } if (rNext6 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask = 1U << rTop9; + nextRegisterMask = ((rTop9 < 0) ? (((usqInt)(1)) >> (-rTop9)) : (1U << rTop9)); if (rNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNext < 0) ? (((usqInt)(1)) >> (-rNextNext)) : (1U << rNextNext))); } if (rNextNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNextNext < 0) ? (((usqInt)(1)) >> (-rNextNextNext)) : (1U << rNextNextNext))); } rNext6 = allocateRegNotConflictingWith(nextRegisterMask); } @@ -35874,7 +35794,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) /* begin registerMaskFor:and: */ nextRegisterMask = (1U << rTop9) | (1U << rNext6); if (rNextNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNextNext < 0) ? (((usqInt)(1)) >> (-rNextNextNext)) : (1U << rNextNextNext))); } rNextNext = allocateRegNotConflictingWith(nextRegisterMask); } @@ -35939,14 +35859,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg7 = (rNext7 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask8 = 1U << reg7; + topRegistersMask8 = ((reg7 < 0) ? (((usqInt)(1)) >> (-reg7)) : (1U << reg7)); } } if (rTop10 == NoReg) { rTop10 = allocateRegNotConflictingWith(topRegistersMask8); } if (rNext7 == NoReg) { - rNext7 = allocateRegNotConflictingWith(1U << rTop10); + rNext7 = allocateRegNotConflictingWith(((rTop10 < 0) ? (((usqInt)(1)) >> (-rTop10)) : (1U << rTop10))); } assert(!(((rTop10 == NoReg) || (rNext7 == NoReg)))); @@ -35977,14 +35897,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg8 = (rNext8 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask9 = 1U << reg8; + topRegistersMask9 = ((reg8 < 0) ? (((usqInt)(1)) >> (-reg8)) : (1U << reg8)); } } if (rTop12 == NoReg) { rTop12 = allocateRegNotConflictingWith(topRegistersMask9); } if (rNext8 == NoReg) { - rNext8 = allocateRegNotConflictingWith(1U << rTop12); + rNext8 = allocateRegNotConflictingWith(((rTop12 < 0) ? (((usqInt)(1)) >> (-rTop12)) : (1U << rTop12))); } assert(!(((rTop12 == NoReg) || (rNext8 == NoReg)))); @@ -36015,14 +35935,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg9 = (rNext9 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask10 = 1U << reg9; + topRegistersMask10 = ((reg9 < 0) ? (((usqInt)(1)) >> (-reg9)) : (1U << reg9)); } } if (rTop13 == NoReg) { rTop13 = allocateRegNotConflictingWith(topRegistersMask10); } if (rNext9 == NoReg) { - rNext9 = allocateRegNotConflictingWith(1U << rTop13); + rNext9 = allocateRegNotConflictingWith(((rTop13 < 0) ? (((usqInt)(1)) >> (-rTop13)) : (1U << rTop13))); } assert(!(((rTop13 == NoReg) || (rNext9 == NoReg)))); @@ -36053,14 +35973,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg10 = (rNext10 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask11 = 1U << reg10; + topRegistersMask11 = ((reg10 < 0) ? (((usqInt)(1)) >> (-reg10)) : (1U << reg10)); } } if (rTop14 == NoReg) { rTop14 = allocateRegNotConflictingWith(topRegistersMask11); } if (rNext10 == NoReg) { - rNext10 = allocateRegNotConflictingWith(1U << rTop14); + rNext10 = allocateRegNotConflictingWith(((rTop14 < 0) ? (((usqInt)(1)) >> (-rTop14)) : (1U << rTop14))); } assert(!(((rTop14 == NoReg) || (rNext10 == NoReg)))); @@ -36115,24 +36035,24 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) nextRegisterMask1 = 0; if (rNext12 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask1 = 1U << rNext12; + nextRegisterMask1 = ((rNext12 < 0) ? (((usqInt)(1)) >> (-rNext12)) : (1U << rNext12)); } if (rNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNext1); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNext1)) : (1U << rNextNext1))); } if (rNextNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNextNext1); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNextNext1)) : (1U << rNextNextNext1))); } rTop15 = allocateRegNotConflictingWith(nextRegisterMask1); } if (rNext12 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask1 = 1U << rTop15; + nextRegisterMask1 = ((rTop15 < 0) ? (((usqInt)(1)) >> (-rTop15)) : (1U << rTop15)); if (rNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNext1); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNext1)) : (1U << rNextNext1))); } if (rNextNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNextNext1); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNextNext1)) : (1U << rNextNextNext1))); } rNext12 = allocateRegNotConflictingWith(nextRegisterMask1); } @@ -36140,7 +36060,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) /* begin registerMaskFor:and: */ nextRegisterMask1 = (1U << rTop15) | (1U << rNext12); if (rNextNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNextNext1); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNextNext1)) : (1U << rNextNextNext1))); } rNextNext1 = allocateRegNotConflictingWith(nextRegisterMask1); } @@ -36245,14 +36165,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg12 = (rNext14 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask13 = 1U << reg12; + topRegistersMask13 = ((reg12 < 0) ? (((usqInt)(1)) >> (-reg12)) : (1U << reg12)); } } if (rTop20 == NoReg) { rTop20 = allocateRegNotConflictingWith(topRegistersMask13); } if (rNext14 == NoReg) { - rNext14 = allocateRegNotConflictingWith(1U << rTop20); + rNext14 = allocateRegNotConflictingWith(((rTop20 < 0) ? (((usqInt)(1)) >> (-rTop20)) : (1U << rTop20))); } assert(!(((rTop20 == NoReg) || (rNext14 == NoReg)))); @@ -36277,14 +36197,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg13 = (rNext15 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask14 = 1U << reg13; + topRegistersMask14 = ((reg13 < 0) ? (((usqInt)(1)) >> (-reg13)) : (1U << reg13)); } } if (rTop21 == NoReg) { rTop21 = allocateRegNotConflictingWith(topRegistersMask14); } if (rNext15 == NoReg) { - rNext15 = allocateRegNotConflictingWith(1U << rTop21); + rNext15 = allocateRegNotConflictingWith(((rTop21 < 0) ? (((usqInt)(1)) >> (-rTop21)) : (1U << rTop21))); } assert(!(((rTop21 == NoReg) || (rNext15 == NoReg)))); @@ -36314,14 +36234,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg14 = (rNext16 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask15 = 1U << reg14; + topRegistersMask15 = ((reg14 < 0) ? (((usqInt)(1)) >> (-reg14)) : (1U << reg14)); } } if (rTop22 == NoReg) { rTop22 = allocateRegNotConflictingWith(topRegistersMask15); } if (rNext16 == NoReg) { - rNext16 = allocateRegNotConflictingWith(1U << rTop22); + rNext16 = allocateRegNotConflictingWith(((rTop22 < 0) ? (((usqInt)(1)) >> (-rTop22)) : (1U << rTop22))); } assert(!(((rTop22 == NoReg) || (rNext16 == NoReg)))); @@ -36443,7 +36363,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) /* begin allocateRegistersForLowcodeResultInteger2: */ rResult25 = (rResult26 = NoReg); rResult25 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - rResult26 = allocateRegNotConflictingWith(1U << rResult25); + rResult26 = allocateRegNotConflictingWith(((rResult25 < 0) ? (((usqInt)(1)) >> (-rResult25)) : (1U << rResult25))); assert(!(((rResult25 == NoReg) || (rResult26 == NoReg)))); valueLow4 = rResult25; @@ -36556,7 +36476,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) /* begin allocateRegistersForLowcodeResultInteger2: */ rResult27 = (rResult28 = NoReg); rResult27 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - rResult28 = allocateRegNotConflictingWith(1U << rResult27); + rResult28 = allocateRegNotConflictingWith(((rResult27 < 0) ? (((usqInt)(1)) >> (-rResult27)) : (1U << rResult27))); assert(!(((rResult27 == NoReg) || (rResult28 == NoReg)))); valueLow5 = rResult27; @@ -36654,7 +36574,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if (rTop25 == NoReg) { rTop25 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult29 = allocateRegNotConflictingWith(1U << rTop25); + rResult29 = allocateRegNotConflictingWith(((rTop25 < 0) ? (((usqInt)(1)) >> (-rTop25)) : (1U << rTop25))); assert(!(((rTop25 == NoReg) || (rResult29 == NoReg)))); pointer4 = rTop25; @@ -36694,7 +36614,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if (rTop26 == NoReg) { rTop26 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult30 = allocateRegNotConflictingWith(1U << rTop26); + rResult30 = allocateRegNotConflictingWith(((rTop26 < 0) ? (((usqInt)(1)) >> (-rTop26)) : (1U << rTop26))); assert(!(((rTop26 == NoReg) || (rResult30 == NoReg)))); pointer5 = rTop26; @@ -36720,7 +36640,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if (rTop27 == NoReg) { rTop27 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult31 = allocateRegNotConflictingWith(1U << rTop27); + rResult31 = allocateRegNotConflictingWith(((rTop27 < 0) ? (((usqInt)(1)) >> (-rTop27)) : (1U << rTop27))); rResult210 = allocateRegNotConflictingWith((1U << rTop27) | (1U << rResult31)); assert(!(((rTop27 == NoReg) || ((rResult31 == NoReg) @@ -36753,7 +36673,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if (rTop28 == NoReg) { rTop28 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult32 = allocateRegNotConflictingWith(1U << rTop28); + rResult32 = allocateRegNotConflictingWith(((rTop28 < 0) ? (((usqInt)(1)) >> (-rTop28)) : (1U << rTop28))); assert(!(((rTop28 == NoReg) || (rResult32 == NoReg)))); pointer7 = rTop28; @@ -36889,7 +36809,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) /* begin allocateRegistersForLowcodeResultInteger2: */ rResult33 = (rResult211 = NoReg); rResult33 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - rResult211 = allocateRegNotConflictingWith(1U << rResult33); + rResult211 = allocateRegNotConflictingWith(((rResult33 < 0) ? (((usqInt)(1)) >> (-rResult33)) : (1U << rResult33))); assert(!(((rResult33 == NoReg) || (rResult211 == NoReg)))); valueLow7 = rResult33; @@ -37002,7 +36922,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) /* begin allocateRegistersForLowcodeResultInteger2: */ rResult34 = (rResult212 = NoReg); rResult34 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - rResult212 = allocateRegNotConflictingWith(1U << rResult34); + rResult212 = allocateRegNotConflictingWith(((rResult34 < 0) ? (((usqInt)(1)) >> (-rResult34)) : (1U << rResult34))); assert(!(((rResult34 == NoReg) || (rResult212 == NoReg)))); valueLow8 = rResult34; @@ -37050,13 +36970,13 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((registerOrNone(ssTop())) != NoReg) { rOopTop = registerOrNone(ssTop()); /* begin registerMaskFor: */ - topRegisterMask = 1U << rOopTop; + topRegisterMask = ((rOopTop < 0) ? (((usqInt)(1)) >> (-rOopTop)) : (1U << rOopTop)); } if (rTop29 == NoReg) { rTop29 = allocateRegNotConflictingWith(topRegisterMask); } if (rOopTop == NoReg) { - rOopTop = allocateRegNotConflictingWith(1U << rTop29); + rOopTop = allocateRegNotConflictingWith(((rTop29 < 0) ? (((usqInt)(1)) >> (-rTop29)) : (1U << rTop29))); } assert(!(((rTop29 == NoReg) || (rOopTop == NoReg)))); @@ -37341,7 +37261,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult = allocateRegNotConflictingWith(1U << rTop); + rResult = allocateRegNotConflictingWith(((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1U << rTop))); assert(!(((rTop == NoReg) || (rResult == NoReg)))); pointer = rTop; @@ -37366,7 +37286,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult1 = allocateRegNotConflictingWith(1U << rTop1); + rResult1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); assert(!(((rTop1 == NoReg) || (rResult1 == NoReg)))); pointer1 = rTop1; @@ -37391,7 +37311,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop2 == NoReg) { rTop2 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult2 = allocateRegNotConflictingWith(1U << rTop2); + rResult2 = allocateRegNotConflictingWith(((rTop2 < 0) ? (((usqInt)(1)) >> (-rTop2)) : (1U << rTop2))); assert(!(((rTop2 == NoReg) || (rResult2 == NoReg)))); pointer2 = rTop2; @@ -37417,7 +37337,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop3 == NoReg) { rTop3 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult3 = allocateRegNotConflictingWith(1U << rTop3); + rResult3 = allocateRegNotConflictingWith(((rTop3 < 0) ? (((usqInt)(1)) >> (-rTop3)) : (1U << rTop3))); rResult21 = allocateRegNotConflictingWith((1U << rTop3) | (1U << rResult3)); assert(!(((rTop3 == NoReg) || ((rResult3 == NoReg) @@ -37450,7 +37370,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop4 == NoReg) { rTop4 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult4 = allocateRegNotConflictingWith(1U << rTop4); + rResult4 = allocateRegNotConflictingWith(((rTop4 < 0) ? (((usqInt)(1)) >> (-rTop4)) : (1U << rTop4))); assert(!(((rTop4 == NoReg) || (rResult4 == NoReg)))); pointer4 = rTop4; @@ -37561,7 +37481,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop28 == NoReg) { rTop28 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult8 = allocateRegNotConflictingWith(1U << rTop28); + rResult8 = allocateRegNotConflictingWith(((rTop28 < 0) ? (((usqInt)(1)) >> (-rTop28)) : (1U << rTop28))); assert(!(((rTop28 == NoReg) || (rResult8 == NoReg)))); size1 = rTop28; @@ -37607,14 +37527,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg10 = (rNext10 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask12 = 1U << reg10; + topRegistersMask12 = ((reg10 < 0) ? (((usqInt)(1)) >> (-reg10)) : (1U << reg10)); } } if (rTop29 == NoReg) { rTop29 = allocateRegNotConflictingWith(topRegistersMask12); } if (rNext10 == NoReg) { - rNext10 = allocateRegNotConflictingWith(1U << rTop29); + rNext10 = allocateRegNotConflictingWith(((rTop29 < 0) ? (((usqInt)(1)) >> (-rTop29)) : (1U << rTop29))); } assert(!(((rTop29 == NoReg) || (rNext10 == NoReg)))); @@ -37676,18 +37596,18 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) nextRegisterMask2 = 0; if (rNext13 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask2 = 1U << rNext13; + nextRegisterMask2 = ((rNext13 < 0) ? (((usqInt)(1)) >> (-rNext13)) : (1U << rNext13)); } if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1U << rNextNext2); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNext2)) : (1U << rNextNext2))); } rTop30 = allocateRegNotConflictingWith(nextRegisterMask2); } if (rNext13 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask2 = 1U << rTop30; + nextRegisterMask2 = ((rTop30 < 0) ? (((usqInt)(1)) >> (-rTop30)) : (1U << rTop30)); if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1U << rNextNext2); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNext2)) : (1U << rNextNext2))); } rNext13 = allocateRegNotConflictingWith(nextRegisterMask2); } @@ -37750,18 +37670,18 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) nextRegisterMask3 = 0; if (rNext14 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask3 = 1U << rNext14; + nextRegisterMask3 = ((rNext14 < 0) ? (((usqInt)(1)) >> (-rNext14)) : (1U << rNext14)); } if (rNextNext3 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1U << rNextNext3); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNext3)) : (1U << rNextNext3))); } rTop31 = allocateRegNotConflictingWith(nextRegisterMask3); } if (rNext14 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask3 = 1U << rTop31; + nextRegisterMask3 = ((rTop31 < 0) ? (((usqInt)(1)) >> (-rTop31)) : (1U << rTop31)); if (rNextNext3 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1U << rNextNext3); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNext3)) : (1U << rNextNext3))); } rNext14 = allocateRegNotConflictingWith(nextRegisterMask3); } @@ -37812,14 +37732,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg11 = (rNext15 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask13 = 1U << reg11; + topRegistersMask13 = ((reg11 < 0) ? (((usqInt)(1)) >> (-reg11)) : (1U << reg11)); } } if (rTop32 == NoReg) { rTop32 = allocateRegNotConflictingWith(topRegistersMask13); } if (rNext15 == NoReg) { - rNext15 = allocateRegNotConflictingWith(1U << rTop32); + rNext15 = allocateRegNotConflictingWith(((rTop32 < 0) ? (((usqInt)(1)) >> (-rTop32)) : (1U << rTop32))); } assert(!(((rTop32 == NoReg) || (rNext15 == NoReg)))); @@ -37912,14 +37832,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } } if (rTop5 == NoReg) { rTop5 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1U << rTop5); + rNext = allocateRegNotConflictingWith(((rTop5 < 0) ? (((usqInt)(1)) >> (-rTop5)) : (1U << rTop5))); } assert(!(((rTop5 == NoReg) || (rNext == NoReg)))); @@ -37949,14 +37869,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg1 = (rNext1 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask1 = 1U << reg1; + topRegistersMask1 = ((reg1 < 0) ? (((usqInt)(1)) >> (-reg1)) : (1U << reg1)); } } if (rTop6 == NoReg) { rTop6 = allocateRegNotConflictingWith(topRegistersMask1); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop6); + rNext1 = allocateRegNotConflictingWith(((rTop6 < 0) ? (((usqInt)(1)) >> (-rTop6)) : (1U << rTop6))); } assert(!(((rTop6 == NoReg) || (rNext1 == NoReg)))); @@ -38005,14 +37925,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg2 = (rNext2 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask2 = 1U << reg2; + topRegistersMask2 = ((reg2 < 0) ? (((usqInt)(1)) >> (-reg2)) : (1U << reg2)); } } if (rTop8 == NoReg) { rTop8 = allocateRegNotConflictingWith(topRegistersMask2); } if (rNext2 == NoReg) { - rNext2 = allocateRegNotConflictingWith(1U << rTop8); + rNext2 = allocateRegNotConflictingWith(((rTop8 < 0) ? (((usqInt)(1)) >> (-rTop8)) : (1U << rTop8))); } assert(!(((rTop8 == NoReg) || (rNext2 == NoReg)))); @@ -38070,14 +37990,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg3 = (rNext3 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask3 = 1U << reg3; + topRegistersMask3 = ((reg3 < 0) ? (((usqInt)(1)) >> (-reg3)) : (1U << reg3)); } } if (rTop10 == NoReg) { rTop10 = allocateRegNotConflictingWith(topRegistersMask3); } if (rNext3 == NoReg) { - rNext3 = allocateRegNotConflictingWith(1U << rTop10); + rNext3 = allocateRegNotConflictingWith(((rTop10 < 0) ? (((usqInt)(1)) >> (-rTop10)) : (1U << rTop10))); } assert(!(((rTop10 == NoReg) || (rNext3 == NoReg)))); @@ -38107,14 +38027,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg4 = (rNext4 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask4 = 1U << reg4; + topRegistersMask4 = ((reg4 < 0) ? (((usqInt)(1)) >> (-reg4)) : (1U << reg4)); } } if (rTop14 == NoReg) { rTop14 = allocateRegNotConflictingWith(topRegistersMask4); } if (rNext4 == NoReg) { - rNext4 = allocateRegNotConflictingWith(1U << rTop14); + rNext4 = allocateRegNotConflictingWith(((rTop14 < 0) ? (((usqInt)(1)) >> (-rTop14)) : (1U << rTop14))); } assert(!(((rTop14 == NoReg) || (rNext4 == NoReg)))); @@ -38171,24 +38091,24 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) nextRegisterMask = 0; if (rNext5 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask = 1U << rNext5; + nextRegisterMask = ((rNext5 < 0) ? (((usqInt)(1)) >> (-rNext5)) : (1U << rNext5)); } if (rNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNext < 0) ? (((usqInt)(1)) >> (-rNextNext)) : (1U << rNextNext))); } if (rNextNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNextNext < 0) ? (((usqInt)(1)) >> (-rNextNextNext)) : (1U << rNextNextNext))); } rTop15 = allocateRegNotConflictingWith(nextRegisterMask); } if (rNext5 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask = 1U << rTop15; + nextRegisterMask = ((rTop15 < 0) ? (((usqInt)(1)) >> (-rTop15)) : (1U << rTop15)); if (rNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNext < 0) ? (((usqInt)(1)) >> (-rNextNext)) : (1U << rNextNext))); } if (rNextNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNextNext < 0) ? (((usqInt)(1)) >> (-rNextNextNext)) : (1U << rNextNextNext))); } rNext5 = allocateRegNotConflictingWith(nextRegisterMask); } @@ -38196,7 +38116,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) /* begin registerMaskFor:and: */ nextRegisterMask = (1U << rTop15) | (1U << rNext5); if (rNextNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNextNext < 0) ? (((usqInt)(1)) >> (-rNextNextNext)) : (1U << rNextNextNext))); } rNextNext = allocateRegNotConflictingWith(nextRegisterMask); } @@ -38327,14 +38247,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg6 = (rNext6 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask6 = 1U << reg6; + topRegistersMask6 = ((reg6 < 0) ? (((usqInt)(1)) >> (-reg6)) : (1U << reg6)); } } if (rTop18 == NoReg) { rTop18 = allocateRegNotConflictingWith(topRegistersMask6); } if (rNext6 == NoReg) { - rNext6 = allocateRegNotConflictingWith(1U << rTop18); + rNext6 = allocateRegNotConflictingWith(((rTop18 < 0) ? (((usqInt)(1)) >> (-rTop18)) : (1U << rTop18))); } assert(!(((rTop18 == NoReg) || (rNext6 == NoReg)))); @@ -38378,18 +38298,18 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) nextRegisterMask1 = 0; if (rNext7 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask1 = 1U << rNext7; + nextRegisterMask1 = ((rNext7 < 0) ? (((usqInt)(1)) >> (-rNext7)) : (1U << rNext7)); } if (rNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNext1); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNext1)) : (1U << rNextNext1))); } rTop20 = allocateRegNotConflictingWith(nextRegisterMask1); } if (rNext7 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask1 = 1U << rTop20; + nextRegisterMask1 = ((rTop20 < 0) ? (((usqInt)(1)) >> (-rTop20)) : (1U << rTop20)); if (rNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNext1); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNext1)) : (1U << rNextNext1))); } rNext7 = allocateRegNotConflictingWith(nextRegisterMask1); } @@ -38427,14 +38347,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg8 = (rNext8 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask8 = 1U << reg8; + topRegistersMask8 = ((reg8 < 0) ? (((usqInt)(1)) >> (-reg8)) : (1U << reg8)); } } if (rTop21 == NoReg) { rTop21 = allocateRegNotConflictingWith(topRegistersMask8); } if (rNext8 == NoReg) { - rNext8 = allocateRegNotConflictingWith(1U << rTop21); + rNext8 = allocateRegNotConflictingWith(((rTop21 < 0) ? (((usqInt)(1)) >> (-rTop21)) : (1U << rTop21))); } assert(!(((rTop21 == NoReg) || (rNext8 == NoReg)))); @@ -38480,14 +38400,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg9 = (rNext9 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask9 = 1U << reg9; + topRegistersMask9 = ((reg9 < 0) ? (((usqInt)(1)) >> (-reg9)) : (1U << reg9)); } } if (rTop22 == NoReg) { rTop22 = allocateRegNotConflictingWith(topRegistersMask9); } if (rNext9 == NoReg) { - rNext9 = allocateRegNotConflictingWith(1U << rTop22); + rNext9 = allocateRegNotConflictingWith(((rTop22 < 0) ? (((usqInt)(1)) >> (-rTop22)) : (1U << rTop22))); } assert(!(((rTop22 == NoReg) || (rNext9 == NoReg)))); @@ -38546,7 +38466,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop24 == NoReg) { rTop24 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult7 = allocateRegNotConflictingWith(1U << rTop24); + rResult7 = allocateRegNotConflictingWith(((rTop24 < 0) ? (((usqInt)(1)) >> (-rTop24)) : (1U << rTop24))); rResult22 = allocateRegNotConflictingWith((1U << rTop24) | (1U << rResult7)); assert(!(((rTop24 == NoReg) || ((rResult7 == NoReg) @@ -39135,14 +39055,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } } if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(topRegistersMask); } if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1U << rTop); + rNext = allocateRegNotConflictingWith(((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1U << rTop))); } assert(!(((rTop == NoReg) || (rNext == NoReg)))); @@ -39171,14 +39091,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg1 = (rNext1 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask1 = 1U << reg1; + topRegistersMask1 = ((reg1 < 0) ? (((usqInt)(1)) >> (-reg1)) : (1U << reg1)); } } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask1); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -39208,14 +39128,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg2 = (rNext2 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask2 = 1U << reg2; + topRegistersMask2 = ((reg2 < 0) ? (((usqInt)(1)) >> (-reg2)) : (1U << reg2)); } } if (rTop2 == NoReg) { rTop2 = allocateRegNotConflictingWith(topRegistersMask2); } if (rNext2 == NoReg) { - rNext2 = allocateRegNotConflictingWith(1U << rTop2); + rNext2 = allocateRegNotConflictingWith(((rTop2 < 0) ? (((usqInt)(1)) >> (-rTop2)) : (1U << rTop2))); } assert(!(((rTop2 == NoReg) || (rNext2 == NoReg)))); @@ -39245,14 +39165,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg3 = (rNext3 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask3 = 1U << reg3; + topRegistersMask3 = ((reg3 < 0) ? (((usqInt)(1)) >> (-reg3)) : (1U << reg3)); } } if (rTop3 == NoReg) { rTop3 = allocateRegNotConflictingWith(topRegistersMask3); } if (rNext3 == NoReg) { - rNext3 = allocateRegNotConflictingWith(1U << rTop3); + rNext3 = allocateRegNotConflictingWith(((rTop3 < 0) ? (((usqInt)(1)) >> (-rTop3)) : (1U << rTop3))); } assert(!(((rTop3 == NoReg) || (rNext3 == NoReg)))); @@ -39345,14 +39265,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg4 = (rNext4 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask4 = 1U << reg4; + topRegistersMask4 = ((reg4 < 0) ? (((usqInt)(1)) >> (-reg4)) : (1U << reg4)); } } if (rTop6 == NoReg) { rTop6 = allocateRegNotConflictingWith(topRegistersMask4); } if (rNext4 == NoReg) { - rNext4 = allocateRegNotConflictingWith(1U << rTop6); + rNext4 = allocateRegNotConflictingWith(((rTop6 < 0) ? (((usqInt)(1)) >> (-rTop6)) : (1U << rTop6))); } assert(!(((rTop6 == NoReg) || (rNext4 == NoReg)))); @@ -39405,7 +39325,7 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if (rTop7 == NoReg) { rTop7 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult3 = allocateRegNotConflictingWith(1U << rTop7); + rResult3 = allocateRegNotConflictingWith(((rTop7 < 0) ? (((usqInt)(1)) >> (-rTop7)) : (1U << rTop7))); rResult2 = allocateRegNotConflictingWith((1U << rTop7) | (1U << rResult3)); assert(!(((rTop7 == NoReg) || ((rResult3 == NoReg) @@ -39452,14 +39372,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg5 = (rNext5 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask5 = 1U << reg5; + topRegistersMask5 = ((reg5 < 0) ? (((usqInt)(1)) >> (-reg5)) : (1U << reg5)); } } if (rTop8 == NoReg) { rTop8 = allocateRegNotConflictingWith(topRegistersMask5); } if (rNext5 == NoReg) { - rNext5 = allocateRegNotConflictingWith(1U << rTop8); + rNext5 = allocateRegNotConflictingWith(((rTop8 < 0) ? (((usqInt)(1)) >> (-rTop8)) : (1U << rTop8))); } assert(!(((rTop8 == NoReg) || (rNext5 == NoReg)))); @@ -39585,14 +39505,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg6 = (rNext6 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask6 = 1U << reg6; + topRegistersMask6 = ((reg6 < 0) ? (((usqInt)(1)) >> (-reg6)) : (1U << reg6)); } } if (rTop14 == NoReg) { rTop14 = allocateRegNotConflictingWith(topRegistersMask6); } if (rNext6 == NoReg) { - rNext6 = allocateRegNotConflictingWith(1U << rTop14); + rNext6 = allocateRegNotConflictingWith(((rTop14 < 0) ? (((usqInt)(1)) >> (-rTop14)) : (1U << rTop14))); } assert(!(((rTop14 == NoReg) || (rNext6 == NoReg)))); @@ -39625,14 +39545,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg7 = (rNext7 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask7 = 1U << reg7; + topRegistersMask7 = ((reg7 < 0) ? (((usqInt)(1)) >> (-reg7)) : (1U << reg7)); } } if (rTop15 == NoReg) { rTop15 = allocateRegNotConflictingWith(topRegistersMask7); } if (rNext7 == NoReg) { - rNext7 = allocateRegNotConflictingWith(1U << rTop15); + rNext7 = allocateRegNotConflictingWith(((rTop15 < 0) ? (((usqInt)(1)) >> (-rTop15)) : (1U << rTop15))); } assert(!(((rTop15 == NoReg) || (rNext7 == NoReg)))); @@ -39678,18 +39598,18 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) nextRegisterMask = 0; if (rNext8 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask = 1U << rNext8; + nextRegisterMask = ((rNext8 < 0) ? (((usqInt)(1)) >> (-rNext8)) : (1U << rNext8)); } if (rNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNext < 0) ? (((usqInt)(1)) >> (-rNextNext)) : (1U << rNextNext))); } rTop17 = allocateRegNotConflictingWith(nextRegisterMask); } if (rNext8 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask = 1U << rTop17; + nextRegisterMask = ((rTop17 < 0) ? (((usqInt)(1)) >> (-rTop17)) : (1U << rTop17)); if (rNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNext < 0) ? (((usqInt)(1)) >> (-rNextNext)) : (1U << rNextNext))); } rNext8 = allocateRegNotConflictingWith(nextRegisterMask); } @@ -39734,14 +39654,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg9 = (rNext9 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask9 = 1U << reg9; + topRegistersMask9 = ((reg9 < 0) ? (((usqInt)(1)) >> (-reg9)) : (1U << reg9)); } } if (rTop18 == NoReg) { rTop18 = allocateRegNotConflictingWith(topRegistersMask9); } if (rNext9 == NoReg) { - rNext9 = allocateRegNotConflictingWith(1U << rTop18); + rNext9 = allocateRegNotConflictingWith(((rTop18 < 0) ? (((usqInt)(1)) >> (-rTop18)) : (1U << rTop18))); } assert(!(((rTop18 == NoReg) || (rNext9 == NoReg)))); @@ -39876,14 +39796,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg10 = (rNext10 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask12 = 1U << reg10; + topRegistersMask12 = ((reg10 < 0) ? (((usqInt)(1)) >> (-reg10)) : (1U << reg10)); } } if (rTop21 == NoReg) { rTop21 = allocateRegNotConflictingWith(topRegistersMask12); } if (rNext10 == NoReg) { - rNext10 = allocateRegNotConflictingWith(1U << rTop21); + rNext10 = allocateRegNotConflictingWith(((rTop21 < 0) ? (((usqInt)(1)) >> (-rTop21)) : (1U << rTop21))); } assert(!(((rTop21 == NoReg) || (rNext10 == NoReg)))); @@ -39969,14 +39889,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg11 = (rNext12 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask13 = 1U << reg11; + topRegistersMask13 = ((reg11 < 0) ? (((usqInt)(1)) >> (-reg11)) : (1U << reg11)); } } if (rTop24 == NoReg) { rTop24 = allocateRegNotConflictingWith(topRegistersMask13); } if (rNext12 == NoReg) { - rNext12 = allocateRegNotConflictingWith(1U << rTop24); + rNext12 = allocateRegNotConflictingWith(((rTop24 < 0) ? (((usqInt)(1)) >> (-rTop24)) : (1U << rTop24))); } assert(!(((rTop24 == NoReg) || (rNext12 == NoReg)))); @@ -40007,14 +39927,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg12 = (rNext13 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask14 = 1U << reg12; + topRegistersMask14 = ((reg12 < 0) ? (((usqInt)(1)) >> (-reg12)) : (1U << reg12)); } } if (rTop25 == NoReg) { rTop25 = allocateRegNotConflictingWith(topRegistersMask14); } if (rNext13 == NoReg) { - rNext13 = allocateRegNotConflictingWith(1U << rTop25); + rNext13 = allocateRegNotConflictingWith(((rTop25 < 0) ? (((usqInt)(1)) >> (-rTop25)) : (1U << rTop25))); } assert(!(((rTop25 == NoReg) || (rNext13 == NoReg)))); @@ -40068,24 +39988,24 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) nextRegisterMask1 = 0; if (rNext14 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask1 = 1U << rNext14; + nextRegisterMask1 = ((rNext14 < 0) ? (((usqInt)(1)) >> (-rNext14)) : (1U << rNext14)); } if (rNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNext1); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNext1)) : (1U << rNextNext1))); } if (rNextNextNext != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNextNext); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNextNext < 0) ? (((usqInt)(1)) >> (-rNextNextNext)) : (1U << rNextNextNext))); } rTop26 = allocateRegNotConflictingWith(nextRegisterMask1); } if (rNext14 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask1 = 1U << rTop26; + nextRegisterMask1 = ((rTop26 < 0) ? (((usqInt)(1)) >> (-rTop26)) : (1U << rTop26)); if (rNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNext1); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNext1)) : (1U << rNextNext1))); } if (rNextNextNext != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNextNext); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNextNext < 0) ? (((usqInt)(1)) >> (-rNextNextNext)) : (1U << rNextNextNext))); } rNext14 = allocateRegNotConflictingWith(nextRegisterMask1); } @@ -40093,7 +40013,7 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) /* begin registerMaskFor:and: */ nextRegisterMask1 = (1U << rTop26) | (1U << rNext14); if (rNextNextNext != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNextNext); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNextNext < 0) ? (((usqInt)(1)) >> (-rNextNextNext)) : (1U << rNextNextNext))); } rNextNext1 = allocateRegNotConflictingWith(nextRegisterMask1); } @@ -40178,14 +40098,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg14 = (rNext16 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask16 = 1U << reg14; + topRegistersMask16 = ((reg14 < 0) ? (((usqInt)(1)) >> (-reg14)) : (1U << reg14)); } } if (rTop29 == NoReg) { rTop29 = allocateRegNotConflictingWith(topRegistersMask16); } if (rNext16 == NoReg) { - rNext16 = allocateRegNotConflictingWith(1U << rTop29); + rNext16 = allocateRegNotConflictingWith(((rTop29 < 0) ? (((usqInt)(1)) >> (-rTop29)) : (1U << rTop29))); } assert(!(((rTop29 == NoReg) || (rNext16 == NoReg)))); @@ -40216,14 +40136,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg15 = (rNext17 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask17 = 1U << reg15; + topRegistersMask17 = ((reg15 < 0) ? (((usqInt)(1)) >> (-reg15)) : (1U << reg15)); } } if (rTop30 == NoReg) { rTop30 = allocateRegNotConflictingWith(topRegistersMask17); } if (rNext17 == NoReg) { - rNext17 = allocateRegNotConflictingWith(1U << rTop30); + rNext17 = allocateRegNotConflictingWith(((rTop30 < 0) ? (((usqInt)(1)) >> (-rTop30)) : (1U << rTop30))); } assert(!(((rTop30 == NoReg) || (rNext17 == NoReg)))); @@ -40250,14 +40170,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg16 = (rNext18 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask18 = 1U << reg16; + topRegistersMask18 = ((reg16 < 0) ? (((usqInt)(1)) >> (-reg16)) : (1U << reg16)); } } if (rTop31 == NoReg) { rTop31 = allocateRegNotConflictingWith(topRegistersMask18); } if (rNext18 == NoReg) { - rNext18 = allocateRegNotConflictingWith(1U << rTop31); + rNext18 = allocateRegNotConflictingWith(((rTop31 < 0) ? (((usqInt)(1)) >> (-rTop31)) : (1U << rTop31))); } assert(!(((rTop31 == NoReg) || (rNext18 == NoReg)))); @@ -40290,14 +40210,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg17 = (rNext19 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask19 = 1U << reg17; + topRegistersMask19 = ((reg17 < 0) ? (((usqInt)(1)) >> (-reg17)) : (1U << reg17)); } } if (rTop32 == NoReg) { rTop32 = allocateRegNotConflictingWith(topRegistersMask19); } if (rNext19 == NoReg) { - rNext19 = allocateRegNotConflictingWith(1U << rTop32); + rNext19 = allocateRegNotConflictingWith(((rTop32 < 0) ? (((usqInt)(1)) >> (-rTop32)) : (1U << rTop32))); } assert(!(((rTop32 == NoReg) || (rNext19 == NoReg)))); @@ -40326,14 +40246,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg18 = (rNext20 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask20 = 1U << reg18; + topRegistersMask20 = ((reg18 < 0) ? (((usqInt)(1)) >> (-reg18)) : (1U << reg18)); } } if (rTop33 == NoReg) { rTop33 = allocateRegNotConflictingWith(topRegistersMask20); } if (rNext20 == NoReg) { - rNext20 = allocateRegNotConflictingWith(1U << rTop33); + rNext20 = allocateRegNotConflictingWith(((rTop33 < 0) ? (((usqInt)(1)) >> (-rTop33)) : (1U << rTop33))); } assert(!(((rTop33 == NoReg) || (rNext20 == NoReg)))); @@ -40363,14 +40283,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg19 = (rNext21 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask21 = 1U << reg19; + topRegistersMask21 = ((reg19 < 0) ? (((usqInt)(1)) >> (-reg19)) : (1U << reg19)); } } if (rTop34 == NoReg) { rTop34 = allocateRegNotConflictingWith(topRegistersMask21); } if (rNext21 == NoReg) { - rNext21 = allocateRegNotConflictingWith(1U << rTop34); + rNext21 = allocateRegNotConflictingWith(((rTop34 < 0) ? (((usqInt)(1)) >> (-rTop34)) : (1U << rTop34))); } assert(!(((rTop34 == NoReg) || (rNext21 == NoReg)))); @@ -40416,14 +40336,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg20 = (rNext22 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask22 = 1U << reg20; + topRegistersMask22 = ((reg20 < 0) ? (((usqInt)(1)) >> (-reg20)) : (1U << reg20)); } } if (rTop35 == NoReg) { rTop35 = allocateRegNotConflictingWith(topRegistersMask22); } if (rNext22 == NoReg) { - rNext22 = allocateRegNotConflictingWith(1U << rTop35); + rNext22 = allocateRegNotConflictingWith(((rTop35 < 0) ? (((usqInt)(1)) >> (-rTop35)) : (1U << rTop35))); } assert(!(((rTop35 == NoReg) || (rNext22 == NoReg)))); @@ -40469,14 +40389,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg21 = (rNext23 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask23 = 1U << reg21; + topRegistersMask23 = ((reg21 < 0) ? (((usqInt)(1)) >> (-reg21)) : (1U << reg21)); } } if (rTop36 == NoReg) { rTop36 = allocateRegNotConflictingWith(topRegistersMask23); } if (rNext23 == NoReg) { - rNext23 = allocateRegNotConflictingWith(1U << rTop36); + rNext23 = allocateRegNotConflictingWith(((rTop36 < 0) ? (((usqInt)(1)) >> (-rTop36)) : (1U << rTop36))); } assert(!(((rTop36 == NoReg) || (rNext23 == NoReg)))); @@ -40522,14 +40442,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg22 = (rNext24 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask24 = 1U << reg22; + topRegistersMask24 = ((reg22 < 0) ? (((usqInt)(1)) >> (-reg22)) : (1U << reg22)); } } if (rTop37 == NoReg) { rTop37 = allocateRegNotConflictingWith(topRegistersMask24); } if (rNext24 == NoReg) { - rNext24 = allocateRegNotConflictingWith(1U << rTop37); + rNext24 = allocateRegNotConflictingWith(((rTop37 < 0) ? (((usqInt)(1)) >> (-rTop37)) : (1U << rTop37))); } assert(!(((rTop37 == NoReg) || (rNext24 == NoReg)))); @@ -40620,14 +40540,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg23 = (rNext25 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask25 = 1U << reg23; + topRegistersMask25 = ((reg23 < 0) ? (((usqInt)(1)) >> (-reg23)) : (1U << reg23)); } } if (rTop40 == NoReg) { rTop40 = allocateRegNotConflictingWith(topRegistersMask25); } if (rNext25 == NoReg) { - rNext25 = allocateRegNotConflictingWith(1U << rTop40); + rNext25 = allocateRegNotConflictingWith(((rTop40 < 0) ? (((usqInt)(1)) >> (-rTop40)) : (1U << rTop40))); } assert(!(((rTop40 == NoReg) || (rNext25 == NoReg)))); @@ -40658,14 +40578,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg24 = (rNext26 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask26 = 1U << reg24; + topRegistersMask26 = ((reg24 < 0) ? (((usqInt)(1)) >> (-reg24)) : (1U << reg24)); } } if (rTop41 == NoReg) { rTop41 = allocateRegNotConflictingWith(topRegistersMask26); } if (rNext26 == NoReg) { - rNext26 = allocateRegNotConflictingWith(1U << rTop41); + rNext26 = allocateRegNotConflictingWith(((rTop41 < 0) ? (((usqInt)(1)) >> (-rTop41)) : (1U << rTop41))); } assert(!(((rTop41 == NoReg) || (rNext26 == NoReg)))); @@ -40696,14 +40616,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg25 = (rNext27 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask27 = 1U << reg25; + topRegistersMask27 = ((reg25 < 0) ? (((usqInt)(1)) >> (-reg25)) : (1U << reg25)); } } if (rTop42 == NoReg) { rTop42 = allocateRegNotConflictingWith(topRegistersMask27); } if (rNext27 == NoReg) { - rNext27 = allocateRegNotConflictingWith(1U << rTop42); + rNext27 = allocateRegNotConflictingWith(((rTop42 < 0) ? (((usqInt)(1)) >> (-rTop42)) : (1U << rTop42))); } assert(!(((rTop42 == NoReg) || (rNext27 == NoReg)))); @@ -40734,14 +40654,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg26 = (rNext28 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask28 = 1U << reg26; + topRegistersMask28 = ((reg26 < 0) ? (((usqInt)(1)) >> (-reg26)) : (1U << reg26)); } } if (rTop43 == NoReg) { rTop43 = allocateRegNotConflictingWith(topRegistersMask28); } if (rNext28 == NoReg) { - rNext28 = allocateRegNotConflictingWith(1U << rTop43); + rNext28 = allocateRegNotConflictingWith(((rTop43 < 0) ? (((usqInt)(1)) >> (-rTop43)) : (1U << rTop43))); } assert(!(((rTop43 == NoReg) || (rNext28 == NoReg)))); @@ -40811,14 +40731,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg27 = (rNext29 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask29 = 1U << reg27; + topRegistersMask29 = ((reg27 < 0) ? (((usqInt)(1)) >> (-reg27)) : (1U << reg27)); } } if (rTop46 == NoReg) { rTop46 = allocateRegNotConflictingWith(topRegistersMask29); } if (rNext29 == NoReg) { - rNext29 = allocateRegNotConflictingWith(1U << rTop46); + rNext29 = allocateRegNotConflictingWith(((rTop46 < 0) ? (((usqInt)(1)) >> (-rTop46)) : (1U << rTop46))); } assert(!(((rTop46 == NoReg) || (rNext29 == NoReg)))); @@ -40848,14 +40768,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg28 = (rNext30 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask30 = 1U << reg28; + topRegistersMask30 = ((reg28 < 0) ? (((usqInt)(1)) >> (-reg28)) : (1U << reg28)); } } if (rTop47 == NoReg) { rTop47 = allocateRegNotConflictingWith(topRegistersMask30); } if (rNext30 == NoReg) { - rNext30 = allocateRegNotConflictingWith(1U << rTop47); + rNext30 = allocateRegNotConflictingWith(((rTop47 < 0) ? (((usqInt)(1)) >> (-rTop47)) : (1U << rTop47))); } assert(!(((rTop47 == NoReg) || (rNext30 == NoReg)))); @@ -40893,14 +40813,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg29 = (rNext31 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask31 = 1U << reg29; + topRegistersMask31 = ((reg29 < 0) ? (((usqInt)(1)) >> (-reg29)) : (1U << reg29)); } } if (rTop48 == NoReg) { rTop48 = allocateRegNotConflictingWith(topRegistersMask31); } if (rNext31 == NoReg) { - rNext31 = allocateRegNotConflictingWith(1U << rTop48); + rNext31 = allocateRegNotConflictingWith(((rTop48 < 0) ? (((usqInt)(1)) >> (-rTop48)) : (1U << rTop48))); } assert(!(((rTop48 == NoReg) || (rNext31 == NoReg)))); @@ -40929,14 +40849,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg30 = (rNext32 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask32 = 1U << reg30; + topRegistersMask32 = ((reg30 < 0) ? (((usqInt)(1)) >> (-reg30)) : (1U << reg30)); } } if (rTop49 == NoReg) { rTop49 = allocateRegNotConflictingWith(topRegistersMask32); } if (rNext32 == NoReg) { - rNext32 = allocateRegNotConflictingWith(1U << rTop49); + rNext32 = allocateRegNotConflictingWith(((rTop49 < 0) ? (((usqInt)(1)) >> (-rTop49)) : (1U << rTop49))); } assert(!(((rTop49 == NoReg) || (rNext32 == NoReg)))); @@ -40966,14 +40886,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg31 = (rNext33 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask33 = 1U << reg31; + topRegistersMask33 = ((reg31 < 0) ? (((usqInt)(1)) >> (-reg31)) : (1U << reg31)); } } if (rTop50 == NoReg) { rTop50 = allocateRegNotConflictingWith(topRegistersMask33); } if (rNext33 == NoReg) { - rNext33 = allocateRegNotConflictingWith(1U << rTop50); + rNext33 = allocateRegNotConflictingWith(((rTop50 < 0) ? (((usqInt)(1)) >> (-rTop50)) : (1U << rTop50))); } assert(!(((rTop50 == NoReg) || (rNext33 == NoReg)))); @@ -41027,24 +40947,24 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) nextRegisterMask2 = 0; if (rNext34 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask2 = 1U << rNext34; + nextRegisterMask2 = ((rNext34 < 0) ? (((usqInt)(1)) >> (-rNext34)) : (1U << rNext34)); } if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1U << rNextNext2); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNext2)) : (1U << rNextNext2))); } if (rNextNextNext1 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1U << rNextNextNext1); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNextNext1)) : (1U << rNextNextNext1))); } rTop51 = allocateRegNotConflictingWith(nextRegisterMask2); } if (rNext34 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask2 = 1U << rTop51; + nextRegisterMask2 = ((rTop51 < 0) ? (((usqInt)(1)) >> (-rTop51)) : (1U << rTop51)); if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1U << rNextNext2); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNext2)) : (1U << rNextNext2))); } if (rNextNextNext1 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1U << rNextNextNext1); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNextNext1)) : (1U << rNextNextNext1))); } rNext34 = allocateRegNotConflictingWith(nextRegisterMask2); } @@ -41052,7 +40972,7 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) /* begin registerMaskFor:and: */ nextRegisterMask2 = (1U << rTop51) | (1U << rNext34); if (rNextNextNext1 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1U << rNextNextNext1); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNextNext1)) : (1U << rNextNextNext1))); } rNextNext2 = allocateRegNotConflictingWith(nextRegisterMask2); } @@ -41159,14 +41079,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg33 = (rNext35 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask35 = 1U << reg33; + topRegistersMask35 = ((reg33 < 0) ? (((usqInt)(1)) >> (-reg33)) : (1U << reg33)); } } if (rTop54 == NoReg) { rTop54 = allocateRegNotConflictingWith(topRegistersMask35); } if (rNext35 == NoReg) { - rNext35 = allocateRegNotConflictingWith(1U << rTop54); + rNext35 = allocateRegNotConflictingWith(((rTop54 < 0) ? (((usqInt)(1)) >> (-rTop54)) : (1U << rTop54))); } assert(!(((rTop54 == NoReg) || (rNext35 == NoReg)))); @@ -41240,7 +41160,7 @@ genLowcodeUnaryInlinePrimitive5(sqInt prim) if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult = allocateRegNotConflictingWith(1U << rTop); + rResult = allocateRegNotConflictingWith(((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1U << rTop))); rResult2 = allocateRegNotConflictingWith((1U << rTop) | (1U << rResult)); assert(!(((rTop == NoReg) || ((rResult == NoReg) @@ -41275,14 +41195,14 @@ genLowcodeUnaryInlinePrimitive5(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } } if (rTop2 == NoReg) { rTop2 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1U << rTop2); + rNext = allocateRegNotConflictingWith(((rTop2 < 0) ? (((usqInt)(1)) >> (-rTop2)) : (1U << rTop2))); } assert(!(((rTop2 == NoReg) || (rNext == NoReg)))); @@ -41709,14 +41629,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } } if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(topRegistersMask); } if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1U << rTop); + rNext = allocateRegNotConflictingWith(((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1U << rTop))); } assert(!(((rTop == NoReg) || (rNext == NoReg)))); @@ -41770,24 +41690,24 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) nextRegisterMask = 0; if (rNext2 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask = 1U << rNext2; + nextRegisterMask = ((rNext2 < 0) ? (((usqInt)(1)) >> (-rNext2)) : (1U << rNext2)); } if (rNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNext < 0) ? (((usqInt)(1)) >> (-rNextNext)) : (1U << rNextNext))); } if (rNextNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNextNext < 0) ? (((usqInt)(1)) >> (-rNextNextNext)) : (1U << rNextNextNext))); } rTop2 = allocateRegNotConflictingWith(nextRegisterMask); } if (rNext2 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask = 1U << rTop2; + nextRegisterMask = ((rTop2 < 0) ? (((usqInt)(1)) >> (-rTop2)) : (1U << rTop2)); if (rNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNext < 0) ? (((usqInt)(1)) >> (-rNextNext)) : (1U << rNextNext))); } if (rNextNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNextNext < 0) ? (((usqInt)(1)) >> (-rNextNextNext)) : (1U << rNextNextNext))); } rNext2 = allocateRegNotConflictingWith(nextRegisterMask); } @@ -41795,7 +41715,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) /* begin registerMaskFor:and: */ nextRegisterMask = (1U << rTop2) | (1U << rNext2); if (rNextNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNextNext < 0) ? (((usqInt)(1)) >> (-rNextNextNext)) : (1U << rNextNextNext))); } rNextNext = allocateRegNotConflictingWith(nextRegisterMask); } @@ -41871,14 +41791,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg2 = (rNext3 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask2 = 1U << reg2; + topRegistersMask2 = ((reg2 < 0) ? (((usqInt)(1)) >> (-reg2)) : (1U << reg2)); } } if (rTop4 == NoReg) { rTop4 = allocateRegNotConflictingWith(topRegistersMask2); } if (rNext3 == NoReg) { - rNext3 = allocateRegNotConflictingWith(1U << rTop4); + rNext3 = allocateRegNotConflictingWith(((rTop4 < 0) ? (((usqInt)(1)) >> (-rTop4)) : (1U << rTop4))); } assert(!(((rTop4 == NoReg) || (rNext3 == NoReg)))); @@ -41907,14 +41827,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg3 = (rNext4 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask3 = 1U << reg3; + topRegistersMask3 = ((reg3 < 0) ? (((usqInt)(1)) >> (-reg3)) : (1U << reg3)); } } if (rTop5 == NoReg) { rTop5 = allocateRegNotConflictingWith(topRegistersMask3); } if (rNext4 == NoReg) { - rNext4 = allocateRegNotConflictingWith(1U << rTop5); + rNext4 = allocateRegNotConflictingWith(((rTop5 < 0) ? (((usqInt)(1)) >> (-rTop5)) : (1U << rTop5))); } assert(!(((rTop5 == NoReg) || (rNext4 == NoReg)))); @@ -41968,24 +41888,24 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) nextRegisterMask1 = 0; if (rNext5 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask1 = 1U << rNext5; + nextRegisterMask1 = ((rNext5 < 0) ? (((usqInt)(1)) >> (-rNext5)) : (1U << rNext5)); } if (rNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNext1); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNext1)) : (1U << rNextNext1))); } if (rNextNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNextNext1); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNextNext1)) : (1U << rNextNextNext1))); } rTop6 = allocateRegNotConflictingWith(nextRegisterMask1); } if (rNext5 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask1 = 1U << rTop6; + nextRegisterMask1 = ((rTop6 < 0) ? (((usqInt)(1)) >> (-rTop6)) : (1U << rTop6)); if (rNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNext1); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNext1)) : (1U << rNextNext1))); } if (rNextNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNextNext1); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNextNext1)) : (1U << rNextNextNext1))); } rNext5 = allocateRegNotConflictingWith(nextRegisterMask1); } @@ -41993,7 +41913,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) /* begin registerMaskFor:and: */ nextRegisterMask1 = (1U << rTop6) | (1U << rNext5); if (rNextNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNextNext1); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNextNext1)) : (1U << rNextNextNext1))); } rNextNext1 = allocateRegNotConflictingWith(nextRegisterMask1); } @@ -42035,14 +41955,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg5 = (rNext6 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask5 = 1U << reg5; + topRegistersMask5 = ((reg5 < 0) ? (((usqInt)(1)) >> (-reg5)) : (1U << reg5)); } } if (rTop7 == NoReg) { rTop7 = allocateRegNotConflictingWith(topRegistersMask5); } if (rNext6 == NoReg) { - rNext6 = allocateRegNotConflictingWith(1U << rTop7); + rNext6 = allocateRegNotConflictingWith(((rTop7 < 0) ? (((usqInt)(1)) >> (-rTop7)) : (1U << rTop7))); } assert(!(((rTop7 == NoReg) || (rNext6 == NoReg)))); @@ -42072,14 +41992,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg6 = (rNext7 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask6 = 1U << reg6; + topRegistersMask6 = ((reg6 < 0) ? (((usqInt)(1)) >> (-reg6)) : (1U << reg6)); } } if (rTop8 == NoReg) { rTop8 = allocateRegNotConflictingWith(topRegistersMask6); } if (rNext7 == NoReg) { - rNext7 = allocateRegNotConflictingWith(1U << rTop8); + rNext7 = allocateRegNotConflictingWith(((rTop8 < 0) ? (((usqInt)(1)) >> (-rTop8)) : (1U << rTop8))); } assert(!(((rTop8 == NoReg) || (rNext7 == NoReg)))); @@ -42245,18 +42165,18 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) nextRegisterMask2 = 0; if (rNext8 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask2 = 1U << rNext8; + nextRegisterMask2 = ((rNext8 < 0) ? (((usqInt)(1)) >> (-rNext8)) : (1U << rNext8)); } if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1U << rNextNext2); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNext2)) : (1U << rNextNext2))); } rTop9 = allocateRegNotConflictingWith(nextRegisterMask2); } if (rNext8 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask2 = 1U << rTop9; + nextRegisterMask2 = ((rTop9 < 0) ? (((usqInt)(1)) >> (-rTop9)) : (1U << rTop9)); if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1U << rNextNext2); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNext2)) : (1U << rNextNext2))); } rNext8 = allocateRegNotConflictingWith(nextRegisterMask2); } @@ -42297,14 +42217,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg7 = (rNext9 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask7 = 1U << reg7; + topRegistersMask7 = ((reg7 < 0) ? (((usqInt)(1)) >> (-reg7)) : (1U << reg7)); } } if (rTop10 == NoReg) { rTop10 = allocateRegNotConflictingWith(topRegistersMask7); } if (rNext9 == NoReg) { - rNext9 = allocateRegNotConflictingWith(1U << rTop10); + rNext9 = allocateRegNotConflictingWith(((rTop10 < 0) ? (((usqInt)(1)) >> (-rTop10)) : (1U << rTop10))); } assert(!(((rTop10 == NoReg) || (rNext9 == NoReg)))); @@ -42333,14 +42253,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg8 = (rNext10 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask8 = 1U << reg8; + topRegistersMask8 = ((reg8 < 0) ? (((usqInt)(1)) >> (-reg8)) : (1U << reg8)); } } if (rTop13 == NoReg) { rTop13 = allocateRegNotConflictingWith(topRegistersMask8); } if (rNext10 == NoReg) { - rNext10 = allocateRegNotConflictingWith(1U << rTop13); + rNext10 = allocateRegNotConflictingWith(((rTop13 < 0) ? (((usqInt)(1)) >> (-rTop13)) : (1U << rTop13))); } assert(!(((rTop13 == NoReg) || (rNext10 == NoReg)))); @@ -42368,7 +42288,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (frTop == NoReg) { frTop = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); } - frResult = allocateFloatRegNotConflictingWith(1U << frTop); + frResult = allocateFloatRegNotConflictingWith(((frTop < 0) ? (((usqInt)(1)) >> (-frTop)) : (1U << frTop))); assert(!(((frTop == NoReg) || (frResult == NoReg)))); value3 = frTop; @@ -42393,7 +42313,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (frTop1 == NoReg) { frTop1 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); } - frResult1 = allocateFloatRegNotConflictingWith(1U << frTop1); + frResult1 = allocateFloatRegNotConflictingWith(((frTop1 < 0) ? (((usqInt)(1)) >> (-frTop1)) : (1U << frTop1))); assert(!(((frTop1 == NoReg) || (frResult1 == NoReg)))); value4 = frTop1; @@ -42416,7 +42336,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (rTop14 == NoReg) { rTop14 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult3 = allocateRegNotConflictingWith(1U << rTop14); + rResult3 = allocateRegNotConflictingWith(((rTop14 < 0) ? (((usqInt)(1)) >> (-rTop14)) : (1U << rTop14))); assert(!(((rTop14 == NoReg) || (rResult3 == NoReg)))); value5 = rTop14; @@ -42445,14 +42365,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg9 = (rNext12 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask9 = 1U << reg9; + topRegistersMask9 = ((reg9 < 0) ? (((usqInt)(1)) >> (-reg9)) : (1U << reg9)); } } if (rTop15 == NoReg) { rTop15 = allocateRegNotConflictingWith(topRegistersMask9); } if (rNext12 == NoReg) { - rNext12 = allocateRegNotConflictingWith(1U << rTop15); + rNext12 = allocateRegNotConflictingWith(((rTop15 < 0) ? (((usqInt)(1)) >> (-rTop15)) : (1U << rTop15))); } assert(!(((rTop15 == NoReg) || (rNext12 == NoReg)))); @@ -42484,7 +42404,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (rTop17 == NoReg) { rTop17 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult5 = allocateRegNotConflictingWith(1U << rTop17); + rResult5 = allocateRegNotConflictingWith(((rTop17 < 0) ? (((usqInt)(1)) >> (-rTop17)) : (1U << rTop17))); assert(!(((rTop17 == NoReg) || (rResult5 == NoReg)))); pointerValue = rTop17; @@ -42535,24 +42455,24 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) nextRegisterMask3 = 0; if (rNext13 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask3 = 1U << rNext13; + nextRegisterMask3 = ((rNext13 < 0) ? (((usqInt)(1)) >> (-rNext13)) : (1U << rNext13)); } if (rNextNext3 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1U << rNextNext3); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNext3)) : (1U << rNextNext3))); } if (rNextNextNext2 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1U << rNextNextNext2); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNextNext2)) : (1U << rNextNextNext2))); } rTop18 = allocateRegNotConflictingWith(nextRegisterMask3); } if (rNext13 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask3 = 1U << rTop18; + nextRegisterMask3 = ((rTop18 < 0) ? (((usqInt)(1)) >> (-rTop18)) : (1U << rTop18)); if (rNextNext3 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1U << rNextNext3); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNext3)) : (1U << rNextNext3))); } if (rNextNextNext2 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1U << rNextNextNext2); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNextNext2)) : (1U << rNextNextNext2))); } rNext13 = allocateRegNotConflictingWith(nextRegisterMask3); } @@ -42560,7 +42480,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) /* begin registerMaskFor:and: */ nextRegisterMask3 = (1U << rTop18) | (1U << rNext13); if (rNextNextNext2 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1U << rNextNextNext2); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNextNext2)) : (1U << rNextNextNext2))); } rNextNext3 = allocateRegNotConflictingWith(nextRegisterMask3); } @@ -42633,24 +42553,24 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) nextRegisterMask4 = 0; if (rNext14 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask4 = 1U << rNext14; + nextRegisterMask4 = ((rNext14 < 0) ? (((usqInt)(1)) >> (-rNext14)) : (1U << rNext14)); } if (rNextNext4 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1U << rNextNext4); + nextRegisterMask4 = nextRegisterMask4 | (((rNextNext4 < 0) ? (((usqInt)(1)) >> (-rNextNext4)) : (1U << rNextNext4))); } if (rNextNextNext3 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1U << rNextNextNext3); + nextRegisterMask4 = nextRegisterMask4 | (((rNextNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNextNext3)) : (1U << rNextNextNext3))); } rTop19 = allocateRegNotConflictingWith(nextRegisterMask4); } if (rNext14 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask4 = 1U << rTop19; + nextRegisterMask4 = ((rTop19 < 0) ? (((usqInt)(1)) >> (-rTop19)) : (1U << rTop19)); if (rNextNext4 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1U << rNextNext4); + nextRegisterMask4 = nextRegisterMask4 | (((rNextNext4 < 0) ? (((usqInt)(1)) >> (-rNextNext4)) : (1U << rNextNext4))); } if (rNextNextNext3 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1U << rNextNextNext3); + nextRegisterMask4 = nextRegisterMask4 | (((rNextNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNextNext3)) : (1U << rNextNextNext3))); } rNext14 = allocateRegNotConflictingWith(nextRegisterMask4); } @@ -42658,7 +42578,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) /* begin registerMaskFor:and: */ nextRegisterMask4 = (1U << rTop19) | (1U << rNext14); if (rNextNextNext3 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1U << rNextNextNext3); + nextRegisterMask4 = nextRegisterMask4 | (((rNextNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNextNext3)) : (1U << rNextNextNext3))); } rNextNext4 = allocateRegNotConflictingWith(nextRegisterMask4); } @@ -42708,13 +42628,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg10 = (rNext15 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask10 = 1U << reg10; + topRegistersMask10 = ((reg10 < 0) ? (((usqInt)(1)) >> (-reg10)) : (1U << reg10)); } if (rTop20 == NoReg) { rTop20 = allocateFloatRegNotConflictingWith(topRegistersMask10); } if (rNext15 == NoReg) { - rNext15 = allocateFloatRegNotConflictingWith(1U << rTop20); + rNext15 = allocateFloatRegNotConflictingWith(((rTop20 < 0) ? (((usqInt)(1)) >> (-rTop20)) : (1U << rTop20))); } assert(!(((rTop20 == NoReg) || (rNext15 == NoReg)))); @@ -42739,13 +42659,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg11 = (rNext16 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask11 = 1U << reg11; + topRegistersMask11 = ((reg11 < 0) ? (((usqInt)(1)) >> (-reg11)) : (1U << reg11)); } if (rTop21 == NoReg) { rTop21 = allocateFloatRegNotConflictingWith(topRegistersMask11); } if (rNext16 == NoReg) { - rNext16 = allocateFloatRegNotConflictingWith(1U << rTop21); + rNext16 = allocateFloatRegNotConflictingWith(((rTop21 < 0) ? (((usqInt)(1)) >> (-rTop21)) : (1U << rTop21))); } assert(!(((rTop21 == NoReg) || (rNext16 == NoReg)))); @@ -42771,13 +42691,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg12 = (frNext = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask12 = 1U << reg12; + topRegistersMask12 = ((reg12 < 0) ? (((usqInt)(1)) >> (-reg12)) : (1U << reg12)); } if (frTop2 == NoReg) { frTop2 = allocateFloatRegNotConflictingWith(topRegistersMask12); } if (frNext == NoReg) { - frNext = allocateFloatRegNotConflictingWith(1U << frTop2); + frNext = allocateFloatRegNotConflictingWith(((frTop2 < 0) ? (((usqInt)(1)) >> (-frTop2)) : (1U << frTop2))); } rResult7 = allocateRegNotConflictingWith(0); assert(!(((frTop2 == NoReg) @@ -42823,13 +42743,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg13 = (frNext1 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask13 = 1U << reg13; + topRegistersMask13 = ((reg13 < 0) ? (((usqInt)(1)) >> (-reg13)) : (1U << reg13)); } if (frTop3 == NoReg) { frTop3 = allocateFloatRegNotConflictingWith(topRegistersMask13); } if (frNext1 == NoReg) { - frNext1 = allocateFloatRegNotConflictingWith(1U << frTop3); + frNext1 = allocateFloatRegNotConflictingWith(((frTop3 < 0) ? (((usqInt)(1)) >> (-frTop3)) : (1U << frTop3))); } rResult8 = allocateRegNotConflictingWith(0); assert(!(((frTop3 == NoReg) @@ -42875,13 +42795,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg14 = (frNext2 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask14 = 1U << reg14; + topRegistersMask14 = ((reg14 < 0) ? (((usqInt)(1)) >> (-reg14)) : (1U << reg14)); } if (frTop4 == NoReg) { frTop4 = allocateFloatRegNotConflictingWith(topRegistersMask14); } if (frNext2 == NoReg) { - frNext2 = allocateFloatRegNotConflictingWith(1U << frTop4); + frNext2 = allocateFloatRegNotConflictingWith(((frTop4 < 0) ? (((usqInt)(1)) >> (-frTop4)) : (1U << frTop4))); } rResult9 = allocateRegNotConflictingWith(0); assert(!(((frTop4 == NoReg) @@ -42927,13 +42847,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg15 = (frNext3 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask15 = 1U << reg15; + topRegistersMask15 = ((reg15 < 0) ? (((usqInt)(1)) >> (-reg15)) : (1U << reg15)); } if (frTop5 == NoReg) { frTop5 = allocateFloatRegNotConflictingWith(topRegistersMask15); } if (frNext3 == NoReg) { - frNext3 = allocateFloatRegNotConflictingWith(1U << frTop5); + frNext3 = allocateFloatRegNotConflictingWith(((frTop5 < 0) ? (((usqInt)(1)) >> (-frTop5)) : (1U << frTop5))); } rResult10 = allocateRegNotConflictingWith(0); assert(!(((frTop5 == NoReg) @@ -42979,13 +42899,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg16 = (frNext4 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask16 = 1U << reg16; + topRegistersMask16 = ((reg16 < 0) ? (((usqInt)(1)) >> (-reg16)) : (1U << reg16)); } if (frTop6 == NoReg) { frTop6 = allocateFloatRegNotConflictingWith(topRegistersMask16); } if (frNext4 == NoReg) { - frNext4 = allocateFloatRegNotConflictingWith(1U << frTop6); + frNext4 = allocateFloatRegNotConflictingWith(((frTop6 < 0) ? (((usqInt)(1)) >> (-frTop6)) : (1U << frTop6))); } rResult12 = allocateRegNotConflictingWith(0); assert(!(((frTop6 == NoReg) @@ -43030,13 +42950,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg17 = (rNext17 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask17 = 1U << reg17; + topRegistersMask17 = ((reg17 < 0) ? (((usqInt)(1)) >> (-reg17)) : (1U << reg17)); } if (rTop22 == NoReg) { rTop22 = allocateFloatRegNotConflictingWith(topRegistersMask17); } if (rNext17 == NoReg) { - rNext17 = allocateFloatRegNotConflictingWith(1U << rTop22); + rNext17 = allocateFloatRegNotConflictingWith(((rTop22 < 0) ? (((usqInt)(1)) >> (-rTop22)) : (1U << rTop22))); } assert(!(((rTop22 == NoReg) || (rNext17 == NoReg)))); @@ -43063,7 +42983,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (frTop7 == NoReg) { frTop7 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); } - frResult2 = allocateFloatRegNotConflictingWith(1U << frTop7); + frResult2 = allocateFloatRegNotConflictingWith(((frTop7 < 0) ? (((usqInt)(1)) >> (-frTop7)) : (1U << frTop7))); assert(!(((frTop7 == NoReg) || (frResult2 == NoReg)))); value12 = frTop7; @@ -43088,13 +43008,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg18 = (frNext5 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask18 = 1U << reg18; + topRegistersMask18 = ((reg18 < 0) ? (((usqInt)(1)) >> (-reg18)) : (1U << reg18)); } if (frTop8 == NoReg) { frTop8 = allocateFloatRegNotConflictingWith(topRegistersMask18); } if (frNext5 == NoReg) { - frNext5 = allocateFloatRegNotConflictingWith(1U << frTop8); + frNext5 = allocateFloatRegNotConflictingWith(((frTop8 < 0) ? (((usqInt)(1)) >> (-frTop8)) : (1U << frTop8))); } rResult13 = allocateRegNotConflictingWith(0); assert(!(((frTop8 == NoReg) @@ -43158,13 +43078,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg19 = (rNext18 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask20 = 1U << reg19; + topRegistersMask20 = ((reg19 < 0) ? (((usqInt)(1)) >> (-reg19)) : (1U << reg19)); } if (rTop23 == NoReg) { rTop23 = allocateFloatRegNotConflictingWith(topRegistersMask20); } if (rNext18 == NoReg) { - rNext18 = allocateFloatRegNotConflictingWith(1U << rTop23); + rNext18 = allocateFloatRegNotConflictingWith(((rTop23 < 0) ? (((usqInt)(1)) >> (-rTop23)) : (1U << rTop23))); } assert(!(((rTop23 == NoReg) || (rNext18 == NoReg)))); @@ -43300,13 +43220,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg20 = (rNext19 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask22 = 1U << reg20; + topRegistersMask22 = ((reg20 < 0) ? (((usqInt)(1)) >> (-reg20)) : (1U << reg20)); } if (rTop24 == NoReg) { rTop24 = allocateFloatRegNotConflictingWith(topRegistersMask22); } if (rNext19 == NoReg) { - rNext19 = allocateFloatRegNotConflictingWith(1U << rTop24); + rNext19 = allocateFloatRegNotConflictingWith(((rTop24 < 0) ? (((usqInt)(1)) >> (-rTop24)) : (1U << rTop24))); } assert(!(((rTop24 == NoReg) || (rNext19 == NoReg)))); @@ -43331,13 +43251,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg21 = (rNext20 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask23 = 1U << reg21; + topRegistersMask23 = ((reg21 < 0) ? (((usqInt)(1)) >> (-reg21)) : (1U << reg21)); } if (rTop25 == NoReg) { rTop25 = allocateFloatRegNotConflictingWith(topRegistersMask23); } if (rNext20 == NoReg) { - rNext20 = allocateFloatRegNotConflictingWith(1U << rTop25); + rNext20 = allocateFloatRegNotConflictingWith(((rTop25 < 0) ? (((usqInt)(1)) >> (-rTop25)) : (1U << rTop25))); } assert(!(((rTop25 == NoReg) || (rNext20 == NoReg)))); @@ -43363,13 +43283,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg22 = (frNext6 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask24 = 1U << reg22; + topRegistersMask24 = ((reg22 < 0) ? (((usqInt)(1)) >> (-reg22)) : (1U << reg22)); } if (frTop15 == NoReg) { frTop15 = allocateFloatRegNotConflictingWith(topRegistersMask24); } if (frNext6 == NoReg) { - frNext6 = allocateFloatRegNotConflictingWith(1U << frTop15); + frNext6 = allocateFloatRegNotConflictingWith(((frTop15 < 0) ? (((usqInt)(1)) >> (-frTop15)) : (1U << frTop15))); } rResult18 = allocateRegNotConflictingWith(0); assert(!(((frTop15 == NoReg) @@ -43415,13 +43335,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg23 = (frNext7 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask25 = 1U << reg23; + topRegistersMask25 = ((reg23 < 0) ? (((usqInt)(1)) >> (-reg23)) : (1U << reg23)); } if (frTop16 == NoReg) { frTop16 = allocateFloatRegNotConflictingWith(topRegistersMask25); } if (frNext7 == NoReg) { - frNext7 = allocateFloatRegNotConflictingWith(1U << frTop16); + frNext7 = allocateFloatRegNotConflictingWith(((frTop16 < 0) ? (((usqInt)(1)) >> (-frTop16)) : (1U << frTop16))); } rResult19 = allocateRegNotConflictingWith(0); assert(!(((frTop16 == NoReg) @@ -43467,13 +43387,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg24 = (frNext8 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask26 = 1U << reg24; + topRegistersMask26 = ((reg24 < 0) ? (((usqInt)(1)) >> (-reg24)) : (1U << reg24)); } if (frTop17 == NoReg) { frTop17 = allocateFloatRegNotConflictingWith(topRegistersMask26); } if (frNext8 == NoReg) { - frNext8 = allocateFloatRegNotConflictingWith(1U << frTop17); + frNext8 = allocateFloatRegNotConflictingWith(((frTop17 < 0) ? (((usqInt)(1)) >> (-frTop17)) : (1U << frTop17))); } rResult20 = allocateRegNotConflictingWith(0); assert(!(((frTop17 == NoReg) @@ -43519,13 +43439,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg25 = (frNext9 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask27 = 1U << reg25; + topRegistersMask27 = ((reg25 < 0) ? (((usqInt)(1)) >> (-reg25)) : (1U << reg25)); } if (frTop18 == NoReg) { frTop18 = allocateFloatRegNotConflictingWith(topRegistersMask27); } if (frNext9 == NoReg) { - frNext9 = allocateFloatRegNotConflictingWith(1U << frTop18); + frNext9 = allocateFloatRegNotConflictingWith(((frTop18 < 0) ? (((usqInt)(1)) >> (-frTop18)) : (1U << frTop18))); } rResult22 = allocateRegNotConflictingWith(0); assert(!(((frTop18 == NoReg) @@ -43571,13 +43491,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg26 = (frNext10 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask28 = 1U << reg26; + topRegistersMask28 = ((reg26 < 0) ? (((usqInt)(1)) >> (-reg26)) : (1U << reg26)); } if (frTop19 == NoReg) { frTop19 = allocateFloatRegNotConflictingWith(topRegistersMask28); } if (frNext10 == NoReg) { - frNext10 = allocateFloatRegNotConflictingWith(1U << frTop19); + frNext10 = allocateFloatRegNotConflictingWith(((frTop19 < 0) ? (((usqInt)(1)) >> (-frTop19)) : (1U << frTop19))); } rResult23 = allocateRegNotConflictingWith(0); assert(!(((frTop19 == NoReg) @@ -43622,13 +43542,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg27 = (rNext21 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask29 = 1U << reg27; + topRegistersMask29 = ((reg27 < 0) ? (((usqInt)(1)) >> (-reg27)) : (1U << reg27)); } if (rTop26 == NoReg) { rTop26 = allocateFloatRegNotConflictingWith(topRegistersMask29); } if (rNext21 == NoReg) { - rNext21 = allocateFloatRegNotConflictingWith(1U << rTop26); + rNext21 = allocateFloatRegNotConflictingWith(((rTop26 < 0) ? (((usqInt)(1)) >> (-rTop26)) : (1U << rTop26))); } assert(!(((rTop26 == NoReg) || (rNext21 == NoReg)))); @@ -43655,7 +43575,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (frTop20 == NoReg) { frTop20 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); } - frResult3 = allocateFloatRegNotConflictingWith(1U << frTop20); + frResult3 = allocateFloatRegNotConflictingWith(((frTop20 < 0) ? (((usqInt)(1)) >> (-frTop20)) : (1U << frTop20))); assert(!(((frTop20 == NoReg) || (frResult3 == NoReg)))); value24 = frTop20; @@ -43680,13 +43600,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg28 = (frNext11 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask30 = 1U << reg28; + topRegistersMask30 = ((reg28 < 0) ? (((usqInt)(1)) >> (-reg28)) : (1U << reg28)); } if (frTop21 == NoReg) { frTop21 = allocateFloatRegNotConflictingWith(topRegistersMask30); } if (frNext11 == NoReg) { - frNext11 = allocateFloatRegNotConflictingWith(1U << frTop21); + frNext11 = allocateFloatRegNotConflictingWith(((frTop21 < 0) ? (((usqInt)(1)) >> (-frTop21)) : (1U << frTop21))); } rResult24 = allocateRegNotConflictingWith(0); assert(!(((frTop21 == NoReg) @@ -43750,13 +43670,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg29 = (rNext22 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask32 = 1U << reg29; + topRegistersMask32 = ((reg29 < 0) ? (((usqInt)(1)) >> (-reg29)) : (1U << reg29)); } if (rTop27 == NoReg) { rTop27 = allocateFloatRegNotConflictingWith(topRegistersMask32); } if (rNext22 == NoReg) { - rNext22 = allocateFloatRegNotConflictingWith(1U << rTop27); + rNext22 = allocateFloatRegNotConflictingWith(((rTop27 < 0) ? (((usqInt)(1)) >> (-rTop27)) : (1U << rTop27))); } assert(!(((rTop27 == NoReg) || (rNext22 == NoReg)))); @@ -44273,11 +44193,11 @@ genPushMaybeContextReceiverVariable(sqInt slotIndex) AbstractInstruction *jmpSingle; /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ensureReceiverResultRegContainsSelf(); /* begin genPushMaybeContextSlotIndex: */ assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ voidReceiverResultRegContainsSelf(); @@ -44336,7 +44256,7 @@ genPushNewArrayBytecode(void) } else { /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << SendNumArgsReg)) | ((1U << ReceiverResultReg))), simStackPtr, simNativeStackPtr); } size = byte1 & 0x7F; if (!popValues) { @@ -44412,7 +44332,7 @@ genPushRemoteTempLongBytecode(void) (anInstruction->dependent = locateLiteral(offset)); } /* begin availableRegOrNoneNotConflictingWith: */ - regMask = 1U << tempVectReg; + regMask = ((tempVectReg < 0) ? (((usqInt)(1)) >> (-tempVectReg)) : (1U << tempVectReg)); remoteTempReg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); if (remoteTempReg == NoReg) { remoteTempReg = tempVectReg; @@ -44791,11 +44711,11 @@ genSpecialSelectorClass(void) || (topReg == ClassReg)) { /* begin ssAllocateRequiredReg:and: */ requiredReg1 = (topReg = SendNumArgsReg); - ssAllocateRequiredRegMaskupThroughupThroughNative((1U << requiredReg1) | (1U << ClassReg), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((((requiredReg1 < 0) ? (((usqInt)(1)) >> (-requiredReg1)) : (1U << requiredReg1))) | ((1U << ClassReg)), simStackPtr, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr, simNativeStackPtr); } ssPush(1); popToReg(ssTop(), topReg); @@ -45035,7 +44955,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean association = getLiteral(litVarIndex); voidReceiverResultRegContainsSelf(); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin genMoveConstant:R: */ if (shouldAnnotateObjectReference(association)) { annotateobjRef(gMoveCwR(association, ReceiverResultReg), association); @@ -45051,7 +44971,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean # if IMMUTABILITY if (needsImmCheck) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -45066,7 +44986,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -45130,7 +45050,7 @@ genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqI # endif // IMMUTABILITY ssPop(1); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ClassReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ssPush(1); genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); @@ -45179,7 +45099,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea # if IMMUTABILITY if (needsImmCheck1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -45194,7 +45114,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck1, 1); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck1); } @@ -45218,7 +45138,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt assert(needsFrame); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); /* begin MoveMw:r:R: */ offset = frameOffsetOfTemporary(remoteTempIndex); @@ -45231,7 +45151,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt # if IMMUTABILITY # endif - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -45426,13 +45346,13 @@ genVanillaInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -45747,12 +45667,12 @@ liveRegisters(void) } else { /* begin registerMaskFor: */ - regsSet = 1U << ReceiverResultReg; + regsSet = (1U << ReceiverResultReg); if ((methodOrBlockNumArgs <= 2 /* numRegArgs */) && (methodOrBlockNumArgs > 0)) { - regsSet = regsSet | (1U << Arg0Reg); + regsSet = regsSet | ((1U << Arg0Reg)); if (methodOrBlockNumArgs > 1) { - regsSet = regsSet | (1U << Arg1Reg); + regsSet = regsSet | ((1U << Arg1Reg)); } } } @@ -45861,13 +45781,13 @@ marshallSendArguments(sqInt numArgs) if (numArgs > 0) { if (numArgs > 1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 2, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 2, simNativeStackPtr); /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg1Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg1Reg), simStackPtr - 1, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 1, simNativeStackPtr); } } if (numArgs > 1) { @@ -46447,7 +46367,7 @@ ssAllocateRequiredFloatRegMaskupThroughupThroughNative(sqInt requiredRegsMask, s static void NoDbgRegParms ssAllocateRequiredFloatReg(sqInt requiredReg) { - ssAllocateRequiredFloatRegMaskupThroughupThroughNative(1U << requiredReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredFloatRegMaskupThroughupThroughNative(((requiredReg < 0) ? (((usqInt)(1)) >> (-requiredReg)) : (1U << requiredReg)), simStackPtr, simNativeStackPtr); } /* StackToRegisterMappingCogit>>#ssAllocateRequiredRegMask:upThrough:upThroughNative: */ diff --git a/spurlowcodesrc/vm/cogitIA32.c b/spurlowcodesrc/vm/cogitIA32.c index 6885de2ebb..b06f2efa42 100644 --- a/spurlowcodesrc/vm/cogitIA32.c +++ b/spurlowcodesrc/vm/cogitIA32.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + CCodeGenerator VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + StackToRegisterMappingCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 " __DATE__ ; +static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__cogitBuildInfo = __buildInfo; @@ -55,17 +55,17 @@ char *__cogitBuildInfo = __buildInfo; #define ArithmeticShiftRightRR 92 #define BadRegisterSet 1 #define BlockCreationBytecodeSize 4 -#define BSR 168 +#define BSR 170 #define BytecodeSetHasDirectedSuperSend 1 #define Call 6 #define CallerSavedRegisterMask 0x6 #define CallFull 7 #define CallR 8 -#define CDQ 159 +#define CDQ 161 #if !defined(CheckRememberedInTrampoline) /* Allow this to be overridden on the compiler command line */ # define CheckRememberedInTrampoline 0 #endif -#define CLD 164 +#define CLD 166 #define ClassArray 7 #define ClassArrayCompactIndex 51 #define ClassBlockClosureCompactIndex 37 @@ -89,7 +89,7 @@ char *__cogitBuildInfo = __buildInfo; #define CMMaxUsageCount 7 #define CMMethod 2 #define CMOpenPIC 5 -#define CMPXCHGRAw 174 +#define CMPXCHGRAw 176 #define CmpC32R 113 #define CmpCqR 105 #define CmpCwR 112 @@ -104,7 +104,7 @@ char *__cogitBuildInfo = __buildInfo; #define ConvertRRs 150 #define ConvertRsR 149 #define ConvertRsRd 147 -#define CPUID 158 +#define CPUID 160 #define Debug DEBUGVM #define DisplacementMask 0x1F #define DisplacementX2N 0 @@ -142,8 +142,8 @@ char *__cogitBuildInfo = __buildInfo; #define FoxSavedFP 0 #define FoxThisContext -8 #define FPReg 5 -#define FSTPD 163 -#define FSTPS 162 +#define FSTPD 165 +#define FSTPS 164 #define FullClosureCompiledBlockIndex 1 #define FullClosureFirstCopiedValueIndex 4 #define FullClosureReceiverIndex 3 @@ -154,11 +154,11 @@ char *__cogitBuildInfo = __buildInfo; #define HashMultiplyConstant 1664525 #define HashMultiplyMask 0xFFFFFFF #define HeaderIndex 0 -#define IDIVR 160 +#define IDIVR 162 #if !defined(IMMUTABILITY) /* Allow this to be overridden on the compiler command line */ # define IMMUTABILITY 1 #endif -#define IMULRR 161 +#define IMULRR 163 #define InFullBlock 2 #define InstanceSpecificationIndex 2 #define InstructionPointerIndex 1 @@ -209,10 +209,10 @@ char *__cogitBuildInfo = __buildInfo; #define Label 1 #define LargeContextSlots 62 #define LastJump 42 -#define LFENCE 170 +#define LFENCE 172 #undef LinkReg #define Literal 2 -#define LOCK 173 +#define LOCK 175 #define LoadEffectiveAddressMwrR 88 #define LogicalShiftLeftCqR 95 #define LogicalShiftLeftCqRR 129 @@ -236,11 +236,11 @@ char *__cogitBuildInfo = __buildInfo; #define MethodCacheSelector 1 #define MethodIndex 3 #define MethodTooBig -4 -#define MFENCE 171 +#define MFENCE 173 #define MFMethodFlagHasContextFlag 1 #define MFMethodFlagIsBlockFlag 2 -#define MOVSB 166 -#define MOVSD 167 +#define MOVSB 168 +#define MOVSD 169 #define ModReg 3 #define ModRegInd 0 #define ModRegRegDisp32 2 @@ -257,6 +257,8 @@ char *__cogitBuildInfo = __buildInfo; #define MoveM8rR 54 #define MoveMbrR 65 #define MoveMwrR 50 +#define MovePerfCnt64RL 159 +#define MovePerfCnt64RRL 158 #define MoveRAb 49 #define MoveRAw 46 #define MoveRdM64r 76 @@ -315,17 +317,17 @@ char *__cogitBuildInfo = __buildInfo; #define PushCq 82 #define PushCw 83 #define PushR 81 -#define REP 165 +#define REP 167 #define ReceiverIndex 5 #define ReceiverResultReg 2 #define RetN 9 #undef RISCTempReg -#define SETE 175 +#define SETE 177 #define SelectorCannotInterpret 34 #define SelectorDoesNotUnderstand 20 #define SenderIndex 0 #define SendNumArgsReg 3 -#define SFENCE 172 +#define SFENCE 174 #define ShouldNotJIT -8 #define SIB1 0 #define SIB4 2 @@ -372,7 +374,7 @@ char *__cogitBuildInfo = __buildInfo; #define UnimplementedPrimitive -7 #define ValueIndex 1 #undef VarBaseReg -#define XCHGRR 169 +#define XCHGRR 171 #define XorCwR 118 #define XorRdRd 137 #define XorRR 104 @@ -519,7 +521,7 @@ static sqInt NoDbgRegParms concretizeAt(AbstractInstruction * self_in_concretize static sqInt NoDbgRegParms genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer); static sqInt NoDbgRegParms genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers); static sqInt NoDbgRegParms genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers); -static sqInt NoDbgRegParms genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg); +static sqInt NoDbgRegParms genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg); static sqInt NoDbgRegParms genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers); static void NoDbgRegParms genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister); static void NoDbgRegParms genWriteCSecondResultIntoReg(AbstractInstruction * self_in_genWriteCSecondResultIntoReg, sqInt abstractRegister); @@ -546,6 +548,7 @@ static sqInt NoDbgRegParms cmpC32RTempByteSize(AbstractInstruction * self_in_cmp static sqInt NoDbgRegParms computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize); static sqInt NoDbgRegParms computeShiftRRSize(AbstractInstruction * self_in_computeShiftRRSize); static sqInt NoDbgRegParms concretizeFill32(AbstractInstruction * self_in_concretizeFill32); +static sqInt NoDbgRegParms concretizeMovePerfCnt64RRL(AbstractInstruction * self_in_concretizeMovePerfCnt64RRL); static sqInt NoDbgRegParms concretizeOpRR(AbstractInstruction * self_in_concretizeOpRR, sqInt x86opcode); static sqInt NoDbgRegParms concretizeReverseOpRR(AbstractInstruction * self_in_concretizeReverseOpRR, sqInt x86opcode); static sqInt NoDbgRegParms concretizeSet(AbstractInstruction * self_in_concretizeSet, sqInt conditionCode); @@ -782,6 +785,8 @@ extern void linkSendAtintooffsetreceiver(sqInt callSiteReturnAddress, CogMethod static BytecodeDescriptor * loadBytesAndGetDescriptor(void); static void NoDbgRegParms loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc); static AbstractInstruction * NoDbgRegParms gMoveCwR(sqInt wordConstant, sqInt reg); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters); static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg); static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC); @@ -1209,6 +1214,7 @@ static sqInt genStoreAndPopReceiverVariableBytecode(void); static sqInt genStoreAndPopRemoteTempLongBytecode(void); static sqInt genStoreAndPopTemporaryVariableBytecode(void); static sqInt genStoreRemoteTempLongBytecode(void); +static void genTakeProfileSample(void); static sqInt genUnconditionalTrapBytecode(void); static void NoDbgRegParms loadNativeArgumentAddressto(sqInt baseOffset, sqInt reg); static void NoDbgRegParms loadNativeFramePointerInto(sqInt reg); @@ -2811,28 +2817,28 @@ addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *an static sqInt NoDbgRegParms availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << DPFPReg0)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg0))) != 0))) { return DPFPReg0; } - if (!(((liveRegsMask & (1U << DPFPReg1)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg1))) != 0))) { return DPFPReg1; } - if (!(((liveRegsMask & (1U << DPFPReg2)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg2))) != 0))) { return DPFPReg2; } - if (!(((liveRegsMask & (1U << DPFPReg3)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg3))) != 0))) { return DPFPReg3; } - if (!(((liveRegsMask & (1U << DPFPReg4)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg4))) != 0))) { return DPFPReg4; } - if (!(((liveRegsMask & (1U << DPFPReg5)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg5))) != 0))) { return DPFPReg5; } - if (!(((liveRegsMask & (1U << DPFPReg6)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg6))) != 0))) { return DPFPReg6; } - if (!(((liveRegsMask & (1U << DPFPReg7)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg7))) != 0))) { return DPFPReg7; } return NoReg; @@ -2847,19 +2853,19 @@ availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegi static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << Arg1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg1Reg))) != 0))) { return Arg1Reg; } - if (!(((liveRegsMask & (1U << Arg0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg0Reg))) != 0))) { return Arg0Reg; } - if (!(((liveRegsMask & (1U << SendNumArgsReg)) != 0))) { + if (!(((liveRegsMask & ((1U << SendNumArgsReg))) != 0))) { return SendNumArgsReg; } - if (!(((liveRegsMask & (1U << ClassReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ClassReg))) != 0))) { return ClassReg; } - if (!(((liveRegsMask & (1U << ReceiverResultReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ReceiverResultReg))) != 0))) { return ReceiverResultReg; } return NoReg; @@ -2974,9 +2980,9 @@ genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers) used immediately afterwards. */ - /* CogAbstractInstruction>>#genLoadStackPointersForFastPrimCall: */ + /* CogAbstractInstruction>>#genLoadStackPointersForPrimCall: */ static sqInt NoDbgRegParms -genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg) +genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg) { AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; @@ -3336,6 +3342,7 @@ computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize) case OrRR: case XorRR: case SubRR: + case SubbRR: case NegateR: case NotR: case MoveRR: @@ -3574,6 +3581,11 @@ computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize) ? 7 : 0); + case MovePerfCnt64RRL: + + /* it is easier to calculate the right value by concretizing. We concretize twice, but so what? */ + return concretizeMovePerfCnt64RRL(self_in_computeMaximumSize); + default: error("Case not found and no otherwise clause"); } @@ -3613,6 +3625,63 @@ concretizeFill32(AbstractInstruction * self_in_concretizeFill32) return 4; } + +/* Generate code for + 0x0: 50 pushl %eax + 0x1: 52 pushl %edx + 0x2: 0f 31 rdtsc + 0x4: 89 f8 movl %edi, %eax + 0x6: 89 f2 movl %esi, %edx + 0x8: 5a popl %edx + et al */ + + /* CogIA32Compiler>>#concretizeMovePerfCnt64RRL */ +static sqInt NoDbgRegParms +concretizeMovePerfCnt64RRL(AbstractInstruction * self_in_concretizeMovePerfCnt64RRL) +{ + usqInt liveRegisters; + sqInt offset; + usqInt regHi; + usqInt regLo; + + regLo = ((self_in_concretizeMovePerfCnt64RRL->operands))[0]; + regHi = ((self_in_concretizeMovePerfCnt64RRL->operands))[1]; + liveRegisters = ((self_in_concretizeMovePerfCnt64RRL->operands))[2]; + offset = 0; + if (((liveRegisters & ((1U << EAX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[0] = 80; + offset += 1; + } + if (((liveRegisters & ((1U << EDX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset] = 82; + offset += 1; + } + assert(!(((regLo == EDX) + || (regHi == EAX)))); + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset] = 15; + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset + 1] = 49; + offset += 2; + if (regHi != EDX) { + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset] = 137; + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset + 1] = (modRMRO(self_in_concretizeMovePerfCnt64RRL, ModReg, regHi, EDX)); + offset += 2; + } + if (regLo != EAX) { + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset + 4] = 137; + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset + 5] = (modRMRO(self_in_concretizeMovePerfCnt64RRL, ModReg, regLo, EAX)); + offset += 2; + } + if (((liveRegisters & ((1U << EDX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset] = 90; + offset += 1; + } + if (((liveRegisters & ((1U << EAX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset] = 88; + offset += 1; + } + return offset; +} + /* CogIA32Compiler>>#concretizeOpRR: */ static sqInt NoDbgRegParms concretizeOpRR(AbstractInstruction * self_in_concretizeOpRR, sqInt x86opcode) @@ -3956,7 +4025,6 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) usqInt regLHS10; usqInt regLHS11; usqInt regLHS12; - usqInt regLHS13; usqInt regLHS2; usqInt regLHS3; usqInt regLHS4; @@ -3970,7 +4038,6 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) usqInt regRHS10; usqInt regRHS11; usqInt regRHS12; - usqInt regRHS13; usqInt regRHS2; usqInt regRHS3; usqInt regRHS4; @@ -5121,31 +5188,26 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) return concretizeOpRR(self_in_dispatchConcretize, 43); case SubbRR: - /* begin concretizeSubbRR */ - regLHS9 = ((self_in_dispatchConcretize->operands))[0]; - regRHS9 = ((self_in_dispatchConcretize->operands))[1]; - ((self_in_dispatchConcretize->machineCode))[0] = 27; - ((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, regLHS9, regRHS9)); - return 2; + return concretizeOpRR(self_in_dispatchConcretize, 27); case SubRdRd: /* begin concretizeSEE2OpRdRd: */ - regRHS10 = ((self_in_dispatchConcretize->operands))[0]; - regLHS10 = ((self_in_dispatchConcretize->operands))[1]; + regRHS9 = ((self_in_dispatchConcretize->operands))[0]; + regLHS9 = ((self_in_dispatchConcretize->operands))[1]; ((self_in_dispatchConcretize->machineCode))[0] = 242; ((self_in_dispatchConcretize->machineCode))[1] = 15; ((self_in_dispatchConcretize->machineCode))[2] = 92; - ((self_in_dispatchConcretize->machineCode))[3] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS10, regLHS10)); + ((self_in_dispatchConcretize->machineCode))[3] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS9, regLHS9)); return 4; case SubRsRs: /* begin concretizeSEEOpRsRs: */ - regRHS11 = ((self_in_dispatchConcretize->operands))[0]; - regLHS11 = ((self_in_dispatchConcretize->operands))[1]; + regRHS10 = ((self_in_dispatchConcretize->operands))[0]; + regLHS10 = ((self_in_dispatchConcretize->operands))[1]; ((self_in_dispatchConcretize->machineCode))[0] = 243; ((self_in_dispatchConcretize->machineCode))[1] = 15; ((self_in_dispatchConcretize->machineCode))[2] = 92; - ((self_in_dispatchConcretize->machineCode))[3] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS11, regLHS11)); + ((self_in_dispatchConcretize->machineCode))[3] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS10, regLHS10)); return 4; case SqrtRd: @@ -5191,21 +5253,21 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) case XorRdRd: /* begin concretizeXorRdRd */ - regRHS12 = ((self_in_dispatchConcretize->operands))[0]; - regLHS12 = ((self_in_dispatchConcretize->operands))[1]; + regRHS11 = ((self_in_dispatchConcretize->operands))[0]; + regLHS11 = ((self_in_dispatchConcretize->operands))[1]; ((self_in_dispatchConcretize->machineCode))[0] = 102; ((self_in_dispatchConcretize->machineCode))[1] = 15; ((self_in_dispatchConcretize->machineCode))[2] = 87; - ((self_in_dispatchConcretize->machineCode))[3] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS12, regLHS12)); + ((self_in_dispatchConcretize->machineCode))[3] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS11, regLHS11)); return 4; case XorRsRs: /* begin concretizeXorRsRs */ - regRHS13 = ((self_in_dispatchConcretize->operands))[0]; - regLHS13 = ((self_in_dispatchConcretize->operands))[1]; + regRHS12 = ((self_in_dispatchConcretize->operands))[0]; + regLHS12 = ((self_in_dispatchConcretize->operands))[1]; ((self_in_dispatchConcretize->machineCode))[0] = 15; ((self_in_dispatchConcretize->machineCode))[1] = 87; - ((self_in_dispatchConcretize->machineCode))[2] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS13, regLHS13)); + ((self_in_dispatchConcretize->machineCode))[2] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS12, regLHS12)); return 3; case NegateR: @@ -6199,6 +6261,9 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) case ZeroExtend16RR: return concretizeZeroExtend16RR(self_in_dispatchConcretize); + case MovePerfCnt64RRL: + return concretizeMovePerfCnt64RRL(self_in_dispatchConcretize); + default: error("Case not found and no otherwise clause"); } @@ -6872,7 +6937,7 @@ genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask) assert(!((((regMask & (registerMaskForand(ESP, EBP))) != 0)))); for (reg = EAX; reg <= EDI; reg += 1) { - if (((regMask & (1U << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)))) != 0)) { genoperand(PopR, reg); } } @@ -6893,7 +6958,7 @@ genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask) assert(((EDI - EAX) + 1) == 8); assert(!((((regMask & (registerMaskForand(ESP, EBP))) != 0)))); for (reg = EDI; reg >= EAX; reg += -1) { - if (((regMask & (1U << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)))) != 0)) { genoperand(PushR, reg); } } @@ -9997,7 +10062,7 @@ compileCallFornumArgsargargargargfloatResultRegregsToSave(void *aRoutine, sqInt regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1U << resultRegOrNone)) - (1U << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1U << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1U << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ regMaskCopy = ((usqInt)regsToSave); @@ -10100,7 +10165,7 @@ compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numAr regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1U << resultRegOrNone)) - (1U << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1U << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1U << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ regMaskCopy = ((usqInt)regsToSave); @@ -10201,7 +10266,7 @@ compileCallFornumArgsargargargargresultRegresultRegregsToSave(void *aRoutine, sq regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1U << resultRegOrNone)) - (1U << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1U << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1U << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ regMaskCopy = ((usqInt)regsToSave); @@ -10311,7 +10376,7 @@ compileCallFornumArgsfloatArgfloatArgfloatArgfloatArgresultRegregsToSave(void *a regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1U << resultRegOrNone)) - (1U << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1U << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1U << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ regMaskCopy = ((usqInt)regsToSave); @@ -13459,6 +13524,22 @@ gMoveCwR(sqInt wordConstant, sqInt reg) return anInstruction; } + /* Cogit>>#MovePerfCnt64R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters) +{ + assert(BytesPerWord == 8); + return genoperandoperand(MovePerfCnt64RL, destReg, liveRegisters); +} + + /* Cogit>>#MovePerfCnt64R:R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters) +{ + assert(BytesPerWord == 4); + return genoperandoperandoperand(MovePerfCnt64RRL, destRegLo, destRegHi, liveRegisters); +} + /* Answer the address of the null byte at the end of the method map. */ @@ -14990,11 +15071,14 @@ recordRunTimeObjectReferences(void) } } + +/* N.B. (self registerMaskFor: NoReg) = 0 */ + /* Cogit>>#registerMaskFor: */ static sqInt NoDbgRegParms registerMaskFor(sqInt reg) { - return 1U << reg; + return ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } /* Cogit>>#registerMaskFor:and: */ @@ -21813,7 +21897,7 @@ generateObjectRepresentationTrampolines(void) } # endif // IMMUTABILITY ceNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceNewHash", 1, ReceiverResultReg, null, null, null, /* begin emptyRegisterMask */ 0, 1, ReceiverResultReg, 0); - ceInlineNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceInlineNewHash", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, ReceiverResultReg, 0); + ceInlineNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceInlineNewHash", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))), 1, ReceiverResultReg, 0); /* begin genStoreCheckTrampoline */ if (CheckRememberedInTrampoline) { zeroOpcodeIndex(); @@ -21824,7 +21908,7 @@ generateObjectRepresentationTrampolines(void) genoperand(RetN, 0); jmpTarget(jumpSC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); } - ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))), 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), CheckRememberedInTrampoline); ceStoreCheckContextReceiverTrampoline = genStoreCheckContextReceiverTrampoline(); @@ -23964,7 +24048,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jumpRC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg)); jmpTarget(jumpImmutable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); @@ -23980,7 +24064,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* Store check */ jumpImmutable1 = genJumpImmutablescratchReg(ReceiverResultReg, SendNumArgsReg); - compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), 0 /* emptyRegisterMask */); genLoadStackPointers(backEnd()); @@ -24545,7 +24629,7 @@ registerMask(SimStackEntry * self_in_registerMask) || (((self_in_registerMask->type)) == SSRegister) ? (/* begin registerMaskFor: */ (reg = (self_in_registerMask->registerr)), - 1U << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg))) : 0); } @@ -24558,7 +24642,7 @@ registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone) return (((self_in_registerMaskOrNone->type)) == SSRegister ? (/* begin registerMaskFor: */ (reg = (self_in_registerMaskOrNone->registerr)), - 1U << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg))) : 0); } @@ -24756,7 +24840,7 @@ nativeFloatRegisterMask(CogSimStackNativeEntry * self_in_nativeFloatRegisterMask || (((self_in_nativeFloatRegisterMask->type)) == SSRegisterDoubleFloat) ? (/* begin registerMaskFor: */ (reg = (self_in_nativeFloatRegisterMask->registerr)), - 1U << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg))) : 0); } @@ -24958,9 +25042,9 @@ nativeRegisterMask(CogSimStackNativeEntry * self_in_nativeRegisterMask) || (((self_in_nativeRegisterMask->type)) == SSRegisterDoubleFloat) ? (/* begin registerMaskFor: */ (reg = (self_in_nativeRegisterMask->registerr)), - 1U << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg))) : (((self_in_nativeRegisterMask->type)) == SSRegisterPair - ? (1U << ((self_in_nativeRegisterMask->registerr))) | (1U << ((self_in_nativeRegisterMask->registerSecond))) + ? (((((self_in_nativeRegisterMask->registerr)) < 0) ? (((usqInt)(1)) >> (-((self_in_nativeRegisterMask->registerr)))) : (1U << ((self_in_nativeRegisterMask->registerr))))) | (((((self_in_nativeRegisterMask->registerSecond)) < 0) ? (((usqInt)(1)) >> (-((self_in_nativeRegisterMask->registerSecond)))) : (1U << ((self_in_nativeRegisterMask->registerSecond))))) : 0)); } @@ -25208,54 +25292,43 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) { AbstractInstruction *abstractInstruction; AbstractInstruction *abstractInstruction1; - AbstractInstruction *abstractInstruction2; - AbstractInstruction *abstractInstruction3; sqInt address; - sqInt address1; - sqInt address2; AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; + AbstractInstruction *anInstruction10; AbstractInstruction *anInstruction11; + AbstractInstruction *anInstruction110; AbstractInstruction *anInstruction13; AbstractInstruction *anInstruction14; + AbstractInstruction *anInstruction15; + AbstractInstruction *anInstruction16; AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction18; AbstractInstruction *anInstruction19; + AbstractInstruction *anInstruction2; AbstractInstruction *anInstruction20; AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction25; + AbstractInstruction *anInstruction210; + AbstractInstruction *anInstruction22; AbstractInstruction *anInstruction26; AbstractInstruction *anInstruction27; - AbstractInstruction *anInstruction28; - AbstractInstruction *anInstruction29; - AbstractInstruction *anInstruction30; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction35; - AbstractInstruction *anInstruction36; + AbstractInstruction *anInstruction3; AbstractInstruction *anInstruction4; AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - AbstractInstruction * continuePostSampleNonPrim; - AbstractInstruction * continuePostSamplePrim; + AbstractInstruction * continueAfterProfileSample; + sqInt effectiveLiveRegisters; AbstractInstruction * jmp; - AbstractInstruction * jmpSampleNonPrim; - AbstractInstruction * jmpSamplePrim; + AbstractInstruction * jumpToTakeSample; + sqInt liveRegisters; sqInt offset; sqInt offset1; sqInt offset2; - sqInt operand; - sqInt operand2; - sqInt reg; + sqInt regHi; + sqInt regLo; sqInt retpc; - continuePostSampleNonPrim = ((AbstractInstruction *) 0); - continuePostSamplePrim = ((AbstractInstruction *) 0); - jmpSampleNonPrim = ((AbstractInstruction *) 0); - jmpSamplePrim = ((AbstractInstruction *) 0); + jumpToTakeSample = ((AbstractInstruction *) 0); assert(!((0))); genExternalizePointersForPrimitiveCall(); /* begin genLoadCStackPointersForPrimCall */ @@ -25265,45 +25338,28 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) else { genLoadCStackPointer(backEnd); } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick if so */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin MoveAw:R: */ - address = (nextProfileTickAddress()) + BytesPerWord; - /* begin checkLiteral:forInstruction: */ - anInstruction1 = genoperandoperand(MoveAwR, address, ClassReg); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSampleNonPrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSampleNonPrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } if (recordPrimTraceForMethod(methodObj)) { genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction28 = genoperandoperand(MoveCqR, 0, TempReg); + anInstruction15 = genoperandoperand(MoveCqR, 0, TempReg); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction29 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); + anInstruction16 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); + anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); } /* begin checkLiteral:forInstruction: */ argumentCountAddress(); - anInstruction30 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); + anInstruction17 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { /* begin checkLiteral:forInstruction: */ ((sqInt)primitiveRoutine); - anInstruction5 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); + anInstruction1 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); /* begin checkLiteral:forInstruction: */ primitiveFunctionPointerAddress(); - anInstruction6 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); + anInstruction2 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); } if (((flags & (PrimCallNeedsNewMethod + PrimCallMayEndureCodeCompaction)) != 0)) { @@ -25315,135 +25371,120 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) /* begin MoveMw:r:R: */ offset = offsetof(CogMethod, methodObject); /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); + anInstruction3 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); /* begin checkLiteral:forInstruction: */ newMethodAddress(); - anInstruction8 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); + anInstruction4 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); } /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction31 = genoperand(PrefetchAw, primFailCodeAddress()); + anInstruction18 = genoperand(PrefetchAw, primFailCodeAddress()); if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - /* Sideways call the C primitive routine so that we return through cePrimReturnEnterCogCode. */ /* On Spur ceActivateFailingPrimitiveMethod: would like to retry if forwarders are found. So insist on PrimCallNeedsPrimitiveFunction being set too. */ assert(((flags & PrimCallNeedsPrimitiveFunction) != 0)); /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l23; + goto l11; if (null < NoReg) { /* begin checkQuickConstant:forInstruction: */ - anInstruction35 = genoperand(PushCq, -2 - null); + anInstruction26 = genoperand(PushCq, -2 - null); } else { genoperand(PushR, null); } - l23: /* end genMarshallNArgs:arg:arg:arg:arg: */; + l11: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin genSubstituteReturnAddress: */ retpc = (((flags & PrimCallCollectsProfileSamples) != 0) ? cePrimReturnEnterCogCodeProfiling : cePrimReturnEnterCogCode); /* begin checkLiteral:forInstruction: */ - anInstruction36 = genoperand(PushCw, retpc); + anInstruction27 = genoperand(PushCw, retpc); /* begin annotateCall: */ - anInstruction9 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); - abstractInstruction = anInstruction9; + anInstruction5 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); + abstractInstruction = anInstruction5; (abstractInstruction->annotation = IsRelativeCall); - jmp = (jmpSamplePrim = (continuePostSamplePrim = null)); + return 0; } - else { - - /* Call the C primitive routine. */ - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l31; - genoperand(PushR, 0); - l31: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin annotateCall: */ - anInstruction11 = genoperand(CallFull, ((sqInt)primitiveRoutine)); - abstractInstruction1 = anInstruction11; - (abstractInstruction1->annotation = IsRelativeCall); - /* begin genRemoveNArgsFromStack: */ - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction13 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin MoveAw:R: */ - address1 = (nextProfileTickAddress()) + BytesPerWord; - /* begin checkLiteral:forInstruction: */ - anInstruction14 = genoperandoperand(MoveAwR, address1, ClassReg); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSamplePrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSamplePrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + goto l25; + genoperand(PushR, 0); + l25: /* end genMarshallNArgs:arg:arg:arg:arg: */; + /* begin annotateCall: */ + anInstruction7 = genoperand(CallFull, ((sqInt)primitiveRoutine)); + abstractInstruction1 = anInstruction7; + (abstractInstruction1->annotation = IsRelativeCall); + /* begin genRemoveNArgsFromStack: */ + maybeCompileRetryOnPrimitiveFail(primitiveIndex); + genLoadStackPointersForPrimCall(backEnd, ClassReg); + /* begin checkLiteral:forInstruction: */ + instructionPointerAddress(); + anInstruction10 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); + /* begin checkQuickConstant:forInstruction: */ + anInstruction11 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + /* begin checkLiteral:forInstruction: */ + primFailCodeAddress(); + anInstruction19 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + flag("ask concrete code gen if move sets condition codes?"); + /* begin checkQuickConstant:forInstruction: */ + anInstruction20 = genoperandoperand(CmpCqR, 0, TempReg); + /* begin JumpNonZero: */ + jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + flag("endianness"); + assert(!(((((registerMaskForand(ClassReg, SendNumArgsReg)) & liveRegisters) != 0)))); + effectiveLiveRegisters = liveRegisters | ((1U << ClassReg) | (1U << SendNumArgsReg)); + regLo = Arg0Reg; + regHi = Arg1Reg; + /* begin preferredRegisterPairForMovePerfCnt64RRLInto: */ + if (!(((liveRegisters & ((1U << EAX))) != 0))) { + regLo = EAX; + } + if (!(((liveRegisters & ((1U << EDX))) != 0))) { + regHi = EDX; } - maybeCompileRetryOnPrimitiveFail(primitiveIndex); - /* begin MoveAw:R: */ - address2 = instructionPointerAddress(); - reg = ClassReg; /* begin checkLiteral:forInstruction: */ - anInstruction17 = genoperandoperand(MoveAwR, address2, reg); - genLoadStackPointers(backEnd); + nextProfileTickAddress(); + anInstruction110 = genoperandoperand(MoveAwR, nextProfileTickAddress(), ClassReg); + /* begin MoveAw:R: */ + address = (nextProfileTickAddress()) + 4; /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction18 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - /* begin PushR: */ - genoperand(PushR, ClassReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset1 = BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, BytesPerWord); + anInstruction210 = genoperandoperand(MoveAwR, address, SendNumArgsReg); + gMovePerfCnt64RRL(regLo, regHi, liveRegisters); + /* begin SubR:R: */ + genoperandoperand(SubRR, regLo, ClassReg); + /* begin SubbR:R: */ + genoperandoperand(SubbRR, regHi, SendNumArgsReg); + /* begin JumpGreaterOrEqual: */ + jumpToTakeSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l47; + l47: /* end genCheckForProfileTimerTick: */; } + /* begin MoveMw:r:R: */ + offset1 = BytesPerWord; + /* begin checkQuickConstant:forInstruction: */ + anInstruction21 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); + continueAfterProfileSample = anInstruction21; + /* begin RetN: */ + genoperand(RetN, BytesPerWord); if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* The sample is collected by cePrimReturnEnterCogCode for external calls */ - if (!(jmpSamplePrim == null)) { - - /* Call ceCheckProfileTick: to record sample and then continue. */ - jmpTarget(jmpSamplePrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin annotateCall: */ - operand = ((usqIntptr_t)ceCheckProfileTick); - /* begin checkLiteral:forInstruction: */ - anInstruction21 = genoperand(CallFull, operand); - abstractInstruction2 = anInstruction21; - (abstractInstruction2->annotation = IsRelativeCall); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSamplePrim)); - } - jmpTarget(jmpSampleNonPrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction25 = genoperandoperand(MoveCqR, 0, TempReg); - /* begin checkLiteral:forInstruction: */ - newMethodAddress(); - anInstruction26 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); - /* begin annotateCall: */ - operand2 = ((usqIntptr_t)ceCheckProfileTick); + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); /* begin checkLiteral:forInstruction: */ - anInstruction23 = genoperand(CallFull, operand2); - abstractInstruction3 = anInstruction23; - (abstractInstruction3->annotation = IsRelativeCall); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSampleNonPrim)); - } - if (!(jmp == null)) { - - /* Jump to restore of receiver reg and proceed to frame build for failure. */ - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin MoveMw:r:R: */ - offset2 = BytesPerWord * (methodOrBlockNumArgs + (1)); + instructionPointerAddress(); + anInstruction13 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction27 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); + anInstruction14 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + /* begin Jump: */ + genoperand(Jump, ((sqInt)continueAfterProfileSample)); } + jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + /* begin MoveMw:r:R: */ + offset2 = BytesPerWord * (methodOrBlockNumArgs + (1)); + /* begin checkQuickConstant:forInstruction: */ + anInstruction22 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); return 0; } @@ -25473,7 +25514,7 @@ compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)) if ((methodOrBlockNumArgs > 2 /* numRegArgs */) || (methodOrBlockNumArgs == 0)) { /* begin registerMaskFor: */ - liveRegsMask = 1U << ReceiverResultReg; + liveRegsMask = (1U << ReceiverResultReg); } else { if (methodOrBlockNumArgs > 1) { @@ -25551,10 +25592,12 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags { AbstractInstruction *abstractInstruction; AbstractInstruction *abstractInstruction1; + sqInt address; AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; AbstractInstruction *anInstruction10; AbstractInstruction *anInstruction11; + AbstractInstruction *anInstruction110; AbstractInstruction *anInstruction12; AbstractInstruction *anInstruction13; AbstractInstruction *anInstruction14; @@ -25565,6 +25608,7 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags AbstractInstruction *anInstruction19; AbstractInstruction *anInstruction20; AbstractInstruction *anInstruction21; + AbstractInstruction *anInstruction210; AbstractInstruction *anInstruction22; AbstractInstruction *anInstruction23; AbstractInstruction *anInstruction4; @@ -25573,15 +25617,22 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags AbstractInstruction *anInstruction7; AbstractInstruction *anInstruction9; sqInt calleeSavedRegisterMask; + AbstractInstruction * continueAfterProfileSample; + sqInt effectiveLiveRegisters; AbstractInstruction * jmp; + AbstractInstruction * jumpToTakeSample; + sqInt liveRegisters; sqInt offset; sqInt offset1; sqInt operand; + sqInt regHi; + sqInt regLo; sqInt retpcOffset; AbstractInstruction * retry; AbstractInstruction * skip; sqInt spRegSaveRegister; + jumpToTakeSample = ((AbstractInstruction *) 0); assert(((flags & PrimCallOnSmalltalkStack) != 0)); assert(!((0))); if (recordFastCCallPrimTraceForMethod(methodObj)) { @@ -25600,7 +25651,7 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags argumentCountAddress(); anInstruction20 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); genExternalizeStackPointerForFastPrimitiveCall(); - calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | (1U << ClassReg)) - (1U << ClassReg)); + calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | ((1U << ClassReg))) - ((1U << ClassReg))); spRegSaveRegister = NoReg; /* begin Label */ retry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); @@ -25609,10 +25660,15 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags } else { } + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + goto l35; + genoperand(PushR, 0); + l35: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin annotateCall: */ - anInstruction1 = genoperand(CallFull, primitiveRoutine); + anInstruction1 = genoperand(CallFull, ((sqInt)primitiveRoutine)); abstractInstruction = anInstruction1; (abstractInstruction->annotation = IsRelativeCall); + /* begin genRemoveNArgsFromStack: */ /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); anInstruction21 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); @@ -25624,9 +25680,42 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags anInstruction22 = genoperandoperand(CmpCqR, 0, TempReg); /* begin JumpNonZero: */ jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + flag("endianness"); + assert(!(((((registerMaskForand(ClassReg, SendNumArgsReg)) & liveRegisters) != 0)))); + effectiveLiveRegisters = liveRegisters | ((1U << ClassReg) | (1U << SendNumArgsReg)); + regLo = Arg0Reg; + regHi = Arg1Reg; + /* begin preferredRegisterPairForMovePerfCnt64RRLInto: */ + if (!(((liveRegisters & ((1U << EAX))) != 0))) { + regLo = EAX; + } + if (!(((liveRegisters & ((1U << EDX))) != 0))) { + regHi = EDX; + } + /* begin checkLiteral:forInstruction: */ + nextProfileTickAddress(); + anInstruction110 = genoperandoperand(MoveAwR, nextProfileTickAddress(), ClassReg); + /* begin MoveAw:R: */ + address = (nextProfileTickAddress()) + 4; + /* begin checkLiteral:forInstruction: */ + anInstruction210 = genoperandoperand(MoveAwR, address, SendNumArgsReg); + gMovePerfCnt64RRL(regLo, regHi, liveRegisters); + /* begin SubR:R: */ + genoperandoperand(SubRR, regLo, ClassReg); + /* begin SubbR:R: */ + genoperandoperand(SubbRR, regHi, SendNumArgsReg); + /* begin JumpGreaterOrEqual: */ + jumpToTakeSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l51; + l51: /* end genCheckForProfileTimerTick: */; + } /* begin checkLiteral:forInstruction: */ stackPointerAddress(); anInstruction23 = genoperandoperand(MoveAwR, stackPointerAddress(), TempReg); + continueAfterProfileSample = anInstruction23; /* The original retpc is (argumentCount + 1) words below stackPointer. */ retpcOffset = -((methodOrBlockNumArgs + 1) * BytesPerWord); @@ -25640,6 +25729,12 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags anInstruction6 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, TempReg); /* begin RetN: */ genoperand(RetN, 0); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); + /* begin Jump: */ + genoperand(Jump, ((sqInt)continueAfterProfileSample)); + } jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); if ((accessorDepthForExternalPrimitiveMethod(methodObj)) >= 0) { @@ -25670,13 +25765,17 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags else { genLoadCStackPointer(backEnd); } + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + goto l27; + genoperand(PushR, 0); + l27: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin annotateCall: */ operand = ((usqIntptr_t)checkForAndFollowForwardedPrimitiveState); /* begin checkLiteral:forInstruction: */ anInstruction7 = genoperand(CallFull, operand); abstractInstruction1 = anInstruction7; (abstractInstruction1->annotation = IsRelativeCall); - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); /* begin checkQuickConstant:forInstruction: */ anInstruction14 = genoperandoperand(CmpCqR, 0, ABIResultReg); /* begin JumpZero: */ @@ -25694,10 +25793,10 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags /* must reload SPReg to undo any alignment change, */ if (((flags & PrimCallOnSmalltalkStackAlign2x) != 0)) { - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); } } - if (((ABICallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((ABICallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* begin MoveMw:r:R: */ offset1 = (methodOrBlockNumArgs + (1)) * BytesPerWord; /* begin checkQuickConstant:forInstruction: */ @@ -26702,79 +26801,101 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) sqInt address; sqInt address1; AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; + AbstractInstruction *anInstruction11; AbstractInstruction *anInstruction12; AbstractInstruction *anInstruction13; AbstractInstruction *anInstruction14; AbstractInstruction *anInstruction15; AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction2; + AbstractInstruction *anInstruction7; AbstractInstruction *anInstruction8; AbstractInstruction *anInstruction9; sqInt callTarget; AbstractInstruction *continuePostSample; + sqInt effectiveLiveRegisters; AbstractInstruction *jmpFail; AbstractInstruction *jmpSample; - sqInt reg; + sqInt liveRegisters; + sqInt reg1; + sqInt regHi; + sqInt regLo; continuePostSample = ((AbstractInstruction *) 0); jmpSample = ((AbstractInstruction *) 0); zeroOpcodeIndex(); - if (profiling) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick: if so. - N.B. nextProfileTick is 64-bits so 32-bit systems need to test both halves. */ + /* begin checkLiteral:forInstruction: */ + primFailCodeAddress(); + anInstruction12 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + flag("ask concrete code gen if move sets condition codes?"); + /* begin checkQuickConstant:forInstruction: */ + anInstruction13 = genoperandoperand(CmpCqR, 0, TempReg); + /* begin JumpNonZero: */ + jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (profiling + && (1)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + flag("endianness"); + assert(!(((((registerMaskForand(ClassReg, SendNumArgsReg)) & liveRegisters) != 0)))); + effectiveLiveRegisters = liveRegisters | ((1U << ClassReg) | (1U << SendNumArgsReg)); + regLo = Arg0Reg; + regHi = Arg1Reg; + /* begin preferredRegisterPairForMovePerfCnt64RRLInto: */ + if (!(((liveRegisters & ((1U << EAX))) != 0))) { + regLo = EAX; + } + if (!(((liveRegisters & ((1U << EDX))) != 0))) { + regHi = EDX; + } /* begin checkLiteral:forInstruction: */ nextProfileTickAddress(); - anInstruction1 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); + anInstruction1 = genoperandoperand(MoveAwR, nextProfileTickAddress(), ClassReg); /* begin MoveAw:R: */ - address = (nextProfileTickAddress()) + BytesPerWord; + address = (nextProfileTickAddress()) + 4; /* begin checkLiteral:forInstruction: */ - anInstruction2 = genoperandoperand(MoveAwR, address, ClassReg); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSample = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + anInstruction2 = genoperandoperand(MoveAwR, address, SendNumArgsReg); + gMovePerfCnt64RRL(regLo, regHi, liveRegisters); + /* begin SubR:R: */ + genoperandoperand(SubRR, regLo, ClassReg); + /* begin SubbR:R: */ + genoperandoperand(SubbRR, regHi, SendNumArgsReg); + /* begin JumpGreaterOrEqual: */ + jmpSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l17; + l17: /* end genCheckForProfileTimerTick: */; /* begin Label */ continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); } /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction13 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkLiteral:forInstruction: */ instructionPointerAddress(); - anInstruction8 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); + anInstruction7 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); + anInstruction8 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + anInstruction9 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jmpFail, checkLiteralforInstruction(newMethodAddress(), genoperandoperand(MoveAwR, newMethodAddress(), SendNumArgsReg))); /* begin checkLiteral:forInstruction: */ cStackPointerAddress(); - anInstruction15 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); + anInstruction14 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); compileCallFornumArgsargargargargresultRegregsToSave(ceActivateFailingPrimitiveMethod, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); /* begin MoveAw:R: */ address1 = instructionPointerAddress(); - reg = ClassReg; + reg1 = ClassReg; /* begin checkLiteral:forInstruction: */ - anInstruction16 = genoperandoperand(MoveAwR, address1, reg); + anInstruction15 = genoperandoperand(MoveAwR, address1, reg1); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveMwrR, BytesPerWord, SPReg, ReceiverResultReg); + anInstruction11 = genoperandoperandoperand(MoveMwrR, BytesPerWord, SPReg, ReceiverResultReg); /* begin PushR: */ genoperand(PushR, ClassReg); /* begin RetN: */ genoperand(RetN, BytesPerWord); - if (profiling) { + if (profiling + && (1)) { /* Call ceCheckProfileTick: to record sample and then continue. newMethod should be up-to-date. Need to save and restore the link reg around this call. */ @@ -26783,8 +26904,8 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) /* begin CallFullRT: */ callTarget = (usqIntptr_t)ceCheckProfileTick; /* begin annotateCall: */ - anInstruction17 = genoperand(CallFull, callTarget); - abstractInstruction = anInstruction17; + anInstruction16 = genoperand(CallFull, callTarget); + abstractInstruction = anInstruction16; (abstractInstruction->annotation = IsRelativeCall); /* begin Jump: */ genoperand(Jump, ((sqInt)continuePostSample)); @@ -27140,6 +27261,30 @@ genStoreRemoteTempLongBytecode(void) && (shouldAnnotateObjectReference(((ssTop())->constant))))); } + /* SimpleStackBasedCogit>>#genTakeProfileSample */ +static void +genTakeProfileSample(void) +{ + AbstractInstruction *abstractInstruction; + AbstractInstruction *anInstruction; + AbstractInstruction *anInstruction6; + sqInt operand; + + addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + genoperand(PushR, ClassReg); + l3: /* end genMarshallNArgs:arg:arg:arg:arg: */; + /* begin annotateCall: */ + operand = ((usqIntptr_t)ceTakeProfileSample); + /* begin checkLiteral:forInstruction: */ + anInstruction = genoperand(CallFull, operand); + abstractInstruction = anInstruction; + (abstractInstruction->annotation = IsRelativeCall); + /* begin genRemoveNArgsFromStack: */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction6 = genoperandoperand(AddCqR, 4, ESP); + } + /* SistaV1: * 217 Trap */ @@ -27527,7 +27672,7 @@ primitiveGeneratorOrNil(void) static sqInt NoDbgRegParms registerisInMask(sqInt reg, sqInt mask) { - return ((mask & (1U << reg)) != 0); + return ((mask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)))) != 0); } /* SimpleStackBasedCogit>>#v3:Block:Code:Size: */ @@ -27907,7 +28052,7 @@ anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n) sqInt regMask; /* begin registerMaskFor: */ - regMask = 1U << reg; + regMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { if ((((registerMask(simStackAt(i))) & regMask) != 0)) { return 1; @@ -29002,7 +29147,7 @@ ensureReceiverResultRegContainsSelf(void) if (needsFrame) { if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin putSelfInReceiverResultReg */ storeToReg(simSelf(), ReceiverResultReg); ((simSelf())->liveRegister = ReceiverResultReg); @@ -29136,7 +29281,7 @@ freeAnyFloatRegNotConflictingWith(sqInt regMask) desc = simNativeStackAt(index); if ((((desc->type)) == SSRegisterSingleFloat) || (((desc->type)) == SSRegisterDoubleFloat)) { - if (!(((regMask & (1U << ((desc->registerr)))) != 0))) { + if (!(((regMask & (((((desc->registerr)) < 0) ? (((usqInt)(1)) >> (-((desc->registerr)))) : (1U << ((desc->registerr)))))) != 0))) { reg = (desc->registerr); } } @@ -29166,7 +29311,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) && (index < simStackPtr)) { desc = simStackAt(index); if (((desc->type)) == SSRegister) { - if (!(((regMask & (1U << ((desc->registerr)))) != 0))) { + if (!(((regMask & (((((desc->registerr)) < 0) ? (((usqInt)(1)) >> (-((desc->registerr)))) : (1U << ((desc->registerr)))))) != 0))) { reg = (desc->registerr); } } @@ -29174,7 +29319,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) } assert(!((reg == NoReg))); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << reg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)), simStackPtr, simNativeStackPtr); return reg; } @@ -29728,13 +29873,13 @@ genForwardersInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -30366,7 +30511,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop19 == NoReg) { rOopTop19 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult10 = allocateRegNotConflictingWith(1U << rOopTop19); + rResult10 = allocateRegNotConflictingWith(((rOopTop19 < 0) ? (((usqInt)(1)) >> (-rOopTop19)) : (1U << rOopTop19))); assert(!(((rOopTop19 == NoReg) || (rResult10 == NoReg)))); object17 = rOopTop19; @@ -30462,7 +30607,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop2 == NoReg) { rOopTop2 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult = allocateRegNotConflictingWith(1U << rOopTop2); + rResult = allocateRegNotConflictingWith(((rOopTop2 < 0) ? (((usqInt)(1)) >> (-rOopTop2)) : (1U << rOopTop2))); assert(!(((rOopTop2 == NoReg) || (rResult == NoReg)))); object2 = rOopTop2; @@ -30493,7 +30638,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop3 == NoReg) { rOopTop3 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult1 = allocateRegNotConflictingWith(1U << rOopTop3); + rResult1 = allocateRegNotConflictingWith(((rOopTop3 < 0) ? (((usqInt)(1)) >> (-rOopTop3)) : (1U << rOopTop3))); assert(!(((rOopTop3 == NoReg) || (rResult1 == NoReg)))); object3 = rOopTop3; @@ -30524,7 +30669,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop4 == NoReg) { rOopTop4 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult2 = allocateRegNotConflictingWith(1U << rOopTop4); + rResult2 = allocateRegNotConflictingWith(((rOopTop4 < 0) ? (((usqInt)(1)) >> (-rOopTop4)) : (1U << rOopTop4))); assert(!(((rOopTop4 == NoReg) || (rResult2 == NoReg)))); object4 = rOopTop4; @@ -30555,7 +30700,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop5 == NoReg) { rOopTop5 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult3 = allocateRegNotConflictingWith(1U << rOopTop5); + rResult3 = allocateRegNotConflictingWith(((rOopTop5 < 0) ? (((usqInt)(1)) >> (-rOopTop5)) : (1U << rOopTop5))); assert(!(((rOopTop5 == NoReg) || (rResult3 == NoReg)))); object5 = rOopTop5; @@ -30586,7 +30731,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop6 == NoReg) { rOopTop6 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult4 = allocateRegNotConflictingWith(1U << rOopTop6); + rResult4 = allocateRegNotConflictingWith(((rOopTop6 < 0) ? (((usqInt)(1)) >> (-rOopTop6)) : (1U << rOopTop6))); assert(!(((rOopTop6 == NoReg) || (rResult4 == NoReg)))); object6 = rOopTop6; @@ -30617,7 +30762,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop7 == NoReg) { rOopTop7 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult5 = allocateRegNotConflictingWith(1U << rOopTop7); + rResult5 = allocateRegNotConflictingWith(((rOopTop7 < 0) ? (((usqInt)(1)) >> (-rOopTop7)) : (1U << rOopTop7))); assert(!(((rOopTop7 == NoReg) || (rResult5 == NoReg)))); object7 = rOopTop7; @@ -30648,7 +30793,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop8 == NoReg) { rOopTop8 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult6 = allocateRegNotConflictingWith(1U << rOopTop8); + rResult6 = allocateRegNotConflictingWith(((rOopTop8 < 0) ? (((usqInt)(1)) >> (-rOopTop8)) : (1U << rOopTop8))); assert(!(((rOopTop8 == NoReg) || (rResult6 == NoReg)))); object8 = rOopTop8; @@ -30708,7 +30853,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop10 == NoReg) { rOopTop10 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult7 = allocateRegNotConflictingWith(1U << rOopTop10); + rResult7 = allocateRegNotConflictingWith(((rOopTop10 < 0) ? (((usqInt)(1)) >> (-rOopTop10)) : (1U << rOopTop10))); rResult21 = allocateRegNotConflictingWith((1U << rOopTop10) | (1U << rResult7)); assert(!(((rOopTop10 == NoReg) || (rResult7 == NoReg)))); @@ -30773,7 +30918,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop13 == NoReg) { rOopTop13 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult8 = allocateRegNotConflictingWith(1U << rOopTop13); + rResult8 = allocateRegNotConflictingWith(((rOopTop13 < 0) ? (((usqInt)(1)) >> (-rOopTop13)) : (1U << rOopTop13))); rResult22 = allocateRegNotConflictingWith((1U << rOopTop13) | (1U << rResult8)); assert(!(((rOopTop13 == NoReg) || (rResult8 == NoReg)))); @@ -30932,7 +31077,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop23 == NoReg) { rOopTop23 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult14 = allocateRegNotConflictingWith(1U << rOopTop23); + rResult14 = allocateRegNotConflictingWith(((rOopTop23 < 0) ? (((usqInt)(1)) >> (-rOopTop23)) : (1U << rOopTop23))); rResult23 = allocateRegNotConflictingWith((1U << rOopTop23) | (1U << rResult14)); assert(!(((rOopTop23 == NoReg) || (rResult14 == NoReg)))); @@ -31003,7 +31148,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop16 == NoReg) { rOopTop16 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult9 = allocateRegNotConflictingWith(1U << rOopTop16); + rResult9 = allocateRegNotConflictingWith(((rOopTop16 < 0) ? (((usqInt)(1)) >> (-rOopTop16)) : (1U << rOopTop16))); assert(!(((rOopTop16 == NoReg) || (rResult9 == NoReg)))); object14 = rOopTop16; @@ -31034,7 +31179,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop24 == NoReg) { rOopTop24 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult15 = allocateRegNotConflictingWith(1U << rOopTop24); + rResult15 = allocateRegNotConflictingWith(((rOopTop24 < 0) ? (((usqInt)(1)) >> (-rOopTop24)) : (1U << rOopTop24))); assert(!(((rOopTop24 == NoReg) || (rResult15 == NoReg)))); object22 = rOopTop24; @@ -31077,7 +31222,7 @@ genLowcodeBinaryInlinePrimitive(sqInt prim) if (rOopTop25 == NoReg) { rOopTop25 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult17 = allocateRegNotConflictingWith(1U << rOopTop25); + rResult17 = allocateRegNotConflictingWith(((rOopTop25 < 0) ? (((usqInt)(1)) >> (-rOopTop25)) : (1U << rOopTop25))); rResult24 = allocateRegNotConflictingWith((1U << rOopTop25) | (1U << rResult17)); assert(!(((rOopTop25 == NoReg) || (rResult17 == NoReg)))); @@ -31241,7 +31386,7 @@ genLowcodeNullaryInlinePrimitive(sqInt prim) if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult = allocateRegNotConflictingWith(1U << rTop); + rResult = allocateRegNotConflictingWith(((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1U << rTop))); assert(!(((rTop == NoReg) || (rResult == NoReg)))); value = rTop; @@ -31281,14 +31426,14 @@ genLowcodeNullaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } } if (rTop2 == NoReg) { rTop2 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1U << rTop2); + rNext = allocateRegNotConflictingWith(((rTop2 < 0) ? (((usqInt)(1)) >> (-rTop2)) : (1U << rTop2))); } assert(!(((rTop2 == NoReg) || (rNext == NoReg)))); @@ -31424,14 +31569,14 @@ genLowcodeNullaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg1 = (rNext1 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask1 = 1U << reg1; + topRegistersMask1 = ((reg1 < 0) ? (((usqInt)(1)) >> (-reg1)) : (1U << reg1)); } } if (rTop4 == NoReg) { rTop4 = allocateRegNotConflictingWith(topRegistersMask1); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop4); + rNext1 = allocateRegNotConflictingWith(((rTop4 < 0) ? (((usqInt)(1)) >> (-rTop4)) : (1U << rTop4))); } assert(!(((rTop4 == NoReg) || (rNext1 == NoReg)))); @@ -31559,14 +31704,14 @@ genLowcodeNullaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg2 = (rNext2 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask2 = 1U << reg2; + topRegistersMask2 = ((reg2 < 0) ? (((usqInt)(1)) >> (-reg2)) : (1U << reg2)); } } if (rTop9 == NoReg) { rTop9 = allocateRegNotConflictingWith(topRegistersMask2); } if (rNext2 == NoReg) { - rNext2 = allocateRegNotConflictingWith(1U << rTop9); + rNext2 = allocateRegNotConflictingWith(((rTop9 < 0) ? (((usqInt)(1)) >> (-rTop9)) : (1U << rTop9))); } assert(!(((rTop9 == NoReg) || (rNext2 == NoReg)))); @@ -31681,14 +31826,14 @@ genLowcodeTrinaryInlinePrimitive(sqInt prim) l4: ; if (rOopNext != NoReg) { /* begin registerMaskFor: */ - oopTopRegisterMask = 1U << rOopNext; + oopTopRegisterMask = ((rOopNext < 0) ? (((usqInt)(1)) >> (-rOopNext)) : (1U << rOopNext)); } } if (rOopTop == NoReg) { rOopTop = allocateRegNotConflictingWith(oopTopRegisterMask); } if (rOopNext == NoReg) { - rOopNext = allocateRegNotConflictingWith(1U << rOopTop); + rOopNext = allocateRegNotConflictingWith(((rOopTop < 0) ? (((usqInt)(1)) >> (-rOopTop)) : (1U << rOopTop))); } rResult = allocateRegNotConflictingWith((1U << rOopTop) | (1U << rOopNext)); assert(!(((rOopTop == NoReg) @@ -31750,14 +31895,14 @@ genLowcodeTrinaryInlinePrimitive(sqInt prim) l18: ; if (rOopNext1 != NoReg) { /* begin registerMaskFor: */ - oopTopRegisterMask1 = 1U << rOopNext1; + oopTopRegisterMask1 = ((rOopNext1 < 0) ? (((usqInt)(1)) >> (-rOopNext1)) : (1U << rOopNext1)); } } if (rOopTop1 == NoReg) { rOopTop1 = allocateRegNotConflictingWith(oopTopRegisterMask1); } if (rOopNext1 == NoReg) { - rOopNext1 = allocateRegNotConflictingWith(1U << rOopTop1); + rOopNext1 = allocateRegNotConflictingWith(((rOopTop1 < 0) ? (((usqInt)(1)) >> (-rOopTop1)) : (1U << rOopTop1))); } assert(!(((rOopTop1 == NoReg) || (rOopNext1 == NoReg)))); @@ -31818,14 +31963,14 @@ genLowcodeTrinaryInlinePrimitive(sqInt prim) l23: ; if (rOopNext2 != NoReg) { /* begin registerMaskFor: */ - oopTopRegisterMask2 = 1U << rOopNext2; + oopTopRegisterMask2 = ((rOopNext2 < 0) ? (((usqInt)(1)) >> (-rOopNext2)) : (1U << rOopNext2)); } } if (rOopTop2 == NoReg) { rOopTop2 = allocateRegNotConflictingWith(oopTopRegisterMask2); } if (rOopNext2 == NoReg) { - rOopNext2 = allocateRegNotConflictingWith(1U << rOopTop2); + rOopNext2 = allocateRegNotConflictingWith(((rOopTop2 < 0) ? (((usqInt)(1)) >> (-rOopTop2)) : (1U << rOopTop2))); } assert(!(((rOopTop2 == NoReg) || (rOopNext2 == NoReg)))); @@ -31846,17 +31991,17 @@ genLowcodeTrinaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { rTop = nativeRegisterOrNone(ssNativeTop()); /* begin registerMaskFor: */ - oopTopRegisterMask3 = 1U << rTop; + oopTopRegisterMask3 = ((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1U << rTop)); } if ((registerOrNone(ssTop())) != NoReg) { rOopTop3 = registerOrNone(ssTop()); /* begin registerMaskFor: */ - topRegisterMask = 1U << rOopTop3; + topRegisterMask = ((rOopTop3 < 0) ? (((usqInt)(1)) >> (-rOopTop3)) : (1U << rOopTop3)); } if ((registerOrNone(ssValue(1))) != NoReg) { rOopNext3 = registerOrNone(ssValue(1)); - topRegisterMask = topRegisterMask | (1U << rOopNext3); - oopTopRegisterMask3 = oopTopRegisterMask3 | (1U << rOopNext3); + topRegisterMask = topRegisterMask | (((rOopNext3 < 0) ? (((usqInt)(1)) >> (-rOopNext3)) : (1U << rOopNext3))); + oopTopRegisterMask3 = oopTopRegisterMask3 | (((rOopNext3 < 0) ? (((usqInt)(1)) >> (-rOopNext3)) : (1U << rOopNext3))); } if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(topRegisterMask); @@ -32403,13 +32548,13 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((registerOrNone(ssTop())) != NoReg) { rOopTop1 = registerOrNone(ssTop()); /* begin registerMaskFor: */ - topRegisterMask1 = 1U << rOopTop1; + topRegisterMask1 = ((rOopTop1 < 0) ? (((usqInt)(1)) >> (-rOopTop1)) : (1U << rOopTop1)); } if (rTop31 == NoReg) { rTop31 = allocateRegNotConflictingWith(topRegisterMask1); } if (rOopTop1 == NoReg) { - rOopTop1 = allocateRegNotConflictingWith(1U << rTop31); + rOopTop1 = allocateRegNotConflictingWith(((rTop31 < 0) ? (((usqInt)(1)) >> (-rTop31)) : (1U << rTop31))); } rOopResult = allocateRegNotConflictingWith((1U << rTop31) | (1U << rOopTop1)); assert(!(((rTop31 == NoReg) @@ -32459,7 +32604,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if (rOopTop2 == NoReg) { rOopTop2 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult35 = allocateRegNotConflictingWith(1U << rOopTop2); + rResult35 = allocateRegNotConflictingWith(((rOopTop2 < 0) ? (((usqInt)(1)) >> (-rOopTop2)) : (1U << rOopTop2))); assert(!(((rOopTop2 == NoReg) || (rResult35 == NoReg)))); classOop1 = rOopTop2; @@ -32533,14 +32678,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask1 = 1U << reg; + topRegistersMask1 = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } } if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(topRegistersMask1); } if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1U << rTop); + rNext = allocateRegNotConflictingWith(((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1U << rTop))); } assert(!(((rTop == NoReg) || (rNext == NoReg)))); @@ -32580,14 +32725,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg1 = (rNext1 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask2 = 1U << reg1; + topRegistersMask2 = ((reg1 < 0) ? (((usqInt)(1)) >> (-reg1)) : (1U << reg1)); } } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask2); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -32627,14 +32772,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg2 = (rNext2 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask3 = 1U << reg2; + topRegistersMask3 = ((reg2 < 0) ? (((usqInt)(1)) >> (-reg2)) : (1U << reg2)); } } if (rTop2 == NoReg) { rTop2 = allocateRegNotConflictingWith(topRegistersMask3); } if (rNext2 == NoReg) { - rNext2 = allocateRegNotConflictingWith(1U << rTop2); + rNext2 = allocateRegNotConflictingWith(((rTop2 < 0) ? (((usqInt)(1)) >> (-rTop2)) : (1U << rTop2))); } assert(!(((rTop2 == NoReg) || (rNext2 == NoReg)))); @@ -32674,14 +32819,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg3 = (rNext3 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask4 = 1U << reg3; + topRegistersMask4 = ((reg3 < 0) ? (((usqInt)(1)) >> (-reg3)) : (1U << reg3)); } } if (rTop3 == NoReg) { rTop3 = allocateRegNotConflictingWith(topRegistersMask4); } if (rNext3 == NoReg) { - rNext3 = allocateRegNotConflictingWith(1U << rTop3); + rNext3 = allocateRegNotConflictingWith(((rTop3 < 0) ? (((usqInt)(1)) >> (-rTop3)) : (1U << rTop3))); } assert(!(((rTop3 == NoReg) || (rNext3 == NoReg)))); @@ -32721,14 +32866,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg4 = (rNext4 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask5 = 1U << reg4; + topRegistersMask5 = ((reg4 < 0) ? (((usqInt)(1)) >> (-reg4)) : (1U << reg4)); } } if (rTop4 == NoReg) { rTop4 = allocateRegNotConflictingWith(topRegistersMask5); } if (rNext4 == NoReg) { - rNext4 = allocateRegNotConflictingWith(1U << rTop4); + rNext4 = allocateRegNotConflictingWith(((rTop4 < 0) ? (((usqInt)(1)) >> (-rTop4)) : (1U << rTop4))); } assert(!(((rTop4 == NoReg) || (rNext4 == NoReg)))); @@ -32768,14 +32913,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg5 = (rNext5 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask6 = 1U << reg5; + topRegistersMask6 = ((reg5 < 0) ? (((usqInt)(1)) >> (-reg5)) : (1U << reg5)); } } if (rTop5 == NoReg) { rTop5 = allocateRegNotConflictingWith(topRegistersMask6); } if (rNext5 == NoReg) { - rNext5 = allocateRegNotConflictingWith(1U << rTop5); + rNext5 = allocateRegNotConflictingWith(((rTop5 < 0) ? (((usqInt)(1)) >> (-rTop5)) : (1U << rTop5))); } assert(!(((rTop5 == NoReg) || (rNext5 == NoReg)))); @@ -32900,24 +33045,24 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) nextRegisterMask = 0; if (rNext6 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask = 1U << rNext6; + nextRegisterMask = ((rNext6 < 0) ? (((usqInt)(1)) >> (-rNext6)) : (1U << rNext6)); } if (rNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNext < 0) ? (((usqInt)(1)) >> (-rNextNext)) : (1U << rNextNext))); } if (rNextNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNextNext < 0) ? (((usqInt)(1)) >> (-rNextNextNext)) : (1U << rNextNextNext))); } rTop9 = allocateRegNotConflictingWith(nextRegisterMask); } if (rNext6 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask = 1U << rTop9; + nextRegisterMask = ((rTop9 < 0) ? (((usqInt)(1)) >> (-rTop9)) : (1U << rTop9)); if (rNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNext < 0) ? (((usqInt)(1)) >> (-rNextNext)) : (1U << rNextNext))); } if (rNextNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNextNext < 0) ? (((usqInt)(1)) >> (-rNextNextNext)) : (1U << rNextNextNext))); } rNext6 = allocateRegNotConflictingWith(nextRegisterMask); } @@ -32925,7 +33070,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) /* begin registerMaskFor:and: */ nextRegisterMask = (1U << rTop9) | (1U << rNext6); if (rNextNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNextNext < 0) ? (((usqInt)(1)) >> (-rNextNextNext)) : (1U << rNextNextNext))); } rNextNext = allocateRegNotConflictingWith(nextRegisterMask); } @@ -32984,14 +33129,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg7 = (rNext7 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask8 = 1U << reg7; + topRegistersMask8 = ((reg7 < 0) ? (((usqInt)(1)) >> (-reg7)) : (1U << reg7)); } } if (rTop10 == NoReg) { rTop10 = allocateRegNotConflictingWith(topRegistersMask8); } if (rNext7 == NoReg) { - rNext7 = allocateRegNotConflictingWith(1U << rTop10); + rNext7 = allocateRegNotConflictingWith(((rTop10 < 0) ? (((usqInt)(1)) >> (-rTop10)) : (1U << rTop10))); } assert(!(((rTop10 == NoReg) || (rNext7 == NoReg)))); @@ -33022,14 +33167,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg8 = (rNext8 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask9 = 1U << reg8; + topRegistersMask9 = ((reg8 < 0) ? (((usqInt)(1)) >> (-reg8)) : (1U << reg8)); } } if (rTop12 == NoReg) { rTop12 = allocateRegNotConflictingWith(topRegistersMask9); } if (rNext8 == NoReg) { - rNext8 = allocateRegNotConflictingWith(1U << rTop12); + rNext8 = allocateRegNotConflictingWith(((rTop12 < 0) ? (((usqInt)(1)) >> (-rTop12)) : (1U << rTop12))); } assert(!(((rTop12 == NoReg) || (rNext8 == NoReg)))); @@ -33060,14 +33205,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg9 = (rNext9 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask10 = 1U << reg9; + topRegistersMask10 = ((reg9 < 0) ? (((usqInt)(1)) >> (-reg9)) : (1U << reg9)); } } if (rTop13 == NoReg) { rTop13 = allocateRegNotConflictingWith(topRegistersMask10); } if (rNext9 == NoReg) { - rNext9 = allocateRegNotConflictingWith(1U << rTop13); + rNext9 = allocateRegNotConflictingWith(((rTop13 < 0) ? (((usqInt)(1)) >> (-rTop13)) : (1U << rTop13))); } assert(!(((rTop13 == NoReg) || (rNext9 == NoReg)))); @@ -33098,14 +33243,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg10 = (rNext10 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask11 = 1U << reg10; + topRegistersMask11 = ((reg10 < 0) ? (((usqInt)(1)) >> (-reg10)) : (1U << reg10)); } } if (rTop14 == NoReg) { rTop14 = allocateRegNotConflictingWith(topRegistersMask11); } if (rNext10 == NoReg) { - rNext10 = allocateRegNotConflictingWith(1U << rTop14); + rNext10 = allocateRegNotConflictingWith(((rTop14 < 0) ? (((usqInt)(1)) >> (-rTop14)) : (1U << rTop14))); } assert(!(((rTop14 == NoReg) || (rNext10 == NoReg)))); @@ -33160,24 +33305,24 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) nextRegisterMask1 = 0; if (rNext12 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask1 = 1U << rNext12; + nextRegisterMask1 = ((rNext12 < 0) ? (((usqInt)(1)) >> (-rNext12)) : (1U << rNext12)); } if (rNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNext1); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNext1)) : (1U << rNextNext1))); } if (rNextNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNextNext1); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNextNext1)) : (1U << rNextNextNext1))); } rTop15 = allocateRegNotConflictingWith(nextRegisterMask1); } if (rNext12 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask1 = 1U << rTop15; + nextRegisterMask1 = ((rTop15 < 0) ? (((usqInt)(1)) >> (-rTop15)) : (1U << rTop15)); if (rNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNext1); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNext1)) : (1U << rNextNext1))); } if (rNextNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNextNext1); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNextNext1)) : (1U << rNextNextNext1))); } rNext12 = allocateRegNotConflictingWith(nextRegisterMask1); } @@ -33185,7 +33330,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) /* begin registerMaskFor:and: */ nextRegisterMask1 = (1U << rTop15) | (1U << rNext12); if (rNextNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNextNext1); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNextNext1)) : (1U << rNextNextNext1))); } rNextNext1 = allocateRegNotConflictingWith(nextRegisterMask1); } @@ -33284,14 +33429,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg12 = (rNext14 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask13 = 1U << reg12; + topRegistersMask13 = ((reg12 < 0) ? (((usqInt)(1)) >> (-reg12)) : (1U << reg12)); } } if (rTop20 == NoReg) { rTop20 = allocateRegNotConflictingWith(topRegistersMask13); } if (rNext14 == NoReg) { - rNext14 = allocateRegNotConflictingWith(1U << rTop20); + rNext14 = allocateRegNotConflictingWith(((rTop20 < 0) ? (((usqInt)(1)) >> (-rTop20)) : (1U << rTop20))); } assert(!(((rTop20 == NoReg) || (rNext14 == NoReg)))); @@ -33316,14 +33461,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg13 = (rNext15 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask14 = 1U << reg13; + topRegistersMask14 = ((reg13 < 0) ? (((usqInt)(1)) >> (-reg13)) : (1U << reg13)); } } if (rTop21 == NoReg) { rTop21 = allocateRegNotConflictingWith(topRegistersMask14); } if (rNext15 == NoReg) { - rNext15 = allocateRegNotConflictingWith(1U << rTop21); + rNext15 = allocateRegNotConflictingWith(((rTop21 < 0) ? (((usqInt)(1)) >> (-rTop21)) : (1U << rTop21))); } assert(!(((rTop21 == NoReg) || (rNext15 == NoReg)))); @@ -33353,14 +33498,14 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg14 = (rNext16 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask15 = 1U << reg14; + topRegistersMask15 = ((reg14 < 0) ? (((usqInt)(1)) >> (-reg14)) : (1U << reg14)); } } if (rTop22 == NoReg) { rTop22 = allocateRegNotConflictingWith(topRegistersMask15); } if (rNext16 == NoReg) { - rNext16 = allocateRegNotConflictingWith(1U << rTop22); + rNext16 = allocateRegNotConflictingWith(((rTop22 < 0) ? (((usqInt)(1)) >> (-rTop22)) : (1U << rTop22))); } assert(!(((rTop22 == NoReg) || (rNext16 == NoReg)))); @@ -33459,7 +33604,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) /* begin allocateRegistersForLowcodeResultInteger2: */ rResult25 = (rResult26 = NoReg); rResult25 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - rResult26 = allocateRegNotConflictingWith(1U << rResult25); + rResult26 = allocateRegNotConflictingWith(((rResult25 < 0) ? (((usqInt)(1)) >> (-rResult25)) : (1U << rResult25))); assert(!(((rResult25 == NoReg) || (rResult26 == NoReg)))); valueLow4 = rResult25; @@ -33543,7 +33688,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) /* begin allocateRegistersForLowcodeResultInteger2: */ rResult27 = (rResult28 = NoReg); rResult27 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - rResult28 = allocateRegNotConflictingWith(1U << rResult27); + rResult28 = allocateRegNotConflictingWith(((rResult27 < 0) ? (((usqInt)(1)) >> (-rResult27)) : (1U << rResult27))); assert(!(((rResult27 == NoReg) || (rResult28 == NoReg)))); valueLow5 = rResult27; @@ -33626,7 +33771,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if (rTop25 == NoReg) { rTop25 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult29 = allocateRegNotConflictingWith(1U << rTop25); + rResult29 = allocateRegNotConflictingWith(((rTop25 < 0) ? (((usqInt)(1)) >> (-rTop25)) : (1U << rTop25))); assert(!(((rTop25 == NoReg) || (rResult29 == NoReg)))); pointer4 = rTop25; @@ -33652,7 +33797,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if (rTop26 == NoReg) { rTop26 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult30 = allocateRegNotConflictingWith(1U << rTop26); + rResult30 = allocateRegNotConflictingWith(((rTop26 < 0) ? (((usqInt)(1)) >> (-rTop26)) : (1U << rTop26))); assert(!(((rTop26 == NoReg) || (rResult30 == NoReg)))); pointer5 = rTop26; @@ -33675,7 +33820,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if (rTop27 == NoReg) { rTop27 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult31 = allocateRegNotConflictingWith(1U << rTop27); + rResult31 = allocateRegNotConflictingWith(((rTop27 < 0) ? (((usqInt)(1)) >> (-rTop27)) : (1U << rTop27))); rResult210 = allocateRegNotConflictingWith((1U << rTop27) | (1U << rResult31)); assert(!(((rTop27 == NoReg) || ((rResult31 == NoReg) @@ -33702,7 +33847,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if (rTop28 == NoReg) { rTop28 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult32 = allocateRegNotConflictingWith(1U << rTop28); + rResult32 = allocateRegNotConflictingWith(((rTop28 < 0) ? (((usqInt)(1)) >> (-rTop28)) : (1U << rTop28))); assert(!(((rTop28 == NoReg) || (rResult32 == NoReg)))); pointer7 = rTop28; @@ -33801,7 +33946,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) /* begin allocateRegistersForLowcodeResultInteger2: */ rResult33 = (rResult211 = NoReg); rResult33 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - rResult211 = allocateRegNotConflictingWith(1U << rResult33); + rResult211 = allocateRegNotConflictingWith(((rResult33 < 0) ? (((usqInt)(1)) >> (-rResult33)) : (1U << rResult33))); assert(!(((rResult33 == NoReg) || (rResult211 == NoReg)))); valueLow7 = rResult33; @@ -33885,7 +34030,7 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) /* begin allocateRegistersForLowcodeResultInteger2: */ rResult34 = (rResult212 = NoReg); rResult34 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - rResult212 = allocateRegNotConflictingWith(1U << rResult34); + rResult212 = allocateRegNotConflictingWith(((rResult34 < 0) ? (((usqInt)(1)) >> (-rResult34)) : (1U << rResult34))); assert(!(((rResult34 == NoReg) || (rResult212 == NoReg)))); valueLow8 = rResult34; @@ -33924,13 +34069,13 @@ genLowcodeUnaryInlinePrimitive2(sqInt prim) if ((registerOrNone(ssTop())) != NoReg) { rOopTop = registerOrNone(ssTop()); /* begin registerMaskFor: */ - topRegisterMask = 1U << rOopTop; + topRegisterMask = ((rOopTop < 0) ? (((usqInt)(1)) >> (-rOopTop)) : (1U << rOopTop)); } if (rTop29 == NoReg) { rTop29 = allocateRegNotConflictingWith(topRegisterMask); } if (rOopTop == NoReg) { - rOopTop = allocateRegNotConflictingWith(1U << rTop29); + rOopTop = allocateRegNotConflictingWith(((rTop29 < 0) ? (((usqInt)(1)) >> (-rTop29)) : (1U << rTop29))); } assert(!(((rTop29 == NoReg) || (rOopTop == NoReg)))); @@ -34216,7 +34361,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult = allocateRegNotConflictingWith(1U << rTop); + rResult = allocateRegNotConflictingWith(((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1U << rTop))); assert(!(((rTop == NoReg) || (rResult == NoReg)))); pointer = rTop; @@ -34238,7 +34383,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult1 = allocateRegNotConflictingWith(1U << rTop1); + rResult1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); assert(!(((rTop1 == NoReg) || (rResult1 == NoReg)))); pointer1 = rTop1; @@ -34260,7 +34405,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop2 == NoReg) { rTop2 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult2 = allocateRegNotConflictingWith(1U << rTop2); + rResult2 = allocateRegNotConflictingWith(((rTop2 < 0) ? (((usqInt)(1)) >> (-rTop2)) : (1U << rTop2))); assert(!(((rTop2 == NoReg) || (rResult2 == NoReg)))); pointer2 = rTop2; @@ -34283,7 +34428,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop3 == NoReg) { rTop3 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult3 = allocateRegNotConflictingWith(1U << rTop3); + rResult3 = allocateRegNotConflictingWith(((rTop3 < 0) ? (((usqInt)(1)) >> (-rTop3)) : (1U << rTop3))); rResult21 = allocateRegNotConflictingWith((1U << rTop3) | (1U << rResult3)); assert(!(((rTop3 == NoReg) || ((rResult3 == NoReg) @@ -34310,7 +34455,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop4 == NoReg) { rTop4 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult4 = allocateRegNotConflictingWith(1U << rTop4); + rResult4 = allocateRegNotConflictingWith(((rTop4 < 0) ? (((usqInt)(1)) >> (-rTop4)) : (1U << rTop4))); assert(!(((rTop4 == NoReg) || (rResult4 == NoReg)))); pointer4 = rTop4; @@ -34395,7 +34540,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop28 == NoReg) { rTop28 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult8 = allocateRegNotConflictingWith(1U << rTop28); + rResult8 = allocateRegNotConflictingWith(((rTop28 < 0) ? (((usqInt)(1)) >> (-rTop28)) : (1U << rTop28))); assert(!(((rTop28 == NoReg) || (rResult8 == NoReg)))); size1 = rTop28; @@ -34441,14 +34586,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg10 = (rNext10 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask12 = 1U << reg10; + topRegistersMask12 = ((reg10 < 0) ? (((usqInt)(1)) >> (-reg10)) : (1U << reg10)); } } if (rTop29 == NoReg) { rTop29 = allocateRegNotConflictingWith(topRegistersMask12); } if (rNext10 == NoReg) { - rNext10 = allocateRegNotConflictingWith(1U << rTop29); + rNext10 = allocateRegNotConflictingWith(((rTop29 < 0) ? (((usqInt)(1)) >> (-rTop29)) : (1U << rTop29))); } assert(!(((rTop29 == NoReg) || (rNext10 == NoReg)))); @@ -34510,18 +34655,18 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) nextRegisterMask2 = 0; if (rNext13 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask2 = 1U << rNext13; + nextRegisterMask2 = ((rNext13 < 0) ? (((usqInt)(1)) >> (-rNext13)) : (1U << rNext13)); } if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1U << rNextNext2); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNext2)) : (1U << rNextNext2))); } rTop30 = allocateRegNotConflictingWith(nextRegisterMask2); } if (rNext13 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask2 = 1U << rTop30; + nextRegisterMask2 = ((rTop30 < 0) ? (((usqInt)(1)) >> (-rTop30)) : (1U << rTop30)); if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1U << rNextNext2); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNext2)) : (1U << rNextNext2))); } rNext13 = allocateRegNotConflictingWith(nextRegisterMask2); } @@ -34584,18 +34729,18 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) nextRegisterMask3 = 0; if (rNext14 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask3 = 1U << rNext14; + nextRegisterMask3 = ((rNext14 < 0) ? (((usqInt)(1)) >> (-rNext14)) : (1U << rNext14)); } if (rNextNext3 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1U << rNextNext3); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNext3)) : (1U << rNextNext3))); } rTop31 = allocateRegNotConflictingWith(nextRegisterMask3); } if (rNext14 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask3 = 1U << rTop31; + nextRegisterMask3 = ((rTop31 < 0) ? (((usqInt)(1)) >> (-rTop31)) : (1U << rTop31)); if (rNextNext3 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1U << rNextNext3); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNext3)) : (1U << rNextNext3))); } rNext14 = allocateRegNotConflictingWith(nextRegisterMask3); } @@ -34646,14 +34791,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg11 = (rNext15 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask13 = 1U << reg11; + topRegistersMask13 = ((reg11 < 0) ? (((usqInt)(1)) >> (-reg11)) : (1U << reg11)); } } if (rTop32 == NoReg) { rTop32 = allocateRegNotConflictingWith(topRegistersMask13); } if (rNext15 == NoReg) { - rNext15 = allocateRegNotConflictingWith(1U << rTop32); + rNext15 = allocateRegNotConflictingWith(((rTop32 < 0) ? (((usqInt)(1)) >> (-rTop32)) : (1U << rTop32))); } assert(!(((rTop32 == NoReg) || (rNext15 == NoReg)))); @@ -34740,14 +34885,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } } if (rTop5 == NoReg) { rTop5 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1U << rTop5); + rNext = allocateRegNotConflictingWith(((rTop5 < 0) ? (((usqInt)(1)) >> (-rTop5)) : (1U << rTop5))); } assert(!(((rTop5 == NoReg) || (rNext == NoReg)))); @@ -34777,14 +34922,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg1 = (rNext1 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask1 = 1U << reg1; + topRegistersMask1 = ((reg1 < 0) ? (((usqInt)(1)) >> (-reg1)) : (1U << reg1)); } } if (rTop6 == NoReg) { rTop6 = allocateRegNotConflictingWith(topRegistersMask1); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop6); + rNext1 = allocateRegNotConflictingWith(((rTop6 < 0) ? (((usqInt)(1)) >> (-rTop6)) : (1U << rTop6))); } assert(!(((rTop6 == NoReg) || (rNext1 == NoReg)))); @@ -34833,14 +34978,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg2 = (rNext2 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask2 = 1U << reg2; + topRegistersMask2 = ((reg2 < 0) ? (((usqInt)(1)) >> (-reg2)) : (1U << reg2)); } } if (rTop8 == NoReg) { rTop8 = allocateRegNotConflictingWith(topRegistersMask2); } if (rNext2 == NoReg) { - rNext2 = allocateRegNotConflictingWith(1U << rTop8); + rNext2 = allocateRegNotConflictingWith(((rTop8 < 0) ? (((usqInt)(1)) >> (-rTop8)) : (1U << rTop8))); } assert(!(((rTop8 == NoReg) || (rNext2 == NoReg)))); @@ -34892,14 +35037,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg3 = (rNext3 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask3 = 1U << reg3; + topRegistersMask3 = ((reg3 < 0) ? (((usqInt)(1)) >> (-reg3)) : (1U << reg3)); } } if (rTop10 == NoReg) { rTop10 = allocateRegNotConflictingWith(topRegistersMask3); } if (rNext3 == NoReg) { - rNext3 = allocateRegNotConflictingWith(1U << rTop10); + rNext3 = allocateRegNotConflictingWith(((rTop10 < 0) ? (((usqInt)(1)) >> (-rTop10)) : (1U << rTop10))); } assert(!(((rTop10 == NoReg) || (rNext3 == NoReg)))); @@ -34929,14 +35074,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg4 = (rNext4 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask4 = 1U << reg4; + topRegistersMask4 = ((reg4 < 0) ? (((usqInt)(1)) >> (-reg4)) : (1U << reg4)); } } if (rTop14 == NoReg) { rTop14 = allocateRegNotConflictingWith(topRegistersMask4); } if (rNext4 == NoReg) { - rNext4 = allocateRegNotConflictingWith(1U << rTop14); + rNext4 = allocateRegNotConflictingWith(((rTop14 < 0) ? (((usqInt)(1)) >> (-rTop14)) : (1U << rTop14))); } assert(!(((rTop14 == NoReg) || (rNext4 == NoReg)))); @@ -34993,24 +35138,24 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) nextRegisterMask = 0; if (rNext5 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask = 1U << rNext5; + nextRegisterMask = ((rNext5 < 0) ? (((usqInt)(1)) >> (-rNext5)) : (1U << rNext5)); } if (rNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNext < 0) ? (((usqInt)(1)) >> (-rNextNext)) : (1U << rNextNext))); } if (rNextNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNextNext < 0) ? (((usqInt)(1)) >> (-rNextNextNext)) : (1U << rNextNextNext))); } rTop15 = allocateRegNotConflictingWith(nextRegisterMask); } if (rNext5 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask = 1U << rTop15; + nextRegisterMask = ((rTop15 < 0) ? (((usqInt)(1)) >> (-rTop15)) : (1U << rTop15)); if (rNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNext < 0) ? (((usqInt)(1)) >> (-rNextNext)) : (1U << rNextNext))); } if (rNextNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNextNext < 0) ? (((usqInt)(1)) >> (-rNextNextNext)) : (1U << rNextNextNext))); } rNext5 = allocateRegNotConflictingWith(nextRegisterMask); } @@ -35018,7 +35163,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) /* begin registerMaskFor:and: */ nextRegisterMask = (1U << rTop15) | (1U << rNext5); if (rNextNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNextNext < 0) ? (((usqInt)(1)) >> (-rNextNextNext)) : (1U << rNextNextNext))); } rNextNext = allocateRegNotConflictingWith(nextRegisterMask); } @@ -35146,14 +35291,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg6 = (rNext6 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask6 = 1U << reg6; + topRegistersMask6 = ((reg6 < 0) ? (((usqInt)(1)) >> (-reg6)) : (1U << reg6)); } } if (rTop18 == NoReg) { rTop18 = allocateRegNotConflictingWith(topRegistersMask6); } if (rNext6 == NoReg) { - rNext6 = allocateRegNotConflictingWith(1U << rTop18); + rNext6 = allocateRegNotConflictingWith(((rTop18 < 0) ? (((usqInt)(1)) >> (-rTop18)) : (1U << rTop18))); } assert(!(((rTop18 == NoReg) || (rNext6 == NoReg)))); @@ -35197,18 +35342,18 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) nextRegisterMask1 = 0; if (rNext7 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask1 = 1U << rNext7; + nextRegisterMask1 = ((rNext7 < 0) ? (((usqInt)(1)) >> (-rNext7)) : (1U << rNext7)); } if (rNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNext1); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNext1)) : (1U << rNextNext1))); } rTop20 = allocateRegNotConflictingWith(nextRegisterMask1); } if (rNext7 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask1 = 1U << rTop20; + nextRegisterMask1 = ((rTop20 < 0) ? (((usqInt)(1)) >> (-rTop20)) : (1U << rTop20)); if (rNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNext1); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNext1)) : (1U << rNextNext1))); } rNext7 = allocateRegNotConflictingWith(nextRegisterMask1); } @@ -35246,14 +35391,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg8 = (rNext8 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask8 = 1U << reg8; + topRegistersMask8 = ((reg8 < 0) ? (((usqInt)(1)) >> (-reg8)) : (1U << reg8)); } } if (rTop21 == NoReg) { rTop21 = allocateRegNotConflictingWith(topRegistersMask8); } if (rNext8 == NoReg) { - rNext8 = allocateRegNotConflictingWith(1U << rTop21); + rNext8 = allocateRegNotConflictingWith(((rTop21 < 0) ? (((usqInt)(1)) >> (-rTop21)) : (1U << rTop21))); } assert(!(((rTop21 == NoReg) || (rNext8 == NoReg)))); @@ -35293,14 +35438,14 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg9 = (rNext9 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask9 = 1U << reg9; + topRegistersMask9 = ((reg9 < 0) ? (((usqInt)(1)) >> (-reg9)) : (1U << reg9)); } } if (rTop22 == NoReg) { rTop22 = allocateRegNotConflictingWith(topRegistersMask9); } if (rNext9 == NoReg) { - rNext9 = allocateRegNotConflictingWith(1U << rTop22); + rNext9 = allocateRegNotConflictingWith(((rTop22 < 0) ? (((usqInt)(1)) >> (-rTop22)) : (1U << rTop22))); } assert(!(((rTop22 == NoReg) || (rNext9 == NoReg)))); @@ -35353,7 +35498,7 @@ genLowcodeUnaryInlinePrimitive3(sqInt prim) if (rTop24 == NoReg) { rTop24 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult7 = allocateRegNotConflictingWith(1U << rTop24); + rResult7 = allocateRegNotConflictingWith(((rTop24 < 0) ? (((usqInt)(1)) >> (-rTop24)) : (1U << rTop24))); rResult22 = allocateRegNotConflictingWith((1U << rTop24) | (1U << rResult7)); assert(!(((rTop24 == NoReg) || ((rResult7 == NoReg) @@ -35932,14 +36077,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } } if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(topRegistersMask); } if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1U << rTop); + rNext = allocateRegNotConflictingWith(((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1U << rTop))); } assert(!(((rTop == NoReg) || (rNext == NoReg)))); @@ -35968,14 +36113,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg1 = (rNext1 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask1 = 1U << reg1; + topRegistersMask1 = ((reg1 < 0) ? (((usqInt)(1)) >> (-reg1)) : (1U << reg1)); } } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask1); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -36005,14 +36150,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg2 = (rNext2 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask2 = 1U << reg2; + topRegistersMask2 = ((reg2 < 0) ? (((usqInt)(1)) >> (-reg2)) : (1U << reg2)); } } if (rTop2 == NoReg) { rTop2 = allocateRegNotConflictingWith(topRegistersMask2); } if (rNext2 == NoReg) { - rNext2 = allocateRegNotConflictingWith(1U << rTop2); + rNext2 = allocateRegNotConflictingWith(((rTop2 < 0) ? (((usqInt)(1)) >> (-rTop2)) : (1U << rTop2))); } assert(!(((rTop2 == NoReg) || (rNext2 == NoReg)))); @@ -36042,14 +36187,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg3 = (rNext3 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask3 = 1U << reg3; + topRegistersMask3 = ((reg3 < 0) ? (((usqInt)(1)) >> (-reg3)) : (1U << reg3)); } } if (rTop3 == NoReg) { rTop3 = allocateRegNotConflictingWith(topRegistersMask3); } if (rNext3 == NoReg) { - rNext3 = allocateRegNotConflictingWith(1U << rTop3); + rNext3 = allocateRegNotConflictingWith(((rTop3 < 0) ? (((usqInt)(1)) >> (-rTop3)) : (1U << rTop3))); } assert(!(((rTop3 == NoReg) || (rNext3 == NoReg)))); @@ -36120,14 +36265,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg4 = (rNext4 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask4 = 1U << reg4; + topRegistersMask4 = ((reg4 < 0) ? (((usqInt)(1)) >> (-reg4)) : (1U << reg4)); } } if (rTop6 == NoReg) { rTop6 = allocateRegNotConflictingWith(topRegistersMask4); } if (rNext4 == NoReg) { - rNext4 = allocateRegNotConflictingWith(1U << rTop6); + rNext4 = allocateRegNotConflictingWith(((rTop6 < 0) ? (((usqInt)(1)) >> (-rTop6)) : (1U << rTop6))); } assert(!(((rTop6 == NoReg) || (rNext4 == NoReg)))); @@ -36163,7 +36308,7 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if (rTop7 == NoReg) { rTop7 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult3 = allocateRegNotConflictingWith(1U << rTop7); + rResult3 = allocateRegNotConflictingWith(((rTop7 < 0) ? (((usqInt)(1)) >> (-rTop7)) : (1U << rTop7))); rResult2 = allocateRegNotConflictingWith((1U << rTop7) | (1U << rResult3)); assert(!(((rTop7 == NoReg) || ((rResult3 == NoReg) @@ -36204,14 +36349,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg5 = (rNext5 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask5 = 1U << reg5; + topRegistersMask5 = ((reg5 < 0) ? (((usqInt)(1)) >> (-reg5)) : (1U << reg5)); } } if (rTop8 == NoReg) { rTop8 = allocateRegNotConflictingWith(topRegistersMask5); } if (rNext5 == NoReg) { - rNext5 = allocateRegNotConflictingWith(1U << rTop8); + rNext5 = allocateRegNotConflictingWith(((rTop8 < 0) ? (((usqInt)(1)) >> (-rTop8)) : (1U << rTop8))); } assert(!(((rTop8 == NoReg) || (rNext5 == NoReg)))); @@ -36314,14 +36459,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg6 = (rNext6 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask6 = 1U << reg6; + topRegistersMask6 = ((reg6 < 0) ? (((usqInt)(1)) >> (-reg6)) : (1U << reg6)); } } if (rTop14 == NoReg) { rTop14 = allocateRegNotConflictingWith(topRegistersMask6); } if (rNext6 == NoReg) { - rNext6 = allocateRegNotConflictingWith(1U << rTop14); + rNext6 = allocateRegNotConflictingWith(((rTop14 < 0) ? (((usqInt)(1)) >> (-rTop14)) : (1U << rTop14))); } assert(!(((rTop14 == NoReg) || (rNext6 == NoReg)))); @@ -36351,14 +36496,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg7 = (rNext7 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask7 = 1U << reg7; + topRegistersMask7 = ((reg7 < 0) ? (((usqInt)(1)) >> (-reg7)) : (1U << reg7)); } } if (rTop15 == NoReg) { rTop15 = allocateRegNotConflictingWith(topRegistersMask7); } if (rNext7 == NoReg) { - rNext7 = allocateRegNotConflictingWith(1U << rTop15); + rNext7 = allocateRegNotConflictingWith(((rTop15 < 0) ? (((usqInt)(1)) >> (-rTop15)) : (1U << rTop15))); } assert(!(((rTop15 == NoReg) || (rNext7 == NoReg)))); @@ -36401,18 +36546,18 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) nextRegisterMask = 0; if (rNext8 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask = 1U << rNext8; + nextRegisterMask = ((rNext8 < 0) ? (((usqInt)(1)) >> (-rNext8)) : (1U << rNext8)); } if (rNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNext < 0) ? (((usqInt)(1)) >> (-rNextNext)) : (1U << rNextNext))); } rTop17 = allocateRegNotConflictingWith(nextRegisterMask); } if (rNext8 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask = 1U << rTop17; + nextRegisterMask = ((rTop17 < 0) ? (((usqInt)(1)) >> (-rTop17)) : (1U << rTop17)); if (rNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNext < 0) ? (((usqInt)(1)) >> (-rNextNext)) : (1U << rNextNext))); } rNext8 = allocateRegNotConflictingWith(nextRegisterMask); } @@ -36451,14 +36596,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg9 = (rNext9 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask9 = 1U << reg9; + topRegistersMask9 = ((reg9 < 0) ? (((usqInt)(1)) >> (-reg9)) : (1U << reg9)); } } if (rTop18 == NoReg) { rTop18 = allocateRegNotConflictingWith(topRegistersMask9); } if (rNext9 == NoReg) { - rNext9 = allocateRegNotConflictingWith(1U << rTop18); + rNext9 = allocateRegNotConflictingWith(((rTop18 < 0) ? (((usqInt)(1)) >> (-rTop18)) : (1U << rTop18))); } assert(!(((rTop18 == NoReg) || (rNext9 == NoReg)))); @@ -36578,14 +36723,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg10 = (rNext10 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask12 = 1U << reg10; + topRegistersMask12 = ((reg10 < 0) ? (((usqInt)(1)) >> (-reg10)) : (1U << reg10)); } } if (rTop21 == NoReg) { rTop21 = allocateRegNotConflictingWith(topRegistersMask12); } if (rNext10 == NoReg) { - rNext10 = allocateRegNotConflictingWith(1U << rTop21); + rNext10 = allocateRegNotConflictingWith(((rTop21 < 0) ? (((usqInt)(1)) >> (-rTop21)) : (1U << rTop21))); } assert(!(((rTop21 == NoReg) || (rNext10 == NoReg)))); @@ -36659,14 +36804,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg11 = (rNext12 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask13 = 1U << reg11; + topRegistersMask13 = ((reg11 < 0) ? (((usqInt)(1)) >> (-reg11)) : (1U << reg11)); } } if (rTop24 == NoReg) { rTop24 = allocateRegNotConflictingWith(topRegistersMask13); } if (rNext12 == NoReg) { - rNext12 = allocateRegNotConflictingWith(1U << rTop24); + rNext12 = allocateRegNotConflictingWith(((rTop24 < 0) ? (((usqInt)(1)) >> (-rTop24)) : (1U << rTop24))); } assert(!(((rTop24 == NoReg) || (rNext12 == NoReg)))); @@ -36694,14 +36839,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg12 = (rNext13 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask14 = 1U << reg12; + topRegistersMask14 = ((reg12 < 0) ? (((usqInt)(1)) >> (-reg12)) : (1U << reg12)); } } if (rTop25 == NoReg) { rTop25 = allocateRegNotConflictingWith(topRegistersMask14); } if (rNext13 == NoReg) { - rNext13 = allocateRegNotConflictingWith(1U << rTop25); + rNext13 = allocateRegNotConflictingWith(((rTop25 < 0) ? (((usqInt)(1)) >> (-rTop25)) : (1U << rTop25))); } assert(!(((rTop25 == NoReg) || (rNext13 == NoReg)))); @@ -36755,24 +36900,24 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) nextRegisterMask1 = 0; if (rNext14 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask1 = 1U << rNext14; + nextRegisterMask1 = ((rNext14 < 0) ? (((usqInt)(1)) >> (-rNext14)) : (1U << rNext14)); } if (rNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNext1); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNext1)) : (1U << rNextNext1))); } if (rNextNextNext != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNextNext); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNextNext < 0) ? (((usqInt)(1)) >> (-rNextNextNext)) : (1U << rNextNextNext))); } rTop26 = allocateRegNotConflictingWith(nextRegisterMask1); } if (rNext14 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask1 = 1U << rTop26; + nextRegisterMask1 = ((rTop26 < 0) ? (((usqInt)(1)) >> (-rTop26)) : (1U << rTop26)); if (rNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNext1); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNext1)) : (1U << rNextNext1))); } if (rNextNextNext != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNextNext); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNextNext < 0) ? (((usqInt)(1)) >> (-rNextNextNext)) : (1U << rNextNextNext))); } rNext14 = allocateRegNotConflictingWith(nextRegisterMask1); } @@ -36780,7 +36925,7 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) /* begin registerMaskFor:and: */ nextRegisterMask1 = (1U << rTop26) | (1U << rNext14); if (rNextNextNext != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNextNext); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNextNext < 0) ? (((usqInt)(1)) >> (-rNextNextNext)) : (1U << rNextNextNext))); } rNextNext1 = allocateRegNotConflictingWith(nextRegisterMask1); } @@ -36859,14 +37004,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg14 = (rNext16 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask16 = 1U << reg14; + topRegistersMask16 = ((reg14 < 0) ? (((usqInt)(1)) >> (-reg14)) : (1U << reg14)); } } if (rTop29 == NoReg) { rTop29 = allocateRegNotConflictingWith(topRegistersMask16); } if (rNext16 == NoReg) { - rNext16 = allocateRegNotConflictingWith(1U << rTop29); + rNext16 = allocateRegNotConflictingWith(((rTop29 < 0) ? (((usqInt)(1)) >> (-rTop29)) : (1U << rTop29))); } assert(!(((rTop29 == NoReg) || (rNext16 == NoReg)))); @@ -36894,14 +37039,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg15 = (rNext17 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask17 = 1U << reg15; + topRegistersMask17 = ((reg15 < 0) ? (((usqInt)(1)) >> (-reg15)) : (1U << reg15)); } } if (rTop30 == NoReg) { rTop30 = allocateRegNotConflictingWith(topRegistersMask17); } if (rNext17 == NoReg) { - rNext17 = allocateRegNotConflictingWith(1U << rTop30); + rNext17 = allocateRegNotConflictingWith(((rTop30 < 0) ? (((usqInt)(1)) >> (-rTop30)) : (1U << rTop30))); } assert(!(((rTop30 == NoReg) || (rNext17 == NoReg)))); @@ -36928,14 +37073,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg16 = (rNext18 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask18 = 1U << reg16; + topRegistersMask18 = ((reg16 < 0) ? (((usqInt)(1)) >> (-reg16)) : (1U << reg16)); } } if (rTop31 == NoReg) { rTop31 = allocateRegNotConflictingWith(topRegistersMask18); } if (rNext18 == NoReg) { - rNext18 = allocateRegNotConflictingWith(1U << rTop31); + rNext18 = allocateRegNotConflictingWith(((rTop31 < 0) ? (((usqInt)(1)) >> (-rTop31)) : (1U << rTop31))); } assert(!(((rTop31 == NoReg) || (rNext18 == NoReg)))); @@ -36965,14 +37110,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg17 = (rNext19 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask19 = 1U << reg17; + topRegistersMask19 = ((reg17 < 0) ? (((usqInt)(1)) >> (-reg17)) : (1U << reg17)); } } if (rTop32 == NoReg) { rTop32 = allocateRegNotConflictingWith(topRegistersMask19); } if (rNext19 == NoReg) { - rNext19 = allocateRegNotConflictingWith(1U << rTop32); + rNext19 = allocateRegNotConflictingWith(((rTop32 < 0) ? (((usqInt)(1)) >> (-rTop32)) : (1U << rTop32))); } assert(!(((rTop32 == NoReg) || (rNext19 == NoReg)))); @@ -37001,14 +37146,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg18 = (rNext20 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask20 = 1U << reg18; + topRegistersMask20 = ((reg18 < 0) ? (((usqInt)(1)) >> (-reg18)) : (1U << reg18)); } } if (rTop33 == NoReg) { rTop33 = allocateRegNotConflictingWith(topRegistersMask20); } if (rNext20 == NoReg) { - rNext20 = allocateRegNotConflictingWith(1U << rTop33); + rNext20 = allocateRegNotConflictingWith(((rTop33 < 0) ? (((usqInt)(1)) >> (-rTop33)) : (1U << rTop33))); } assert(!(((rTop33 == NoReg) || (rNext20 == NoReg)))); @@ -37038,14 +37183,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg19 = (rNext21 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask21 = 1U << reg19; + topRegistersMask21 = ((reg19 < 0) ? (((usqInt)(1)) >> (-reg19)) : (1U << reg19)); } } if (rTop34 == NoReg) { rTop34 = allocateRegNotConflictingWith(topRegistersMask21); } if (rNext21 == NoReg) { - rNext21 = allocateRegNotConflictingWith(1U << rTop34); + rNext21 = allocateRegNotConflictingWith(((rTop34 < 0) ? (((usqInt)(1)) >> (-rTop34)) : (1U << rTop34))); } assert(!(((rTop34 == NoReg) || (rNext21 == NoReg)))); @@ -37085,14 +37230,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg20 = (rNext22 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask22 = 1U << reg20; + topRegistersMask22 = ((reg20 < 0) ? (((usqInt)(1)) >> (-reg20)) : (1U << reg20)); } } if (rTop35 == NoReg) { rTop35 = allocateRegNotConflictingWith(topRegistersMask22); } if (rNext22 == NoReg) { - rNext22 = allocateRegNotConflictingWith(1U << rTop35); + rNext22 = allocateRegNotConflictingWith(((rTop35 < 0) ? (((usqInt)(1)) >> (-rTop35)) : (1U << rTop35))); } assert(!(((rTop35 == NoReg) || (rNext22 == NoReg)))); @@ -37132,14 +37277,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg21 = (rNext23 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask23 = 1U << reg21; + topRegistersMask23 = ((reg21 < 0) ? (((usqInt)(1)) >> (-reg21)) : (1U << reg21)); } } if (rTop36 == NoReg) { rTop36 = allocateRegNotConflictingWith(topRegistersMask23); } if (rNext23 == NoReg) { - rNext23 = allocateRegNotConflictingWith(1U << rTop36); + rNext23 = allocateRegNotConflictingWith(((rTop36 < 0) ? (((usqInt)(1)) >> (-rTop36)) : (1U << rTop36))); } assert(!(((rTop36 == NoReg) || (rNext23 == NoReg)))); @@ -37179,14 +37324,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg22 = (rNext24 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask24 = 1U << reg22; + topRegistersMask24 = ((reg22 < 0) ? (((usqInt)(1)) >> (-reg22)) : (1U << reg22)); } } if (rTop37 == NoReg) { rTop37 = allocateRegNotConflictingWith(topRegistersMask24); } if (rNext24 == NoReg) { - rNext24 = allocateRegNotConflictingWith(1U << rTop37); + rNext24 = allocateRegNotConflictingWith(((rTop37 < 0) ? (((usqInt)(1)) >> (-rTop37)) : (1U << rTop37))); } assert(!(((rTop37 == NoReg) || (rNext24 == NoReg)))); @@ -37271,14 +37416,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg23 = (rNext25 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask25 = 1U << reg23; + topRegistersMask25 = ((reg23 < 0) ? (((usqInt)(1)) >> (-reg23)) : (1U << reg23)); } } if (rTop40 == NoReg) { rTop40 = allocateRegNotConflictingWith(topRegistersMask25); } if (rNext25 == NoReg) { - rNext25 = allocateRegNotConflictingWith(1U << rTop40); + rNext25 = allocateRegNotConflictingWith(((rTop40 < 0) ? (((usqInt)(1)) >> (-rTop40)) : (1U << rTop40))); } assert(!(((rTop40 == NoReg) || (rNext25 == NoReg)))); @@ -37309,14 +37454,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg24 = (rNext26 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask26 = 1U << reg24; + topRegistersMask26 = ((reg24 < 0) ? (((usqInt)(1)) >> (-reg24)) : (1U << reg24)); } } if (rTop41 == NoReg) { rTop41 = allocateRegNotConflictingWith(topRegistersMask26); } if (rNext26 == NoReg) { - rNext26 = allocateRegNotConflictingWith(1U << rTop41); + rNext26 = allocateRegNotConflictingWith(((rTop41 < 0) ? (((usqInt)(1)) >> (-rTop41)) : (1U << rTop41))); } assert(!(((rTop41 == NoReg) || (rNext26 == NoReg)))); @@ -37347,14 +37492,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg25 = (rNext27 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask27 = 1U << reg25; + topRegistersMask27 = ((reg25 < 0) ? (((usqInt)(1)) >> (-reg25)) : (1U << reg25)); } } if (rTop42 == NoReg) { rTop42 = allocateRegNotConflictingWith(topRegistersMask27); } if (rNext27 == NoReg) { - rNext27 = allocateRegNotConflictingWith(1U << rTop42); + rNext27 = allocateRegNotConflictingWith(((rTop42 < 0) ? (((usqInt)(1)) >> (-rTop42)) : (1U << rTop42))); } assert(!(((rTop42 == NoReg) || (rNext27 == NoReg)))); @@ -37385,14 +37530,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg26 = (rNext28 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask28 = 1U << reg26; + topRegistersMask28 = ((reg26 < 0) ? (((usqInt)(1)) >> (-reg26)) : (1U << reg26)); } } if (rTop43 == NoReg) { rTop43 = allocateRegNotConflictingWith(topRegistersMask28); } if (rNext28 == NoReg) { - rNext28 = allocateRegNotConflictingWith(1U << rTop43); + rNext28 = allocateRegNotConflictingWith(((rTop43 < 0) ? (((usqInt)(1)) >> (-rTop43)) : (1U << rTop43))); } assert(!(((rTop43 == NoReg) || (rNext28 == NoReg)))); @@ -37462,14 +37607,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg27 = (rNext29 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask29 = 1U << reg27; + topRegistersMask29 = ((reg27 < 0) ? (((usqInt)(1)) >> (-reg27)) : (1U << reg27)); } } if (rTop46 == NoReg) { rTop46 = allocateRegNotConflictingWith(topRegistersMask29); } if (rNext29 == NoReg) { - rNext29 = allocateRegNotConflictingWith(1U << rTop46); + rNext29 = allocateRegNotConflictingWith(((rTop46 < 0) ? (((usqInt)(1)) >> (-rTop46)) : (1U << rTop46))); } assert(!(((rTop46 == NoReg) || (rNext29 == NoReg)))); @@ -37499,14 +37644,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg28 = (rNext30 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask30 = 1U << reg28; + topRegistersMask30 = ((reg28 < 0) ? (((usqInt)(1)) >> (-reg28)) : (1U << reg28)); } } if (rTop47 == NoReg) { rTop47 = allocateRegNotConflictingWith(topRegistersMask30); } if (rNext30 == NoReg) { - rNext30 = allocateRegNotConflictingWith(1U << rTop47); + rNext30 = allocateRegNotConflictingWith(((rTop47 < 0) ? (((usqInt)(1)) >> (-rTop47)) : (1U << rTop47))); } assert(!(((rTop47 == NoReg) || (rNext30 == NoReg)))); @@ -37544,14 +37689,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg29 = (rNext31 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask31 = 1U << reg29; + topRegistersMask31 = ((reg29 < 0) ? (((usqInt)(1)) >> (-reg29)) : (1U << reg29)); } } if (rTop48 == NoReg) { rTop48 = allocateRegNotConflictingWith(topRegistersMask31); } if (rNext31 == NoReg) { - rNext31 = allocateRegNotConflictingWith(1U << rTop48); + rNext31 = allocateRegNotConflictingWith(((rTop48 < 0) ? (((usqInt)(1)) >> (-rTop48)) : (1U << rTop48))); } assert(!(((rTop48 == NoReg) || (rNext31 == NoReg)))); @@ -37580,14 +37725,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg30 = (rNext32 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask32 = 1U << reg30; + topRegistersMask32 = ((reg30 < 0) ? (((usqInt)(1)) >> (-reg30)) : (1U << reg30)); } } if (rTop49 == NoReg) { rTop49 = allocateRegNotConflictingWith(topRegistersMask32); } if (rNext32 == NoReg) { - rNext32 = allocateRegNotConflictingWith(1U << rTop49); + rNext32 = allocateRegNotConflictingWith(((rTop49 < 0) ? (((usqInt)(1)) >> (-rTop49)) : (1U << rTop49))); } assert(!(((rTop49 == NoReg) || (rNext32 == NoReg)))); @@ -37617,14 +37762,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg31 = (rNext33 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask33 = 1U << reg31; + topRegistersMask33 = ((reg31 < 0) ? (((usqInt)(1)) >> (-reg31)) : (1U << reg31)); } } if (rTop50 == NoReg) { rTop50 = allocateRegNotConflictingWith(topRegistersMask33); } if (rNext33 == NoReg) { - rNext33 = allocateRegNotConflictingWith(1U << rTop50); + rNext33 = allocateRegNotConflictingWith(((rTop50 < 0) ? (((usqInt)(1)) >> (-rTop50)) : (1U << rTop50))); } assert(!(((rTop50 == NoReg) || (rNext33 == NoReg)))); @@ -37678,24 +37823,24 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) nextRegisterMask2 = 0; if (rNext34 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask2 = 1U << rNext34; + nextRegisterMask2 = ((rNext34 < 0) ? (((usqInt)(1)) >> (-rNext34)) : (1U << rNext34)); } if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1U << rNextNext2); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNext2)) : (1U << rNextNext2))); } if (rNextNextNext1 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1U << rNextNextNext1); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNextNext1)) : (1U << rNextNextNext1))); } rTop51 = allocateRegNotConflictingWith(nextRegisterMask2); } if (rNext34 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask2 = 1U << rTop51; + nextRegisterMask2 = ((rTop51 < 0) ? (((usqInt)(1)) >> (-rTop51)) : (1U << rTop51)); if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1U << rNextNext2); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNext2)) : (1U << rNextNext2))); } if (rNextNextNext1 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1U << rNextNextNext1); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNextNext1)) : (1U << rNextNextNext1))); } rNext34 = allocateRegNotConflictingWith(nextRegisterMask2); } @@ -37703,7 +37848,7 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) /* begin registerMaskFor:and: */ nextRegisterMask2 = (1U << rTop51) | (1U << rNext34); if (rNextNextNext1 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1U << rNextNextNext1); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNextNext1)) : (1U << rNextNextNext1))); } rNextNext2 = allocateRegNotConflictingWith(nextRegisterMask2); } @@ -37784,14 +37929,14 @@ genLowcodeUnaryInlinePrimitive4(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg33 = (rNext35 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask35 = 1U << reg33; + topRegistersMask35 = ((reg33 < 0) ? (((usqInt)(1)) >> (-reg33)) : (1U << reg33)); } } if (rTop54 == NoReg) { rTop54 = allocateRegNotConflictingWith(topRegistersMask35); } if (rNext35 == NoReg) { - rNext35 = allocateRegNotConflictingWith(1U << rTop54); + rNext35 = allocateRegNotConflictingWith(((rTop54 < 0) ? (((usqInt)(1)) >> (-rTop54)) : (1U << rTop54))); } assert(!(((rTop54 == NoReg) || (rNext35 == NoReg)))); @@ -37848,7 +37993,7 @@ genLowcodeUnaryInlinePrimitive5(sqInt prim) if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult = allocateRegNotConflictingWith(1U << rTop); + rResult = allocateRegNotConflictingWith(((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1U << rTop))); rResult2 = allocateRegNotConflictingWith((1U << rTop) | (1U << rResult)); assert(!(((rTop == NoReg) || ((rResult == NoReg) @@ -37880,14 +38025,14 @@ genLowcodeUnaryInlinePrimitive5(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } } if (rTop2 == NoReg) { rTop2 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1U << rTop2); + rNext = allocateRegNotConflictingWith(((rTop2 < 0) ? (((usqInt)(1)) >> (-rTop2)) : (1U << rTop2))); } assert(!(((rTop2 == NoReg) || (rNext == NoReg)))); @@ -38298,14 +38443,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } } if (rTop == NoReg) { rTop = allocateRegNotConflictingWith(topRegistersMask); } if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1U << rTop); + rNext = allocateRegNotConflictingWith(((rTop < 0) ? (((usqInt)(1)) >> (-rTop)) : (1U << rTop))); } assert(!(((rTop == NoReg) || (rNext == NoReg)))); @@ -38359,24 +38504,24 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) nextRegisterMask = 0; if (rNext2 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask = 1U << rNext2; + nextRegisterMask = ((rNext2 < 0) ? (((usqInt)(1)) >> (-rNext2)) : (1U << rNext2)); } if (rNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNext < 0) ? (((usqInt)(1)) >> (-rNextNext)) : (1U << rNextNext))); } if (rNextNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNextNext < 0) ? (((usqInt)(1)) >> (-rNextNextNext)) : (1U << rNextNextNext))); } rTop2 = allocateRegNotConflictingWith(nextRegisterMask); } if (rNext2 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask = 1U << rTop2; + nextRegisterMask = ((rTop2 < 0) ? (((usqInt)(1)) >> (-rTop2)) : (1U << rTop2)); if (rNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNext < 0) ? (((usqInt)(1)) >> (-rNextNext)) : (1U << rNextNext))); } if (rNextNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNextNext < 0) ? (((usqInt)(1)) >> (-rNextNextNext)) : (1U << rNextNextNext))); } rNext2 = allocateRegNotConflictingWith(nextRegisterMask); } @@ -38384,7 +38529,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) /* begin registerMaskFor:and: */ nextRegisterMask = (1U << rTop2) | (1U << rNext2); if (rNextNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNextNext); + nextRegisterMask = nextRegisterMask | (((rNextNextNext < 0) ? (((usqInt)(1)) >> (-rNextNextNext)) : (1U << rNextNextNext))); } rNextNext = allocateRegNotConflictingWith(nextRegisterMask); } @@ -38455,14 +38600,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg2 = (rNext3 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask2 = 1U << reg2; + topRegistersMask2 = ((reg2 < 0) ? (((usqInt)(1)) >> (-reg2)) : (1U << reg2)); } } if (rTop4 == NoReg) { rTop4 = allocateRegNotConflictingWith(topRegistersMask2); } if (rNext3 == NoReg) { - rNext3 = allocateRegNotConflictingWith(1U << rTop4); + rNext3 = allocateRegNotConflictingWith(((rTop4 < 0) ? (((usqInt)(1)) >> (-rTop4)) : (1U << rTop4))); } assert(!(((rTop4 == NoReg) || (rNext3 == NoReg)))); @@ -38491,14 +38636,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg3 = (rNext4 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask3 = 1U << reg3; + topRegistersMask3 = ((reg3 < 0) ? (((usqInt)(1)) >> (-reg3)) : (1U << reg3)); } } if (rTop5 == NoReg) { rTop5 = allocateRegNotConflictingWith(topRegistersMask3); } if (rNext4 == NoReg) { - rNext4 = allocateRegNotConflictingWith(1U << rTop5); + rNext4 = allocateRegNotConflictingWith(((rTop5 < 0) ? (((usqInt)(1)) >> (-rTop5)) : (1U << rTop5))); } assert(!(((rTop5 == NoReg) || (rNext4 == NoReg)))); @@ -38552,24 +38697,24 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) nextRegisterMask1 = 0; if (rNext5 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask1 = 1U << rNext5; + nextRegisterMask1 = ((rNext5 < 0) ? (((usqInt)(1)) >> (-rNext5)) : (1U << rNext5)); } if (rNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNext1); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNext1)) : (1U << rNextNext1))); } if (rNextNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNextNext1); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNextNext1)) : (1U << rNextNextNext1))); } rTop6 = allocateRegNotConflictingWith(nextRegisterMask1); } if (rNext5 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask1 = 1U << rTop6; + nextRegisterMask1 = ((rTop6 < 0) ? (((usqInt)(1)) >> (-rTop6)) : (1U << rTop6)); if (rNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNext1); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNext1)) : (1U << rNextNext1))); } if (rNextNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNextNext1); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNextNext1)) : (1U << rNextNextNext1))); } rNext5 = allocateRegNotConflictingWith(nextRegisterMask1); } @@ -38577,7 +38722,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) /* begin registerMaskFor:and: */ nextRegisterMask1 = (1U << rTop6) | (1U << rNext5); if (rNextNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNextNext1); + nextRegisterMask1 = nextRegisterMask1 | (((rNextNextNext1 < 0) ? (((usqInt)(1)) >> (-rNextNextNext1)) : (1U << rNextNextNext1))); } rNextNext1 = allocateRegNotConflictingWith(nextRegisterMask1); } @@ -38619,14 +38764,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg5 = (rNext6 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask5 = 1U << reg5; + topRegistersMask5 = ((reg5 < 0) ? (((usqInt)(1)) >> (-reg5)) : (1U << reg5)); } } if (rTop7 == NoReg) { rTop7 = allocateRegNotConflictingWith(topRegistersMask5); } if (rNext6 == NoReg) { - rNext6 = allocateRegNotConflictingWith(1U << rTop7); + rNext6 = allocateRegNotConflictingWith(((rTop7 < 0) ? (((usqInt)(1)) >> (-rTop7)) : (1U << rTop7))); } assert(!(((rTop7 == NoReg) || (rNext6 == NoReg)))); @@ -38656,14 +38801,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg6 = (rNext7 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask6 = 1U << reg6; + topRegistersMask6 = ((reg6 < 0) ? (((usqInt)(1)) >> (-reg6)) : (1U << reg6)); } } if (rTop8 == NoReg) { rTop8 = allocateRegNotConflictingWith(topRegistersMask6); } if (rNext7 == NoReg) { - rNext7 = allocateRegNotConflictingWith(1U << rTop8); + rNext7 = allocateRegNotConflictingWith(((rTop8 < 0) ? (((usqInt)(1)) >> (-rTop8)) : (1U << rTop8))); } assert(!(((rTop8 == NoReg) || (rNext7 == NoReg)))); @@ -38812,18 +38957,18 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) nextRegisterMask2 = 0; if (rNext8 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask2 = 1U << rNext8; + nextRegisterMask2 = ((rNext8 < 0) ? (((usqInt)(1)) >> (-rNext8)) : (1U << rNext8)); } if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1U << rNextNext2); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNext2)) : (1U << rNextNext2))); } rTop9 = allocateRegNotConflictingWith(nextRegisterMask2); } if (rNext8 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask2 = 1U << rTop9; + nextRegisterMask2 = ((rTop9 < 0) ? (((usqInt)(1)) >> (-rTop9)) : (1U << rTop9)); if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1U << rNextNext2); + nextRegisterMask2 = nextRegisterMask2 | (((rNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNext2)) : (1U << rNextNext2))); } rNext8 = allocateRegNotConflictingWith(nextRegisterMask2); } @@ -38864,14 +39009,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg7 = (rNext9 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask7 = 1U << reg7; + topRegistersMask7 = ((reg7 < 0) ? (((usqInt)(1)) >> (-reg7)) : (1U << reg7)); } } if (rTop10 == NoReg) { rTop10 = allocateRegNotConflictingWith(topRegistersMask7); } if (rNext9 == NoReg) { - rNext9 = allocateRegNotConflictingWith(1U << rTop10); + rNext9 = allocateRegNotConflictingWith(((rTop10 < 0) ? (((usqInt)(1)) >> (-rTop10)) : (1U << rTop10))); } assert(!(((rTop10 == NoReg) || (rNext9 == NoReg)))); @@ -38900,14 +39045,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg8 = (rNext10 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask8 = 1U << reg8; + topRegistersMask8 = ((reg8 < 0) ? (((usqInt)(1)) >> (-reg8)) : (1U << reg8)); } } if (rTop13 == NoReg) { rTop13 = allocateRegNotConflictingWith(topRegistersMask8); } if (rNext10 == NoReg) { - rNext10 = allocateRegNotConflictingWith(1U << rTop13); + rNext10 = allocateRegNotConflictingWith(((rTop13 < 0) ? (((usqInt)(1)) >> (-rTop13)) : (1U << rTop13))); } assert(!(((rTop13 == NoReg) || (rNext10 == NoReg)))); @@ -38935,7 +39080,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (frTop == NoReg) { frTop = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); } - frResult = allocateFloatRegNotConflictingWith(1U << frTop); + frResult = allocateFloatRegNotConflictingWith(((frTop < 0) ? (((usqInt)(1)) >> (-frTop)) : (1U << frTop))); assert(!(((frTop == NoReg) || (frResult == NoReg)))); value3 = frTop; @@ -38960,7 +39105,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (frTop1 == NoReg) { frTop1 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); } - frResult1 = allocateFloatRegNotConflictingWith(1U << frTop1); + frResult1 = allocateFloatRegNotConflictingWith(((frTop1 < 0) ? (((usqInt)(1)) >> (-frTop1)) : (1U << frTop1))); assert(!(((frTop1 == NoReg) || (frResult1 == NoReg)))); value4 = frTop1; @@ -38983,7 +39128,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (rTop14 == NoReg) { rTop14 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult3 = allocateRegNotConflictingWith(1U << rTop14); + rResult3 = allocateRegNotConflictingWith(((rTop14 < 0) ? (((usqInt)(1)) >> (-rTop14)) : (1U << rTop14))); assert(!(((rTop14 == NoReg) || (rResult3 == NoReg)))); value5 = rTop14; @@ -39012,14 +39157,14 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg9 = (rNext12 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask9 = 1U << reg9; + topRegistersMask9 = ((reg9 < 0) ? (((usqInt)(1)) >> (-reg9)) : (1U << reg9)); } } if (rTop15 == NoReg) { rTop15 = allocateRegNotConflictingWith(topRegistersMask9); } if (rNext12 == NoReg) { - rNext12 = allocateRegNotConflictingWith(1U << rTop15); + rNext12 = allocateRegNotConflictingWith(((rTop15 < 0) ? (((usqInt)(1)) >> (-rTop15)) : (1U << rTop15))); } assert(!(((rTop15 == NoReg) || (rNext12 == NoReg)))); @@ -39051,7 +39196,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (rTop17 == NoReg) { rTop17 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); } - rResult5 = allocateRegNotConflictingWith(1U << rTop17); + rResult5 = allocateRegNotConflictingWith(((rTop17 < 0) ? (((usqInt)(1)) >> (-rTop17)) : (1U << rTop17))); assert(!(((rTop17 == NoReg) || (rResult5 == NoReg)))); pointerValue = rTop17; @@ -39102,24 +39247,24 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) nextRegisterMask3 = 0; if (rNext13 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask3 = 1U << rNext13; + nextRegisterMask3 = ((rNext13 < 0) ? (((usqInt)(1)) >> (-rNext13)) : (1U << rNext13)); } if (rNextNext3 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1U << rNextNext3); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNext3)) : (1U << rNextNext3))); } if (rNextNextNext2 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1U << rNextNextNext2); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNextNext2)) : (1U << rNextNextNext2))); } rTop18 = allocateRegNotConflictingWith(nextRegisterMask3); } if (rNext13 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask3 = 1U << rTop18; + nextRegisterMask3 = ((rTop18 < 0) ? (((usqInt)(1)) >> (-rTop18)) : (1U << rTop18)); if (rNextNext3 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1U << rNextNext3); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNext3)) : (1U << rNextNext3))); } if (rNextNextNext2 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1U << rNextNextNext2); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNextNext2)) : (1U << rNextNextNext2))); } rNext13 = allocateRegNotConflictingWith(nextRegisterMask3); } @@ -39127,7 +39272,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) /* begin registerMaskFor:and: */ nextRegisterMask3 = (1U << rTop18) | (1U << rNext13); if (rNextNextNext2 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1U << rNextNextNext2); + nextRegisterMask3 = nextRegisterMask3 | (((rNextNextNext2 < 0) ? (((usqInt)(1)) >> (-rNextNextNext2)) : (1U << rNextNextNext2))); } rNextNext3 = allocateRegNotConflictingWith(nextRegisterMask3); } @@ -39200,24 +39345,24 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) nextRegisterMask4 = 0; if (rNext14 != NoReg) { /* begin registerMaskFor: */ - nextRegisterMask4 = 1U << rNext14; + nextRegisterMask4 = ((rNext14 < 0) ? (((usqInt)(1)) >> (-rNext14)) : (1U << rNext14)); } if (rNextNext4 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1U << rNextNext4); + nextRegisterMask4 = nextRegisterMask4 | (((rNextNext4 < 0) ? (((usqInt)(1)) >> (-rNextNext4)) : (1U << rNextNext4))); } if (rNextNextNext3 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1U << rNextNextNext3); + nextRegisterMask4 = nextRegisterMask4 | (((rNextNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNextNext3)) : (1U << rNextNextNext3))); } rTop19 = allocateRegNotConflictingWith(nextRegisterMask4); } if (rNext14 == NoReg) { /* begin registerMaskFor: */ - nextRegisterMask4 = 1U << rTop19; + nextRegisterMask4 = ((rTop19 < 0) ? (((usqInt)(1)) >> (-rTop19)) : (1U << rTop19)); if (rNextNext4 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1U << rNextNext4); + nextRegisterMask4 = nextRegisterMask4 | (((rNextNext4 < 0) ? (((usqInt)(1)) >> (-rNextNext4)) : (1U << rNextNext4))); } if (rNextNextNext3 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1U << rNextNextNext3); + nextRegisterMask4 = nextRegisterMask4 | (((rNextNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNextNext3)) : (1U << rNextNextNext3))); } rNext14 = allocateRegNotConflictingWith(nextRegisterMask4); } @@ -39225,7 +39370,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) /* begin registerMaskFor:and: */ nextRegisterMask4 = (1U << rTop19) | (1U << rNext14); if (rNextNextNext3 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1U << rNextNextNext3); + nextRegisterMask4 = nextRegisterMask4 | (((rNextNextNext3 < 0) ? (((usqInt)(1)) >> (-rNextNextNext3)) : (1U << rNextNextNext3))); } rNextNext4 = allocateRegNotConflictingWith(nextRegisterMask4); } @@ -39275,13 +39420,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg10 = (rNext15 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask10 = 1U << reg10; + topRegistersMask10 = ((reg10 < 0) ? (((usqInt)(1)) >> (-reg10)) : (1U << reg10)); } if (rTop20 == NoReg) { rTop20 = allocateFloatRegNotConflictingWith(topRegistersMask10); } if (rNext15 == NoReg) { - rNext15 = allocateFloatRegNotConflictingWith(1U << rTop20); + rNext15 = allocateFloatRegNotConflictingWith(((rTop20 < 0) ? (((usqInt)(1)) >> (-rTop20)) : (1U << rTop20))); } assert(!(((rTop20 == NoReg) || (rNext15 == NoReg)))); @@ -39306,13 +39451,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg11 = (rNext16 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask11 = 1U << reg11; + topRegistersMask11 = ((reg11 < 0) ? (((usqInt)(1)) >> (-reg11)) : (1U << reg11)); } if (rTop21 == NoReg) { rTop21 = allocateFloatRegNotConflictingWith(topRegistersMask11); } if (rNext16 == NoReg) { - rNext16 = allocateFloatRegNotConflictingWith(1U << rTop21); + rNext16 = allocateFloatRegNotConflictingWith(((rTop21 < 0) ? (((usqInt)(1)) >> (-rTop21)) : (1U << rTop21))); } assert(!(((rTop21 == NoReg) || (rNext16 == NoReg)))); @@ -39338,13 +39483,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg12 = (frNext = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask12 = 1U << reg12; + topRegistersMask12 = ((reg12 < 0) ? (((usqInt)(1)) >> (-reg12)) : (1U << reg12)); } if (frTop2 == NoReg) { frTop2 = allocateFloatRegNotConflictingWith(topRegistersMask12); } if (frNext == NoReg) { - frNext = allocateFloatRegNotConflictingWith(1U << frTop2); + frNext = allocateFloatRegNotConflictingWith(((frTop2 < 0) ? (((usqInt)(1)) >> (-frTop2)) : (1U << frTop2))); } rResult7 = allocateRegNotConflictingWith(0); assert(!(((frTop2 == NoReg) @@ -39384,13 +39529,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg13 = (frNext1 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask13 = 1U << reg13; + topRegistersMask13 = ((reg13 < 0) ? (((usqInt)(1)) >> (-reg13)) : (1U << reg13)); } if (frTop3 == NoReg) { frTop3 = allocateFloatRegNotConflictingWith(topRegistersMask13); } if (frNext1 == NoReg) { - frNext1 = allocateFloatRegNotConflictingWith(1U << frTop3); + frNext1 = allocateFloatRegNotConflictingWith(((frTop3 < 0) ? (((usqInt)(1)) >> (-frTop3)) : (1U << frTop3))); } rResult8 = allocateRegNotConflictingWith(0); assert(!(((frTop3 == NoReg) @@ -39430,13 +39575,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg14 = (frNext2 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask14 = 1U << reg14; + topRegistersMask14 = ((reg14 < 0) ? (((usqInt)(1)) >> (-reg14)) : (1U << reg14)); } if (frTop4 == NoReg) { frTop4 = allocateFloatRegNotConflictingWith(topRegistersMask14); } if (frNext2 == NoReg) { - frNext2 = allocateFloatRegNotConflictingWith(1U << frTop4); + frNext2 = allocateFloatRegNotConflictingWith(((frTop4 < 0) ? (((usqInt)(1)) >> (-frTop4)) : (1U << frTop4))); } rResult9 = allocateRegNotConflictingWith(0); assert(!(((frTop4 == NoReg) @@ -39476,13 +39621,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg15 = (frNext3 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask15 = 1U << reg15; + topRegistersMask15 = ((reg15 < 0) ? (((usqInt)(1)) >> (-reg15)) : (1U << reg15)); } if (frTop5 == NoReg) { frTop5 = allocateFloatRegNotConflictingWith(topRegistersMask15); } if (frNext3 == NoReg) { - frNext3 = allocateFloatRegNotConflictingWith(1U << frTop5); + frNext3 = allocateFloatRegNotConflictingWith(((frTop5 < 0) ? (((usqInt)(1)) >> (-frTop5)) : (1U << frTop5))); } rResult10 = allocateRegNotConflictingWith(0); assert(!(((frTop5 == NoReg) @@ -39522,13 +39667,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg16 = (frNext4 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask16 = 1U << reg16; + topRegistersMask16 = ((reg16 < 0) ? (((usqInt)(1)) >> (-reg16)) : (1U << reg16)); } if (frTop6 == NoReg) { frTop6 = allocateFloatRegNotConflictingWith(topRegistersMask16); } if (frNext4 == NoReg) { - frNext4 = allocateFloatRegNotConflictingWith(1U << frTop6); + frNext4 = allocateFloatRegNotConflictingWith(((frTop6 < 0) ? (((usqInt)(1)) >> (-frTop6)) : (1U << frTop6))); } rResult12 = allocateRegNotConflictingWith(0); assert(!(((frTop6 == NoReg) @@ -39567,13 +39712,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg17 = (rNext17 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask17 = 1U << reg17; + topRegistersMask17 = ((reg17 < 0) ? (((usqInt)(1)) >> (-reg17)) : (1U << reg17)); } if (rTop22 == NoReg) { rTop22 = allocateFloatRegNotConflictingWith(topRegistersMask17); } if (rNext17 == NoReg) { - rNext17 = allocateFloatRegNotConflictingWith(1U << rTop22); + rNext17 = allocateFloatRegNotConflictingWith(((rTop22 < 0) ? (((usqInt)(1)) >> (-rTop22)) : (1U << rTop22))); } assert(!(((rTop22 == NoReg) || (rNext17 == NoReg)))); @@ -39600,7 +39745,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (frTop7 == NoReg) { frTop7 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); } - frResult2 = allocateFloatRegNotConflictingWith(1U << frTop7); + frResult2 = allocateFloatRegNotConflictingWith(((frTop7 < 0) ? (((usqInt)(1)) >> (-frTop7)) : (1U << frTop7))); assert(!(((frTop7 == NoReg) || (frResult2 == NoReg)))); value12 = frTop7; @@ -39625,13 +39770,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg18 = (frNext5 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask18 = 1U << reg18; + topRegistersMask18 = ((reg18 < 0) ? (((usqInt)(1)) >> (-reg18)) : (1U << reg18)); } if (frTop8 == NoReg) { frTop8 = allocateFloatRegNotConflictingWith(topRegistersMask18); } if (frNext5 == NoReg) { - frNext5 = allocateFloatRegNotConflictingWith(1U << frTop8); + frNext5 = allocateFloatRegNotConflictingWith(((frTop8 < 0) ? (((usqInt)(1)) >> (-frTop8)) : (1U << frTop8))); } rResult13 = allocateRegNotConflictingWith(0); assert(!(((frTop8 == NoReg) @@ -39689,13 +39834,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg19 = (rNext18 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask20 = 1U << reg19; + topRegistersMask20 = ((reg19 < 0) ? (((usqInt)(1)) >> (-reg19)) : (1U << reg19)); } if (rTop23 == NoReg) { rTop23 = allocateFloatRegNotConflictingWith(topRegistersMask20); } if (rNext18 == NoReg) { - rNext18 = allocateFloatRegNotConflictingWith(1U << rTop23); + rNext18 = allocateFloatRegNotConflictingWith(((rTop23 < 0) ? (((usqInt)(1)) >> (-rTop23)) : (1U << rTop23))); } assert(!(((rTop23 == NoReg) || (rNext18 == NoReg)))); @@ -39831,13 +39976,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg20 = (rNext19 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask22 = 1U << reg20; + topRegistersMask22 = ((reg20 < 0) ? (((usqInt)(1)) >> (-reg20)) : (1U << reg20)); } if (rTop24 == NoReg) { rTop24 = allocateFloatRegNotConflictingWith(topRegistersMask22); } if (rNext19 == NoReg) { - rNext19 = allocateFloatRegNotConflictingWith(1U << rTop24); + rNext19 = allocateFloatRegNotConflictingWith(((rTop24 < 0) ? (((usqInt)(1)) >> (-rTop24)) : (1U << rTop24))); } assert(!(((rTop24 == NoReg) || (rNext19 == NoReg)))); @@ -39862,13 +40007,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg21 = (rNext20 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask23 = 1U << reg21; + topRegistersMask23 = ((reg21 < 0) ? (((usqInt)(1)) >> (-reg21)) : (1U << reg21)); } if (rTop25 == NoReg) { rTop25 = allocateFloatRegNotConflictingWith(topRegistersMask23); } if (rNext20 == NoReg) { - rNext20 = allocateFloatRegNotConflictingWith(1U << rTop25); + rNext20 = allocateFloatRegNotConflictingWith(((rTop25 < 0) ? (((usqInt)(1)) >> (-rTop25)) : (1U << rTop25))); } assert(!(((rTop25 == NoReg) || (rNext20 == NoReg)))); @@ -39894,13 +40039,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg22 = (frNext6 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask24 = 1U << reg22; + topRegistersMask24 = ((reg22 < 0) ? (((usqInt)(1)) >> (-reg22)) : (1U << reg22)); } if (frTop15 == NoReg) { frTop15 = allocateFloatRegNotConflictingWith(topRegistersMask24); } if (frNext6 == NoReg) { - frNext6 = allocateFloatRegNotConflictingWith(1U << frTop15); + frNext6 = allocateFloatRegNotConflictingWith(((frTop15 < 0) ? (((usqInt)(1)) >> (-frTop15)) : (1U << frTop15))); } rResult18 = allocateRegNotConflictingWith(0); assert(!(((frTop15 == NoReg) @@ -39940,13 +40085,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg23 = (frNext7 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask25 = 1U << reg23; + topRegistersMask25 = ((reg23 < 0) ? (((usqInt)(1)) >> (-reg23)) : (1U << reg23)); } if (frTop16 == NoReg) { frTop16 = allocateFloatRegNotConflictingWith(topRegistersMask25); } if (frNext7 == NoReg) { - frNext7 = allocateFloatRegNotConflictingWith(1U << frTop16); + frNext7 = allocateFloatRegNotConflictingWith(((frTop16 < 0) ? (((usqInt)(1)) >> (-frTop16)) : (1U << frTop16))); } rResult19 = allocateRegNotConflictingWith(0); assert(!(((frTop16 == NoReg) @@ -39986,13 +40131,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg24 = (frNext8 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask26 = 1U << reg24; + topRegistersMask26 = ((reg24 < 0) ? (((usqInt)(1)) >> (-reg24)) : (1U << reg24)); } if (frTop17 == NoReg) { frTop17 = allocateFloatRegNotConflictingWith(topRegistersMask26); } if (frNext8 == NoReg) { - frNext8 = allocateFloatRegNotConflictingWith(1U << frTop17); + frNext8 = allocateFloatRegNotConflictingWith(((frTop17 < 0) ? (((usqInt)(1)) >> (-frTop17)) : (1U << frTop17))); } rResult20 = allocateRegNotConflictingWith(0); assert(!(((frTop17 == NoReg) @@ -40032,13 +40177,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg25 = (frNext9 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask27 = 1U << reg25; + topRegistersMask27 = ((reg25 < 0) ? (((usqInt)(1)) >> (-reg25)) : (1U << reg25)); } if (frTop18 == NoReg) { frTop18 = allocateFloatRegNotConflictingWith(topRegistersMask27); } if (frNext9 == NoReg) { - frNext9 = allocateFloatRegNotConflictingWith(1U << frTop18); + frNext9 = allocateFloatRegNotConflictingWith(((frTop18 < 0) ? (((usqInt)(1)) >> (-frTop18)) : (1U << frTop18))); } rResult22 = allocateRegNotConflictingWith(0); assert(!(((frTop18 == NoReg) @@ -40078,13 +40223,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg26 = (frNext10 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask28 = 1U << reg26; + topRegistersMask28 = ((reg26 < 0) ? (((usqInt)(1)) >> (-reg26)) : (1U << reg26)); } if (frTop19 == NoReg) { frTop19 = allocateFloatRegNotConflictingWith(topRegistersMask28); } if (frNext10 == NoReg) { - frNext10 = allocateFloatRegNotConflictingWith(1U << frTop19); + frNext10 = allocateFloatRegNotConflictingWith(((frTop19 < 0) ? (((usqInt)(1)) >> (-frTop19)) : (1U << frTop19))); } rResult23 = allocateRegNotConflictingWith(0); assert(!(((frTop19 == NoReg) @@ -40123,13 +40268,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg27 = (rNext21 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask29 = 1U << reg27; + topRegistersMask29 = ((reg27 < 0) ? (((usqInt)(1)) >> (-reg27)) : (1U << reg27)); } if (rTop26 == NoReg) { rTop26 = allocateFloatRegNotConflictingWith(topRegistersMask29); } if (rNext21 == NoReg) { - rNext21 = allocateFloatRegNotConflictingWith(1U << rTop26); + rNext21 = allocateFloatRegNotConflictingWith(((rTop26 < 0) ? (((usqInt)(1)) >> (-rTop26)) : (1U << rTop26))); } assert(!(((rTop26 == NoReg) || (rNext21 == NoReg)))); @@ -40156,7 +40301,7 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if (frTop20 == NoReg) { frTop20 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); } - frResult3 = allocateFloatRegNotConflictingWith(1U << frTop20); + frResult3 = allocateFloatRegNotConflictingWith(((frTop20 < 0) ? (((usqInt)(1)) >> (-frTop20)) : (1U << frTop20))); assert(!(((frTop20 == NoReg) || (frResult3 == NoReg)))); value24 = frTop20; @@ -40181,13 +40326,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg28 = (frNext11 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask30 = 1U << reg28; + topRegistersMask30 = ((reg28 < 0) ? (((usqInt)(1)) >> (-reg28)) : (1U << reg28)); } if (frTop21 == NoReg) { frTop21 = allocateFloatRegNotConflictingWith(topRegistersMask30); } if (frNext11 == NoReg) { - frNext11 = allocateFloatRegNotConflictingWith(1U << frTop21); + frNext11 = allocateFloatRegNotConflictingWith(((frTop21 < 0) ? (((usqInt)(1)) >> (-frTop21)) : (1U << frTop21))); } rResult24 = allocateRegNotConflictingWith(0); assert(!(((frTop21 == NoReg) @@ -40245,13 +40390,13 @@ genLowcodeUnaryInlinePrimitive(sqInt prim) if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { /* begin registerMaskFor: */ reg29 = (rNext22 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask32 = 1U << reg29; + topRegistersMask32 = ((reg29 < 0) ? (((usqInt)(1)) >> (-reg29)) : (1U << reg29)); } if (rTop27 == NoReg) { rTop27 = allocateFloatRegNotConflictingWith(topRegistersMask32); } if (rNext22 == NoReg) { - rNext22 = allocateFloatRegNotConflictingWith(1U << rTop27); + rNext22 = allocateFloatRegNotConflictingWith(((rTop27 < 0) ? (((usqInt)(1)) >> (-rTop27)) : (1U << rTop27))); } assert(!(((rTop27 == NoReg) || (rNext22 == NoReg)))); @@ -40719,11 +40864,11 @@ genPushMaybeContextReceiverVariable(sqInt slotIndex) AbstractInstruction *jmpSingle; /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ensureReceiverResultRegContainsSelf(); /* begin genPushMaybeContextSlotIndex: */ assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ voidReceiverResultRegContainsSelf(); @@ -40776,7 +40921,7 @@ genPushNewArrayBytecode(void) } else { /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << SendNumArgsReg)) | ((1U << ReceiverResultReg))), simStackPtr, simNativeStackPtr); } size = byte1 & 0x7F; if (!popValues) { @@ -40849,7 +40994,7 @@ genPushRemoteTempLongBytecode(void) /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperandoperand(MoveMwrR, offset, FPReg, tempVectReg); /* begin availableRegOrNoneNotConflictingWith: */ - regMask = 1U << tempVectReg; + regMask = ((tempVectReg < 0) ? (((usqInt)(1)) >> (-tempVectReg)) : (1U << tempVectReg)); remoteTempReg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); if (remoteTempReg == NoReg) { remoteTempReg = tempVectReg; @@ -41200,11 +41345,11 @@ genSpecialSelectorClass(void) || (topReg == ClassReg)) { /* begin ssAllocateRequiredReg:and: */ requiredReg1 = (topReg = SendNumArgsReg); - ssAllocateRequiredRegMaskupThroughupThroughNative((1U << requiredReg1) | (1U << ClassReg), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((((requiredReg1 < 0) ? (((usqInt)(1)) >> (-requiredReg1)) : (1U << requiredReg1))) | ((1U << ClassReg)), simStackPtr, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr, simNativeStackPtr); } ssPush(1); popToReg(ssTop(), topReg); @@ -41438,7 +41583,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean association = getLiteral(litVarIndex); voidReceiverResultRegContainsSelf(); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin genMoveConstant:R: */ if (shouldAnnotateObjectReference(association)) { annotateobjRef(checkLiteralforInstruction(association, genoperandoperand(MoveCwR, association, ReceiverResultReg)), association); @@ -41451,7 +41596,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean # if IMMUTABILITY if (needsImmCheck) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -41466,7 +41611,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -41527,7 +41672,7 @@ genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqI # endif // IMMUTABILITY ssPop(1); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ClassReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ssPush(1); genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); @@ -41573,7 +41718,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea # if IMMUTABILITY if (needsImmCheck1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -41588,7 +41733,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck1, 1); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck1); } @@ -41612,7 +41757,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt assert(needsFrame); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); /* begin MoveMw:r:R: */ offset = frameOffsetOfTemporary(remoteTempIndex); @@ -41622,7 +41767,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt # if IMMUTABILITY # endif - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -41812,13 +41957,13 @@ genVanillaInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -42117,12 +42262,12 @@ liveRegisters(void) } else { /* begin registerMaskFor: */ - regsSet = 1U << ReceiverResultReg; + regsSet = (1U << ReceiverResultReg); if ((methodOrBlockNumArgs <= 2 /* numRegArgs */) && (methodOrBlockNumArgs > 0)) { - regsSet = regsSet | (1U << Arg0Reg); + regsSet = regsSet | ((1U << Arg0Reg)); if (methodOrBlockNumArgs > 1) { - regsSet = regsSet | (1U << Arg1Reg); + regsSet = regsSet | ((1U << Arg1Reg)); } } } @@ -42231,13 +42376,13 @@ marshallSendArguments(sqInt numArgs) if (numArgs > 0) { if (numArgs > 1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 2, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 2, simNativeStackPtr); /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg1Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg1Reg), simStackPtr - 1, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 1, simNativeStackPtr); } } if (numArgs > 1) { @@ -42817,7 +42962,7 @@ ssAllocateRequiredFloatRegMaskupThroughupThroughNative(sqInt requiredRegsMask, s static void NoDbgRegParms ssAllocateRequiredFloatReg(sqInt requiredReg) { - ssAllocateRequiredFloatRegMaskupThroughupThroughNative(1U << requiredReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredFloatRegMaskupThroughupThroughNative(((requiredReg < 0) ? (((usqInt)(1)) >> (-requiredReg)) : (1U << requiredReg)), simStackPtr, simNativeStackPtr); } /* StackToRegisterMappingCogit>>#ssAllocateRequiredRegMask:upThrough:upThroughNative: */ diff --git a/spurlowcodesrc/vm/cogitMIPSEL.c b/spurlowcodesrc/vm/cogitMIPSEL.c deleted file mode 100644 index 1683d99c2f..0000000000 --- a/spurlowcodesrc/vm/cogitMIPSEL.c +++ /dev/null @@ -1,43413 +0,0 @@ -/* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 - from - StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 - */ -static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 " __DATE__ ; -char *__cogitBuildInfo = __buildInfo; - - - -#include "sqConfig.h" -#include -#include -#include -#include -#include "sqPlatformSpecific.h" -#include "sqMemoryAccess.h" -#include "sqCogStackAlignment.h" -#include "dispdbg.h" -#include "cogmethod.h" -#if COGMTVM -#include "cointerpmt.h" -#else -#include "cointerp.h" -#endif -#include "cogit.h" -#include - - -/*** Constants ***/ -#define A0 4 -#define A1 5 -#define A2 6 -#define A3 7 -#define ABICalleeSavedRegisterMask 0xFF0000 -#define ABICallerSavedRegisterMask 0x300FF00 -#define ABIResultReg 2 -#define ABIResultRegHigh 3 -#define ADDIU 9 -#define ADDU 33 -#define AddCheckOverflowCqR 162 -#define AddCheckOverflowRR 163 -#define AddCqR 106 -#define AddCqRR 123 -#define AddCwR 114 -#define AddcCqR 120 -#define AddcRR 119 -#define AddRdRd 132 -#define AddRR 100 -#define AddRRR 126 -#define AddRsRs 139 -#define AlignmentNops 3 -#define AltBlockCreationBytecodeSize 3 -#define AltFirstSpecialSelector 96 -#define AltNumSpecialSelectors 32 -#define AND 36 -#define ANDI 12 -#define AndCqR 108 -#define AndCqRR 124 -#define AndCwR 116 -#define AndRR 102 -#define AnnotationShift 5 -#define Arg0Reg 17 -#define Arg1Reg 18 -#define ArithmeticShiftRightCqR 91 -#define ArithmeticShiftRightCqRR 128 -#define ArithmeticShiftRightRR 92 -#define AT 1 -#define BadRegisterSet 1 -#define BEQ 4 -#define BGEZ 1 -#define BGTZ 7 -#define BLEZ 6 -#define BLTZ 0 -#define BlockCreationBytecodeSize 4 -#define BNE 5 -#define BREAK 13 -#define BranchTemp 11 -#define BrEqualRR 167 -#define BrLongEqualRR 177 -#define BrLongNotEqualRR 178 -#define BrNotEqualRR 168 -#define BrSignedGreaterEqualRR 176 -#define BrSignedGreaterRR 175 -#define BrSignedLessEqualRR 174 -#define BrSignedLessRR 173 -#define BrUnsignedGreaterEqualRR 172 -#define BrUnsignedGreaterRR 171 -#define BrUnsignedLessEqualRR 170 -#define BrUnsignedLessRR 169 -#define BytecodeSetHasDirectedSuperSend 1 -#define Call 6 -#define CallerSavedRegisterMask 0x0 -#define CallFull 7 -#define CallR 8 -#if !defined(CheckRememberedInTrampoline) /* Allow this to be overridden on the compiler command line */ -# define CheckRememberedInTrampoline 0 -#endif -#define ClassArray 7 -#define ClassArrayCompactIndex 51 -#define ClassBlockClosureCompactIndex 37 -#define ClassFloatCompactIndex 34 -#define ClassFullBlockClosureCompactIndex 38 -#define ClassLargeNegativeInteger 42 -#define ClassLargePositiveInteger 13 -#define ClassLargePositiveIntegerCompactIndex 33 -#define ClassMethodContextCompactIndex 36 -#define ClassPointCompactIndex 54 -#define ClassReg 19 -#define ClosureFirstCopiedValueIndex 3 -#define ClosureIndex 4 -#define ClosureNumArgsIndex 2 -#define ClosureOuterContextIndex 0 -#define ClosureStartPCIndex 1 -#define ClzRR 157 -#define CMBlock 3 -#define CMClosedPIC 4 -#define CMFree 1 -#define CMMaxUsageCount 7 -#define CMMethod 2 -#define CMOpenPIC 5 -#define Cmp 8 -#define CmpC32R 113 -#define CmpCqR 105 -#define CmpCwR 112 -#define CmpRdRd 131 -#define CmpRR 99 -#define CmpRsRs 138 -#define CompletePrimitive 4 -#define ConcreteVarBaseReg 22 -#define ConstZero 1 -#define ConvertRdR 146 -#define ConvertRdRs 148 -#define ConvertRRd 145 -#define ConvertRRs 150 -#define ConvertRsR 149 -#define ConvertRsRd 147 -#define Debug DEBUGVM -#define DIV 26 -#define DisplacementMask 0x1F -#define DisplacementX2N 0 -#define DivRdRd 135 -#define DivRR 159 -#define DivRsRs 142 -#undef DPFPReg0 -#undef DPFPReg1 -#undef DPFPReg2 -#undef DPFPReg3 -#undef DPFPReg4 -#undef DPFPReg5 -#undef DPFPReg6 -#undef DPFPReg7 -#define EncounteredUnknownBytecode -6 -#undef Extra0Reg -#undef Extra2Reg -#define FastCPrimitiveUseCABIFlag 4 -#define Fill32 4 -#define FirstAnnotation 64 -#define FirstJump 12 -#define FirstSpecialSelector 176 -#define FoxCallerSavedIP 4 -#define FoxIFSavedIP -16 -#define FoxMethod -4 -#define FoxMFReceiver -12 -#define FoxSavedFP 0 -#define FoxThisContext -8 -#define FP 30 -#define FPReg 30 -#define FullClosureCompiledBlockIndex 1 -#define FullClosureFirstCopiedValueIndex 4 -#define FullClosureReceiverIndex 3 -#define GCModeBecome 8 -#define GCModeFull 1 -#define GCModeNewSpace 2 -#define HasBytecodePC 5 -#define HashMultiplyConstant 1664525 -#define HashMultiplyMask 0xFFFFFFF -#define HeaderIndex 0 -#define HintLoad 0 -#define HintStore 1 -#if !defined(IMMUTABILITY) /* Allow this to be overridden on the compiler command line */ -# define IMMUTABILITY 1 -#endif -#define InFullBlock 2 -#define InstanceSpecificationIndex 2 -#define InstructionPointerIndex 1 -#define InsufficientCodeSpace -2 -#define InVanillaBlock 1 -#define IsAbsPCReference 3 -#define IsAnnotationExtension 1 -#define IsDirectedSuperBindingSend 10 -#define IsDirectedSuperSend 9 -#define IsDisplacementX2N 0 -#define IsNSDynamicSuperSend null -#define IsNSSelfSend null -#define IsNSSendCall null -#define IsObjectReference 2 -#define IsRelativeCall 4 -#define IsSendCall 7 -#define IsSuperSend 8 -#define J 2 -#define JAL 3 -#define JALR 9 -#define JR 8 -#define Jump 16 -#define JumpAbove 33 -#define JumpAboveOrEqual 32 -#define JumpBelow 31 -#define JumpBelowOrEqual 34 -#define JumpCarry 25 -#define JumpFPEqual 35 -#define JumpFPGreater 39 -#define JumpFPGreaterOrEqual 40 -#define JumpFPLess 37 -#define JumpFPLessOrEqual 38 -#define JumpFPNotEqual 36 -#define JumpFPOrdered 41 -#define JumpFPUnordered 42 -#define JumpFull 12 -#define JumpGreater 29 -#define JumpGreaterOrEqual 28 -#define JumpLess 27 -#define JumpLessOrEqual 30 -#define JumpLong 13 -#define JumpLongNonZero 15 -#define JumpLongZero 14 -#define JumpNegative 19 -#define JumpNoCarry 26 -#define JumpNonNegative 20 -#define JumpNonZero 18 -#define JumpNoOverflow 22 -#define JumpOverflow 21 -#define JumpR 10 -#define JumpZero 17 -#define Label 1 -#define LargeContextSlots 62 -#define LastJump 42 -#define LB 32 -#define LBU 36 -#define LH 33 -#define LHU 37 -#define LinkReg 31 -#define Literal 2 -#define LoadEffectiveAddressMwrR 88 -#define LogicalShiftLeftCqR 95 -#define LogicalShiftLeftCqRR 129 -#define LogicalShiftLeftRR 96 -#define LogicalShiftRightCqR 93 -#define LogicalShiftRightCqRR 130 -#define LogicalShiftRightRR 94 -#define LowcodeContextMark 60 -#define LowcodeVM 1 -#define LUI 15 -#define LW 35 -#define MapEnd 0 -#define MaxCompiledPrimitiveIndex 575 -#define MaxCPICCases 6 -#define MaxMethodSize 65535 -#define MaxNegativeErrorCode -8 -#define MaxStackAllocSize 1572864 -#define MaxStackCheckOffset 0xFFF -#define MaxX2NDisplacement 992 -#define MethodCacheClass 2 -#define MethodCacheMask 0xFFC -#define MethodCacheMethod 3 -#define MethodCacheSelector 1 -#define MethodIndex 3 -#define MethodTooBig -4 -#define MFHI 16 -#define MFLO 18 -#define MFMethodFlagHasContextFlag 1 -#define MFMethodFlagIsBlockFlag 2 -#define MoveAbR 48 -#define MoveAwR 44 -#define MoveC32R 71 -#define MoveCqR 69 -#define MoveCwR 70 -#define MoveHighR 161 -#define MoveLowR 160 -#define MoveM16rR 57 -#define MoveM32rR 61 -#define MoveM32rRs 78 -#define MoveM64rRd 75 -#define MoveM8rR 54 -#define MoveMbrR 65 -#define MoveMwrR 50 -#define MoveRAb 49 -#define MoveRAw 46 -#define MoveRdM64r 76 -#define MoveRdRd 74 -#define MoveRM16r 58 -#define MoveRM32r 62 -#define MoveRM8r 56 -#define MoveRMbr 66 -#define MoveRMwr 51 -#define MoveRR 43 -#define MoveRsM32r 79 -#define MoveRsRs 77 -#define MoveRXbrR 68 -#define MoveRXwrR 53 -#define MoveXbrRR 67 -#define MoveXwrRR 52 -#define MULT 24 -#define MULTIPLEBYTECODESETS 1 -#define MulCheckOverflowRR 164 -#define MulRdRd 134 -#define MulRR 158 -#define MulRsRs 141 -#define NativePopR 84 -#define NativePushR 85 -#define NativeRetN 86 -#define NativeSPReg 29 -#define NeedsMergeFixupFlag 2 -#define NeedsNonMergeFixupFlag 1 -#define NegateR 89 -#define NewspeakVM 0 -#define Nop 5 -#define NoReg -1 -#define NotFullyInitialized -1 -#define NotR 90 -#define NumObjRefsInRuntime 0 -#define NumOopsPerNSC 6 -#define NumSendTrampolines 4 -#define NumSpecialSelectors 32 -#define NumStoreTrampolines 5 -#define NumTrampolines (84 + (COGMTVM ? 1 : 0) + (IMMUTABILITY ? 5 : 0)) -#define OneInstruction 4 -#define OR 37 -#define ORI 13 -#define OrCqR 109 -#define OrCqRR 125 -#define OrCwR 117 -#define OrRR 103 -#define Overflow 8 -#define OverflowTemp1 9 -#define OverflowTemp2 10 -#undef PCReg -#define PopR 80 -#define PREF 51 -#define PrefetchAw 87 -#define PrimCallCollectsProfileSamples 8 -#define PrimCallDoNotJIT 16 -#define PrimCallMayEndureCodeCompaction 4 -#define PrimCallNeedsNewMethod 1 -#define PrimCallNeedsPrimitiveFunction 2 -#define PrimCallOnSmalltalkStack 64 -#define PrimCallOnSmalltalkStackAlign2x 128 -#define PrimErrBadArgument 3 -#define PrimErrNoMemory 9 -#define PrimNumberExternalCall 117 -#define PrimNumberFFICall 120 -#define PushCq 82 -#define PushCw 83 -#define PushR 81 -#define R0 0 -#define R28 28 -#define RA 31 -#define REGIMM 1 -#define ReceiverIndex 5 -#define ReceiverResultReg 16 -#define RetN 9 -#define RISCTempReg 1 -#define SB 40 -#define SelectorCannotInterpret 34 -#define SelectorDoesNotUnderstand 20 -#define SenderIndex 0 -#define SendNumArgsReg 20 -#define SH 41 -#define ShouldNotJIT -8 -#define SignExtend16RR 152 -#define SignExtend32RR 153 -#define SignExtend8RR 151 -#define SistaV1BytecodeSet 1 -#define SistaVM 1 -#define SLL 0 -#define SLLV 4 -#define SLT 42 -#define SLTI 10 -#define SLTIU 11 -#define SLTU 43 -#define SmallContextSlots 22 -#define SP 29 -#define SPECIAL 0 -#define SPReg 29 -#define SPURVM 1 -#define SqrtRd 136 -#define SqrtRs 143 -#define SRA 3 -#define SRAV 7 -#define SRL 2 -#define SRLV 6 -#define SSBaseOffset 1 -#define SSConstant 2 -#define SSConstantFloat32 15 -#define SSConstantFloat64 16 -#define SSConstantInt32 13 -#define SSConstantInt64 14 -#define SSConstantNativePointer 17 -#define SSNativeRegister 5 -#define SSRegister 3 -#define SSRegisterDoubleFloat 7 -#define SSRegisterPair 6 -#define SSRegisterSingleFloat 8 -#define SSSpill 4 -#define SSSpillFloat32 11 -#define SSSpillFloat64 12 -#define SSSpillInt64 10 -#define SSSpillNative 9 -#define StackPointerIndex 2 -#define Stop 11 -#define SUBU 35 -#define SubbRR 121 -#define SubCheckOverflowCqR 165 -#define SubCheckOverflowRR 166 -#define SubCqR 107 -#define SubCwR 115 -#define SubRdRd 133 -#define SubRR 101 -#define SubRRR 127 -#define SubRsRs 140 -#define SW 43 -#define TargetReg 25 -#define TempReg 21 -#define TempVectReadBarrier 0 -#define TstCqR 110 -#define UnfailingPrimitive 3 -#define UnimplementedPrimitive -7 -#define ValueIndex 1 -#define VarBaseReg 22 -#define XOR 38 -#define XORI 14 -#define XorCqR 111 -#define XorCwR 118 -#define XorRdRd 137 -#define XorRR 104 -#define XorRsRs 144 -#define YoungSelectorInPIC -5 -#define ZeroExtend16RR 155 -#define ZeroExtend32RR 156 -#define ZeroExtend8RR 154 -#define ZR 0 - -typedef struct _AbstractInstruction { - unsigned char opcode; - unsigned char machineCodeSize; - unsigned char maxSize; - unsigned char annotation; - unsigned int machineCode[7]; - usqInt operands[3]; - usqInt address; - struct _AbstractInstruction *dependent; - } AbstractInstruction; - -#define CogMIPSELCompiler AbstractInstruction -#define CogAbstractInstruction AbstractInstruction - - -typedef struct { - AbstractInstruction *fakeHeader; - AbstractInstruction *fillInstruction; - sqInt numArgs; - sqInt numCopied; - sqInt numInitialNils; - sqInt startpc; - AbstractInstruction *entryLabel; - AbstractInstruction *stackCheckLabel; - sqInt span; - sqInt hasInstVarRef; - } BlockStart; - -#define CogBlockStart BlockStart - - -typedef struct _BytecodeDescriptor { - sqInt (*generator)(void); - sqInt NoDbgRegParms (*spanFunction)(struct _BytecodeDescriptor *,sqInt,sqInt,sqInt); - sqInt NoDbgRegParms (*needsFrameFunction)(sqInt); - signed char stackDelta; - unsigned char opcode; - unsigned char numBytes; - unsigned isBranchTrue : 1; - unsigned isBranchFalse : 1; - unsigned isReturn : 1; - unsigned isBlockCreation : 1; - unsigned isMapped : 1; - unsigned isMappedInBlock : 1; - unsigned isExtension : 1; - unsigned isInstVarRef : 1; - unsigned is1ByteInstVarStore : 1; - unsigned hasUnsafeJump : 1; - } BytecodeDescriptor; - -#define CogBytecodeDescriptor BytecodeDescriptor - - -typedef struct { - sqInt (*primitiveGenerator)(void); - sqInt primNumArgs; - } PrimitiveDescriptor; - -#define CogPrimitiveDescriptor PrimitiveDescriptor - - -typedef struct { - char type; - char spilled; - signed char liveRegister; - signed char registerr; - sqInt offset; - sqInt constant; - sqInt bcptr; - } SimStackEntry; - -#define CogSimStackEntry SimStackEntry - - -typedef struct { - AbstractInstruction *targetInstruction; - unsigned char simStackPtr; - char isTargetOfBackwardBranch; - unsigned short instructionIndex; -#if LowcodeVM - short simNativeStackPtr; - unsigned short simNativeStackSize; -#endif - } BytecodeFixup; - -#define CogSSBytecodeFixup BytecodeFixup -#define CogBytecodeFixup BytecodeFixup - - -typedef struct { - sqInt isReceiverResultRegLive; - CogSimStackEntry *ssEntry; - } CogSSOptStatus; - - -typedef struct { - char type; - char spilled; - sqInt registerr; - sqInt registerSecond; - sqInt offset; - sqInt constant; - sqInt constantInt32; - sqLong constantInt64; - float constantFloat32; - double constantFloat64; - sqInt constantNativePointer; - sqInt bcptr; - } CogSimStackNativeEntry; - - - -/*** Function Prototypes ***/ - - -#if !PRODUCTION && defined(PlatformNoDbgRegParms) -# define NoDbgRegParms PlatformNoDbgRegParms -#endif - -#if !defined(NoDbgRegParms) -# define NoDbgRegParms /*empty*/ -#endif - - - -#if !defined(NeverInline) -# define NeverInline /*empty*/ -#endif - -static AbstractInstruction * NoDbgRegParms addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *anInstruction); -static sqInt NoDbgRegParms availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask); -static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask); -static void NoDbgRegParms cloneLiteralFrom(AbstractInstruction * self_in_cloneLiteralFrom, AbstractInstruction *existingLiteral); -static sqInt NoDbgRegParms genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer); -static sqInt NoDbgRegParms genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers); -static sqInt NoDbgRegParms genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers); -static sqInt NoDbgRegParms genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg); -static sqInt NoDbgRegParms genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers); -static AbstractInstruction * NoDbgRegParms genSwapRRScratch(AbstractInstruction * self_in_genSwapRRScratch, sqInt regA, sqInt regB, sqInt regTmp); -static void NoDbgRegParms genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister); -static void NoDbgRegParms genWriteCSecondResultIntoReg(AbstractInstruction * self_in_genWriteCSecondResultIntoReg, sqInt abstractRegister); -static void NoDbgRegParms initializeSharableLiteral(AbstractInstruction * self_in_initializeSharableLiteral, sqInt literal); -static void NoDbgRegParms initializeUniqueLiteral(AbstractInstruction * self_in_initializeUniqueLiteral, sqInt literal); -static sqInt NoDbgRegParms isWithinMwOffsetRange(AbstractInstruction * self_in_isWithinMwOffsetRange, sqInt anAddress); -static AbstractInstruction * NoDbgRegParms jmpTarget(AbstractInstruction * self_in_jmpTarget, AbstractInstruction *anAbstractInstruction); -static void NoDbgRegParms resolveJumpTarget(AbstractInstruction * self_in_resolveJumpTarget); -static sqInt NoDbgRegParms rewriteCallFullAttarget(AbstractInstruction * self_in_rewriteCallFullAttarget, sqInt callSiteReturnAddress, sqInt callTargetAddress); -static sqInt NoDbgRegParms rewriteJumpFullAttarget(AbstractInstruction * self_in_rewriteJumpFullAttarget, sqInt callSiteReturnAddress, sqInt callTargetAddress); -static CogMethod * NoDbgRegParms cmHomeMethod(CogBlockMethod * self_in_cmHomeMethod); -static sqInt NoDbgRegParms isBranch(BytecodeDescriptor * self_in_isBranch); -static AbstractInstruction * NoDbgRegParms gAddCqR(sqInt quickConstant, sqInt reg); -static AbstractInstruction * NoDbgRegParms gAddCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); -static AbstractInstruction * NoDbgRegParms gAndCqR(sqInt quickConstant, sqInt reg); -static AbstractInstruction * NoDbgRegParms gAndCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); -static AbstractInstruction * NoDbgRegParms gArithmeticShiftRightCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); -extern sqInt abortOffset(void); -static void addCleanBlockStarts(void); -extern void addCogMethodsToHeapMap(void); -static sqInt NoDbgRegParms addressIsInCurrentCompilation(sqInt address); -static sqInt NoDbgRegParms addressIsInFixups(BytecodeFixup *address); -static sqInt NoDbgRegParms addressOfEndOfCaseinCPIC(sqInt n, CogMethod *cPIC); -static void alignMethodZoneBase(void); -static sqInt NoDbgRegParms alignUptoRoutineBoundary(sqInt anAddress); -static sqInt allMachineCodeObjectReferencesValid(void); -static sqInt allMethodsHaveCorrectHeader(void); -static AbstractInstruction * NoDbgRegParms annotateAbsolutePCRef(AbstractInstruction *abstractInstruction); -static AbstractInstruction * NoDbgRegParms annotateBytecode(AbstractInstruction *abstractInstruction); -static AbstractInstruction * NoDbgRegParms annotateobjRef(AbstractInstruction *abstractInstruction, sqInt anOop); -static void NoDbgRegParms assertSaneJumpTarget(AbstractInstruction *jumpTarget); -static void assertValidDualZone(void); -static sqInt NoDbgRegParms availableRegisterOrNoneIn(sqInt liveRegsMask); -static sqInt NoDbgRegParms blockDispatchTargetsForperformarg(CogMethod *cogMethod, usqInt (*binaryFunction)(sqInt mcpc, sqInt arg), sqInt arg); -extern sqInt bytecodePCForstartBcpcin(sqInt mcpc, sqInt startbcpc, CogBlockMethod *cogMethod); -static AbstractInstruction * NoDbgRegParms CallRTregistersToBeSavedMask(sqInt callTarget, sqInt registersToBeSaved); -static AbstractInstruction * NoDbgRegParms gCall(sqInt callTarget); -static AbstractInstruction * NoDbgRegParms gCmpCqR(sqInt quickConstant, sqInt reg); -extern void callCogCodePopReceiver(void); -extern void callCogCodePopReceiverAndClassRegs(void); -static sqInt NoDbgRegParms ceCPICMissreceiver(CogMethod *cPIC, sqInt receiver); -extern void ceFree(void *pointer); -static void* NoDbgRegParms ceMalloc(size_t size); -static sqInt NoDbgRegParms ceSICMiss(sqInt receiver); -static sqInt NoDbgRegParms checkIfValidOopRefAndTargetpccogMethod(sqInt annotation, char *mcpc, CogMethod *cogMethod); -static sqInt NoDbgRegParms checkIfValidOopRefpccogMethod(sqInt annotation, char *mcpc, CogMethod *cogMethod); -extern sqInt checkIntegrityOfObjectReferencesInCode(sqInt gcModes); -static sqInt NoDbgRegParms checkMaybeObjRefInClosedPIC(sqInt maybeObject); -static sqInt NoDbgRegParms checkValidObjectReferencesInClosedPIC(CogMethod *cPIC); -static sqInt NoDbgRegParms NeverInline cleanUpFailingCogCodeConstituents(CogMethod *cogMethodArg); -static sqInt NoDbgRegParms closedPICRefersToUnmarkedObject(CogMethod *cPIC); -extern char * codeEntryFor(char *address); -extern char * codeEntryNameFor(char *address); -extern sqInt cogCodeBase(void); -extern sqInt cogCodeConstituents(sqInt withDetails); -static void NoDbgRegParms cogExtendPICCaseNMethodtagisMNUCase(CogMethod *cPIC, sqInt caseNMethod, sqInt caseNTag, sqInt isMNUCase); -extern CogMethod * cogFullBlockMethodnumCopied(sqInt aMethodObj, sqInt numCopied); -extern void cogitPostGCAction(sqInt gcMode); -extern sqInt cogMethodDoesntLookKosher(CogMethod *cogMethod); -extern CogMethod * cogMNUPICSelectorreceivermethodOperandnumArgs(sqInt selector, sqInt rcvr, sqInt methodOperand, sqInt numArgs); -static CogMethod * NoDbgRegParms cogOpenPICSelectornumArgs(sqInt selector, sqInt numArgs); -static CogMethod * NoDbgRegParms cogPICSelectornumArgsCase0MethodCase1MethodtagisMNUCase(sqInt selector, sqInt numArgs, CogMethod *case0CogMethod, sqInt case1MethodOrNil, sqInt case1Tag, sqInt isMNUCase); -extern CogMethod * cogselector(sqInt aMethodObj, sqInt aSelectorOop); -static sqInt NoDbgRegParms collectCogConstituentForAnnotationMcpcBcpcMethod(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *cogMethodArg); -static sqInt NoDbgRegParms collectCogMethodConstituent(CogMethod *cogMethod); -extern void compactCogCompiledCode(void); -static void compactPICsWithFreedTargets(void); -static AbstractInstruction * compileAbort(void); -static sqInt NoDbgRegParms compileBlockDispatchFromto(sqInt lowBlockStartIndex, sqInt highBlockStartIndex); -static void NoDbgRegParms compileBlockEntry(BlockStart *blockStart); -static void NoDbgRegParms compileCallFornumArgsargargargargfloatResultRegregsToSave(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt resultRegOrNone, sqInt regMask); -static void NoDbgRegParms compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt resultRegOrNone, sqInt regMask); -static void NoDbgRegParms compileCallFornumArgsargargargargresultRegresultRegregsToSave(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt resultRegOrNone, sqInt resultReg2OrNone, sqInt regMask); -static void NoDbgRegParms compileCallFornumArgsfloatArgfloatArgfloatArgfloatArgresultRegregsToSave(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt resultRegOrNone, sqInt regMask); -static AbstractInstruction * compileCPICEntry(void); -static sqInt NoDbgRegParms compileEntireFullBlockMethod(sqInt numCopied); -static void compileEntry(void); -static sqInt compileFullBlockEntry(void); -static sqInt compileMethodBody(void); -static sqInt NoDbgRegParms compilePICAbort(sqInt numArgs); -static AbstractInstruction * NoDbgRegParms compileStackOverflowCheck(sqInt canContextSwitch); -static void NoDbgRegParms compileTrampolineFornumArgsargargargargregsToSavepushLinkRegfloatResultReg(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone); -static void NoDbgRegParms compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone); -static void NoDbgRegParms compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultRegresultReg(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone, sqInt resultReg2OrNone); -static void NoDbgRegParms compileTrampolineFornumArgsfloatArgfloatArgfloatArgfloatArgregsToSavepushLinkRegresultReg(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone); -static void computeEntryOffsets(void); -static void computeFullBlockEntryOffsets(void); -static usqInt computeGoodVarBaseAddress(void); -static void computeMaximumSizes(void); -static sqInt NoDbgRegParms configureCPICCase0Case1MethodtagisMNUCasenumArgsdelta(CogMethod *cPIC, CogMethod *case0CogMethod, sqInt case1Method, sqInt case1Tag, sqInt isMNUCase, sqInt numArgs, sqInt addrDelta); -static sqInt NoDbgRegParms configureMNUCPICmethodOperandnumArgsdelta(CogMethod *cPIC, sqInt methodOperand, sqInt numArgs, sqInt addrDelta); -static sqInt NoDbgRegParms cPICCompactAndIsNowEmpty(CogMethod *cPIC); -static sqInt NoDbgRegParms cPICHasForwardedClass(CogMethod *cPIC); -static sqInt NoDbgRegParms cPICHasFreedTargets(CogMethod *cPIC); -static usqInt cPICPrototypeCaseOffset(void); -static sqInt NoDbgRegParms cPICHasTarget(CogMethod *cPIC, CogMethod *targetMethod); -static sqInt NoDbgRegParms createCPICData(CogMethod *cPIC); -static AbstractInstruction * NoDbgRegParms gDivRRQuoRem(sqInt rDivisor, sqInt rDividend, sqInt rQuotient, sqInt rRemainder); -extern sqInt defaultCogCodeSize(void); -static sqInt NoDbgRegParms deltaToSkipPrimAndErrorStoreInheader(sqInt aMethodObj, sqInt aMethodHeader); -static sqInt NoDbgRegParms endPCOf(sqInt aMethod); -extern void enterCogCodePopReceiver(void); -static sqInt NoDbgRegParms entryPointTagIsSelector(sqInt entryPoint); -static sqInt NoDbgRegParms expectedClosedPICPrototype(CogMethod *cPIC); -static sqInt extABytecode(void); -static sqInt extBBytecode(void); -static sqInt NoDbgRegParms fillInBlockHeadersAt(sqInt startAddress); -static void NoDbgRegParms fillInMethodHeadersizeselector(CogMethod *method, sqInt size, sqInt selector); -static sqInt NoDbgRegParms findBackwardBranchIsBackwardBranchMcpcBcpcMatchingBcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *targetBcpc); -static usqInt NoDbgRegParms findBlockMethodWithEntrystartBcpc(sqInt blockEntryMcpc, sqInt startBcpc); -static usqInt NoDbgRegParms findMapLocationForMcpcinMethod(usqInt targetMcpc, CogMethod *cogMethod); -extern CogBlockMethod * findMethodForStartBcpcinHomeMethod(sqInt startbcpc, CogMethod *cogMethod); -static sqInt NoDbgRegParms findIsBackwardBranchMcpcBcpcMatchingMcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *targetMcpc); -static sqInt NoDbgRegParms firstMappedPCFor(CogMethod *cogMethod); -static sqInt firstPrototypeMethodOop(void); -static BytecodeFixup * NoDbgRegParms fixupAt(sqInt fixupPC); -extern void followForwardedLiteralsIn(CogMethod *cogMethod); -extern void followForwardedMethods(void); -static sqInt NoDbgRegParms followMaybeObjRefInClosedPICAt(sqInt mcpc); -static sqInt NoDbgRegParms followMethodReferencesInClosedPIC(CogMethod *cPIC); -extern void followMovableLiteralsAndUpdateYoungReferrers(void); -extern void freeCogMethod(CogMethod *cogMethod); -extern void freeUnmarkedMachineCode(void); -static AbstractInstruction * NoDbgRegParms genCallMustBeBooleanFor(sqInt boolean); -static AbstractInstruction * NoDbgRegParms genConditionalBranchoperand(sqInt opcode, sqInt operandOne); -static void (*genEnilopmartForandandforCallcalled(sqInt regArg1, sqInt regArg2OrNone, sqInt regArg3OrNone, sqInt forCall, char *trampolineName))(void) ; -static void NoDbgRegParms genEnilopmartReturn(sqInt forCall); -static void NoDbgRegParms NeverInline generateCaptureCStackPointers(sqInt captureFramePointer); -static void generateClosedPICPrototype(void); -static CogMethod * generateCogFullBlock(void); -static CogMethod * NoDbgRegParms generateCogMethod(sqInt selector); -static sqInt NoDbgRegParms generateMapAtstart(usqInt addressOrNull, usqInt startAddress); -static void generateOpenPICPrototype(void); -static void generateRunTimeTrampolines(void); -static void generateStackPointerCapture(void); -static void generateTrampolines(void); -static BytecodeDescriptor * NoDbgRegParms generatorForPC(sqInt pc); -static usqInt genFFICalloutTrampoline(void); -static void genGetLeafCallStackPointers(void); -static usqInt NoDbgRegParms genInnerPICAbortTrampoline(char *name); -static void (*genInvokeInterpretTrampoline(void))(void) ; -static void NoDbgRegParms genLoadInlineCacheWithSelector(sqInt selectorIndex); -static usqInt genReturnToInterpreterTrampoline(void); -static sqInt NoDbgRegParms genSmalltalkToCStackSwitch(sqInt pushLinkReg); -static usqInt NoDbgRegParms genTrampolineForcalledargfloatResult(void *aRoutine, char *aString, sqInt regOrConst0, sqInt resultReg); -static usqInt NoDbgRegParms genTrampolineForcalledargresultresult(void *aRoutine, char *aString, sqInt regOrConst0, sqInt resultReg, sqInt resultReg2); -static usqInt NoDbgRegParms genTrampolineForcalledfloatArgresult(void *aRoutine, char *aString, sqInt regOrConst0, sqInt resultReg); -static usqInt NoDbgRegParms genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegfloatResultRegappendOpcodes(void *aRoutine, char *trampolineName, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone, sqInt appendBoolean); -static usqInt NoDbgRegParms genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(void *aRoutine, char *trampolineName, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone, sqInt appendBoolean); -static usqInt NoDbgRegParms genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegresultRegappendOpcodes(void *aRoutine, char *trampolineName, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone, sqInt resultReg2OrNone, sqInt appendBoolean); -static usqInt NoDbgRegParms genTrampolineForcallednumArgsfloatArgfloatArgfloatArgfloatArgregsToSavepushLinkRegresultRegappendOpcodes(void *aRoutine, char *trampolineName, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone, sqInt appendBoolean); -static void NoDbgRegParms genTrampolineReturn(sqInt lnkRegWasPushed); -static AbstractInstruction * NoDbgRegParms gen(sqInt opcode); -static AbstractInstruction * NoDbgRegParms genoperand(sqInt opcode, sqInt operand); -static AbstractInstruction * NoDbgRegParms genoperandoperand(sqInt opcode, sqInt operandOne, sqInt operandTwo); -static AbstractInstruction * NoDbgRegParms genoperandoperandoperand(sqInt opcode, sqInt operandOne, sqInt operandTwo, sqInt operandThree); -static sqInt NoDbgRegParms getLiteral(sqInt litIndex); -static sqInt NoDbgRegParms incrementUsageOfTargetIfLinkedSendmcpcignored(sqInt annotation, char *mcpc, sqInt superfluity); -static sqInt initialClosedPICUsageCount(void); -static void initializeBackend(void); -extern void initializeCodeZoneFromupTo(sqInt startAddress, sqInt endAddress); -static sqInt initialMethodUsageCount(void); -static sqInt initialOpenPICUsageCount(void); -static sqInt NoDbgRegParms inverseBranchFor(sqInt opcode); -static sqInt NoDbgRegParms isPCMappedAnnotation(sqInt annotation); -extern sqInt isPCWithinMethodZone(void *address); -extern sqInt isSendReturnPC(sqInt retpc); -static AbstractInstruction * NoDbgRegParms gJumpFPEqual(void *jumpTarget); -static AbstractInstruction * NoDbgRegParms gJumpFPGreaterOrEqual(void *jumpTarget); -static AbstractInstruction * NoDbgRegParms gJumpFPGreater(void *jumpTarget); -static AbstractInstruction * NoDbgRegParms gJumpFPLessOrEqual(void *jumpTarget); -static AbstractInstruction * NoDbgRegParms gJumpFPLess(void *jumpTarget); -static AbstractInstruction * NoDbgRegParms gJumpFPNotEqual(void *jumpTarget); -static AbstractInstruction * NoDbgRegParms gLogicalShiftLeftCqR(sqInt quickConstant, sqInt reg); -static AbstractInstruction * NoDbgRegParms gLogicalShiftLeftCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); -static AbstractInstruction * NoDbgRegParms gLogicalShiftRightCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); -static AbstractInstruction * lastOpcode(void); -extern void linkSendAtintooffsetreceiver(sqInt callSiteReturnAddress, CogMethod *sendingMethod, CogMethod *targetMethod, sqInt theEntryOffset, sqInt receiver); -static BytecodeDescriptor * loadBytesAndGetDescriptor(void); -static void NoDbgRegParms loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc); -static AbstractInstruction * NoDbgRegParms gMoveCwR(sqInt wordConstant, sqInt reg); -static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); -static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg); -static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC); -static void mapObjectReferencesInGeneratedRuntime(void); -static void mapObjectReferencesInMachineCodeForBecome(void); -static void mapObjectReferencesInMachineCodeForFullGC(void); -static void mapObjectReferencesInMachineCodeForYoungGC(void); -extern void mapObjectReferencesInMachineCode(sqInt gcMode); -extern void markAndTraceMachineCodeOfMarkedMethods(void); -static void markAndTraceObjectReferencesInGeneratedRuntime(void); -static sqInt NoDbgRegParms markAndTraceOrFreeCogMethodfirstVisit(CogMethod *cogMethod, sqInt firstVisit); -static sqInt NoDbgRegParms markAndTraceOrFreePICTargetin(sqInt entryPoint, CogMethod *cPIC); -static sqInt NoDbgRegParms markLiteralsAndUnlinkIfUnmarkedSendpcmethod(sqInt annotation, char *mcpc, sqInt cogMethod); -static sqInt NoDbgRegParms markLiteralspcmethod(sqInt annotation, char *mcpc, CogMethod *cogMethod); -extern void markMethodAndReferents(CogBlockMethod *aCogMethod); -extern usqInt maxCogMethodAddress(void); -static sqInt maybeAllocAndInitIRCs(void); -static sqInt NoDbgRegParms maybeFreeCogMethodDoesntLookKosher(CogMethod *cogMethod); -static sqInt mclassIsSmallInteger(void); -extern usqInt mcPCForBackwardBranchstartBcpcin(sqInt bcpc, sqInt startbcpc, CogBlockMethod *cogMethod); -static sqInt NoDbgRegParms methodhasSameCodeAscheckPenultimate(sqInt methodA, sqInt methodB, sqInt comparePenultimateLiteral); -extern sqInt mnuOffset(void); -static AbstractInstruction * NoDbgRegParms gNativePopR(sqInt reg); -static AbstractInstruction * NoDbgRegParms gNativePushR(sqInt reg); -static AbstractInstruction * NoDbgRegParms gNativeRetN(sqInt offset); -static sqInt NoDbgRegParms needsFrameIfImmutability(sqInt stackDelta); -static sqInt NoDbgRegParms needsFrameIfInBlock(sqInt stackDelta); -static sqInt NoDbgRegParms needsFrameNever(sqInt stackDelta); -static sqInt NoDbgRegParms noAssertMethodClassAssociationOf(sqInt methodPointer); -static sqInt noCogMethodsMaximallyMarked(void); -static sqInt NoDbgRegParms noTargetsFreeInClosedPIC(CogMethod *cPIC); -static AbstractInstruction * NoDbgRegParms gOrCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); -static sqInt NoDbgRegParms outputInstructionsAt(sqInt startAddress); -static sqInt NoDbgRegParms outputInstructionsForGeneratedRuntimeAt(sqInt startAddress); -static AbstractInstruction * NoDbgRegParms gPushCw(sqInt wordConstant); -extern sqInt patchToOpenPICFornumArgsreceiver(sqInt selector, sqInt numArgs, sqInt receiver); -static sqInt picAbortDiscriminatorValue(void); -static sqInt picInterpretAbortOffset(void); -static AbstractInstruction * previousInstruction(void); -extern void printCogMethodFor(void *address); -extern void printTrampolineTable(void); -static sqInt processorHasDivQuoRemAndMClassIsSmallInteger(void); -static sqInt processorHasMultiplyAndMClassIsSmallInteger(void); -static void NoDbgRegParms recordGeneratedRunTimeaddress(char *aString, sqInt address); -extern sqInt recordPrimTraceFunc(void); -static void recordRunTimeObjectReferences(void); -static sqInt NoDbgRegParms registerMaskFor(sqInt reg); -static sqInt NoDbgRegParms registerMaskForandand(sqInt reg1, sqInt reg2, sqInt reg3); -static void NoDbgRegParms relocateCallsAndSelfReferencesInMethod(CogMethod *cogMethod); -static void NoDbgRegParms relocateCallsInClosedPIC(CogMethod *cPIC); -static sqInt NoDbgRegParms relocateIfCallOrMethodReferencemcpcdelta(sqInt annotation, char *mcpc, CogMethod *refDeltaArg); -static sqInt NoDbgRegParms remapIfObjectRefpchasYoung(sqInt annotation, char *mcpc, CogMethod *hasYoungPtr); -static sqInt NoDbgRegParms remapMaybeObjRefInClosedPICAt(sqInt mcpc); -static void NoDbgRegParms rewriteCPICCaseAttagobjReftarget(sqInt followingAddress, sqInt newTag, sqInt newObjRef, sqInt newTarget); -static AbstractInstruction * NoDbgRegParms gSubRRR(sqInt subReg, sqInt fromReg, sqInt destReg); -static sqInt scanForCleanBlocks(void); -extern void setBreakMethod(sqInt anObj); -extern void setSelectorOfto(CogMethod *cogMethod, sqInt aSelectorOop); -static sqInt NoDbgRegParms spanForCleanBlockStartingAt(sqInt startPC); -static usqInt NoDbgRegParms stackCheckOffsetOfBlockAtisMcpc(sqInt blockEntryMcpc, sqInt mcpc); -static sqInt subsequentPrototypeMethodOop(void); -extern sqInt traceLinkedSendOffset(void); -static sqInt NoDbgRegParms trampolineArgConstant(sqInt booleanOrInteger); -static char * NoDbgRegParms trampolineNamenumArgs(char *routinePrefix, sqInt numArgs); -static char * NoDbgRegParms trampolineNamenumArgslimit(char *routinePrefix, int numArgs, sqInt argsLimit); -static char * NoDbgRegParms trampolineNamenumRegArgs(char *routinePrefix, sqInt numArgs); -static sqInt unknownBytecode(void); -extern void unlinkAllSends(void); -static sqInt NoDbgRegParms unlinkIfFreeOrLinkedSendpcof(sqInt annotation, char *mcpc, CogMethod *theSelector); -static sqInt NoDbgRegParms unlinkIfInvalidClassSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity); -static sqInt NoDbgRegParms unlinkIfLinkedSendToFreepcignored(sqInt annotation, char *mcpc, sqInt superfluity); -static sqInt NoDbgRegParms unlinkIfLinkedSendpcif(sqInt annotation, char *mcpc, CogMethod *criterionArg); -static sqInt NoDbgRegParms unlinkIfLinkedSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity); -static sqInt NoDbgRegParms unlinkIfLinkedSendpcto(sqInt annotation, char *mcpc, sqInt theCogMethod); -extern void unlinkSendsLinkedForInvalidClasses(void); -extern void unlinkSendsOfisMNUSelector(sqInt selector, sqInt isMNUSelector); -extern void unlinkSendsToFree(void); -extern void unlinkSendsToMethodsSuchThatAndFreeIf(sqInt (*criterion)(CogMethod *), sqInt freeIfTrue); -extern void unlinkSendsToandFreeIf(sqInt targetMethodObject, sqInt freeIfTrue); -extern void voidCogCompiledCode(void); -static void zeroOpcodeIndex(void); -static void zeroOpcodeIndexForNewOpcodes(void); -static sqInt NoDbgRegParms counters(CogMethod * self_in_counters); -static void NoDbgRegParms addToOpenPICList(CogMethod *anOpenPIC); -static void NoDbgRegParms addToYoungReferrers(CogMethod *cogMethod); -static usqInt NoDbgRegParms allocate(sqInt numBytes); -extern CogMethod * cogMethodContaining(usqInt mcpc); -static void compactCompiledCode(void); -static void NoDbgRegParms ensureInYoungReferrers(CogMethod *cogMethod); -static void followForwardedLiteralsInOpenPICList(void); -static void NoDbgRegParms freeMethod(CogMethod *cogMethod); -static void freeOlderMethodsForCompaction(void); -extern sqInt kosherYoungReferrers(void); -static sqInt NoDbgRegParms mcpcisAtStackCheckOfBlockMethodIn(sqInt mcpc, CogMethod *cogMethod); -extern CogMethod * methodFor(void *address); -extern sqInt methodsCompiledToMachineCodeInto(sqInt arrayObj); -extern sqInt numMethods(void); -extern sqInt numMethodsOfType(sqInt cogMethodType); -static sqInt NoDbgRegParms occurrencesInYoungReferrers(CogMethod *cogMethod); -static CogMethod * NoDbgRegParms openPICWithSelector(sqInt aSelector); -static void planCompaction(void); -extern void printCogMethods(void); -extern void printCogMethodsOfType(sqInt cmType); -extern void printCogMethodsWithMethod(sqInt methodOop); -extern void printCogMethodsWithPrimitive(sqInt primIdx); -extern void printCogMethodsWithSelector(sqInt selectorOop); -extern void printCogYoungReferrers(void); -extern sqInt printOpenPICList(void); -extern sqInt pruneYoungReferrers(void); -static sqInt relocateAndPruneYoungReferrers(void); -static sqInt relocateMethodsPreCompaction(void); -static sqInt NoDbgRegParms removeFromOpenPICList(CogMethod *anOpenPIC); -static void NoDbgRegParms restorePICUsageCount(CogMethod *cogMethod); -static sqInt NoDbgRegParms roundUpLength(sqInt numBytes); -static void NoDbgRegParms savePICUsageCount(CogMethod *cogMethod); -static void voidOpenPICList(void); -static void voidUnpairedMethodList(void); -static void voidYoungReferrersPostTenureAll(void); -EXPORT(char *) whereIsMaybeCodeThing(sqInt anOop); -static sqInt NoDbgRegParms addiuRRC(AbstractInstruction * self_in_addiuRRC, sqInt destReg, sqInt srcReg, sqInt imm); -static sqInt NoDbgRegParms adduRRR(AbstractInstruction * self_in_adduRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms andiRRC(AbstractInstruction * self_in_andiRRC, sqInt destReg, sqInt srcReg, sqInt imm); -static sqInt NoDbgRegParms andRRR(AbstractInstruction * self_in_andRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms beqRRoffset(AbstractInstruction * self_in_beqRRoffset, sqInt leftReg, sqInt rightReg, sqInt offset); -static sqInt NoDbgRegParms bgezRoffset(AbstractInstruction * self_in_bgezRoffset, sqInt cmpReg, sqInt offset); -static sqInt NoDbgRegParms bgtzRoffset(AbstractInstruction * self_in_bgtzRoffset, sqInt cmpReg, sqInt offset); -static sqInt NoDbgRegParms blezRoffset(AbstractInstruction * self_in_blezRoffset, sqInt cmpReg, sqInt offset); -static sqInt NoDbgRegParms bltzRoffset(AbstractInstruction * self_in_bltzRoffset, sqInt cmpReg, sqInt offset); -static sqInt NoDbgRegParms bneRRoffset(AbstractInstruction * self_in_bneRRoffset, sqInt leftReg, sqInt rightReg, sqInt offset); -static sqInt NoDbgRegParms callInstructionByteSize(AbstractInstruction * self_in_callInstructionByteSize); -static usqInt NoDbgRegParms callTargetFromReturnAddress(AbstractInstruction * self_in_callTargetFromReturnAddress, sqInt callSiteReturnAddress); -static sqInt NoDbgRegParms clzRRR(AbstractInstruction * self_in_clzRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms cmpC32RTempByteSize(AbstractInstruction * self_in_cmpC32RTempByteSize); -static sqInt NoDbgRegParms computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize); -static sqInt NoDbgRegParms concretizeAddCheckOverflowCqR(AbstractInstruction * self_in_concretizeAddCheckOverflowCqR); -static sqInt NoDbgRegParms concretizeAddCheckOverflowRR(AbstractInstruction * self_in_concretizeAddCheckOverflowRR); -static sqInt NoDbgRegParms concretizeAddCqR(AbstractInstruction * self_in_concretizeAddCqR); -static sqInt NoDbgRegParms concretizeAddCwR(AbstractInstruction * self_in_concretizeAddCwR); -static sqInt NoDbgRegParms concretizeAddRRDest(AbstractInstruction * self_in_concretizeAddRRDest, sqInt destReg); -static usqInt NoDbgRegParms concretizeAlignmentNops(AbstractInstruction * self_in_concretizeAlignmentNops); -static sqInt NoDbgRegParms concretizeAndCqR(AbstractInstruction * self_in_concretizeAndCqR); -static sqInt NoDbgRegParms concretizeAndCqRDest(AbstractInstruction * self_in_concretizeAndCqRDest, sqInt destReg); -static sqInt NoDbgRegParms concretizeAndCwR(AbstractInstruction * self_in_concretizeAndCwR); -static sqInt NoDbgRegParms concretizeAndRR(AbstractInstruction * self_in_concretizeAndRR); -static sqInt NoDbgRegParms concretizeArithmeticShiftRightCqR(AbstractInstruction * self_in_concretizeArithmeticShiftRightCqR); -static sqInt NoDbgRegParms concretizeArithmeticShiftRightRR(AbstractInstruction * self_in_concretizeArithmeticShiftRightRR); -static sqInt NoDbgRegParms concretizeAt(AbstractInstruction * self_in_concretizeAt, sqInt actualAddress); -static sqInt NoDbgRegParms concretizeBrEqualRR(AbstractInstruction * self_in_concretizeBrEqualRR); -static sqInt NoDbgRegParms concretizeBrLongEqualRR(AbstractInstruction * self_in_concretizeBrLongEqualRR); -static sqInt NoDbgRegParms concretizeBrLongNotEqualRR(AbstractInstruction * self_in_concretizeBrLongNotEqualRR); -static sqInt NoDbgRegParms concretizeBrNotEqualRR(AbstractInstruction * self_in_concretizeBrNotEqualRR); -static sqInt NoDbgRegParms concretizeBrSignedGreaterEqualRR(AbstractInstruction * self_in_concretizeBrSignedGreaterEqualRR); -static sqInt NoDbgRegParms concretizeBrSignedGreaterRR(AbstractInstruction * self_in_concretizeBrSignedGreaterRR); -static sqInt NoDbgRegParms concretizeBrSignedLessEqualRR(AbstractInstruction * self_in_concretizeBrSignedLessEqualRR); -static sqInt NoDbgRegParms concretizeBrSignedLessRR(AbstractInstruction * self_in_concretizeBrSignedLessRR); -static sqInt NoDbgRegParms concretizeBrUnsignedGreaterEqualRR(AbstractInstruction * self_in_concretizeBrUnsignedGreaterEqualRR); -static sqInt NoDbgRegParms concretizeBrUnsignedGreaterRR(AbstractInstruction * self_in_concretizeBrUnsignedGreaterRR); -static sqInt NoDbgRegParms concretizeBrUnsignedLessEqualRR(AbstractInstruction * self_in_concretizeBrUnsignedLessEqualRR); -static sqInt NoDbgRegParms concretizeBrUnsignedLessRR(AbstractInstruction * self_in_concretizeBrUnsignedLessRR); -static sqInt NoDbgRegParms concretizeCall(AbstractInstruction * self_in_concretizeCall); -static sqInt NoDbgRegParms concretizeCallFull(AbstractInstruction * self_in_concretizeCallFull); -static sqInt NoDbgRegParms concretizeClzRR(AbstractInstruction * self_in_concretizeClzRR); -static sqInt NoDbgRegParms concretizeCmpCqR(AbstractInstruction * self_in_concretizeCmpCqR); -static sqInt NoDbgRegParms concretizeCmpCwR(AbstractInstruction * self_in_concretizeCmpCwR); -static sqInt NoDbgRegParms concretizeCmpRR(AbstractInstruction * self_in_concretizeCmpRR); -static sqInt NoDbgRegParms concretizeDivRR(AbstractInstruction * self_in_concretizeDivRR); -static sqInt NoDbgRegParms concretizeFill32(AbstractInstruction * self_in_concretizeFill32); -static sqInt NoDbgRegParms concretizeJump(AbstractInstruction * self_in_concretizeJump); -static sqInt NoDbgRegParms concretizeJumpFull(AbstractInstruction * self_in_concretizeJumpFull); -static sqInt NoDbgRegParms concretizeJumpLong(AbstractInstruction * self_in_concretizeJumpLong); -static sqInt NoDbgRegParms concretizeJumpLongNonZero(AbstractInstruction * self_in_concretizeJumpLongNonZero); -static sqInt NoDbgRegParms concretizeJumpLongZero(AbstractInstruction * self_in_concretizeJumpLongZero); -static sqInt NoDbgRegParms concretizeJumpNonZero(AbstractInstruction * self_in_concretizeJumpNonZero); -static sqInt NoDbgRegParms concretizeJumpNoOverflow(AbstractInstruction * self_in_concretizeJumpNoOverflow); -static sqInt NoDbgRegParms concretizeJumpOverflow(AbstractInstruction * self_in_concretizeJumpOverflow); -static sqInt NoDbgRegParms concretizeJumpR(AbstractInstruction * self_in_concretizeJumpR); -static sqInt NoDbgRegParms concretizeJumpSignedGreaterEqual(AbstractInstruction * self_in_concretizeJumpSignedGreaterEqual); -static sqInt NoDbgRegParms concretizeJumpSignedGreaterThan(AbstractInstruction * self_in_concretizeJumpSignedGreaterThan); -static sqInt NoDbgRegParms concretizeJumpSignedLessEqual(AbstractInstruction * self_in_concretizeJumpSignedLessEqual); -static sqInt NoDbgRegParms concretizeJumpSignedLessThan(AbstractInstruction * self_in_concretizeJumpSignedLessThan); -static sqInt NoDbgRegParms concretizeJumpUnsignedGreaterEqual(AbstractInstruction * self_in_concretizeJumpUnsignedGreaterEqual); -static sqInt NoDbgRegParms concretizeJumpUnsignedGreaterThan(AbstractInstruction * self_in_concretizeJumpUnsignedGreaterThan); -static sqInt NoDbgRegParms concretizeJumpUnsignedLessEqual(AbstractInstruction * self_in_concretizeJumpUnsignedLessEqual); -static sqInt NoDbgRegParms concretizeJumpUnsignedLessThan(AbstractInstruction * self_in_concretizeJumpUnsignedLessThan); -static sqInt NoDbgRegParms concretizeJumpZero(AbstractInstruction * self_in_concretizeJumpZero); -static sqInt NoDbgRegParms concretizeLoadEffectiveAddressMwrR(AbstractInstruction * self_in_concretizeLoadEffectiveAddressMwrR); -static sqInt NoDbgRegParms concretizeLogicalShiftLeftCqR(AbstractInstruction * self_in_concretizeLogicalShiftLeftCqR); -static sqInt NoDbgRegParms concretizeLogicalShiftLeftRR(AbstractInstruction * self_in_concretizeLogicalShiftLeftRR); -static sqInt NoDbgRegParms concretizeLogicalShiftRightCqR(AbstractInstruction * self_in_concretizeLogicalShiftRightCqR); -static sqInt NoDbgRegParms concretizeLogicalShiftRightRR(AbstractInstruction * self_in_concretizeLogicalShiftRightRR); -static sqInt NoDbgRegParms concretizeMoveAbR(AbstractInstruction * self_in_concretizeMoveAbR); -static sqInt NoDbgRegParms concretizeMoveAwR(AbstractInstruction * self_in_concretizeMoveAwR); -static sqInt NoDbgRegParms concretizeMoveCqR(AbstractInstruction * self_in_concretizeMoveCqR); -static sqInt NoDbgRegParms concretizeMoveCwR(AbstractInstruction * self_in_concretizeMoveCwR); -static sqInt NoDbgRegParms concretizeMoveHighR(AbstractInstruction * self_in_concretizeMoveHighR); -static sqInt NoDbgRegParms concretizeMoveLowR(AbstractInstruction * self_in_concretizeMoveLowR); -static sqInt NoDbgRegParms concretizeMoveM16rR(AbstractInstruction * self_in_concretizeMoveM16rR); -static sqInt NoDbgRegParms concretizeMoveMbrR(AbstractInstruction * self_in_concretizeMoveMbrR); -static sqInt NoDbgRegParms concretizeMoveMwrR(AbstractInstruction * self_in_concretizeMoveMwrR); -static sqInt NoDbgRegParms concretizeMoveRAb(AbstractInstruction * self_in_concretizeMoveRAb); -static sqInt NoDbgRegParms concretizeMoveRAw(AbstractInstruction * self_in_concretizeMoveRAw); -static sqInt NoDbgRegParms concretizeMoveRM16r(AbstractInstruction * self_in_concretizeMoveRM16r); -static sqInt NoDbgRegParms concretizeMoveRMbr(AbstractInstruction * self_in_concretizeMoveRMbr); -static sqInt NoDbgRegParms concretizeMoveRMwr(AbstractInstruction * self_in_concretizeMoveRMwr); -static sqInt NoDbgRegParms concretizeMoveRR(AbstractInstruction * self_in_concretizeMoveRR); -static sqInt NoDbgRegParms concretizeMoveRXbrR(AbstractInstruction * self_in_concretizeMoveRXbrR); -static sqInt NoDbgRegParms concretizeMoveRXwrR(AbstractInstruction * self_in_concretizeMoveRXwrR); -static sqInt NoDbgRegParms concretizeMoveXbrRR(AbstractInstruction * self_in_concretizeMoveXbrRR); -static sqInt NoDbgRegParms concretizeMoveXwrRR(AbstractInstruction * self_in_concretizeMoveXwrRR); -static sqInt NoDbgRegParms concretizeMulCheckOverflowRR(AbstractInstruction * self_in_concretizeMulCheckOverflowRR); -static sqInt NoDbgRegParms concretizeNegateR(AbstractInstruction * self_in_concretizeNegateR); -static sqInt NoDbgRegParms concretizeNop(AbstractInstruction * self_in_concretizeNop); -static sqInt NoDbgRegParms concretizeOrCqR(AbstractInstruction * self_in_concretizeOrCqR); -static sqInt NoDbgRegParms concretizeOrCqRR(AbstractInstruction * self_in_concretizeOrCqRR); -static sqInt NoDbgRegParms concretizeOrCwR(AbstractInstruction * self_in_concretizeOrCwR); -static sqInt NoDbgRegParms concretizeOrRR(AbstractInstruction * self_in_concretizeOrRR); -static sqInt NoDbgRegParms concretizePopR(AbstractInstruction * self_in_concretizePopR); -static sqInt NoDbgRegParms concretizePrefetchAw(AbstractInstruction * self_in_concretizePrefetchAw); -static sqInt NoDbgRegParms concretizePushCq(AbstractInstruction * self_in_concretizePushCq); -static sqInt NoDbgRegParms concretizePushCw(AbstractInstruction * self_in_concretizePushCw); -static sqInt NoDbgRegParms concretizePushR(AbstractInstruction * self_in_concretizePushR); -static sqInt NoDbgRegParms concretizeRetN(AbstractInstruction * self_in_concretizeRetN); -static sqInt NoDbgRegParms concretizeStop(AbstractInstruction * self_in_concretizeStop); -static sqInt NoDbgRegParms concretizeSubCheckOverflowCqR(AbstractInstruction * self_in_concretizeSubCheckOverflowCqR); -static sqInt NoDbgRegParms concretizeSubCheckOverflowRR(AbstractInstruction * self_in_concretizeSubCheckOverflowRR); -static sqInt NoDbgRegParms concretizeSubCqR(AbstractInstruction * self_in_concretizeSubCqR); -static sqInt NoDbgRegParms concretizeSubCwR(AbstractInstruction * self_in_concretizeSubCwR); -static sqInt NoDbgRegParms concretizeSubRRDest(AbstractInstruction * self_in_concretizeSubRRDest, sqInt destReg); -static sqInt NoDbgRegParms concretizeTstCqR(AbstractInstruction * self_in_concretizeTstCqR); -static sqInt NoDbgRegParms concretizeTstCwR(AbstractInstruction * self_in_concretizeTstCwR); -static sqInt NoDbgRegParms concretizeUnimplemented(AbstractInstruction * self_in_concretizeUnimplemented); -static sqInt NoDbgRegParms concretizeXorCwR(AbstractInstruction * self_in_concretizeXorCwR); -static sqInt NoDbgRegParms concretizeXorRR(AbstractInstruction * self_in_concretizeXorRR); -static sqInt NoDbgRegParms dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize); -static sqInt NoDbgRegParms divRR(AbstractInstruction * self_in_divRR, sqInt dividendReg, sqInt divisorReg); -static sqInt NoDbgRegParms fullCallsAreRelative(AbstractInstruction * self_in_fullCallsAreRelative); -static sqInt NoDbgRegParms functionAtAddress(AbstractInstruction * self_in_functionAtAddress, sqInt mcpc); -static sqInt NoDbgRegParms genDivRRQuoRem(AbstractInstruction * self_in_genDivRRQuoRem, sqInt abstractRegDivisor, sqInt abstractRegDividend, sqInt abstractRegQuotient, sqInt abstractRegRemainder); -static AbstractInstruction * NoDbgRegParms genMulRR(AbstractInstruction * self_in_genMulRR, sqInt regSource, sqInt regDest); -static void NoDbgRegParms genPushRegisterArgsForAbortMissNumArgs(AbstractInstruction * self_in_genPushRegisterArgsForAbortMissNumArgs, sqInt numArgs); -static void NoDbgRegParms genPushRegisterArgsForNumArgsscratchReg(AbstractInstruction * self_in_genPushRegisterArgsForNumArgsscratchReg, sqInt numArgs, sqInt ignored); -static sqInt NoDbgRegParms genRemoveNArgsFromStack(AbstractInstruction * self_in_genRemoveNArgsFromStack, sqInt n); -static sqInt NoDbgRegParms genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask); -static sqInt NoDbgRegParms genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask); -static AbstractInstruction * NoDbgRegParms genSubstituteReturnAddress(AbstractInstruction * self_in_genSubstituteReturnAddress, sqInt retpc); -static sqInt NoDbgRegParms hasVarBaseRegister(AbstractInstruction * self_in_hasVarBaseRegister); -static usqInt NoDbgRegParms high16BitsOf(AbstractInstruction * self_in_high16BitsOf, usqInt word); -static usqInt NoDbgRegParms inlineCacheTagAt(AbstractInstruction * self_in_inlineCacheTagAt, usqInt callSiteReturnAddress); -static sqInt NoDbgRegParms instructionSizeAt(AbstractInstruction * self_in_instructionSizeAt, sqInt pc); -static sqInt NoDbgRegParms isCallPrecedingReturnPC(AbstractInstruction * self_in_isCallPrecedingReturnPC, sqInt mcpc); -static sqInt NoDbgRegParms isJump(AbstractInstruction * self_in_isJump); -static sqInt NoDbgRegParms isJumpAt(AbstractInstruction * self_in_isJumpAt, sqInt pc); -static sqInt NoDbgRegParms isPCDependent(AbstractInstruction * self_in_isPCDependent); -static sqInt NoDbgRegParms isShortOffset(AbstractInstruction * self_in_isShortOffset, sqInt offset); -static sqInt NoDbgRegParms itypersrteitherImmediate(AbstractInstruction * self_in_itypersrteitherImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate); -static sqInt NoDbgRegParms itypersrtsignedImmediate(AbstractInstruction * self_in_itypersrtsignedImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate); -static sqInt NoDbgRegParms itypersrtunsignedImmediate(AbstractInstruction * self_in_itypersrtunsignedImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate); -static sqInt NoDbgRegParms jA(AbstractInstruction * self_in_jA, sqInt target); -static sqInt NoDbgRegParms jalA(AbstractInstruction * self_in_jalA, sqInt target); -static sqInt NoDbgRegParms jalR(AbstractInstruction * self_in_jalR, sqInt targetReg); -static sqInt NoDbgRegParms jR(AbstractInstruction * self_in_jR, sqInt targetReg); -static sqInt NoDbgRegParms jtypetarget(AbstractInstruction * self_in_jtypetarget, sqInt op, sqInt target); -static sqInt NoDbgRegParms jumpLongByteSize(AbstractInstruction * self_in_jumpLongByteSize); -static sqInt NoDbgRegParms jumpLongConditionalByteSize(AbstractInstruction * self_in_jumpLongConditionalByteSize); -static usqInt NoDbgRegParms jumpLongConditionalTargetBeforeFollowingAddress(AbstractInstruction * self_in_jumpLongConditionalTargetBeforeFollowingAddress, sqInt mcpc); -static usqInt NoDbgRegParms jumpLongTargetBeforeFollowingAddress(AbstractInstruction * self_in_jumpLongTargetBeforeFollowingAddress, sqInt mcpc); -static sqInt NoDbgRegParms jumpShortByteSize(AbstractInstruction * self_in_jumpShortByteSize); -static usqInt NoDbgRegParms jumpTargetPCAt(AbstractInstruction * self_in_jumpTargetPCAt, sqInt pc); -static sqInt NoDbgRegParms lbRbaseoffset(AbstractInstruction * self_in_lbRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset); -static sqInt NoDbgRegParms lbuRbaseoffset(AbstractInstruction * self_in_lbuRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset); -static sqInt NoDbgRegParms lhRbaseoffset(AbstractInstruction * self_in_lhRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset); -static sqInt NoDbgRegParms lhuRbaseoffset(AbstractInstruction * self_in_lhuRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset); -static usqInt NoDbgRegParms literalAtAddress(AbstractInstruction * self_in_literalAtAddress, sqInt mcpc); -static sqInt NoDbgRegParms literalAtAddressput(AbstractInstruction * self_in_literalAtAddressput, sqInt mcpc, sqInt newLiteral); -static usqInt NoDbgRegParms literalBeforeFollowingAddress(AbstractInstruction * self_in_literalBeforeFollowingAddress, sqInt followingAddress); -static sqInt NoDbgRegParms loadLiteralByteSize(AbstractInstruction * self_in_loadLiteralByteSize); -static sqInt NoDbgRegParms loadPICLiteralByteSize(AbstractInstruction * self_in_loadPICLiteralByteSize); -static usqInt NoDbgRegParms low16BitsOf(AbstractInstruction * self_in_low16BitsOf, usqInt word); -static sqInt NoDbgRegParms luiRC(AbstractInstruction * self_in_luiRC, sqInt destReg, sqInt imm); -static sqInt NoDbgRegParms lwRbaseoffset(AbstractInstruction * self_in_lwRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset); -static sqInt NoDbgRegParms machineCodeBytes(AbstractInstruction * self_in_machineCodeBytes); -static sqInt NoDbgRegParms machineCodeWords(AbstractInstruction * self_in_machineCodeWords); -static sqInt NoDbgRegParms mfhiR(AbstractInstruction * self_in_mfhiR, sqInt destReg); -static sqInt NoDbgRegParms mfloR(AbstractInstruction * self_in_mfloR, sqInt destReg); -static sqInt NoDbgRegParms mipsbreak(AbstractInstruction * self_in_mipsbreak, sqInt code); -static sqInt NoDbgRegParms multRR(AbstractInstruction * self_in_multRR, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms nop(AbstractInstruction * self_in_nop); -static AbstractInstruction * NoDbgRegParms noteFollowingConditionalBranch(AbstractInstruction * self_in_noteFollowingConditionalBranch, AbstractInstruction *branch); -static AbstractInstruction * NoDbgRegParms noteFollowingOverflowBranch(AbstractInstruction * self_in_noteFollowingOverflowBranch, AbstractInstruction *branch); -static sqInt NoDbgRegParms numIntRegArgs(AbstractInstruction * self_in_numIntRegArgs); -static sqInt NoDbgRegParms opcodeAtAddress(AbstractInstruction * self_in_opcodeAtAddress, sqInt mcpc); -static sqInt NoDbgRegParms oriRRC(AbstractInstruction * self_in_oriRRC, sqInt destReg, sqInt srcReg, sqInt imm); -static sqInt NoDbgRegParms orRRR(AbstractInstruction * self_in_orRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static void NoDbgRegParms padIfPossibleWithStopsFromto(AbstractInstruction * self_in_padIfPossibleWithStopsFromto, sqInt startAddr, sqInt endAddr); -static sqInt NoDbgRegParms prefRoffsethint(AbstractInstruction * self_in_prefRoffsethint, sqInt baseReg, sqInt offset, sqInt hint); -static sqInt NoDbgRegParms pushLinkRegisterByteSize(AbstractInstruction * self_in_pushLinkRegisterByteSize); -static AbstractInstruction * NoDbgRegParms relocateCallBeforeReturnPCby(AbstractInstruction * self_in_relocateCallBeforeReturnPCby, sqInt retpc, sqInt delta); -static AbstractInstruction * NoDbgRegParms relocateJumpLongBeforeFollowingAddressby(AbstractInstruction * self_in_relocateJumpLongBeforeFollowingAddressby, sqInt pc, sqInt delta); -static void NoDbgRegParms relocateJumpLongConditionalBeforeFollowingAddressby(AbstractInstruction * self_in_relocateJumpLongConditionalBeforeFollowingAddressby, sqInt pc, sqInt delta); -static AbstractInstruction * NoDbgRegParms relocateMethodReferenceBeforeAddressby(AbstractInstruction * self_in_relocateMethodReferenceBeforeAddressby, sqInt pc, sqInt delta); -static sqInt NoDbgRegParms rewriteCallAttarget(AbstractInstruction * self_in_rewriteCallAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress); -static void NoDbgRegParms rewriteConditionalJumpLongAttarget(AbstractInstruction * self_in_rewriteConditionalJumpLongAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress); -static void NoDbgRegParms rewriteCPICJumpAttarget(AbstractInstruction * self_in_rewriteCPICJumpAttarget, usqInt addressFollowingJump, usqInt jumpTargetAddr); -static sqInt NoDbgRegParms rewriteInlineCacheAttagtarget(AbstractInstruction * self_in_rewriteInlineCacheAttagtarget, usqInt callSiteReturnAddress, sqInt cacheTag, usqInt callTargetAddress); -static void NoDbgRegParms rewriteInlineCacheTagat(AbstractInstruction * self_in_rewriteInlineCacheTagat, sqInt cacheTag, usqInt callSiteReturnAddress); -static void NoDbgRegParms rewriteITypeBranchAtAddresstarget(AbstractInstruction * self_in_rewriteITypeBranchAtAddresstarget, sqInt mcpc, sqInt newTarget); -static void NoDbgRegParms rewriteJTypeAtAddressdelta(AbstractInstruction * self_in_rewriteJTypeAtAddressdelta, sqInt mcpc, sqInt delta); -static void NoDbgRegParms rewriteJTypeAtAddresstarget(AbstractInstruction * self_in_rewriteJTypeAtAddresstarget, sqInt mcpc, sqInt newTarget); -static sqInt NoDbgRegParms rewriteJumpLongAttarget(AbstractInstruction * self_in_rewriteJumpLongAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress); -static sqInt NoDbgRegParms rtAtAddress(AbstractInstruction * self_in_rtAtAddress, sqInt mcpc); -static sqInt NoDbgRegParms rtypersrtrdsafunct(AbstractInstruction * self_in_rtypersrtrdsafunct, sqInt op, sqInt rs, sqInt rt, sqInt rd, sqInt sa, sqInt funct); -static sqInt NoDbgRegParms sbRbaseoffset(AbstractInstruction * self_in_sbRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset); -static sqInt NoDbgRegParms setsConditionCodesFor(AbstractInstruction * self_in_setsConditionCodesFor, sqInt aConditionalJumpOpcode); -static sqInt NoDbgRegParms shRbaseoffset(AbstractInstruction * self_in_shRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset); -static usqInt NoDbgRegParms sizePCDependentInstructionAt(AbstractInstruction * self_in_sizePCDependentInstructionAt, sqInt eventualAbsoluteAddress); -static sqInt NoDbgRegParms sllRRC(AbstractInstruction * self_in_sllRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount); -static sqInt NoDbgRegParms sllvRRR(AbstractInstruction * self_in_sllvRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms sltiRRC(AbstractInstruction * self_in_sltiRRC, sqInt destReg, sqInt leftReg, sqInt imm); -static sqInt NoDbgRegParms sltiuRRC(AbstractInstruction * self_in_sltiuRRC, sqInt destReg, sqInt leftReg, sqInt imm); -static sqInt NoDbgRegParms sltRRR(AbstractInstruction * self_in_sltRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms sltuRRR(AbstractInstruction * self_in_sltuRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms sraRRC(AbstractInstruction * self_in_sraRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount); -static sqInt NoDbgRegParms sravRRR(AbstractInstruction * self_in_sravRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms srlRRC(AbstractInstruction * self_in_srlRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount); -static sqInt NoDbgRegParms srlvRRR(AbstractInstruction * self_in_srlvRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms stop(AbstractInstruction * self_in_stop); -static void NoDbgRegParms stopsFromto(AbstractInstruction * self_in_stopsFromto, sqInt startAddr, sqInt endAddr); -static sqInt NoDbgRegParms storeLiteralbeforeFollowingAddress(AbstractInstruction * self_in_storeLiteralbeforeFollowingAddress, sqInt literal, sqInt followingAddress); -static sqInt NoDbgRegParms subuRRR(AbstractInstruction * self_in_subuRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms swRbaseoffset(AbstractInstruction * self_in_swRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset); -static usqInt NoDbgRegParms targetFromITypeAtAddress(AbstractInstruction * self_in_targetFromITypeAtAddress, usqInt mcpc); -static usqInt NoDbgRegParms targetFromJTypeAtAddress(AbstractInstruction * self_in_targetFromJTypeAtAddress, usqInt mcpc); -static sqInt NoDbgRegParms xoriRRC(AbstractInstruction * self_in_xoriRRC, sqInt destReg, sqInt srcReg, sqInt imm); -static sqInt NoDbgRegParms xorRRR(AbstractInstruction * self_in_xorRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms zoneCallsAreRelative(AbstractInstruction * self_in_zoneCallsAreRelative); -static sqInt NoDbgRegParms checkValidObjectReference(sqInt anOop); -static AbstractInstruction * NoDbgRegParms genCmpClassFloatCompactIndexR(sqInt reg); -static AbstractInstruction * NoDbgRegParms genCmpClassMethodContextCompactIndexR(sqInt reg); -static sqInt NoDbgRegParms genGetMethodHeaderOfintoscratch(sqInt methodReg, sqInt headerReg, sqInt scratchReg); -static void NoDbgRegParms genLcByteSizeOfto(sqInt oop, sqInt resultRegister); -static void NoDbgRegParms genLcFloat32toOop(sqInt value, sqInt object); -static void NoDbgRegParms genLcFloat64toOop(sqInt value, sqInt object); -static void NoDbgRegParms genLcInstantiateOop(sqInt classOop); -static void NoDbgRegParms genLcInstantiateOopconstantIndexableSize(sqInt classOop, sqInt indexableSize); -static void NoDbgRegParms genLcInstantiateOopindexableSize(sqInt classOop, sqInt indexableSize); -static void NoDbgRegParms genLcInt64ToOop(sqInt value); -static void NoDbgRegParms genLcInt64ToOophighPart(sqInt valueLow, sqInt valueHigh); -static void NoDbgRegParms genLcOopToInt64(sqInt value); -static void NoDbgRegParms genLcOopToPointer(sqInt object); -static void NoDbgRegParms genLcOopToUInt64(sqInt value); -static void NoDbgRegParms genLcOoptoFloat32(sqInt object, sqInt value); -static void NoDbgRegParms genLcOoptoFloat64(sqInt object, sqInt value); -static void NoDbgRegParms genLcOoptoInt64highPart(sqInt object, sqInt valueLow, sqInt valueHigh); -static void NoDbgRegParms genLcOoptoUInt64highPart(sqInt object, sqInt valueLow, sqInt valueHigh); -static void NoDbgRegParms genLcPointerToOopclass(sqInt pointer, sqInt pointerClass); -static void NoDbgRegParms genLcUInt64ToOop(sqInt value); -static void NoDbgRegParms genLcUInt64ToOophighPart(sqInt valueLow, sqInt valueHigh); -static sqInt NoDbgRegParms genLoadSlotsourceRegdestReg(sqInt index, sqInt sourceReg, sqInt destReg); -static sqInt genPrimitiveAdd(void); -static sqInt genPrimitiveBitAnd(void); -static sqInt genPrimitiveBitOr(void); -static sqInt genPrimitiveBitShift(void); -static sqInt genPrimitiveBitXor(void); -static sqInt genPrimitiveClass(void); -static sqInt genPrimitiveDiv(void); -static sqInt genPrimitiveDivide(void); -static sqInt genPrimitiveEqual(void); -static sqInt genPrimitiveGreaterOrEqual(void); -static sqInt genPrimitiveGreaterThan(void); -static sqInt genPrimitiveHighBit(void); -static sqInt genPrimitiveIdentical(void); -static sqInt genPrimitiveLessOrEqual(void); -static sqInt genPrimitiveLessThan(void); -static sqInt genPrimitiveMod(void); -static sqInt genPrimitiveMultiply(void); -static sqInt genPrimitiveNewMethod(void); -static sqInt genPrimitiveNotEqual(void); -static sqInt genPrimitiveNotIdentical(void); -static sqInt genPrimitiveQuo(void); -static sqInt genPrimitiveSubtract(void); -static sqInt NoDbgRegParms genSmallIntegerComparison(sqInt jumpOpcode); -static sqInt NoDbgRegParms genSmallIntegerComparisonorDoubleComparisoninvert(sqInt jumpOpcode, AbstractInstruction * NoDbgRegParms (*jumpFPOpcodeGenerator)(void *), sqInt invertComparison); -static sqInt NoDbgRegParms isUnannotatableConstant(CogSimStackEntry *simStackEntry); -static sqInt NoDbgRegParms classForInlineCacheTag(sqInt inlineCacheTag); -static sqInt NoDbgRegParms genAddSmallIntegerTagsTo(sqInt aRegister); -static sqInt NoDbgRegParms genClearAndSetSmallIntegerTagsIn(sqInt scratchReg); -static void NoDbgRegParms genConvertCharacterToSmallIntegerInReg(sqInt reg); -static sqInt NoDbgRegParms genConvertIntegerInRegtoSmallIntegerInReg(sqInt srcReg, sqInt destReg); -static sqInt NoDbgRegParms genConvertIntegerToSmallIntegerInReg(sqInt reg); -static void NoDbgRegParms genConvertSmallIntegerToCharacterInReg(sqInt reg); -static sqInt NoDbgRegParms genConvertSmallIntegerToIntegerInReg(sqInt reg); -static void generateLowcodeObjectTrampolines(void); -static sqInt NoDbgRegParms genGetHashFieldNonImmOfasSmallIntegerInto(sqInt instReg, sqInt destReg); -static sqInt NoDbgRegParms genGetHashFieldNonImmOfinto(sqInt instReg, sqInt destReg); -static AbstractInstruction * NoDbgRegParms genGetInlineCacheClassTagFromintoforEntry(sqInt sourceReg, sqInt destReg, sqInt forEntry); -static sqInt NoDbgRegParms genGetNumBytesOfinto(sqInt srcReg, sqInt destReg); -static sqInt NoDbgRegParms genGetOverflowSlotsOfinto(sqInt srcReg, sqInt destReg); -static AbstractInstruction * NoDbgRegParms genJumpIsSmallIntegerValuescratch(sqInt aRegister, sqInt scratchReg); -static AbstractInstruction * NoDbgRegParms genJumpNotSmallIntegerInScratchReg(sqInt aRegister); -static AbstractInstruction * NoDbgRegParms genJumpNotSmallIntegerValuescratch(sqInt aRegister, sqInt scratchReg); -static AbstractInstruction * NoDbgRegParms genJumpNotSmallInteger(sqInt aRegister); -static AbstractInstruction * NoDbgRegParms genJumpSmallInteger(sqInt aRegister); -static void NoDbgRegParms genLcInt32ToOop(sqInt value); -static void NoDbgRegParms genLcOopToInt32(sqInt value); -static void NoDbgRegParms genLcOopToUInt32(sqInt value); -static void NoDbgRegParms genLcUInt32ToOop(sqInt value); -static sqInt genPrimitiveAtPut(void); -static sqInt NoDbgRegParms genPrimitiveAtPutSigned(sqInt signedVersion); -static sqInt NoDbgRegParms genPrimitiveAtSigned(sqInt signedVersion); -static sqInt genPrimitiveIdentityHash(void); -static sqInt genPrimitiveImmediateAsInteger(void); -static sqInt genPrimitiveNew(void); -static sqInt genPrimitiveNewWithArg(void); -static sqInt genPrimitiveShallowCopy(void); -static sqInt genPrimitiveStringAt(void); -static sqInt genPrimitiveStringAtPut(void); -static sqInt NoDbgRegParms genRemoveSmallIntegerTagsInScratchReg(sqInt scratchReg); -static sqInt NoDbgRegParms genShiftAwaySmallIntegerTagsInScratchReg(sqInt scratchReg); -static sqInt NoDbgRegParms getLiteralCountOfplusOneinBytesintoscratch(sqInt methodReg, sqInt plusOne, sqInt inBytes, sqInt litCountReg, sqInt scratchReg); -static sqInt NoDbgRegParms inlineCacheTagForInstance(sqInt oop); -static AbstractInstruction * NoDbgRegParms jumpNotSmallIntegerUnsignedValueInRegister(sqInt reg); -static sqInt NoDbgRegParms markAndTraceCacheTagLiteralinatpc(sqInt literal, CogMethod *cogMethodOrNil, usqInt address); -static sqInt numSmallIntegerBits(void); -static sqInt NoDbgRegParms validInlineCacheTag(usqInt classIndexOrTagPattern); -static void callStoreCheckTrampoline(void); -static sqInt NoDbgRegParms checkValidDerivedObjectReference(sqInt bodyAddress); -static sqInt NoDbgRegParms checkValidOopReference(sqInt anOop); -static sqInt NoDbgRegParms couldBeDerivedObject(sqInt bodyAddress); -static sqInt NoDbgRegParms couldBeObject(sqInt literal); -static usqInt NoDbgRegParms genActiveContextTrampolineLargeinBlockcalled(sqInt isLarge, sqInt isInBlock, char *aString); -static AbstractInstruction * NoDbgRegParms genCheckRememberedBitOfscratch(sqInt objReg, sqInt scratchReg); -static sqInt NoDbgRegParms genConvertCharacterToCodeInReg(sqInt reg); -static sqInt NoDbgRegParms genConvertIntegerToCharacterInReg(sqInt reg); -static sqInt NoDbgRegParms genCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(sqInt bcpc, sqInt numArgs, sqInt numCopied, sqInt ctxtNumArgs, sqInt isLargeCtxt, sqInt isInBlock); -static sqInt NoDbgRegParms genCreateFullClosurenumArgsnumCopiedignoreContextcontextNumArgslargeinBlock(sqInt compiledBlock, sqInt numArgs, sqInt numCopied, sqInt ignoreContext, sqInt contextNumArgs, sqInt contextIsLarge, sqInt contextIsBlock); -static sqInt NoDbgRegParms genEnsureObjInRegNotForwardedscratchReg(sqInt reg, sqInt scratch); -static sqInt NoDbgRegParms genEnsureOopInRegNotForwardedscratchReg(sqInt reg, sqInt scratch); -static sqInt NoDbgRegParms genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(sqInt reg, sqInt scratch, void *fwdJumpTarget, void *nonFwdJumpTargetOrZero); -static sqInt NoDbgRegParms genEnsureOopInRegNotForwardedscratchRegupdatingSlotin(sqInt reg, sqInt scratch, sqInt index, sqInt objReg); -static void generateObjectRepresentationTrampolines(void); -static sqInt NoDbgRegParms genGetActiveContextLargeinBlock(sqInt isLarge, sqInt isInBlock); -static sqInt NoDbgRegParms genGetActiveContextNumArgslargeinBlock(sqInt numArgs, sqInt isLargeContext, sqInt isInBlock); -static sqInt NoDbgRegParms genGetBitsofFormatByteOfinto(sqInt mask, sqInt sourceReg, sqInt destReg); -static sqInt NoDbgRegParms genGetClassIndexOfNonImminto(sqInt sourceReg, sqInt destReg); -static sqInt NoDbgRegParms genGetClassObjectOfClassIndexintoscratchReg(sqInt instReg, sqInt destReg, sqInt scratchReg); -static sqInt NoDbgRegParms genGetClassObjectOfintoscratchRegmayBeAForwarder(sqInt instReg, sqInt destReg, sqInt scratchReg, sqInt mayBeForwarder); -static AbstractInstruction * NoDbgRegParms genGetClassTagOfintoscratchReg(sqInt instReg, sqInt destReg, sqInt scratchReg); -static sqInt NoDbgRegParms genGetCompactClassIndexNonImmOfinto(sqInt instReg, sqInt destReg); -static sqInt NoDbgRegParms genGetDoubleValueOfinto(sqInt srcReg, sqInt destFPReg); -static sqInt NoDbgRegParms genGetFormatOfinto(sqInt srcReg, sqInt destReg); -static sqInt NoDbgRegParms genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(sqInt sourceReg, sqInt destReg, sqInt scratchRegOrNone); -static sqInt NoDbgRegParms genGetNumSlotsOfinto(sqInt srcReg, sqInt destReg); -static sqInt NoDbgRegParms genGetRawSlotSizeOfNonImminto(sqInt sourceReg, sqInt destReg); -static AbstractInstruction * NoDbgRegParms genJumpImmediate(sqInt aRegister); -#if IMMUTABILITY -static AbstractInstruction * NoDbgRegParms genJumpImmutablescratchReg(sqInt sourceReg, sqInt scratchReg); -#endif /* IMMUTABILITY */ -#if IMMUTABILITY -static AbstractInstruction * NoDbgRegParms genJumpMutablescratchReg(sqInt sourceReg, sqInt scratchReg); -#endif /* IMMUTABILITY */ -static AbstractInstruction * NoDbgRegParms genJumpNotCharacterInScratchReg(sqInt reg); -static void NoDbgRegParms genLcFirstFieldPointer(sqInt objectReg); -static void NoDbgRegParms genLcFirstIndexableFieldPointer(sqInt objectReg); -static void NoDbgRegParms genLcIsBytesto(sqInt objectReg, sqInt valueReg); -static void NoDbgRegParms genLcIsFloatObjectto(sqInt objectReg, sqInt valueReg); -static void NoDbgRegParms genLcIsIndexableto(sqInt objectReg, sqInt valueReg); -static void NoDbgRegParms genLcIsIntegerObjectto(sqInt objectReg, sqInt valueReg); -static void NoDbgRegParms genLcIsPointersto(sqInt objectReg, sqInt valueReg); -static void NoDbgRegParms genLcIsWordsOrBytesto(sqInt objectReg, sqInt valueReg); -static void NoDbgRegParms genLcIsWordsto(sqInt objectReg, sqInt valueReg); -static void NoDbgRegParms genLcLoadObjectat(sqInt object, sqInt fieldIndex); -static void NoDbgRegParms genLcLoadObjectfield(sqInt object, sqInt fieldIndex); -static void NoDbgRegParms genLcStoreobjectat(sqInt value, sqInt object, sqInt fieldIndex); -static void NoDbgRegParms genLcStoreobjectfield(sqInt value, sqInt object, sqInt fieldIndex); -static sqInt NoDbgRegParms genNewArrayOfSizeinitialized(sqInt size, sqInt initialize); -static sqInt NoDbgRegParms genNoPopCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(sqInt bcpc, sqInt numArgs, sqInt numCopied, sqInt ctxtNumArgs, sqInt isLargeCtxt, sqInt isInBlock); -static sqInt genPrimitiveAsCharacter(void); -static sqInt genPrimitiveAt(void); -static sqInt NoDbgRegParms genPrimitiveIdenticalOrNotIf(sqInt orNot); -static sqInt genPrimitiveIntegerAt(void); -static sqInt genPrimitiveIntegerAtPut(void); -static sqInt genPrimitiveMakePoint(void); -static sqInt genPrimitiveObjectAt(void); -static sqInt genPrimitiveSize(void); -static sqInt genPrimitiveStringCompareWith(void); -static sqInt genPrimitiveStringReplace(void); -static sqInt NoDbgRegParms genSetSmallIntegerTagsIn(sqInt scratchReg); -static usqInt genStoreCheckContextReceiverTrampoline(void); -static sqInt NoDbgRegParms genStoreCheckReceiverRegvalueRegscratchReginFrame(sqInt destReg, sqInt valueReg, sqInt scratchReg, sqInt inFrame); -static sqInt NoDbgRegParms genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt inFrame, sqInt needsStoreCheck); -static sqInt NoDbgRegParms genStoreSourceRegslotIndexintoNewObjectInDestReg(sqInt sourceReg, sqInt index, sqInt destReg); -#if IMMUTABILITY -static usqInt NoDbgRegParms genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex); -#endif /* IMMUTABILITY */ -#if IMMUTABILITY -static sqInt NoDbgRegParms genStoreWithImmutabilityAndStoreCheckSourceRegslotIndexdestRegscratchRegneedRestoreRcvr(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt needRestoreRcvr); -#endif /* IMMUTABILITY */ -#if IMMUTABILITY -static sqInt NoDbgRegParms genStoreWithImmutabilityButNoStoreCheckSourceRegslotIndexdestRegscratchRegneedRestoreRcvr(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt needRestoreRcvr); -#endif /* IMMUTABILITY */ -#if IMMUTABILITY -static sqInt NoDbgRegParms genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt needsStoreCheck, sqInt needRestoreRcvr); -#endif /* IMMUTABILITY */ -static sqInt getActiveContextAllocatesInMachineCode(void); -static sqInt NoDbgRegParms inlineCacheTagIsYoung(sqInt cacheTag); -static AbstractInstruction * NoDbgRegParms jumpNotCharacterUnsignedValueInRegister(sqInt reg); -static sqInt NoDbgRegParms markAndTraceLiteralinatpc(sqInt literal, CogMethod *cogMethodOrNil, usqInt address); -static void NoDbgRegParms markAndTraceLiteralinat(sqInt literal, CogMethod *cogMethod, sqInt *address); -static void NoDbgRegParms markAndTraceUpdatedLiteralin(sqInt objOop, CogMethod *cogMethodOrNil); -static sqInt NoDbgRegParms maybeCompileRetryOnPrimitiveFail(sqInt primIndex); -static sqInt NoDbgRegParms maybeShiftClassTagRegisterForMethodCacheProbe(sqInt classTagReg); -static sqInt numCharacterBits(void); -extern sqInt numRegArgs(void); -static sqInt NoDbgRegParms remapObject(sqInt objOop); -static sqInt NoDbgRegParms remapOop(sqInt objOop); -static sqInt NoDbgRegParms shouldAnnotateObjectReference(sqInt anOop); -static sqInt NoDbgRegParms slotOffsetOfInstVarIndex(sqInt index); -static SimStackEntry * NoDbgRegParms ensureSpilledAtfrom(SimStackEntry * self_in_ensureSpilledAtfrom, sqInt baseOffset, sqInt baseRegister); -static sqInt NoDbgRegParms isSameEntryAs(SimStackEntry * self_in_isSameEntryAs, CogSimStackEntry *ssEntry); -static sqInt NoDbgRegParms mayBeAForwarder(SimStackEntry * self_in_mayBeAForwarder); -static void NoDbgRegParms popToReg(SimStackEntry * self_in_popToReg, sqInt reg); -static sqInt NoDbgRegParms registerMask(SimStackEntry * self_in_registerMask); -static sqInt NoDbgRegParms registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone); -static sqInt NoDbgRegParms registerOrNone(SimStackEntry * self_in_registerOrNone); -static void NoDbgRegParms storeToReg(SimStackEntry * self_in_storeToReg, sqInt reg); -static void NoDbgRegParms ensureIsMarkedAsSpilled(CogSimStackNativeEntry * self_in_ensureIsMarkedAsSpilled); -static void NoDbgRegParms ensureSpilledSPscratchRegister(CogSimStackNativeEntry * self_in_ensureSpilledSPscratchRegister, sqInt spRegister, sqInt scratchRegister); -static sqInt NoDbgRegParms nativeFloatRegisterMask(CogSimStackNativeEntry * self_in_nativeFloatRegisterMask); -static sqInt NoDbgRegParms nativeFloatRegisterOrNone(CogSimStackNativeEntry * self_in_nativeFloatRegisterOrNone); -static void NoDbgRegParms nativePopToReg(CogSimStackNativeEntry * self_in_nativePopToReg, sqInt reg); -static void NoDbgRegParms nativePopToRegsecondReg(CogSimStackNativeEntry * self_in_nativePopToRegsecondReg, sqInt reg, sqInt secondReg); -static sqInt NoDbgRegParms nativeRegisterMask(CogSimStackNativeEntry * self_in_nativeRegisterMask); -static sqInt NoDbgRegParms nativeRegisterOrNone(CogSimStackNativeEntry * self_in_nativeRegisterOrNone); -static sqInt NoDbgRegParms nativeRegisterSecondOrNone(CogSimStackNativeEntry * self_in_nativeRegisterSecondOrNone); -static void NoDbgRegParms nativeStackPopToReg(CogSimStackNativeEntry * self_in_nativeStackPopToReg, sqInt reg); -static void NoDbgRegParms nativeStackPopToRegsecondReg(CogSimStackNativeEntry * self_in_nativeStackPopToRegsecondReg, sqInt reg, sqInt secondReg); -static sqInt NoDbgRegParms spillingNeedsScratchRegister(CogSimStackNativeEntry * self_in_spillingNeedsScratchRegister); -static sqInt NoDbgRegParms stackSpillSize(CogSimStackNativeEntry * self_in_stackSpillSize); -static sqInt NoDbgRegParms isMergeFixup(BytecodeFixup * self_in_isMergeFixup); -static AbstractInstruction * NoDbgRegParms checkLiteralforInstruction(sqInt literal, AbstractInstruction *anInstruction); -static AbstractInstruction * NoDbgRegParms checkQuickConstantforInstruction(sqInt literal, AbstractInstruction *anInstruction); -extern sqInt cogMethodHasExternalPrim(CogMethod *aCogMethod); -extern sqInt cogMethodHasMachineCodePrim(CogMethod *aCogMethod); -static sqInt compileBlockDispatch(void); -static void compileGetErrorCode(void); -static sqInt compileInterpreterPrimitive(void); -static sqInt NoDbgRegParms compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags); -static sqInt NoDbgRegParms compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)); -static sqInt NoDbgRegParms compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags); -static AbstractInstruction * NoDbgRegParms compileOpenPICMethodCacheProbeForwithShiftbaseRegOrNone(sqInt selector, sqInt shift, sqInt baseRegOrNone); -static void NoDbgRegParms compileOpenPICnumArgs(sqInt selector, sqInt numArgs); -static AbstractInstruction * NoDbgRegParms compilePerformMethodCacheProbeForwithShiftbaseRegOrNone(sqInt selectorReg, sqInt shift, sqInt baseRegOrNone); -static sqInt compilePrimitive(void); -static sqInt extendedPushBytecode(void); -static sqInt extendedStoreAndPopBytecode(void); -static sqInt extendedStoreBytecode(void); -static sqInt frameOffsetOfNativeFrameMark(void); -static sqInt frameOffsetOfNativeFramePointer(void); -static sqInt frameOffsetOfNativeStackPointer(void); -static sqInt frameOffsetOfPreviousNativeStackPointer(void); -static sqInt NoDbgRegParms frameOffsetOfTemporary(sqInt index); -static sqInt genCallMappedInlinedPrimitive(void); -static sqInt genExtendedSendBytecode(void); -static sqInt genExtendedSuperBytecode(void); -static sqInt genExtJumpIfFalse(void); -static sqInt genExtJumpIfTrue(void); -static sqInt genExtNopBytecode(void); -static sqInt genExtPushCharacterBytecode(void); -static sqInt genExtPushIntegerBytecode(void); -static sqInt genExtPushLiteralBytecode(void); -static sqInt genExtPushLiteralVariableBytecode(void); -static sqInt genExtPushPseudoVariable(void); -static sqInt genExtPushReceiverVariableBytecode(void); -static sqInt genExtSendBytecode(void); -static sqInt genExtSendSuperBytecode(void); -static sqInt genExtStoreAndPopLiteralVariableBytecode(void); -static sqInt genExtStoreAndPopReceiverVariableBytecode(void); -static sqInt genExtStoreLiteralVariableBytecode(void); -static sqInt genExtStoreReceiverVariableBytecode(void); -static sqInt genExtUnconditionalJump(void); -static sqInt genFastPrimFail(void); -static void NoDbgRegParms genFastPrimTraceUsingand(sqInt r1, sqInt r2); -static sqInt genLongJumpIfFalse(void); -static sqInt genLongJumpIfTrue(void); -static sqInt genLongPushTemporaryVariableBytecode(void); -static sqInt genLongStoreAndPopTemporaryVariableBytecode(void); -static sqInt genLongStoreTemporaryVariableBytecode(void); -static sqInt genLongUnconditionalBackwardJump(void); -static sqInt genLongUnconditionalForwardJump(void); -static sqInt NoDbgRegParms genLookupForPerformNumArgs(sqInt numArgs); -static usqInt NoDbgRegParms genMustBeBooleanTrampolineForcalled(sqInt boolean, char *trampolineName); -static sqInt genPrimitiveHashMultiply(void); -static void NoDbgRegParms genPrimReturnEnterCogCodeEnilopmart(sqInt profiling); -static sqInt genPushConstantFalseBytecode(void); -static sqInt genPushConstantNilBytecode(void); -static sqInt genPushConstantOneBytecode(void); -static sqInt genPushConstantTrueBytecode(void); -static sqInt genPushConstantZeroBytecode(void); -static sqInt genPushLiteralConstantBytecode(void); -static sqInt genPushLiteralVariable16CasesBytecode(void); -static sqInt genPushLiteralVariableBytecode(void); -static sqInt genPushQuickIntegerConstantBytecode(void); -static sqInt genPushReceiverVariableBytecode(void); -static sqInt genPushTemporaryVariableBytecode(void); -extern sqInt genQuickReturnConst(void); -extern sqInt genQuickReturnInstVar(void); -extern sqInt genQuickReturnSelf(void); -static sqInt genReturnFalse(void); -static sqInt genReturnNil(void); -static sqInt genReturnNilFromBlock(void); -static sqInt genReturnTrue(void); -static sqInt genSecondExtendedSendBytecode(void); -static sqInt genSendLiteralSelector0ArgsBytecode(void); -static sqInt genSendLiteralSelector1ArgBytecode(void); -static sqInt genSendLiteralSelector2ArgsBytecode(void); -static sqInt genShortJumpIfFalse(void); -static sqInt genShortJumpIfTrue(void); -static sqInt genShortUnconditionalJump(void); -static sqInt genSpecialSelectorEqualsEquals(void); -static sqInt genSpecialSelectorNotEqualsEquals(void); -static sqInt genSpecialSelectorSend(void); -static sqInt genStoreAndPopReceiverVariableBytecode(void); -static sqInt genStoreAndPopRemoteTempLongBytecode(void); -static sqInt genStoreAndPopTemporaryVariableBytecode(void); -static sqInt genStoreRemoteTempLongBytecode(void); -static sqInt genUnconditionalTrapBytecode(void); -static void NoDbgRegParms loadNativeArgumentAddressto(sqInt baseOffset, sqInt reg); -static void NoDbgRegParms loadNativeFramePointerInto(sqInt reg); -static void NoDbgRegParms loadNativeLocalAddressto(sqInt baseOffset, sqInt reg); -extern sqInt mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj); -static sqInt numSpecialSelectors(void); -static usqInt NoDbgRegParms pcDataForBlockEntryMethod(sqInt blockEntryMcpc, sqInt cogMethod); -static sqInt NoDbgRegParms pcDataForAnnotationMcpcBcpcMethod(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *cogMethodArg); -static PrimitiveDescriptor * primitiveGeneratorOrNil(void); -static sqInt NoDbgRegParms registerisInMask(sqInt reg, sqInt mask); -static sqInt NoDbgRegParms v3BlockCodeSize(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt NoDbgRegParms v3LongForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt NoDbgRegParms v3LongBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt NoDbgRegParms v3ShortForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt NoDbgRegParms v4BlockCodeSize(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt NoDbgRegParms v4LongForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt NoDbgRegParms v4LongBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -extern double getCogCodeZoneThreshold(void); -extern sqInt setCogCodeZoneThreshold(double ratio); -static BlockStart * NoDbgRegParms addBlockStartAtnumArgsnumCopiedspan(sqInt bytecodepc, sqInt numArgs, sqInt numCopied, sqInt span); -static void NoDbgRegParms adjustArgumentsForPerform(sqInt numArgs); -static sqInt NoDbgRegParms allocateFloatRegNotConflictingWith(sqInt regMask); -static sqInt NoDbgRegParms allocateRegForStackEntryAtnotConflictingWith(sqInt index, sqInt regMask); -static sqInt NoDbgRegParms allocateRegNotConflictingWith(sqInt regMask); -static sqInt NoDbgRegParms anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n); -static void NoDbgRegParms beginHighLevelCall(sqInt alignment); -extern void callCogCodePopReceiverArg0Regs(void); -extern void callCogCodePopReceiverArg1Arg0Regs(void); -static sqInt callSwitchToCStack(void); -static void callSwitchToSmalltalkStack(void); -static sqInt NoDbgRegParms compileAbstractInstructionsFromthrough(sqInt start, sqInt end); -static sqInt compileBlockBodies(void); -static void NoDbgRegParms compileBlockFrameBuild(BlockStart *blockStart); -static void NoDbgRegParms compileBlockFramelessEntry(BlockStart *blockStart); -static CogMethod * NoDbgRegParms compileCogFullBlockMethod(sqInt numCopied); -static CogMethod * NoDbgRegParms compileCogMethod(sqInt selector); -static sqInt compileEntireMethod(void); -static void compileFrameBuild(void); -static void NoDbgRegParms compileFullBlockFramelessEntry(sqInt numCopied); -static void NoDbgRegParms compileFullBlockMethodFrameBuild(sqInt numCopied); -#if IMMUTABILITY -static void compileTwoPathFrameBuild(void); -#endif /* IMMUTABILITY */ -static void compileTwoPathFramelessInit(void); -static sqInt NoDbgRegParms cPICMissTrampolineFor(sqInt numArgs); -static sqInt doubleExtendedDoAnythingBytecode(void); -static sqInt duplicateTopBytecode(void); -static void endHighLevelCallWithCleanup(void); -static void endHighLevelCallWithoutCleanup(void); -static BytecodeFixup * NoDbgRegParms ensureFixupAt(sqInt targetPC); -static BytecodeFixup * NoDbgRegParms ensureNonMergeFixupAt(sqInt targetPC); -static void ensureReceiverResultRegContainsSelf(void); -static void NoDbgRegParms evaluateat(BytecodeDescriptor *descriptor, sqInt pc); -static sqInt NoDbgRegParms eventualTargetOf(sqInt targetBytecodePC); -static sqInt NoDbgRegParms freeAnyFloatRegNotConflictingWith(sqInt regMask); -static sqInt NoDbgRegParms freeAnyRegNotConflictingWith(sqInt regMask); -static sqInt genBlockReturn(void); -static void (*genCallPICEnilopmartNumArgs(sqInt numArgs))(void) ; -static sqInt genCallPrimitiveBytecode(void); -static sqInt genExternalizePointersForPrimitiveCall(void); -static AbstractInstruction * genExternalizeStackPointerForFastPrimitiveCall(void); -static sqInt genExtPushClosureBytecode(void); -static sqInt genExtPushFullClosureBytecode(void); -static void generateEnilopmarts(void); -static sqInt NoDbgRegParms generateInstructionsAt(sqInt eventualAbsoluteAddress); -static void generateMissAbortTrampolines(void); -static void generateSendTrampolines(void); -static void generateTracingTrampolines(void); -static sqInt NoDbgRegParms genForwardersInlinedIdenticalOrNotIf(sqInt orNot); -static sqInt NoDbgRegParms genIdenticalNoBranchArgIsConstantrcvrIsConstantargRegrcvrRegorNotIf(sqInt argIsConstant, sqInt rcvrIsConstant, sqInt argReg, sqInt rcvrRegOrNone, sqInt orNot); -static sqInt NoDbgRegParms genInlinedIdenticalOrNotIf(sqInt orNot); -static sqInt NoDbgRegParms genJumpBackTo(sqInt targetBytecodePC); -static sqInt NoDbgRegParms genJumpIfto(sqInt boolean, sqInt targetBytecodePC); -static sqInt NoDbgRegParms genJumpTo(sqInt targetBytecodePC); -static sqInt NoDbgRegParms genLowcodeBinaryInlinePrimitive(sqInt prim); -static sqInt NoDbgRegParms genLowcodeNullaryInlinePrimitive(sqInt prim); -static sqInt NoDbgRegParms genLowcodeTrinaryInlinePrimitive(sqInt prim); -static sqInt NoDbgRegParms genLowcodeUnaryInlinePrimitive2(sqInt prim); -static sqInt NoDbgRegParms genLowcodeUnaryInlinePrimitive3(sqInt prim); -static sqInt NoDbgRegParms genLowcodeUnaryInlinePrimitive4(sqInt prim); -static sqInt NoDbgRegParms genLowcodeUnaryInlinePrimitive5(sqInt prim); -static sqInt NoDbgRegParms genLowcodeUnaryInlinePrimitive(sqInt prim); -static sqInt NoDbgRegParms genMarshalledSendnumArgssendTable(sqInt selectorIndex, sqInt numArgs, sqInt *sendTable); -static usqInt NoDbgRegParms genMethodAbortTrampolineFor(sqInt numArgs); -static usqInt NoDbgRegParms genPICAbortTrampolineFor(sqInt numArgs); -static usqInt NoDbgRegParms genPICMissTrampolineFor(sqInt numArgs); -static sqInt genPopStackBytecode(void); -static sqInt genPrimitiveClosureValue(void); -static sqInt genPrimitiveFullClosureValue(void); -static sqInt genPrimitivePerform(void); -static sqInt genPushActiveContextBytecode(void); -static sqInt genPushClosureCopyCopiedValuesBytecode(void); -static sqInt NoDbgRegParms genPushLiteralIndex(sqInt literalIndex); -static sqInt NoDbgRegParms genPushLiteralVariable(sqInt literalIndex); -static sqInt NoDbgRegParms genPushLiteral(sqInt literal); -static sqInt NoDbgRegParms genPushMaybeContextReceiverVariable(sqInt slotIndex); -static sqInt genPushNewArrayBytecode(void); -static sqInt genPushReceiverBytecode(void); -static sqInt NoDbgRegParms genPushReceiverVariable(sqInt index); -static void genPushRegisterArgs(void); -static sqInt genPushRemoteTempLongBytecode(void); -static sqInt NoDbgRegParms genPushTemporaryVariable(sqInt index); -static sqInt genReturnReceiver(void); -static sqInt genReturnTopFromBlock(void); -static sqInt genReturnTopFromMethod(void); -static sqInt NoDbgRegParms genSendDirectedSupernumArgs(sqInt selectorIndex, sqInt numArgs); -static sqInt NoDbgRegParms genSendSupernumArgs(sqInt selectorIndex, sqInt numArgs); -static usqInt NoDbgRegParms genSendTrampolineFornumArgscalledargargargarg(void *aRoutine, sqInt numArgs, char *aString, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3); -static sqInt NoDbgRegParms genSendnumArgs(sqInt selectorIndex, sqInt numArgs); -static sqInt genSpecialSelectorArithmetic(void); -static sqInt genSpecialSelectorClass(void); -static sqInt genSpecialSelectorComparison(void); -static sqInt genStaticallyResolvedSpecialSelectorComparison(void); -static sqInt NoDbgRegParms genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt litVarIndex, sqInt needsStoreCheck, sqInt needsImmCheck); -static sqInt NoDbgRegParms genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt slotIndex, sqInt needsStoreCheck, sqInt needsImmCheck); -static sqInt NoDbgRegParms genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt slotIndex, sqInt needsStoreCheck, sqInt needsImmCheck); -static sqInt NoDbgRegParms genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt remoteTempIndex, sqInt needsStoreCheck); -static sqInt NoDbgRegParms genStorePopTemporaryVariable(sqInt popBoolean, sqInt tempIndex); -static sqInt genUpArrowReturn(void); -static sqInt NoDbgRegParms genVanillaInlinedIdenticalOrNotIf(sqInt orNot); -static void NoDbgRegParms initSimStackForFramefulMethod(sqInt startpc); -static void NoDbgRegParms initSimStackForFramelessBlock(sqInt startpc); -static void NoDbgRegParms initSimStackForFramelessMethod(sqInt startpc); -static sqInt NoDbgRegParms isNonForwarderReceiver(sqInt reg); -static void leaveNativeFrame(void); -static sqInt liveFloatRegisters(void); -static sqInt liveRegisters(void); -static sqInt NoDbgRegParms mapDeadDescriptorIfNeeded(BytecodeDescriptor *descriptor); -static void NoDbgRegParms marshallSendArguments(sqInt numArgs); -static sqInt maybeCompilingFirstPassOfBlockWithInitialPushNil(void); -static sqInt NoDbgRegParms mergeWithFixupIfRequired(BytecodeFixup *fixup); -static sqInt NoDbgRegParms methodAbortTrampolineFor(sqInt numArgs); -static sqInt methodFoundInvalidPostScan(void); -static sqInt NoDbgRegParms needsFrameIfMod16GENumArgs(sqInt stackDelta); -static sqInt NoDbgRegParms needsFrameIfStackGreaterThanOne(sqInt stackDelta); -static sqInt NoDbgRegParms numberOfSpillsInTopNItems(sqInt n); -static sqInt NoDbgRegParms picAbortTrampolineFor(sqInt numArgs); -static sqInt prevInstIsPCAnnotated(void); -static sqInt receiverIsInReceiverResultReg(void); -static void NoDbgRegParms reinitializeFixupsFromthrough(sqInt start, sqInt end); -static sqInt NoDbgRegParms scanBlock(BlockStart *blockStart); -static sqInt scanMethod(void); -static sqInt NoDbgRegParms squeakV3orSistaV1PushNilSizenumInitialNils(sqInt aMethodObj, sqInt numInitialNils); -static sqInt NoDbgRegParms squeakV3orSistaV1NumPushNils(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static void NoDbgRegParms ssAllocateRequiredFloatRegMaskupThroughupThroughNative(sqInt requiredRegsMask, sqInt stackPtr, sqInt nativeStackPtr); -static void NoDbgRegParms ssAllocateRequiredFloatReg(sqInt requiredReg); -static void NoDbgRegParms ssAllocateRequiredRegMaskupThroughupThroughNative(sqInt requiredRegsMask, sqInt stackPtr, sqInt nativeStackPtr); -static void NoDbgRegParms ssFlushUpThroughReceiverVariable(sqInt slotIndex); -static void NoDbgRegParms ssFlushUpThroughTemporaryVariable(sqInt tempIndex); -static void NoDbgRegParms ssNativeFlushTo(sqInt index); -static void NoDbgRegParms ssNativePop(sqInt n); -static void NoDbgRegParms ssNativePush(sqInt n); -static CogSimStackNativeEntry * ssNativeTop(void); -static CogSimStackNativeEntry * NoDbgRegParms ssNativeValue(sqInt n); -static void NoDbgRegParms ssPopNativeSize(sqInt popSize); -static void NoDbgRegParms ssPop(sqInt n); -static sqInt NoDbgRegParms ssPushAnnotatedConstant(sqInt literal); -static sqInt NoDbgRegParms ssPushBaseoffset(sqInt reg, sqInt offset); -static sqInt NoDbgRegParms ssPushConstant(sqInt literal); -static sqInt NoDbgRegParms ssPushDesc(SimStackEntry simStackEntry); -static sqInt NoDbgRegParms ssPushNativeConstantFloat32(float aFloat32); -static sqInt NoDbgRegParms ssPushNativeConstantFloat64(double aFloat64); -static sqInt NoDbgRegParms ssPushNativeConstantInt32(sqInt anInt32); -static sqInt NoDbgRegParms ssPushNativeConstantInt64(sqLong anInt64); -static sqInt NoDbgRegParms ssPushNativeConstantPointer(sqInt aNativePointer); -static sqInt NoDbgRegParms ssPushNativeRegisterDoubleFloat(sqInt reg); -static sqInt NoDbgRegParms ssPushNativeRegisterSingleFloat(sqInt reg); -static sqInt NoDbgRegParms ssPushNativeRegister(sqInt reg); -static sqInt NoDbgRegParms ssPushNativeRegistersecondRegister(sqInt reg, sqInt secondReg); -static sqInt NoDbgRegParms ssPushRegister(sqInt reg); -static void NoDbgRegParms ssPush(sqInt n); -static SimStackEntry ssSelfDescriptor(void); -static void NoDbgRegParms ssStoreAndReplacePoptoReg(sqInt popBoolean, sqInt reg); -static sqInt NoDbgRegParms ssStorePoptoPreferredReg(sqInt popBoolean, sqInt preferredReg); -static void NoDbgRegParms ssStorePoptoReg(sqInt popBoolean, sqInt reg); -static CogSimStackEntry * ssTop(void); -static CogSimStackEntry * NoDbgRegParms ssValue(sqInt n); -static sqInt NoDbgRegParms stackEntryIsBoolean(CogSimStackEntry *simStackEntry); -static sqInt tempsValidAndVolatileEntriesSpilled(void); -static sqInt NoDbgRegParms tryCollapseTempVectorInitializationOfSize(sqInt slots); -static sqInt violatesEnsureSpilledSpillAssert(void); -static void voidReceiverResultRegContainsSelf(void); - - -/*** Variables ***/ -static AbstractInstruction * abstractOpcodes; -static usqInt allocationThreshold; -static usqInt baseAddress; -static sqInt blockCount; -static AbstractInstruction * blockEntryLabel; -static AbstractInstruction * blockEntryNoContextSwitch; -static BlockStart * blockStarts; -static sqInt breakBlock; -static sqInt breakMethod; -static sqInt byte0; -static sqInt byte1; -static sqInt byte2; -static sqInt byte3; -static sqInt bytecodePC; -static sqInt bytecodeSetOffset; -static sqInt ceByteSizeOfTrampoline; -static sqInt ceCPICMissTrampoline; -static sqInt ceFetchContextInstVarTrampoline; -static sqInt ceFFICalloutTrampoline; -static sqInt ceFloatObjectOfTrampoline; -static sqInt ceFloatValueOfTrampoline; -static sqInt ceFlushICache; -static sqInt ceFreeTrampoline; -static sqInt ceInlineNewHashTrampoline; -static sqInt ceInstantiateClassIndexableSizeTrampoline; -static sqInt ceInstantiateClassTrampoline; -static sqInt ceLargeActiveContextInBlockTrampoline; -static sqInt ceLargeActiveContextInFullBlockTrampoline; -static sqInt ceLargeActiveContextInMethodTrampoline; -static sqInt ceMallocTrampoline; -static sqInt ceMethodAbortTrampoline; -static sqInt ceNewHashTrampoline; -static sqInt ceNonLocalReturnTrampoline; -static sqInt cePICAbortTrampoline; -static sqInt cePositive32BitIntegerTrampoline; -static sqInt cePositive32BitValueOfTrampoline; -static sqInt cePositive64BitIntegerTrampoline; -static sqInt cePositive64BitValueOfTrampoline; -static sqInt cePrimReturnEnterCogCode; -static sqInt cePrimReturnEnterCogCodeProfiling; -static sqInt ceReapAndResetErrorCodeTrampoline; -static sqInt ceScheduleScavengeTrampoline; -static sqInt ceSendMustBeBooleanAddFalseTrampoline; -static sqInt ceSendMustBeBooleanAddTrueTrampoline; -static sqInt ceSigned32BitIntegerTrampoline; -static sqInt ceSigned32BitValueOfTrampoline; -static sqInt ceSigned64BitIntegerTrampoline; -static sqInt ceSigned64BitValueOfTrampoline; -static sqInt ceSmallActiveContextInBlockTrampoline; -static sqInt ceSmallActiveContextInFullBlockTrampoline; -static sqInt ceSmallActiveContextInMethodTrampoline; -static sqInt ceStoreCheckContextReceiverTrampoline; -static sqInt ceStoreCheckTrampoline; -static sqInt ceStoreContextInstVarTrampoline; -static sqInt ceTraceBlockActivationTrampoline; -static sqInt ceTraceLinkedSendTrampoline; -static sqInt ceTraceStoreTrampoline; -static sqInt checkedEntryAlignment; -static sqInt closedPICSize; -static sqInt codeBase; -static sqInt codeModified; -static sqInt cogConstituentIndex; -static sqInt compactionInProgress; -static sqInt compilationPass; -static sqInt compilationTrace; -static sqInt cPICCaseSize; -static sqInt cPICEndOfCodeOffset; -static sqInt cPICEndSize; -static CogMethod * cPICPrototype; -static const int cStackAlignment = STACK_ALIGN_BYTES; -static sqInt currentCallCleanUpSize; -static sqInt deadCode; -static sqInt debugBytecodePointers; -static sqInt debugFixupBreaks; -static sqInt debugOpcodeIndices; -static sqInt debugStackPointers; -static sqInt directedSendUsesBinding; -static sqInt directedSuperBindingSendTrampolines[NumSendTrampolines]; -static sqInt directedSuperSendTrampolines[NumSendTrampolines]; -static sqInt disassemblingMethod; -static AbstractInstruction * endCPICCase0; -static sqInt endPC; -static AbstractInstruction * entry; -static sqInt entryPointMask; -static CogMethod * enumeratingCogMethod; -static sqInt expectedFPAlignment; -static sqInt expectedSPAlignment; -static sqInt extA; -static sqInt extB; -static sqInt firstCPICCaseOffset; -static sqInt firstSend; -static BytecodeFixup * fixups; -static AbstractInstruction * fullBlockEntry; -static AbstractInstruction * fullBlockNoContextSwitchEntry; -static BytecodeDescriptor generatorTable[512] = { - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushReceiverBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantTrueBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantFalseBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantNilBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushQuickIntegerConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushQuickIntegerConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushQuickIntegerConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushQuickIntegerConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genReturnReceiver, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnTrue, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnFalse, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnNil, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnTopFromMethod, 0, needsFrameIfInBlock, -1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnTopFromBlock, 0, needsFrameNever, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { extendedPushBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { extendedStoreBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 0, 0 }, - { extendedStoreAndPopBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 0, 0 }, - { genExtendedSendBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { doubleExtendedDoAnythingBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genExtendedSuperBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0 }, - { genSecondExtendedSendBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genPopStackBytecode, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { duplicateTopBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushActiveContextBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushNewArrayBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genCallPrimitiveBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushClosureCopyCopiedValuesBytecode, v3BlockCodeSize, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongUnconditionalBackwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongUnconditionalBackwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongUnconditionalBackwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongUnconditionalBackwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongUnconditionalForwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genLongUnconditionalForwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genLongUnconditionalForwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genLongUnconditionalForwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genLongJumpIfTrue, v3LongForwardBranchDistance, 0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongJumpIfTrue, v3LongForwardBranchDistance, 0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongJumpIfTrue, v3LongForwardBranchDistance, 0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongJumpIfTrue, v3LongForwardBranchDistance, 0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongJumpIfFalse, v3LongForwardBranchDistance, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongJumpIfFalse, v3LongForwardBranchDistance, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongJumpIfFalse, v3LongForwardBranchDistance, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongJumpIfFalse, v3LongForwardBranchDistance, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, AddRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, SubRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpLess, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpGreater, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpLessOrEqual, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpGreaterOrEqual, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpZero, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpNonZero, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, AndRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, OrRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorEqualsEquals, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorClass, 0, needsFrameIfStackGreaterThanOne, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorNotEqualsEquals, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushReceiverBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantTrueBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantFalseBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantNilBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantZeroBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantOneBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtPushPseudoVariable, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { duplicateTopBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genReturnReceiver, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnTrue, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnFalse, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnNil, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnTopFromMethod, 0, needsFrameIfInBlock, -1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnNilFromBlock, 0, needsFrameNever, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, - { genReturnTopFromBlock, 0, needsFrameNever, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, - { genExtNopBytecode, 0, needsFrameNever, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, AddRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, SubRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpLess, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpGreater, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpLessOrEqual, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpGreaterOrEqual, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpZero, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpNonZero, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, AndRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, OrRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorEqualsEquals, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorClass, 0, needsFrameIfStackGreaterThanOne, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorNotEqualsEquals, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPopStackBytecode, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genUnconditionalTrapBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { extABytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { extBBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genExtPushReceiverVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genExtPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtPushLiteralBytecode, 0, needsFrameNever, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genLongPushTemporaryVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushNewArrayBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtPushIntegerBytecode, 0, needsFrameNever, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtPushCharacterBytecode, 0, needsFrameNever, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtSendBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genExtSendSuperBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genCallMappedInlinedPrimitive, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 }, - { genExtUnconditionalJump, v4LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genExtJumpIfTrue, v4LongBranchDistance, 0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genExtJumpIfFalse, v4LongBranchDistance, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genExtStoreAndPopReceiverVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 0, 0 }, - { genExtStoreAndPopLiteralVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 0, 0, 0 }, - { genLongStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtStoreReceiverVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 0, 0 }, - { genExtStoreLiteralVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 0, 0, 0 }, - { genLongStoreTemporaryVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genCallPrimitiveBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, - { genExtPushFullClosureBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtPushClosureBytecode, v4BlockCodeSize, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genPushRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 } -}; -static sqInt guardPageSize; -static sqInt hasMovableLiteral; -static sqInt hasNativeFrame; -static sqInt hasYoungReferent; -static sqInt inBlock; -static sqInt initialPC; -static sqInt introspectionData; -static sqInt introspectionDataIndex; -static int labelCounter; -static sqInt lastSend; -static usqInt limitAddress; -static sqInt maxLitIndex; -static sqInt methodAbortTrampolines[4]; -static sqInt methodBytesFreedSinceLastCompaction; -static sqInt methodCount; -static sqInt methodHeader; -static sqInt methodObj; -static sqInt methodOrBlockNumArgs; -static sqInt methodOrBlockNumTemps; -static usqIntptr_t minValidCallAddress; -static usqInt mzFreeStart; -static sqInt needsFrame; -static AbstractInstruction * noCheckEntry; -static sqInt numAbstractOpcodes; -static sqInt numExtB; -static usqInt objectReferencesInRuntime[NumObjRefsInRuntime+1]; -static sqInt opcodeIndex; -static CogMethod *openPICList = 0; -static sqInt openPICSize; -static sqInt ordinarySendTrampolines[NumSendTrampolines]; -static sqInt picAbortTrampolines[4]; -static AbstractInstruction * picInterpretAbort; -static sqInt picMissTrampolines[4]; -static AbstractInstruction * picMNUAbort; -static BytecodeDescriptor * prevBCDescriptor; -static PrimitiveDescriptor primitiveGeneratorTable[MaxCompiledPrimitiveIndex+1] = { - { 0, -1 }, - { genPrimitiveAdd, 1 }, - { genPrimitiveSubtract, 1 }, - { genPrimitiveLessThan, 1 }, - { genPrimitiveGreaterThan, 1 }, - { genPrimitiveLessOrEqual, 1 }, - { genPrimitiveGreaterOrEqual, 1 }, - { genPrimitiveEqual, 1 }, - { genPrimitiveNotEqual, 1 }, - { genPrimitiveMultiply, 1 }, - { genPrimitiveDivide, 1 }, - { genPrimitiveMod, 1 }, - { genPrimitiveDiv, 1 }, - { genPrimitiveQuo, 1 }, - { genPrimitiveBitAnd, 1 }, - { genPrimitiveBitOr, 1 }, - { genPrimitiveBitXor, 1 }, - { genPrimitiveBitShift, 1 }, - { genPrimitiveMakePoint, 1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveAt, 1 }, - { genPrimitiveAtPut, 2 }, - { genPrimitiveSize, 0 }, - { genPrimitiveStringAt, 1 }, - { genPrimitiveStringAtPut, 2 }, - { genFastPrimFail, -1 }, - { genFastPrimFail, -1 }, - { genFastPrimFail, -1 }, - { genPrimitiveObjectAt, 1 }, - { 0, -1 }, - { genPrimitiveNew, 0 }, - { genPrimitiveNewWithArg, 1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveIdentityHash, 0 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveNewMethod, 2 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitivePerform, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveStringReplace, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveIdentical, 1 }, - { genPrimitiveClass, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveShallowCopy, 0 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveStringCompareWith, 1 }, - { genPrimitiveHashMultiply, 0 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveIntegerAt, 1 }, - { genPrimitiveIntegerAtPut, 2 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveNotIdentical, 1 }, - { genPrimitiveAsCharacter, -1 }, - { genPrimitiveImmediateAsInteger, 0 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveIdentityHash, 0 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genFastPrimFail, -1 }, - { genFastPrimFail, -1 }, - { 0, -1 }, - { genPrimitiveClosureValue, 0 }, - { genPrimitiveClosureValue, 1 }, - { genPrimitiveClosureValue, 2 }, - { genPrimitiveClosureValue, 3 }, - { genPrimitiveClosureValue, 4 }, - { 0, -1 }, - { genPrimitiveFullClosureValue, -1 }, - { 0, -1 }, - { genPrimitiveFullClosureValue, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveClosureValue, 0 }, - { genPrimitiveClosureValue, 1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveHighBit, 0 } -}; -static sqInt primitiveIndex; -static sqInt processorLock; -static sqInt receiverTags; -static sqInt regArgsHaveBeenPushed; -static sqInt runtimeObjectRefIndex; -static AbstractInstruction * sendMiss; -static sqInt simNativeSpillBase; -static CogSimStackNativeEntry simNativeStack[70]; -static sqInt simNativeStackPtr; -static sqInt simNativeStackSize; -static sqInt simSpillBase; -static SimStackEntry simStack[70]; -static sqInt simStackPtr; -static AbstractInstruction * stackCheckLabel; -static AbstractInstruction * stackOverflowCall; -static sqInt superSendTrampolines[NumSendTrampolines]; -static sqInt tempOop; -static char *trampolineAddresses[NumTrampolines*2]; -static sqInt trampolineTableIndex; -static sqInt uncheckedEntryAlignment; -static usqInt unpairedMethodList; -static sqInt useTwoPaths; -static sqInt varBaseAddress; -static usqInt youngReferrers; -static AbstractInstruction aMethodLabel; -static AbstractInstruction * const backEnd = &aMethodLabel; -#if DUAL_MAPPED_CODE_ZONE -static void (*ceFlushDCache)(usqIntptr_t from, usqIntptr_t to); -#endif -#if IMMUTABILITY -static sqInt ceStoreTrampolines[5];; -#endif -#if DUAL_MAPPED_CODE_ZONE -static sqInt codeToDataDelta; -#else -# define codeToDataDelta 0 -#endif -static AbstractInstruction * const methodLabel = &aMethodLabel; -static float thresholdRatio = 0.5f; -sqInt blockNoContextSwitchOffset; -sqInt breakPC; -sqInt cbEntryOffset; -sqInt cbNoSwitchEntryOffset; -sqInt ceBaseFrameReturnTrampoline; -sqInt ceCannotResumeTrampoline; -sqInt ceCheckForInterruptTrampoline; -sqInt ceReturnToInterpreterTrampoline; -sqInt cFramePointerInUse; -sqInt cmEntryOffset; -sqInt cmNoCheckEntryOffset; -usqInt methodZoneBase; -sqInt missOffset; -int traceFlags = 8 /* prim trace log on by default */; -sqInt traceStores; -void (*ceCall0ArgsPIC)(void); -void (*ceCall1ArgsPIC)(void); -void (*ceCall2ArgsPIC)(void); -void (*ceCallCogCodePopReceiverAndClassRegs)(void); -void (*ceCallCogCodePopReceiverArg0Regs)(void); -void (*ceCallCogCodePopReceiverArg1Arg0Regs)(void); -void (*ceCallCogCodePopReceiverReg)(void); -void (*ceCaptureCStackPointers)(void); -void (*ceEnterCogCodePopReceiverReg)(void); -usqIntptr_t (*ceGetFP)(void); -usqIntptr_t (*ceGetSP)(void); -void (*ceInvokeInterpret)(void); -#if COGMTVM -usqIntptr_t (*ceTryLockVMOwner)(usqIntptr_t); -#endif -void (*realCECallCogCodePopReceiverAndClassRegs)(void); -void (*realCECallCogCodePopReceiverArg0Regs)(void); -void (*realCECallCogCodePopReceiverArg1Arg0Regs)(void); -void (*realCECallCogCodePopReceiverReg)(void); -void (*realCEEnterCogCodePopReceiverReg)(void); - - -/*** Macros ***/ -#define inlineCacheValueForSelectorin(backEnd,selector,aCogMethod) (selector) -#define roundUpToMethodAlignment(ignored,numBytes) ((numBytes) + 7 & -8) -#define cPICNumCases stackCheckOffset -#define cPICNumCasesHack hack hack hack i.e. the getter macro does all the work -#define abstractInstructionAt(index) (&abstractOpcodes[index]) -#define addressIsInInstructions(address) (!((usqInt)(address) & (BytesPerWord-1)) \ - && (address) >= &abstractOpcodes[0] \ - && (address) < &abstractOpcodes[opcodeIndex]) -#define allocateBlockStarts(numBlocks) do { \ - blockStarts = (numBlocks) ? alloca(sizeof(BlockStart) * (numBlocks)) : 0; \ -} while (0) -#define assertValidDualZoneReadAddress(address) 0 -#define assertValidDualZoneWriteAddress(address) 0 -#define backEnd() backEnd -#define blockAlignment() 8 -#define blockStartAt(index) (&blockStarts[index]) -#define breakOnImplicitReceiver() (traceFlags & 64) -#define ceBaseFrameReturnPC() ceBaseFrameReturnTrampoline -#define ceCannotResumePC() ((usqInt)ceCannotResumeTrampoline) -#define ceCheckForInterruptTrampoline() ceCheckForInterruptTrampoline -#define ceReturnToInterpreterPC() ((usqInt)ceReturnToInterpreterTrampoline) -#define codeByteAtput(address,value) byteAtput((address) + codeToDataDelta, value) -#define codeLong32Atput(address,value) long32Atput((address) + codeToDataDelta, value) -#define codeLong64Atput(address,value) long64Atput((address) + codeToDataDelta, value) -#define codeLongAtput(address,value) longAtput((address) + codeToDataDelta, value) -#define codeMemcpy(dest,src,bytes) memcpy(dest,src,bytes) -#define codeMemmove(dest,src,bytes) memmove((char *)(dest)+codeToDataDelta,src,bytes) -#define cr() putchar('\n') -#define entryOffset() cmEntryOffset -#define generatorAt(index) (&generatorTable[index]) -#define getCodeToDataDelta() codeToDataDelta -#define getIsObjectReference() 2 -#define halt() warning("halt") -#define haltmsg(msg) warning("halt: " msg) -#define interpretOffset() missOffset -#define maxCogCodeSize() (16*1024*1024) -#define maybeBreakGeneratingFromto(address,end) 0 -#define maybeBreakGeneratingInstructionWithIndex(i) 0 -#define maybeHaltIfDebugPC() 0 -#define methodLabel() methodLabel -#define methodZoneBase() methodZoneBase -#define minCallAddress() minValidCallAddress -#define minCogMethodAddress() methodZoneBase -#define noCheckEntryOffset() cmNoCheckEntryOffset -#define noContextSwitchBlockEntryOffset() blockNoContextSwitchOffset -#define notYetImplemented() warning("not yet implemented") -#define null 0 -#define printNum(n) printf("%" PRIdSQINT, (sqInt) (n)) -#define printOnTrace() (traceFlags & 1) -#define print(aString) printf("%s", aString) -#define recordBlockTrace() (traceFlags & 4) -#define recordEventTrace() (traceFlags & 16) -#define recordFastCCallPrimTrace() (traceFlags & 512) -#define recordOverflowTrace() (traceFlags & 32) -#define recordPrimTrace() (traceFlags & 8) -#define recordSendTrace() (traceFlags & 2) -#define reportError(n) warning("compilation error") -#define setHasMovableLiteral(b) (hasMovableLiteral = (b)) -#define setHasYoungReferent(b) (hasYoungReferent = (b)) -#define tryLockVMOwnerTo(value) ceTryLockVMOwner(value) -#define varBaseAddress() varBaseAddress -#define nextOpenPIC methodObject -#define nextOpenPICHack hack hack hack i.e. the getter macro does all the work -#define freeStart() mzFreeStart -#define limitZony() ((CogMethod *)mzFreeStart) -#define methodBytesFreedSinceLastCompaction() methodBytesFreedSinceLastCompaction -#define youngReferrers() youngReferrers -#define flushDCacheFromto(me,startAddress,endAddress) 0 -#define flushICacheFromto(me,startAddress,endAddress) cacheflush((char*) startAddress, endAddress - startAddress, ICACHE) -#define maybeConstant(sse) ((sse)->constant) -#define fullBlockEntryOffset() cbEntryOffset -#define fullBlockNoContextSwitchEntryOffset() cbNoSwitchEntryOffset -#define fixupAtIndex(index) (&fixups[index]) -#define simNativeStackAt(index) (simNativeStack + (index)) -#define simSelf() simStack -#define simStackAt(index) (simStack + (index)) -#define traceDescriptor(ign) 0 -#define traceFixupmerge(igu,ana) 0 -#define traceMerge(ign) 0 -#define traceSimStack() 0 -#define traceSpill(ign) 0 -#define allocatype(numElements, elementType) alloca((numElements)*sizeof(elementType)) -#define numElementsIn(anArray) (sizeof(anArray)/sizeof(anArray[0])) -#define oopisGreaterThanOrEqualTo(anOop,otherOop) ((usqInt)(anOop) >= (usqInt)(otherOop)) -#define oopisGreaterThanOrEqualToandLessThanOrEqualTo(anOop,baseOop,limitOop) ((usqInt)(anOop) >= (usqInt)(baseOop) && (usqInt)(anOop) <= (usqInt)(limitOop)) -#define oopisGreaterThanOrEqualToandLessThan(anOop,baseOop,limitOop) ((usqInt)(anOop) >= (usqInt)(baseOop) && (usqInt)(anOop) < (usqInt)(limitOop)) -#define oopisGreaterThan(anOop,otherOop) ((usqInt)(anOop) > (usqInt)(otherOop)) -#define oopisGreaterThanandLessThan(anOop,baseOop,limitOop) ((usqInt)(anOop) > (usqInt)(baseOop) && (usqInt)(anOop) < (usqInt)(limitOop)) -#define oopisLessThanOrEqualTo(anOop,otherOop) ((usqInt)(anOop) <= (usqInt)(otherOop)) -#define oopisLessThan(anOop,otherOop) ((usqInt)(anOop) < (usqInt)(otherOop)) - - - /* CogAbstractInstruction>>#addDependent: */ -static AbstractInstruction * NoDbgRegParms -addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *anInstruction) -{ - if (!(((self_in_addDependent->dependent)) == null)) { - (anInstruction->dependent = (self_in_addDependent->dependent)); - } - return ((self_in_addDependent->dependent) = anInstruction); -} - - -/* Answer an unused abstract register in the liveRegMask. - Subclasses with more registers can override to answer them. */ - - /* CogAbstractInstruction>>#availableFloatRegisterOrNoneFor: */ -static sqInt NoDbgRegParms -availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask) -{ - if (!(((liveRegsMask & (1U << DPFPReg0)) != 0))) { - return DPFPReg0; - } - if (!(((liveRegsMask & (1U << DPFPReg1)) != 0))) { - return DPFPReg1; - } - if (!(((liveRegsMask & (1U << DPFPReg2)) != 0))) { - return DPFPReg2; - } - if (!(((liveRegsMask & (1U << DPFPReg3)) != 0))) { - return DPFPReg3; - } - if (!(((liveRegsMask & (1U << DPFPReg4)) != 0))) { - return DPFPReg4; - } - if (!(((liveRegsMask & (1U << DPFPReg5)) != 0))) { - return DPFPReg5; - } - if (!(((liveRegsMask & (1U << DPFPReg6)) != 0))) { - return DPFPReg6; - } - if (!(((liveRegsMask & (1U << DPFPReg7)) != 0))) { - return DPFPReg7; - } - return NoReg; -} - - -/* Answer an unused abstract register in the liveRegMask. - Subclasses with more registers can override to answer them. - N.B. Do /not/ allocate TempReg. */ - - /* CogAbstractInstruction>>#availableRegisterOrNoneFor: */ -static sqInt NoDbgRegParms -availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask) -{ - if (!(((liveRegsMask & (1U << Arg1Reg)) != 0))) { - return Arg1Reg; - } - if (!(((liveRegsMask & (1U << Arg0Reg)) != 0))) { - return Arg0Reg; - } - if (!(((liveRegsMask & (1U << SendNumArgsReg)) != 0))) { - return SendNumArgsReg; - } - if (!(((liveRegsMask & (1U << ClassReg)) != 0))) { - return ClassReg; - } - if (!(((liveRegsMask & (1U << ReceiverResultReg)) != 0))) { - return ReceiverResultReg; - } - return NoReg; -} - - -/* For out-of-line literal support, clone a literal from a literal. */ - - /* CogAbstractInstruction>>#cloneLiteralFrom: */ -static void NoDbgRegParms -cloneLiteralFrom(AbstractInstruction * self_in_cloneLiteralFrom, AbstractInstruction *existingLiteral) -{ - assert((((existingLiteral->opcode)) == Literal) - && ((((self_in_cloneLiteralFrom->dependent)) == null) - && (((self_in_cloneLiteralFrom->address)) == null))); - (self_in_cloneLiteralFrom->opcode) = Literal; - (self_in_cloneLiteralFrom->annotation) = (existingLiteral->annotation); - ((self_in_cloneLiteralFrom->operands))[0] = (((existingLiteral->operands))[0]); - ((self_in_cloneLiteralFrom->operands))[1] = (((existingLiteral->operands))[1]); - ((self_in_cloneLiteralFrom->operands))[2] = (((existingLiteral->operands))[2]); -} - - -/* Load the stack pointer register with that of the C stack, effecting - a switch to the C stack. Used when machine code calls into the - CoInterpreter run-time (e.g. to invoke interpreter primitives). */ - - /* CogAbstractInstruction>>#genLoadCStackPointer */ -static sqInt NoDbgRegParms -genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer) -{ - AbstractInstruction *anInstruction; - - /* begin checkLiteral:forInstruction: */ - cStackPointerAddress(); - anInstruction = genoperandoperand(MoveAwR, cStackPointerAddress(), NativeSPReg); - return 0; -} - - -/* Load the frame and stack pointer registers with those of the C stack, - effecting a switch to the C stack. Used when machine code calls into - the CoInterpreter run-time (e.g. to invoke interpreter primitives). - N.B. CoInterpreter stack layout dictates that the stack pointer should be - loaded first. - The stack zone is allocated on the C stack before the interpreter runs and - hence before CStackPointer and CFramePointer are captured. So when running - in machine - code the native stack pointer and frame pointer appear to be on a colder - part of the - stack to CStackPointer and CFramePointer. When CStackPointerhas been set - and the frame pointer is still in machine code the current frame looks - like it has lots of - stack. If the frame pointer was set to CFramePointer before hand then it - would be beyond the stack pointer for that one instruction. */ - - /* CogAbstractInstruction>>#genLoadCStackPointers */ -static sqInt NoDbgRegParms -genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkLiteral:forInstruction: */ - cStackPointerAddress(); - anInstruction = genoperandoperand(MoveAwR, cStackPointerAddress(), NativeSPReg); - /* begin checkLiteral:forInstruction: */ - cFramePointerAddress(); - anInstruction1 = genoperandoperand(MoveAwR, cFramePointerAddress(), FPReg); - return 0; -} - - -/* Switch back to the Smalltalk stack. Assign SPReg first - because typically it is used immediately afterwards. */ - - /* CogAbstractInstruction>>#genLoadStackPointers */ -static sqInt NoDbgRegParms -genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkLiteral:forInstruction: */ - stackPointerAddress(); - anInstruction = genoperandoperand(MoveAwR, stackPointerAddress(), SPReg); - /* begin checkLiteral:forInstruction: */ - framePointerAddress(); - anInstruction1 = genoperandoperand(MoveAwR, framePointerAddress(), FPReg); - return 0; -} - - -/* Switch back to the Smalltalk stack where there may be a C return address - on top of stack below - the last primitive argument. Assign SPReg first because typically it is - used immediately afterwards. - */ - - /* CogAbstractInstruction>>#genLoadStackPointersForFastPrimCall: */ -static sqInt NoDbgRegParms -genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg) -{ - genLoadStackPointers(self_in_genLoadStackPointersForFastPrimCall); - return 0; -} - - -/* Save the frame and stack pointer registers to the framePointer - and stackPointer variables. Used to save the machine code frame - for use by the run-time when calling into the CoInterpreter run-time. */ - - /* CogAbstractInstruction>>#genSaveStackPointers */ -static sqInt NoDbgRegParms -genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkLiteral:forInstruction: */ - framePointerAddress(); - anInstruction = genoperandoperand(MoveRAw, FPReg, framePointerAddress()); - /* begin checkLiteral:forInstruction: */ - stackPointerAddress(); - anInstruction1 = genoperandoperand(MoveRAw, SPReg, stackPointerAddress()); - return 0; -} - - -/* Generic register swap code. Subclasses for processors that have a true - exchange operation will override to use it. */ - - /* CogAbstractInstruction>>#genSwapR:R:Scratch: */ -static AbstractInstruction * NoDbgRegParms -genSwapRRScratch(AbstractInstruction * self_in_genSwapRRScratch, sqInt regA, sqInt regB, sqInt regTmp) -{ - AbstractInstruction *first; - - first = genoperandoperand(MoveRR, regA, regTmp); - genoperandoperand(MoveRR, regB, regA); - genoperandoperand(MoveRR, TempReg, regB); - return first; -} - - /* CogAbstractInstruction>>#genWriteCResultIntoReg: */ -static void NoDbgRegParms -genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister) -{ - if ((abstractRegister != NoReg) - && (abstractRegister != ABIResultReg)) { - genoperandoperand(MoveRR, ABIResultReg, abstractRegister); - } -} - - /* CogAbstractInstruction>>#genWriteCSecondResultIntoReg: */ -static void NoDbgRegParms -genWriteCSecondResultIntoReg(AbstractInstruction * self_in_genWriteCSecondResultIntoReg, sqInt abstractRegister) -{ - if ((abstractRegister != NoReg) - && (abstractRegister != (cResultRegisterHigh()))) { - genoperandoperand(MoveRR, cResultRegisterHigh(), abstractRegister); - } -} - - -/* For out-of-line literal support, initialize a sharable literal. */ - - /* CogAbstractInstruction>>#initializeSharableLiteral: */ -static void NoDbgRegParms -initializeSharableLiteral(AbstractInstruction * self_in_initializeSharableLiteral, sqInt literal) -{ - (self_in_initializeSharableLiteral->opcode) = Literal; - - /* separate := nil for Slang */ - (self_in_initializeSharableLiteral->annotation) = null; - (self_in_initializeSharableLiteral->address) = null; - (self_in_initializeSharableLiteral->dependent) = null; - ((self_in_initializeSharableLiteral->operands))[0] = literal; - ((self_in_initializeSharableLiteral->operands))[1] = (1 + (((sqInt)((usqInt)(BytesPerOop) << 1)))); - ((self_in_initializeSharableLiteral->operands))[2] = -1; -} - - -/* For out-of-line literal support, initialize an unsharable literal. */ - - /* CogAbstractInstruction>>#initializeUniqueLiteral: */ -static void NoDbgRegParms -initializeUniqueLiteral(AbstractInstruction * self_in_initializeUniqueLiteral, sqInt literal) -{ - (self_in_initializeUniqueLiteral->opcode) = Literal; - - /* separate := nil for Slang */ - (self_in_initializeUniqueLiteral->annotation) = null; - (self_in_initializeUniqueLiteral->address) = null; - (self_in_initializeUniqueLiteral->dependent) = null; - ((self_in_initializeUniqueLiteral->operands))[0] = literal; - ((self_in_initializeUniqueLiteral->operands))[1] = (0 + (((sqInt)((usqInt)(BytesPerOop) << 1)))); - ((self_in_initializeUniqueLiteral->operands))[2] = -1; -} - - -/* Answer if an address can be accessed using the offset in a MoveMw:r:R: or - similar instruction. - We assume this is true for 32-bit processors and expect 64-bit processors - to answer false - for values in the interpreter or the object memory. */ - - /* CogAbstractInstruction>>#isWithinMwOffsetRange: */ -static sqInt NoDbgRegParms -isWithinMwOffsetRange(AbstractInstruction * self_in_isWithinMwOffsetRange, sqInt anAddress) -{ - return 1; -} - - -/* Set the target of a jump instruction. These all have the target in the - first operand. */ - - /* CogAbstractInstruction>>#jmpTarget: */ -static AbstractInstruction * NoDbgRegParms -jmpTarget(AbstractInstruction * self_in_jmpTarget, AbstractInstruction *anAbstractInstruction) -{ - ((self_in_jmpTarget->operands))[0] = (((usqInt)anAbstractInstruction)); - return anAbstractInstruction; -} - - /* CogAbstractInstruction>>#resolveJumpTarget */ -static void NoDbgRegParms -resolveJumpTarget(AbstractInstruction * self_in_resolveJumpTarget) -{ - BytecodeFixup *fixup; - - assert(isJump(self_in_resolveJumpTarget)); - fixup = ((BytecodeFixup *) (((self_in_resolveJumpTarget->operands))[0])); - if (addressIsInFixups(fixup)) { - assert(addressIsInInstructions((fixup->targetInstruction))); - jmpTarget(self_in_resolveJumpTarget, (fixup->targetInstruction)); - } -} - - -/* Rewrite a CallFull instruction to call a different target. This variant is - used to rewrite cached primitive calls. - Answer the extent of the code change which is used to compute the range of - the icache to flush. - This defaults to rewriteCallAt:target:; processors that differentiate - between Call and CallFull will override. */ - - /* CogAbstractInstruction>>#rewriteCallFullAt:target: */ -static sqInt NoDbgRegParms -rewriteCallFullAttarget(AbstractInstruction * self_in_rewriteCallFullAttarget, sqInt callSiteReturnAddress, sqInt callTargetAddress) -{ - return rewriteCallAttarget(self_in_rewriteCallFullAttarget, callSiteReturnAddress, callTargetAddress); -} - - -/* Rewrite a JumpFull instruction to jump to a different target. This variant - is used to rewrite cached primitive calls. - Answer the extent of the code change which is used to compute the range of - the icache to flush. - This defaults to rewriteJumpLongAt:target:; processors that differentiate - between Jump and JumpFull will override. */ - - /* CogAbstractInstruction>>#rewriteJumpFullAt:target: */ -static sqInt NoDbgRegParms -rewriteJumpFullAttarget(AbstractInstruction * self_in_rewriteJumpFullAttarget, sqInt callSiteReturnAddress, sqInt callTargetAddress) -{ - return rewriteJumpLongAttarget(self_in_rewriteJumpFullAttarget, callSiteReturnAddress, callTargetAddress); -} - - /* CogBlockMethod>>#cmHomeMethod */ -static CogMethod * NoDbgRegParms -cmHomeMethod(CogBlockMethod * self_in_cmHomeMethod) -{ - return ((self_in_cmHomeMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? ((CogMethod *) self_in_cmHomeMethod) - : ((CogMethod *) ((((usqInt)self_in_cmHomeMethod)) - ((self_in_cmHomeMethod->homeOffset))))); -} - - /* CogBytecodeDescriptor>>#isBranch */ -static sqInt NoDbgRegParms -isBranch(BytecodeDescriptor * self_in_isBranch) -{ - return (((self_in_isBranch->spanFunction)) != null) - && (!((self_in_isBranch->isBlockCreation))); -} - - /* Cogit>>#AddCq:R: */ -static AbstractInstruction * NoDbgRegParms -gAddCqR(sqInt quickConstant, sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, quickConstant, reg); - return anInstruction; -} - - -/* N.B. if the condition codes don't require setting and three address - arithmetic is unavailable, then LoadEffectiveAddressMw:r:R: can be used - instead. - */ - - /* Cogit>>#AddCq:R:R: */ -static AbstractInstruction * NoDbgRegParms -gAddCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction * first; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(AddCqRR, quickConstant, srcReg, destReg); - return anInstruction2; - if (srcReg == destReg) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, quickConstant, destReg); - return anInstruction; - } - first = genoperandoperand(MoveRR, srcReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AddCqR, quickConstant, destReg); - return first; -} - - /* Cogit>>#AndCq:R: */ -static AbstractInstruction * NoDbgRegParms -gAndCqR(sqInt quickConstant, sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, quickConstant, reg); - return anInstruction; -} - - /* Cogit>>#AndCq:R:R: */ -static AbstractInstruction * NoDbgRegParms -gAndCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction * first; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(AndCqRR, quickConstant, srcReg, destReg); - return anInstruction2; - if (srcReg == destReg) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, quickConstant, destReg); - return anInstruction; - } - first = genoperandoperand(MoveRR, srcReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, quickConstant, destReg); - return first; -} - - -/* destReg := (signed)srcReg >> quickConstant */ - - /* Cogit>>#ArithmeticShiftRightCq:R:R: */ -static AbstractInstruction * NoDbgRegParms -gArithmeticShiftRightCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) -{ - AbstractInstruction * first; - - return genoperandoperandoperand(ArithmeticShiftRightCqRR, quickConstant, srcReg, destReg); - first = genoperandoperand(MoveRR, srcReg, destReg); - genoperandoperand(ArithmeticShiftRightCqR, quickConstant, destReg); - return first; -} - - /* Cogit>>#abortOffset */ -sqInt -abortOffset(void) -{ - return missOffset; -} - - /* Cogit>>#addCleanBlockStarts */ -static void -addCleanBlockStarts(void) -{ - sqInt i; - sqInt iLimiT; - sqInt lit; - sqInt startPCOrNil; - - for (i = 1, iLimiT = (literalCountOf(methodObj)); i <= iLimiT; i += 1) { - lit = fetchPointerofObject(i, methodObj); - startPCOrNil = startPCOrNilOfLiteralin(lit, methodObj); - if (!(startPCOrNil == null)) { - maxLitIndex = ((maxLitIndex < i) ? i : maxLitIndex); - addBlockStartAtnumArgsnumCopiedspan(startPCOrNil - 1, argumentCountOfClosure(lit), copiedValueCountOfClosure(lit), spanForCleanBlockStartingAt(startPCOrNil - 1)); - } - } -} - - -/* Perform an integrity/leak check using the heapMap. - Set a bit at each cog method's header. */ - - /* Cogit>>#addCogMethodsToHeapMap */ -void -addCogMethodsToHeapMap(void) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - heapMapAtWordPut(cogMethod, 1); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* Cogit>>#addressIsInCurrentCompilation: */ -static sqInt NoDbgRegParms -addressIsInCurrentCompilation(sqInt address) -{ - return ((((usqInt)address)) >= ((methodLabel->address))) - && ((((usqInt)address)) < ((((youngReferrers()) < (((methodLabel->address)) + MaxMethodSize)) ? (youngReferrers()) : (((methodLabel->address)) + MaxMethodSize)))); -} - - /* Cogit>>#addressIsInFixups: */ -static sqInt NoDbgRegParms -addressIsInFixups(BytecodeFixup *address) -{ - return (BytecodeFixup *)address >= fixups && (BytecodeFixup *)address < (fixups + numAbstractOpcodes); -} - - -/* calculate the end of the n'th case statement - which is complicated - because we have case 1 right at the top of our CPIC and then build up from - the last one. Yes I know this sounds strange, but trust me - I'm an - Engineer, we do things backwards all the emit - */ - - /* Cogit>>#addressOfEndOfCase:inCPIC: */ -static sqInt NoDbgRegParms -addressOfEndOfCaseinCPIC(sqInt n, CogMethod *cPIC) -{ - assert((n >= 1) - && (n <= MaxCPICCases)); - return (n == 1 - ? (((sqInt)cPIC)) + firstCPICCaseOffset - : ((((sqInt)cPIC)) + firstCPICCaseOffset) + (((MaxCPICCases + 1) - n) * cPICCaseSize)); -} - - -/* Align methodZoneBase to that for the start of a method. */ - - /* Cogit>>#alignMethodZoneBase */ -static void -alignMethodZoneBase(void) -{ - usqInt oldBase; - - oldBase = methodZoneBase; - methodZoneBase = roundUpToMethodAlignment(backEnd(), methodZoneBase); - stopsFromto(backEnd, oldBase, methodZoneBase - 1); -} - - /* Cogit>>#alignUptoRoutineBoundary: */ -static sqInt NoDbgRegParms -alignUptoRoutineBoundary(sqInt anAddress) -{ - return (((anAddress + 7) | 7) - 7); -} - - -/* Check that all methods have valid selectors, and that all linked sends are - to valid targets and have valid cache tags - */ - - /* Cogit>>#allMachineCodeObjectReferencesValid */ -static sqInt -allMachineCodeObjectReferencesValid(void) -{ - CogMethod *cogMethod; - sqInt ok; - - ok = 1; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - if (!(asserta(checkValidOopReference((cogMethod->selector))))) { - ok = 0; - } - if (!(asserta((cogMethodDoesntLookKosher(cogMethod)) == 0))) { - ok = 0; - } - } - if ((((cogMethod->cmType)) == CMMethod) - || (((cogMethod->cmType)) == CMOpenPIC)) { - if (!(asserta((mapForperformUntilarg(cogMethod, checkIfValidOopRefAndTargetpccogMethod, cogMethod)) == 0))) { - ok = 0; - } - } - if ((((cogMethod->cmType)) == CMMethod) - && (1)) { - } - if (((cogMethod->cmType)) == CMClosedPIC) { - if (!(asserta(noTargetsFreeInClosedPIC(cogMethod)))) { - ok = 0; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return ok; -} - - /* Cogit>>#allMethodsHaveCorrectHeader */ -static sqInt -allMethodsHaveCorrectHeader(void) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - if (!(((cogMethod->objectHeader)) == (nullHeaderForMachineCodeMethod()))) { - return 0; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return 1; -} - - /* Cogit>>#annotateAbsolutePCRef: */ -static AbstractInstruction * NoDbgRegParms -annotateAbsolutePCRef(AbstractInstruction *abstractInstruction) -{ - (abstractInstruction->annotation = IsAbsPCReference); - return abstractInstruction; -} - - /* Cogit>>#annotateBytecode: */ -static AbstractInstruction * NoDbgRegParms -annotateBytecode(AbstractInstruction *abstractInstruction) -{ - (abstractInstruction->annotation = HasBytecodePC); - return abstractInstruction; -} - - /* Cogit>>#annotate:objRef: */ -static AbstractInstruction * NoDbgRegParms -annotateobjRef(AbstractInstruction *abstractInstruction, sqInt anOop) -{ - if (shouldAnnotateObjectReference(anOop)) { - setHasMovableLiteral(1); - if (isYoungObject(anOop)) { - setHasYoungReferent(1); - } - (abstractInstruction->annotation = IsObjectReference); - } - return abstractInstruction; -} - - /* Cogit>>#assertSaneJumpTarget: */ -static void NoDbgRegParms -assertSaneJumpTarget(AbstractInstruction *jumpTarget) -{ - assert((closedPICSize == null) - || ((openPICSize == null) - || ((addressIsInInstructions(jumpTarget)) - || ((((((usqInt)jumpTarget)) >= codeBase) && ((((usqInt)jumpTarget)) <= ((((sqInt)(limitZony()))) + (((closedPICSize < openPICSize) ? openPICSize : closedPICSize))))))))); -} - - -/* {self firstInvalidDualZoneAddress. self firstInvalidDualZoneAddress + - codeToDataDelta } - */ -/* {self firstInvalidDualZoneAddress hex. (self firstInvalidDualZoneAddress + - codeToDataDelta) hex } - */ -/* {(objectMemory longAt: self firstInvalidDualZoneAddress) hex. - (objectMemory longAt: self firstInvalidDualZoneAddress + codeToDataDelta) - hex } - */ -/* self armDisassembleDualZoneAnomalies */ -/* self armPrintDualZoneAnomalies */ - - /* Cogit>>#assertValidDualZone */ -static void -assertValidDualZone(void) -{ -} - - -/* Answer an unused abstract register in the registerMask, or NoReg if none. */ - - /* Cogit>>#availableRegisterOrNoneIn: */ -static sqInt NoDbgRegParms -availableRegisterOrNoneIn(sqInt liveRegsMask) -{ - sqInt reg; - - if (liveRegsMask != 0) { - for (reg = 0; reg <= 0x1F; reg += 1) { - if (((liveRegsMask & (1U << reg)) != 0)) { - return reg; - } - } - } - return NoReg; -} - - -/* Evaluate binaryFunction with the block start mcpc and supplied arg for - each entry in the block dispatch. If the function answers non-zero answer - the value - it answered. Used to update back-references to the home method in - compaction. */ - - /* Cogit>>#blockDispatchTargetsFor:perform:arg: */ -static sqInt NoDbgRegParms -blockDispatchTargetsForperformarg(CogMethod *cogMethod, usqInt (*binaryFunction)(sqInt mcpc, sqInt arg), sqInt arg) -{ - sqInt blockEntry; - usqInt end; - sqInt pc; - sqInt result; - usqInt targetpc; - - if (((cogMethod->blockEntryOffset)) == 0) { - return null; - } - blockEntry = ((cogMethod->blockEntryOffset)) + (((sqInt)cogMethod)); - pc = blockEntry; - end = (mapEndFor(cogMethod)) - 1; - while (pc < end) { - if (isJumpAt(backEnd, pc)) { - targetpc = jumpTargetPCAt(backEnd, pc); - if (targetpc < blockEntry) { - result = binaryFunction(targetpc, arg); - if (result != 0) { - return result; - } - } - } - pc += 4 /* instructionSizeAt: */; - } - return 0; -} - - -/* Answer the zero-relative bytecode pc matching the machine code pc argument - in cogMethod, given the start of the bytecodes for cogMethod's block or - method object. */ - - /* Cogit>>#bytecodePCFor:startBcpc:in: */ -sqInt -bytecodePCForstartBcpcin(sqInt mcpc, sqInt startbcpc, CogBlockMethod *cogMethod) -{ - sqInt aMethodHeader; - sqInt aMethodHeader1; - sqInt aMethodObj; - sqInt annotation; - sqInt bcpc; - sqInt bsOffset; - sqInt byte; - BytecodeDescriptor *descriptor; - sqInt distance; - sqInt endbcpc; - CogMethod *homeMethod; - sqInt isBackwardBranch; - sqInt isInBlock; - sqInt latestContinuation; - usqInt map; - sqInt mapByte; - usqInt mcpc1; - sqInt nExts; - sqInt nextBcpc; - sqInt result; - sqInt targetPC; - - latestContinuation = 0; - /* begin mapFor:bcpc:performUntil:arg: */ - assert(((cogMethod->stackCheckOffset)) > 0); - - /* The stack check maps to the start of the first bytecode, - the first bytecode being effectively after frame build. */ - mcpc1 = (((usqInt)cogMethod)) + ((cogMethod->stackCheckOffset)); - result = findIsBackwardBranchMcpcBcpcMatchingMcpc(null, (0 + (((int)((usqInt)(HasBytecodePC) << 1)))), (((char *) mcpc1)), startbcpc, (((void *)mcpc))); - if (result != 0) { - return result; - } - - /* In both CMMethod and CMBlock cases find the start of the map and - skip forward to the bytecode pc map entry for the stack check. */ - bcpc = startbcpc; - if (((cogMethod->cmType)) == CMMethod) { - /* begin cmIsFullBlock */ - isInBlock = (cogMethod->cpicHasMNUCaseOrCMIsFullBlock); - homeMethod = ((CogMethod *) cogMethod); - assert(startbcpc == (startPCOfMethodHeader((homeMethod->methodHeader)))); - map = ((((usqInt)homeMethod)) + ((homeMethod->blockSize))) - 1; - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert((annotation == IsAbsPCReference) - || ((annotation == IsObjectReference) - || ((annotation == IsRelativeCall) - || (annotation == IsDisplacementX2N)))); - latestContinuation = startbcpc; - aMethodObj = (homeMethod->methodObject); - endbcpc = (numBytesOf(aMethodObj)) - 1; - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader) - ? 0x100 - : 0) -# else - 0 -# endif - ; - bcpc += deltaToSkipPrimAndErrorStoreInheader(aMethodObj, (homeMethod->methodHeader)); - } - else { - isInBlock = 1; - assert(bcpc == ((cogMethod->startpc))); - homeMethod = cmHomeMethod(cogMethod); - map = findMapLocationForMcpcinMethod((((usqInt)cogMethod)) + (sizeof(CogBlockMethod)), homeMethod); - assert(map != 0); - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert(((((usqInt)(annotation)) >> AnnotationShift) == HasBytecodePC) - || ((((usqInt)(annotation)) >> AnnotationShift) == IsDisplacementX2N)); - while (((annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift)) != HasBytecodePC) { - map -= 1; - } - - /* skip fiducial; i.e. the map entry for the pc immediately following the method header. */ - map -= 1; - aMethodObj = (homeMethod->methodObject); - bcpc = startbcpc - ( -#if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet((homeMethod->methodHeader)) - ? AltBlockCreationBytecodeSize - : BlockCreationBytecodeSize) -#else // MULTIPLEBYTECODESETS - BlockCreationBytecodeSize -#endif - ); - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader1 = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader1) - ? 0x100 - : 0) -# else - 0 -# endif - ; - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - endbcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, -1, aMethodObj)) - : 0)); - bcpc = startbcpc; - } - nExts = 0; - while ((((usqInt)((byteAt(map)))) >> AnnotationShift) != HasBytecodePC) { - map -= 1; - } - map -= 1; - while (((mapByte = byteAt(map))) != MapEnd) { - - /* defensive; we exit on bcpc */ - if (mapByte >= FirstAnnotation) { - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - mcpc1 += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if (annotation >= HasBytecodePC) { - if ((annotation == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - while (1) { - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - if (isInBlock) { - if (bcpc >= endbcpc) { - return 0; - } - } - else { - if (((descriptor->isReturn)) - && (bcpc >= latestContinuation)) { - return 0; - } - if ((isBranch(descriptor)) - || ((descriptor->isBlockCreation))) { - /* begin latestContinuationPCFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj); - targetPC = (bcpc + ((descriptor->numBytes))) + (((distance < 0) ? 0 : distance)); - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - /* latestContinuation = */ latestContinuation; - } - nextBcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) - : 0)); - if (((descriptor->isMapped)) - || (isInBlock - && ((descriptor->isMappedInBlock)))) break; - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - isBackwardBranch = (isBranch(descriptor)) - && ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) < 0)); - result = findIsBackwardBranchMcpcBcpcMatchingMcpc(descriptor, ((isBackwardBranch - ? (((sqInt)((usqInt)(annotation) << 1))) + 1 - : ((sqInt)((usqInt)(annotation) << 1)))), (((char *) mcpc1)), ((isBackwardBranch - ? bcpc - (2 * nExts) - : bcpc)), (((void *)mcpc))); - if (result != 0) { - return result; - } - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - } - else { - assert(((((usqInt)(mapByte)) >> AnnotationShift) == IsDisplacementX2N) - || ((((usqInt)(mapByte)) >> AnnotationShift) == IsAnnotationExtension)); - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc1 += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - return 0; -} - - /* Cogit>>#CallRT:registersToBeSavedMask: */ -static AbstractInstruction * NoDbgRegParms -CallRTregistersToBeSavedMask(sqInt callTarget, sqInt registersToBeSaved) -{ - AbstractInstruction *abstractInstruction; - sqInt callerSavedRegsToBeSaved; - AbstractInstruction *lastInst; - sqInt reg; - sqInt registersToBePushed; - - reg = 0; - callerSavedRegsToBeSaved = CallerSavedRegisterMask & registersToBeSaved; - registersToBePushed = callerSavedRegsToBeSaved; - reg = 0; - while (registersToBePushed != 0) { - if (((registersToBePushed & 1) != 0)) { - genoperand(PushR, reg); - } - reg += 1; - registersToBePushed = (registersToBePushed) >> 1; - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, callTarget); - (abstractInstruction->annotation = IsRelativeCall); - lastInst = abstractInstruction; - while (reg > 0) { - reg -= 1; - if (((callerSavedRegsToBeSaved & (1U << reg)) != 0)) { - lastInst = genoperand(PopR, reg); - } - } - return lastInst; -} - - /* Cogit>>#Call: */ -static AbstractInstruction * NoDbgRegParms -gCall(sqInt callTarget) -{ - return genoperand(Call, callTarget); -} - - /* Cogit>>#CmpCq:R: */ -static AbstractInstruction * NoDbgRegParms -gCmpCqR(sqInt quickConstant, sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, quickConstant, reg); - return anInstruction; -} - - -/* This is a static version of ceCallCogCodePopReceiverReg - for break-pointing when debugging in C. */ -/* This exists only for break-pointing. */ - - /* Cogit>>#callCogCodePopReceiver */ -void -callCogCodePopReceiver(void) -{ - realCECallCogCodePopReceiverReg(); - error("what??"); -} - - -/* This is a static version of ceCallCogCodePopReceiverAndClassRegs - for break-pointing when debugging in C. */ -/* This exists only for break-pointing. */ - - /* Cogit>>#callCogCodePopReceiverAndClassRegs */ -void -callCogCodePopReceiverAndClassRegs(void) -{ - realCECallCogCodePopReceiverAndClassRegs(); -} - - -/* Code entry closed PIC miss. A send has fallen - through a closed (finite) polymorphic inline cache. - Either extend it or patch the send site to an open PIC. - The stack looks like: - receiver - args - sp=> sender return address */ - - /* Cogit>>#ceCPICMiss:receiver: */ -static sqInt NoDbgRegParms -ceCPICMissreceiver(CogMethod *cPIC, sqInt receiver) -{ - sqInt cacheTag; - sqInt errorSelectorOrNil; - sqInt methodOrSelectorIndex; - sqInt newTargetMethodOrNil; - sqInt outerReturn; - sqInt result; - sqInt selector; - - if (isOopForwarded(receiver)) { - return ceSendFromInLineCacheMiss(cPIC); - } - outerReturn = stackTop(); - assert(!(((inlineCacheTagAt(backEnd, outerReturn)) == (picAbortDiscriminatorValue())))); - if (((cPIC->cPICNumCases)) < MaxCPICCases) { - /* begin lookup:for:methodAndErrorSelectorInto: */ - selector = (cPIC->selector); - methodOrSelectorIndex = lookupOrdinaryreceiver(selector, receiver); - if ((((usqInt)methodOrSelectorIndex)) > (maxLookupNoMNUErrorCode())) { - if (!(isOopCompiledMethod(methodOrSelectorIndex))) { - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = SelectorCannotInterpret; - goto l1; - } - if ((!(methodHasCogMethod(methodOrSelectorIndex))) - && (methodShouldBeCogged(methodOrSelectorIndex))) { - - /* We assume cog:selector: will *not* reclaim the method zone */ - cogselector(methodOrSelectorIndex, selector); - } - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = null; - goto l1; - } - if (methodOrSelectorIndex == SelectorDoesNotUnderstand) { - methodOrSelectorIndex = lookupMNUreceiver(splObj(SelectorDoesNotUnderstand), receiver); - if ((((usqInt)methodOrSelectorIndex)) > (maxLookupNoMNUErrorCode())) { - assert(isOopCompiledMethod(methodOrSelectorIndex)); - if ((!(methodHasCogMethod(methodOrSelectorIndex))) - && (methodShouldBeCogged(methodOrSelectorIndex))) { - - /* We assume cog:selector: will *not* reclaim the method zone */ - cogselector(methodOrSelectorIndex, splObj(SelectorDoesNotUnderstand)); - } - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = SelectorDoesNotUnderstand; - goto l1; - } - newTargetMethodOrNil = null; - errorSelectorOrNil = SelectorDoesNotUnderstand; - goto l1; - } - newTargetMethodOrNil = null; - errorSelectorOrNil = methodOrSelectorIndex; - l1: /* end lookup:for:methodAndErrorSelectorInto: */; - } - else { - newTargetMethodOrNil = (errorSelectorOrNil = null); - } - assert(outerReturn == (stackTop())); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - cacheTag = inlineCacheTagForInstance(receiver); - if ((((cPIC->cPICNumCases)) >= MaxCPICCases) - || (((errorSelectorOrNil != null) - && (errorSelectorOrNil != SelectorDoesNotUnderstand)) - || ((newTargetMethodOrNil == null) - || (isYoung(newTargetMethodOrNil))))) { - result = patchToOpenPICFornumArgsreceiver((cPIC->selector), (cPIC->cmNumArgs), receiver); - assert(!result); - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - return ceSendFromInLineCacheMiss(cPIC); - } - cogExtendPICCaseNMethodtagisMNUCase(cPIC, newTargetMethodOrNil, cacheTag, errorSelectorOrNil == SelectorDoesNotUnderstand); - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - executeCogPICfromLinkedSendWithReceiverandCacheTag(cPIC, receiver, inlineCacheTagAt(backEnd, outerReturn)); - return null; -} - - /* Cogit>>#ceFree: */ -void -ceFree(void *pointer) -{ - free(pointer); -} - - /* Cogit>>#ceMalloc: */ -static void* NoDbgRegParms -ceMalloc(size_t size) -{ - return malloc(size); -} - - -/* An in-line cache check in a method has failed. The failing entry check has - jumped to the ceMethodAbort abort call at the start of the method which - has called this routine. - If possible allocate a closed PIC for the current and existing classes. - The stack looks like: - receiver - args - sender return address - sp=> ceMethodAbort call return address - So we can find the method that did the failing entry check at - ceMethodAbort call return address - missOffset - and we can find the send site from the outer return address. */ - - /* Cogit>>#ceSICMiss: */ -static sqInt NoDbgRegParms -ceSICMiss(sqInt receiver) -{ - sqInt cacheTag; - usqInt entryPoint; - sqInt errorSelectorOrNil; - sqInt extent; - usqInt innerReturn; - sqInt methodOrSelectorIndex; - sqInt newTargetMethodOrNil; - usqInt outerReturn; - CogMethod *pic; - sqInt result; - sqInt selector; - CogMethod *targetMethod; - - - /* Whether we can relink to a PIC or not we need to pop off the inner return and identify the target method. */ - innerReturn = ((usqInt)(popStack())); - targetMethod = ((CogMethod *) (innerReturn - missOffset)); - if (isOopForwarded(receiver)) { - return ceSendFromInLineCacheMiss(targetMethod); - } - outerReturn = ((usqInt)(stackTop())); - assert(((outerReturn >= methodZoneBase) && (outerReturn <= (freeStart())))); - entryPoint = callTargetFromReturnAddress(backEnd, outerReturn); - assert(((targetMethod->selector)) != (nilObject())); - assert(((((sqInt)targetMethod)) + cmEntryOffset) == entryPoint); - /* begin lookup:for:methodAndErrorSelectorInto: */ - selector = (targetMethod->selector); - methodOrSelectorIndex = lookupOrdinaryreceiver(selector, receiver); - if ((((usqInt)methodOrSelectorIndex)) > (maxLookupNoMNUErrorCode())) { - if (!(isOopCompiledMethod(methodOrSelectorIndex))) { - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = SelectorCannotInterpret; - goto l1; - } - if ((!(methodHasCogMethod(methodOrSelectorIndex))) - && (methodShouldBeCogged(methodOrSelectorIndex))) { - - /* We assume cog:selector: will *not* reclaim the method zone */ - cogselector(methodOrSelectorIndex, selector); - } - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = null; - goto l1; - } - if (methodOrSelectorIndex == SelectorDoesNotUnderstand) { - methodOrSelectorIndex = lookupMNUreceiver(splObj(SelectorDoesNotUnderstand), receiver); - if ((((usqInt)methodOrSelectorIndex)) > (maxLookupNoMNUErrorCode())) { - assert(isOopCompiledMethod(methodOrSelectorIndex)); - if ((!(methodHasCogMethod(methodOrSelectorIndex))) - && (methodShouldBeCogged(methodOrSelectorIndex))) { - - /* We assume cog:selector: will *not* reclaim the method zone */ - cogselector(methodOrSelectorIndex, splObj(SelectorDoesNotUnderstand)); - } - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = SelectorDoesNotUnderstand; - goto l1; - } - newTargetMethodOrNil = null; - errorSelectorOrNil = SelectorDoesNotUnderstand; - goto l1; - } - newTargetMethodOrNil = null; - errorSelectorOrNil = methodOrSelectorIndex; - l1: /* end lookup:for:methodAndErrorSelectorInto: */; - assert(outerReturn == (stackTop())); - cacheTag = inlineCacheTagForInstance(receiver); - if (((errorSelectorOrNil != null) - && (errorSelectorOrNil != SelectorDoesNotUnderstand)) - || (((inlineCacheTagAt(backEnd, outerReturn)) == 0 /* picAbortDiscriminatorValue */) - || ((newTargetMethodOrNil == null) - || (isYoung(newTargetMethodOrNil))))) { - result = patchToOpenPICFornumArgsreceiver((targetMethod->selector), (targetMethod->cmNumArgs), receiver); - assert(!result); - return ceSendFromInLineCacheMiss(targetMethod); - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - pic = openPICWithSelector((targetMethod->selector)); - if ((pic == null) - || (!1)) { - - /* otherwise attempt to create a closed PIC for the two cases. */ - pic = cogPICSelectornumArgsCase0MethodCase1MethodtagisMNUCase((targetMethod->selector), (targetMethod->cmNumArgs), targetMethod, newTargetMethodOrNil, cacheTag, errorSelectorOrNil == SelectorDoesNotUnderstand); - if ((((((sqInt)pic)) >= MaxNegativeErrorCode) && ((((sqInt)pic)) <= -1))) { - - /* For some reason the PIC couldn't be generated, most likely a lack of code memory. - Continue as if this is an unlinked send. */ - if ((((sqInt)pic)) == InsufficientCodeSpace) { - callForCogCompiledCodeCompaction(); - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - return ceSendFromInLineCacheMiss(targetMethod); - } - } - extent = (((pic->cmType)) == CMOpenPIC - ? rewriteInlineCacheAttagtarget(backEnd, outerReturn, inlineCacheValueForSelectorin(backEnd, (targetMethod->selector), mframeHomeMethodExport()), (((sqInt)pic)) + cmEntryOffset) - : rewriteCallAttarget(backEnd, outerReturn, (((sqInt)pic)) + cmEntryOffset)); - /* begin assertValidDualZoneFrom:to: */ - (((usqInt)pic)) + closedPICSize; -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, (((usqInt)pic)) + cmNoCheckEntryOffset, codeToDataDelta); -# endif - flushICacheFromto(backEnd, ((usqInt)pic), (((usqInt)pic)) + closedPICSize); - flushICacheFromto(backEnd, (((usqInt)outerReturn)) - extent, ((usqInt)outerReturn)); - executeCogPICfromLinkedSendWithReceiverandCacheTag(pic, receiver, inlineCacheTagAt(backEnd, outerReturn)); - return null; -} - - -/* Check for a valid object reference, if any, at a map entry. Answer a code - unique to each error for debugging. */ - - /* Cogit>>#checkIfValidOopRefAndTarget:pc:cogMethod: */ -static sqInt NoDbgRegParms -checkIfValidOopRefAndTargetpccogMethod(sqInt annotation, char *mcpc, CogMethod *cogMethod) -{ - usqInt cacheTag1; - sqInt entryPoint; - usqInt entryPoint1; - usqInt literal; - sqInt offset1; - sqInt *sendTable1; - sqInt tagCouldBeObj; - CogMethod *targetMethod1; - - if (annotation == IsObjectReference) { - literal = literalBeforeFollowingAddress(backEnd, ((usqInt)mcpc)); - if (!(asserta(checkValidOopReference(literal)))) { - return 1; - } - if ((couldBeObject(literal)) - && (isReallyYoungObject(literal))) { - if (!(asserta(((((CogMethod *) cogMethod))->cmRefersToYoung)))) { - return 2; - } - } - } - if (annotation >= IsSendCall) { - if (!(asserta((((((CogMethod *) cogMethod))->cmType)) == CMMethod))) { - return 3; - } - /* begin entryCacheTagAndCouldBeObjectAt:annotation:into: */ - cacheTag1 = inlineCacheTagAt(backEnd, ((sqInt)mcpc)); - - /* in-line cache tags are the selectors of sends if sends are unlinked, - the selectors of super sends (entry offset = cmNoCheckEntryOffset), - the selectors of open PIC sends (entry offset = cmEntryOffset, target is an Open PIC) - or in-line cache tags (classes, class indices, immediate bit patterns, etc). - Note that selectors can be immediate so there is no guarantee that they - are markable/remappable objects. */ - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - tagCouldBeObj = entryPointTagIsSelector(entryPoint1); - entryPoint = entryPoint1; - if (tagCouldBeObj) { - if (couldBeObject(cacheTag1)) { - if (!(asserta(checkValidOopReference(cacheTag1)))) { - return 4; - } - } - else { - if (!(asserta(validInlineCacheTag(cacheTag1)))) { - return 5; - } - } - if ((couldBeObject(cacheTag1)) - && (isReallyYoungObject(cacheTag1))) { - if (!(asserta(((((CogMethod *) cogMethod))->cmRefersToYoung)))) { - return 6; - } - } - } - else { - if (!(asserta(validInlineCacheTag(cacheTag1)))) { - return 9; - } - } - if (entryPoint > methodZoneBase) { - - /* It's a linked send; find which kind. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (!(asserta((((targetMethod1->cmType)) == CMMethod) - || ((((targetMethod1->cmType)) == CMClosedPIC) - || (((targetMethod1->cmType)) == CMOpenPIC))))) { - return 10; - } - } - } - return 0; -} - - -/* Check for a valid object reference, if any, at a map entry. Answer a code - unique to each error for debugging. */ - - /* Cogit>>#checkIfValidOopRef:pc:cogMethod: */ -static sqInt NoDbgRegParms -checkIfValidOopRefpccogMethod(sqInt annotation, char *mcpc, CogMethod *cogMethod) -{ - usqInt entryPoint; - usqInt literal; - usqInt offset; - sqInt offset1; - usqInt selectorOrCacheTag; - sqInt *sendTable; - - if (annotation == IsObjectReference) { - literal = literalBeforeFollowingAddress(backEnd, ((usqInt)mcpc)); - if (!(checkValidOopReference(literal))) { - print("object ref leak in CM "); - printHex(((sqInt)cogMethod)); - print(" @ "); - printHex(((sqInt)mcpc)); - cr(); - return 1; - } - } - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint <= methodZoneBase) { - offset = entryPoint; - } - else { - /* begin offsetAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable = superSendTrampolines; - } - } - } - offset = offset1; - } - selectorOrCacheTag = inlineCacheTagAt(backEnd, ((sqInt)mcpc)); - if ((entryPoint > methodZoneBase) - && ((offset != cmNoCheckEntryOffset) - && ((((((CogMethod *) (entryPoint - offset)))->cmType)) != CMOpenPIC))) { - - /* linked non-super send, cacheTag is a cacheTag */ - if (!(validInlineCacheTag(selectorOrCacheTag))) { - print("cache tag leak in CM "); - printHex(((sqInt)cogMethod)); - print(" @ "); - printHex(((sqInt)mcpc)); - cr(); - return 1; - } - } - else { - - /* unlinked send or super send; cacheTag is a selector unless 64-bit, in which case it is an index. */ - if (!(checkValidOopReference(selectorOrCacheTag))) { - print("selector leak in CM "); - printHex(((sqInt)cogMethod)); - print(" @ "); - printHex(((sqInt)mcpc)); - cr(); - return 1; - } - } - } - return 0; -} - - -/* Answer if all references to objects in machine-code are valid. */ - - /* Cogit>>#checkIntegrityOfObjectReferencesInCode: */ -sqInt -checkIntegrityOfObjectReferencesInCode(sqInt gcModes) -{ - CogMethod *cogMethod; - sqInt count; - sqInt ok; - - cogMethod = ((CogMethod *) methodZoneBase); - ok = 1; - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - if ((cogMethod->cmRefersToYoung)) { - if (((count = occurrencesInYoungReferrers(cogMethod))) != 1) { - print("young referrer CM "); - printHex(((sqInt)cogMethod)); - if (count == 0) { - print(" is not in youngReferrers"); - cr(); - } - else { - print(" is in youngReferrers "); - printNum(count); - print(" times!"); - cr(); - } - ok = 0; - } - } - if (!(checkValidOopReference((cogMethod->selector)))) { - print("object leak in CM "); - printHex(((sqInt)cogMethod)); - print(" selector"); - cr(); - ok = 0; - } - if (((cogMethod->cmType)) == CMMethod) { - assert(((cogMethod->objectHeader)) == (nullHeaderForMachineCodeMethod())); - if (!(checkValidObjectReference((cogMethod->methodObject)))) { - print("object leak in CM "); - printHex(((sqInt)cogMethod)); - print(" methodObject"); - cr(); - ok = 0; - } - if (!(isOopCompiledMethod((cogMethod->methodObject)))) { - print("non-method in CM "); - printHex(((sqInt)cogMethod)); - print(" methodObject"); - cr(); - ok = 0; - } - if ((mapForperformUntilarg(cogMethod, checkIfValidOopRefpccogMethod, cogMethod)) != 0) { - ok = 0; - } - if (((isYoungObject((cogMethod->methodObject))) - || (isYoung((cogMethod->selector)))) - && (!((cogMethod->cmRefersToYoung)))) { - print("CM "); - printHex(((sqInt)cogMethod)); - print(" refers to young but not marked as such"); - cr(); - ok = 0; - } - } - else { - if (((cogMethod->cmType)) == CMClosedPIC) { - if (!(checkValidObjectReferencesInClosedPIC(cogMethod))) { - ok = 0; - } - } - else { - if (((cogMethod->cmType)) == CMOpenPIC) { - if ((mapForperformUntilarg(cogMethod, checkIfValidOopRefpccogMethod, cogMethod)) != 0) { - ok = 0; - } - } - } - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return ok; -} - - /* Cogit>>#checkMaybeObjRefInClosedPIC: */ -static sqInt NoDbgRegParms -checkMaybeObjRefInClosedPIC(sqInt maybeObject) -{ - if (maybeObject == 0) { - return 1; - } - if (!(couldBeObject(maybeObject))) { - return 1; - } - return checkValidObjectReference(maybeObject); -} - - /* Cogit>>#checkValidObjectReferencesInClosedPIC: */ -static sqInt NoDbgRegParms -checkValidObjectReferencesInClosedPIC(CogMethod *cPIC) -{ - sqInt i; - sqInt ok; - sqInt pc; - - ok = 1; - - /* first we check the obj ref at the beginning of the CPIC */ - pc = (((sqInt)cPIC)) + firstCPICCaseOffset; - if (!(checkMaybeObjRefInClosedPIC(literalBeforeFollowingAddress(backEnd, pc - (jumpLongByteSize(backEnd)))))) { - print("object leak in CPIC "); - printHex(((sqInt)cPIC)); - print(" @ "); - printHex(pc - (jumpLongByteSize(backEnd))); - cr(); - ok = 0; - } - - /* For each case we check any object reference at the end address - sizeof(conditional instruction) and then increment the end address by case size */ - pc = addressOfEndOfCaseinCPIC((cPIC->cPICNumCases), cPIC); - for (i = 2; i <= ((cPIC->cPICNumCases)); i += 1) { - if (!(checkMaybeObjRefInClosedPIC(literalBeforeFollowingAddress(backEnd, (pc - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */)))) { - print("object leak in CPIC "); - printHex(((sqInt)cPIC)); - print(" @ "); - printHex(pc - 16 /* jumpLongConditionalByteSize */); - cr(); - ok = 0; - } - pc += cPICCaseSize; - } - return ok; -} - - -/* i.e. this should never be called, so keep it out of the main path. */ - - /* Cogit>>#cleanUpFailingCogCodeConstituents: */ -static sqInt NoDbgRegParms NeverInline -cleanUpFailingCogCodeConstituents(CogMethod *cogMethodArg) -{ - CogMethod *cogMethod; - - cogMethod = cogMethodArg; - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMClosedPIC) { - (cogMethod->methodObject = 0); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - popRemappableOop(); - return null; -} - - -/* Answer if the ClosedPIC refers to any unmarked objects or freed/freeable - target methods, - applying markAndTraceOrFreeCogMethod:firstVisit: to those targets to - determine if freed/freeable. - */ - - /* Cogit>>#closedPICRefersToUnmarkedObject: */ -static sqInt NoDbgRegParms -closedPICRefersToUnmarkedObject(CogMethod *cPIC) -{ - sqInt i; - usqInt object; - sqInt pc; - - if (!((isImmediate((cPIC->selector))) - || (isMarked((cPIC->selector))))) { - return 1; - } - pc = addressOfEndOfCaseinCPIC(1, cPIC); - if (couldBeObject((object = literalBeforeFollowingAddress(backEnd, pc - (jumpLongByteSize(backEnd)))))) { - if (!(isMarked(object))) { - return 1; - } - } - if (markAndTraceOrFreePICTargetin(jumpLongTargetBeforeFollowingAddress(backEnd, pc), cPIC)) { - return 1; - } - for (i = 2; i <= ((cPIC->cPICNumCases)); i += 1) { - pc = addressOfEndOfCaseinCPIC(i, cPIC); - if (couldBeObject((object = literalBeforeFollowingAddress(backEnd, (pc - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */)))) { - if (!(isMarked(object))) { - return 1; - } - } - if (markAndTraceOrFreePICTargetin(jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc), cPIC)) { - return 1; - } - } - return 0; -} - - /* Cogit>>#codeEntryFor: */ -char * -codeEntryFor(char *address) -{ - sqInt i; - - for (i = 0; i <= (trampolineTableIndex - 3); i += 2) { - if (((address >= (trampolineAddresses[i + 1])) && (address <= ((trampolineAddresses[i + 3]) - 1)))) { - return trampolineAddresses[i + 1]; - } - } - return null; -} - - /* Cogit>>#codeEntryNameFor: */ -char * -codeEntryNameFor(char *address) -{ - sqInt i; - - for (i = 0; i <= (trampolineTableIndex - 3); i += 2) { - if (((address >= (trampolineAddresses[i + 1])) && (address <= ((trampolineAddresses[i + 3]) - 1)))) { - return trampolineAddresses[i]; - } - } - return null; -} - - /* Cogit>>#cogCodeBase */ -sqInt -cogCodeBase(void) -{ - return codeBase; -} - - -/* Answer the contents of the code zone as an array of pair-wise element, - address in ascending address order. - Answer a string for a runtime routine or abstract label (beginning, end, - etc), a CompiledMethod for a CMMethod, - or a selector (presumably a Symbol) for a PIC. - If withDetails is true - - answer machine-code to bytecode pc mapping information for methods - - answer class, target pair information for closed PIC - N.B. Since the class tag for the first case of a closed PIC is stored at - the send site, it must be collected - by scanning methods (see - collectCogConstituentFor:Annotation:Mcpc:Bcpc:Method:). Since closed PICs - are never shared they always come after the method that references them, - so we don't need an extra pass - to collect the first case class tags, which are (temporarily) assigned to - each closed PIC's methodObject field. - But we do need to reset the methodObject fields to zero. This is done in - createPICData:, unless memory - runs out, in which case it is done by cleanUpFailingCogCodeConstituents:. */ - - /* Cogit>>#cogCodeConstituents: */ -sqInt -cogCodeConstituents(sqInt withDetails) -{ - CogMethod *cogMethod; - sqInt constituents; - sqInt count; - sqInt i; - sqInt label; - sqInt profileData; - sqInt value; - - - /* + 3 for start, freeStart and end */ - count = (trampolineTableIndex / 2) + 3; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - count += 1; - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - constituents = instantiateClassindexableSize(classArray(), count * 2); - if (!constituents) { - return constituents; - } - pushRemappableOop(constituents); - if ((((label = stringForCString("CogCode"))) == null) - || (((value = positive32BitIntegerFor(codeBase))) == null)) { - popRemappableOop(); - return null; - } - storePointerUncheckedofObjectwithValue(0, constituents, label); - storePointerUncheckedofObjectwithValue(1, constituents, value); - for (i = 0; i < trampolineTableIndex; i += 2) { - if ((((label = stringForCString(trampolineAddresses[i]))) == null) - || (((value = positive32BitIntegerFor(((usqInt)(trampolineAddresses[i + 1]))))) == null)) { - popRemappableOop(); - return null; - } - storePointerUncheckedofObjectwithValue(2 + i, constituents, label); - storePointerUncheckedofObjectwithValue(3 + i, constituents, value); - } - count = trampolineTableIndex + 2; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - profileData = (((cogMethod->cmType)) == CMMethod - ? (cogMethod->methodObject) - : (withDetails - && (((cogMethod->cmType)) == CMClosedPIC) - ? createCPICData(cogMethod) - : (cogMethod->selector))); - if (!profileData) { - return cleanUpFailingCogCodeConstituents(cogMethod); - } - storePointerUncheckedofObjectwithValue(count, constituents, profileData); - if (withDetails) { - value = collectCogMethodConstituent(cogMethod); - } - else { - value = positive32BitIntegerFor(((usqInt)cogMethod)); - } - if (!value) { - return cleanUpFailingCogCodeConstituents(cogMethod); - } - storePointerUncheckedofObjectwithValue(count + 1, constituents, value); - count += 2; - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if ((((label = stringForCString("CCFree"))) == null) - || (((value = positive32BitIntegerFor(mzFreeStart))) == null)) { - popRemappableOop(); - return null; - } - storePointerUncheckedofObjectwithValue(count, constituents, label); - storePointerUncheckedofObjectwithValue(count + 1, constituents, value); - if ((((label = stringForCString("CCEnd"))) == null) - || (((value = positive32BitIntegerFor(limitAddress))) == null)) { - popRemappableOop(); - return null; - } - storePointerUncheckedofObjectwithValue(count + 2, constituents, label); - storePointerUncheckedofObjectwithValue(count + 3, constituents, value); - constituents = popRemappableOop(); - beRootIfOld(constituents); - return constituents; -} - - -/* Extend the cPIC with the supplied case. If caseNMethod is cogged dispatch - direct to - its unchecked entry-point. If caseNMethod is not cogged, jump to the fast - interpreter dispatch, and if isMNUCase then dispatch to fast MNU - invocation and mark the cPIC as - having the MNU case for cache flushing. */ - - /* Cogit>>#cogExtendPIC:CaseNMethod:tag:isMNUCase: */ -static void NoDbgRegParms -cogExtendPICCaseNMethodtagisMNUCase(CogMethod *cPIC, sqInt caseNMethod, sqInt caseNTag, sqInt isMNUCase) -{ - sqInt address; - sqInt operand; - CogBlockMethod * self_in_cpicHasMNUCase; - sqInt target; - - compilationBreakpointclassTagisMNUCase((cPIC->selector), caseNTag, isMNUCase); - assert(!(inlineCacheTagIsYoung(caseNTag))); - assert((caseNMethod != null) - && (!(isYoung(caseNMethod)))); - if ((!isMNUCase) - && (methodHasCogMethod(caseNMethod))) { - - /* this isn't an MNU and we have an already cogged method to jump to */ - operand = 0; - target = (((sqInt)(cogMethodOf(caseNMethod)))) + cmNoCheckEntryOffset; - } - else { - operand = caseNMethod; - if (isMNUCase) { - - /* this is an MNU so tag the CPIC header and setup a jump to the MNUAbort */ - /* begin cpicHasMNUCase: */ - self_in_cpicHasMNUCase = ((CogBlockMethod *) (((CogMethod *) ((((usqInt)cPIC)) + codeToDataDelta)))); - (self_in_cpicHasMNUCase->cpicHasMNUCaseOrCMIsFullBlock) = 1; - target = (((sqInt)cPIC)) + (sizeof(CogMethod)); - } - else { - - /* setup a jump to the interpretAborth so we can cog the target method */ - target = (((sqInt)cPIC)) + (picInterpretAbortOffset()); - } - } - address = addressOfEndOfCaseinCPIC(((cPIC->cPICNumCases)) + 1, cPIC); - rewriteCPICCaseAttagobjReftarget(address, caseNTag, operand, target); - /* begin rewriteCPIC:caseJumpTo: */ - rewriteCPICJumpAttarget(backEnd, (((((sqInt)cPIC)) + firstCPICCaseOffset) - (jumpLongByteSize(backEnd))) - 8 /* loadLiteralByteSize */, address - cPICCaseSize); - ((((CogMethod *) ((((usqInt)cPIC)) + codeToDataDelta)))->cPICNumCases = ((cPIC->cPICNumCases)) + 1); - flushICacheFromto(backEnd, ((usqInt)cPIC), (((usqInt)cPIC)) + closedPICSize); - /* begin assertValidDualZoneFrom:to: */ - (((usqInt)cPIC)) + closedPICSize; -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, (((usqInt)cPIC)) + cmNoCheckEntryOffset, codeToDataDelta); -# endif -} - - -/* Attempt to produce a machine code method for the bytecode method - object aMethodObj. N.B. If there is no code memory available do *NOT* - attempt to reclaim the method zone. Certain clients (e.g. ceSICMiss:) - depend on the zone remaining constant across method generation. */ - - /* Cogit>>#cogFullBlockMethod:numCopied: */ -CogMethod * -cogFullBlockMethodnumCopied(sqInt aMethodObj, sqInt numCopied) -{ - CogMethod *cogMethod; - - - /* inline exclude: */ - assert(!((methodHasCogMethod(aMethodObj)))); - assert(isOopCompiledMethod(ultimateLiteralOf(aMethodObj))); - if (aMethodObj == breakMethod) { - haltmsg("Compilation of breakMethod"); - } - if (methodUsesAlternateBytecodeSet(aMethodObj)) { - if ((numElementsIn(generatorTable)) <= 0x100) { - return null; - } - bytecodeSetOffset = 0x100; - } - else { - bytecodeSetOffset = 0; - } - ensureNoForwardedLiteralsIn(aMethodObj); - methodObj = aMethodObj; - methodHeader = methodHeaderOf(aMethodObj); - receiverTags = receiverTagBitsForMethod(methodObj); - cogMethod = compileCogFullBlockMethod(numCopied); - if ((((((sqInt)cogMethod)) >= MaxNegativeErrorCode) && ((((sqInt)cogMethod)) <= -1))) { - if ((((sqInt)cogMethod)) == InsufficientCodeSpace) { - callForCogCompiledCodeCompaction(); - } - return null; - } - return cogMethod; -} - - /* Cogit>>#cogitPostGCAction: */ -void -cogitPostGCAction(sqInt gcMode) -{ - -# if SPURVM - if (gcMode == GCModeBecome) { - followForwardedLiteralsInOpenPICList(); - } -# endif - assert(allMethodsHaveCorrectHeader()); - assert(((!(gcMode & (GCModeFull + GCModeNewSpace)))) - || (kosherYoungReferrers())); - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - -/* Check that the header fields onf a non-free method are consistent with - the type. Answer 0 if it is ok, otherwise answer a code for the error. */ - - /* Cogit>>#cogMethodDoesntLookKosher: */ -sqInt -cogMethodDoesntLookKosher(CogMethod *cogMethod) -{ - if (((((cogMethod->blockSize)) & (BytesPerWord - 1)) != 0) - || ((((cogMethod->blockSize)) < (sizeof(CogMethod))) - || (((cogMethod->blockSize)) >= 0x8000))) { - return 1; - } - if (((cogMethod->cmType)) == CMFree) { - return 2; - } - if (((cogMethod->cmType)) == CMMethod) { - if (!((((cogMethod->methodHeader)) & 1))) { - return 11; - } - if (!(couldBeObject((cogMethod->methodObject)))) { - return 12; - } - if ((((cogMethod->stackCheckOffset)) > 0) - && (((cogMethod->stackCheckOffset)) < cmNoCheckEntryOffset)) { - return 13; - } - return 0; - } - if (((cogMethod->cmType)) == CMOpenPIC) { - if (((cogMethod->blockSize)) != openPICSize) { - return 21; - } - if (((cogMethod->methodHeader)) != 0) { - return 22; - } - if (((cogMethod->objectHeader)) >= 0) { - if (!((((cogMethod->methodObject)) == 0) - || (compactionInProgress - || (((cogMethod->methodObject)) == (((usqInt)(methodFor(((void *)((cogMethod->methodObject))))))))))) { - return 23; - } - } - if (((cogMethod->stackCheckOffset)) != 0) { - return 24; - } - return 0; - } - if (((cogMethod->cmType)) == CMClosedPIC) { - if (((cogMethod->blockSize)) != closedPICSize) { - return 0x1F; - } - if (!(((((cogMethod->cPICNumCases)) >= 1) && (((cogMethod->cPICNumCases)) <= MaxCPICCases)))) { - return 32; - } - if (((cogMethod->methodHeader)) != 0) { - return 33; - } - if (((cogMethod->methodObject)) != 0) { - return 34; - } - return 0; - } - return 9; -} - - -/* Attempt to create a one-case PIC for an MNU. - The tag for the case is at the send site and so doesn't need to be - generated. - */ - - /* Cogit>>#cogMNUPICSelector:receiver:methodOperand:numArgs: */ -CogMethod * -cogMNUPICSelectorreceivermethodOperandnumArgs(sqInt selector, sqInt rcvr, sqInt methodOperand, sqInt numArgs) -{ - CogMethod * actualPIC; - usqInt startAddress; - CogMethod * writablePIC; - - if ((isYoung(selector)) - || ((inlineCacheTagForInstance(rcvr)) == 0 /* picAbortDiscriminatorValue */)) { - return 0; - } - compilationBreakpointclassTagisMNUCase(selector, fetchClassTagOf(rcvr), 1); - assert(endCPICCase0 != null); - startAddress = allocate(closedPICSize); - if (startAddress == 0) { - callForCogCompiledCodeCompaction(); - return 0; - } - maybeBreakGeneratingFromto(startAddress, startAddress + closedPICSize); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - - /* memcpy the prototype across to our allocated space; because anything else would be silly */ - writablePIC = ((CogMethod *) ((((usqInt)startAddress)) + codeToDataDelta)); - codeMemcpy(writablePIC, cPICPrototype, closedPICSize); - /* begin fillInCPICHeader:numArgs:numCases:hasMNUCase:selector: */ - assert(!(isYoung(selector))); - (writablePIC->cmType = CMClosedPIC); - (writablePIC->objectHeader = 0); - (writablePIC->blockSize = closedPICSize); - (writablePIC->methodObject = 0); - (writablePIC->methodHeader = 0); - (writablePIC->selector = selector); - (writablePIC->cmNumArgs = numArgs); - (writablePIC->cmHasMovableLiteral = 0); - (writablePIC->cmRefersToYoung = 0); - (writablePIC->cmUsageCount = initialClosedPICUsageCount()); - /* begin cpicHasMNUCase: */ - ((((CogBlockMethod *) writablePIC))->cpicHasMNUCaseOrCMIsFullBlock) = 1; - (writablePIC->cPICNumCases = 1); - (writablePIC->blockEntryOffset = 0); - assert(((writablePIC->cmType)) == CMClosedPIC); - assert(((writablePIC->selector)) == selector); - assert(((writablePIC->cmNumArgs)) == numArgs); - assert(((writablePIC->cPICNumCases)) == 1); - assert(closedPICSize == (roundUpLength(closedPICSize))); - /* begin maybeEnableSingleStep */ - configureMNUCPICmethodOperandnumArgsdelta((actualPIC = ((CogMethod *) startAddress)), methodOperand, numArgs, startAddress - (((usqInt)cPICPrototype))); - flushICacheFromto(backEnd, startAddress, startAddress + closedPICSize); - assert((callTargetFromReturnAddress(backEnd, startAddress + missOffset)) == (picAbortTrampolineFor(numArgs))); - /* begin assertValidDualZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, startAddress + cmNoCheckEntryOffset, codeToDataDelta); -# endif - return actualPIC; -} - - -/* Create an Open PIC. Temporarily create a direct call of - ceSendFromOpenPIC:. Should become a probe of the first-level method lookup - cache followed by a - call of ceSendFromOpenPIC: if the probe fails. */ - - /* Cogit>>#cogOpenPICSelector:numArgs: */ -static CogMethod * NoDbgRegParms -cogOpenPICSelectornumArgs(sqInt selector, sqInt numArgs) -{ - sqInt codeSize; - sqInt end; - sqInt fixupSize; - sqInt mapSize; - sqInt opcodeSize; - CogMethod *pic; - usqInt startAddress; - - compilationBreakpointisMNUCase(selector, 0); - startAddress = allocate(openPICSize); - if (startAddress == 0) { - return ((CogMethod *) InsufficientCodeSpace); - } - (methodLabel->address = startAddress); - (methodLabel->dependent = null); - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 100; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - compileOpenPICnumArgs(selector, numArgs); - computeMaximumSizes(); - concretizeAt(methodLabel, startAddress); - codeSize = generateInstructionsAt(startAddress + (sizeof(CogMethod))); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - mapSize = generateMapAtstart((startAddress + openPICSize) - 1, startAddress + cmNoCheckEntryOffset); - assert((((entry->address)) - startAddress) == cmEntryOffset); - assert(((roundUpLength((sizeof(CogMethod)) + codeSize)) + (roundUpLength(mapSize))) <= openPICSize); - end = outputInstructionsAt(startAddress + (sizeof(CogMethod))); - /* begin fillInOPICHeader:numArgs:selector: */ - pic = ((CogMethod *) ((((usqInt)startAddress)) + codeToDataDelta)); - (pic->cmType = CMOpenPIC); - (pic->objectHeader = 0); - (pic->blockSize = openPICSize); - addToOpenPICList(pic); - (pic->methodHeader = 0); - (pic->selector = selector); - (pic->cmNumArgs = numArgs); - (pic->cmHasMovableLiteral = isNonImmediate(selector)); - if ((pic->cmRefersToYoung = isYoung(selector))) { - addToYoungReferrers(pic); - } - (pic->cmUsageCount = initialOpenPICUsageCount()); - /* begin cpicHasMNUCase: */ - ((((CogBlockMethod *) pic))->cpicHasMNUCaseOrCMIsFullBlock) = 0; - (pic->cPICNumCases = 0); - (pic->blockEntryOffset = 0); - flushICacheFromto(backEnd, (((usqInt)pic)) - codeToDataDelta, ((((usqInt)pic)) - codeToDataDelta) + openPICSize); - assert(((pic->cmType)) == CMOpenPIC); - assert(((pic->selector)) == selector); - assert(((pic->cmNumArgs)) == numArgs); - assert((callTargetFromReturnAddress(backEnd, ((((sqInt)pic)) - codeToDataDelta) + missOffset)) == (picAbortTrampolineFor(numArgs))); - assert(openPICSize == (roundUpLength(openPICSize))); - /* begin assertValidDualZoneFrom:to: */ - ((((usqInt)pic)) - codeToDataDelta) + openPICSize; -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, ((((usqInt)pic)) - codeToDataDelta) + cmNoCheckEntryOffset, codeToDataDelta); -# endif - /* begin maybeEnableSingleStep */ - return ((CogMethod *) startAddress); -} - - -/* Attempt to create a two-case PIC for case0CogMethod and - case1Method,case1Tag. The tag for case0CogMethod is at the send site and - so doesn't need to be generated. - case1Method may be any of - - a Cog method; link to its unchecked entry-point - - a CompiledMethod; link to ceInterpretMethodFromPIC: - - a CompiledMethod; link to ceMNUFromPICMNUMethod:receiver: */ - - /* Cogit>>#cogPICSelector:numArgs:Case0Method:Case1Method:tag:isMNUCase: */ -static CogMethod * NoDbgRegParms -cogPICSelectornumArgsCase0MethodCase1MethodtagisMNUCase(sqInt selector, sqInt numArgs, CogMethod *case0CogMethod, sqInt case1MethodOrNil, sqInt case1Tag, sqInt isMNUCase) -{ - CogMethod * actualPIC; - usqInt startAddress; - CogMethod * writablePIC; - - if (isYoung(selector)) { - return ((CogMethod *) YoungSelectorInPIC); - } - compilationBreakpointclassTagisMNUCase(selector, case1Tag, isMNUCase); - startAddress = allocate(closedPICSize); - if (startAddress == 0) { - return ((CogMethod *) InsufficientCodeSpace); - } - maybeBreakGeneratingFromto(startAddress, startAddress + closedPICSize); - - /* memcpy the prototype across to our allocated space; because anything else would be silly */ - writablePIC = ((CogMethod *) ((((usqInt)startAddress)) + codeToDataDelta)); - codeMemcpy(writablePIC, cPICPrototype, closedPICSize); - /* begin fillInCPICHeader:numArgs:numCases:hasMNUCase:selector: */ - assert(!(isYoung(selector))); - (writablePIC->cmType = CMClosedPIC); - (writablePIC->objectHeader = 0); - (writablePIC->blockSize = closedPICSize); - (writablePIC->methodObject = 0); - (writablePIC->methodHeader = 0); - (writablePIC->selector = selector); - (writablePIC->cmNumArgs = numArgs); - (writablePIC->cmHasMovableLiteral = 0); - (writablePIC->cmRefersToYoung = 0); - (writablePIC->cmUsageCount = initialClosedPICUsageCount()); - /* begin cpicHasMNUCase: */ - ((((CogBlockMethod *) writablePIC))->cpicHasMNUCaseOrCMIsFullBlock) = isMNUCase; - (writablePIC->cPICNumCases = 2); - (writablePIC->blockEntryOffset = 0); - assert(((writablePIC->cmType)) == CMClosedPIC); - assert(((writablePIC->selector)) == selector); - assert(((writablePIC->cmNumArgs)) == numArgs); - assert(((writablePIC->cPICNumCases)) == 2); - assert(closedPICSize == (roundUpLength(closedPICSize))); - /* begin maybeEnableSingleStep */ - configureCPICCase0Case1MethodtagisMNUCasenumArgsdelta((actualPIC = ((CogMethod *) startAddress)), case0CogMethod, case1MethodOrNil, case1Tag, isMNUCase, numArgs, startAddress - (((usqInt)cPICPrototype))); - assert((callTargetFromReturnAddress(backEnd, startAddress + missOffset)) == (picAbortTrampolineFor(numArgs))); - return actualPIC; -} - - -/* Attempt to produce a machine code method for the bytecode method - object aMethodObj. N.B. If there is no code memory available do *NOT* - attempt to reclaim the method zone. Certain clients (e.g. ceSICMiss:) - depend on the zone remaining constant across method generation. */ - - /* Cogit>>#cog:selector: */ -CogMethod * -cogselector(sqInt aMethodObj, sqInt aSelectorOop) -{ - CogMethod *cogMethod; - sqInt selector; - - - /* inline exclude:selector: */ - assert(!((methodHasCogMethod(aMethodObj)))); - assert(!((isOopCompiledMethod(ultimateLiteralOf(aMethodObj))))); - - /* coInterpreter stringOf: selector */ - selector = (aSelectorOop == (nilObject()) - ? maybeSelectorOfMethod(aMethodObj) - : aSelectorOop); - if (!(selector == null)) { - compilationBreakpointisMNUCase(selector, 0); - } - if (aMethodObj == breakMethod) { - haltmsg("Compilation of breakMethod"); - } - if (methodUsesAlternateBytecodeSet(aMethodObj)) { - if ((numElementsIn(generatorTable)) <= 0x100) { - return null; - } - bytecodeSetOffset = 0x100; - } - else { - bytecodeSetOffset = 0; - } - ensureNoForwardedLiteralsIn(aMethodObj); - methodObj = aMethodObj; - methodHeader = methodHeaderOf(aMethodObj); - receiverTags = receiverTagBitsForMethod(methodObj); - cogMethod = compileCogMethod(aSelectorOop); - if ((((((sqInt)cogMethod)) >= MaxNegativeErrorCode) && ((((sqInt)cogMethod)) <= -1))) { - if ((((sqInt)cogMethod)) == InsufficientCodeSpace) { - callForCogCompiledCodeCompaction(); - } - return null; - } - return cogMethod; -} - - /* Cogit>>#collectCogConstituentFor:Annotation:Mcpc:Bcpc:Method: */ -static sqInt NoDbgRegParms -collectCogConstituentForAnnotationMcpcBcpcMethod(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *cogMethodArg) -{ - sqInt address; - sqInt annotation; - usqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - - if (!descriptor) { - return 0; - } - if (!((descriptor->isMapped))) { - return 0; - } - address = positive32BitIntegerFor(((usqInt)mcpc)); - if (!address) { - return PrimErrNoMemory; - } - storePointerUncheckedofObjectwithValue(cogConstituentIndex, topRemappableOop(), address); - storePointerUncheckedofObjectwithValue(cogConstituentIndex + 1, topRemappableOop(), (((usqInt)bcpc << 1) | 1)); - - /* Collect any first case classTags for closed PICs. */ - cogConstituentIndex += 2; - if (((!(isBackwardBranchAndAnnotation & 1))) - && (((((usqInt)(isBackwardBranchAndAnnotation)) >> 1) >= IsSendCall) - || (0))) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* send is linked */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - annotation = ((usqInt)(isBackwardBranchAndAnnotation)) >> 1; - /* begin offsetAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (((targetMethod1->cmType)) == CMClosedPIC) { - (targetMethod1->methodObject = classForInlineCacheTag(inlineCacheTagAt(backEnd, mcpc))); - } - } - } - return 0; -} - - -/* Answer a description of the mapping between machine code pointers and - bytecode pointers for the Cog Method. - First value is the address of the cog method. - Following values are pairs of machine code pc and bytecode pc */ - - /* Cogit>>#collectCogMethodConstituent: */ -static sqInt NoDbgRegParms -collectCogMethodConstituent(CogMethod *cogMethod) -{ - sqInt address; - sqInt aMethodHeader; - sqInt aMethodHeader1; - sqInt aMethodObj; - sqInt annotation; - sqInt bcpc; - sqInt bsOffset; - sqInt byte; - sqInt cm; - CogBlockMethod *cogBlockMethod; - sqInt data; - BytecodeDescriptor *descriptor; - sqInt distance; - sqInt endbcpc; - sqInt errCode; - CogMethod *homeMethod; - sqInt isBackwardBranch; - sqInt isInBlock; - sqInt latestContinuation; - usqInt map; - sqInt mapByte; - usqInt mcpc; - sqInt nExts; - sqInt nextBcpc; - sqInt nSlots; - sqInt result; - sqInt startbcpc; - sqInt targetPC; - - latestContinuation = 0; - if (!(((cogMethod->cmType)) == CMMethod)) { - return positive32BitIntegerFor(((usqInt)cogMethod)); - } - cogBlockMethod = ((CogBlockMethod *) cogMethod); - if (((cogBlockMethod->stackCheckOffset)) == 0) { - - /* isFrameless ? */ - return positive32BitIntegerFor(((usqInt)cogMethod)); - } - cm = (cogMethod->methodObject); - - /* +1 for first address */ - nSlots = ((((byteSizeOf(cm)) - (startPCOfMethod(cm))) * 2) + (minSlotsForShortening())) + 1; - data = instantiateClassindexableSize(splObj(ClassArray), nSlots); - if (!data) { - return null; - } - pushRemappableOop(data); - address = positive32BitIntegerFor(((usqInt)cogMethod)); - if (!address) { - popRemappableOop(); - return null; - } - storePointerUncheckedofObjectwithValue(0, topRemappableOop(), address); - cogConstituentIndex = 1; - /* begin mapFor:bcpc:performUntil:arg: */ - startbcpc = startPCOfMethod((cogMethod->methodObject)); - assert(((cogBlockMethod->stackCheckOffset)) > 0); - - /* The stack check maps to the start of the first bytecode, - the first bytecode being effectively after frame build. */ - mcpc = (((usqInt)cogBlockMethod)) + ((cogBlockMethod->stackCheckOffset)); - result = collectCogConstituentForAnnotationMcpcBcpcMethod(null, (0 + (((int)((usqInt)(HasBytecodePC) << 1)))), (((char *) mcpc)), startbcpc, (((void *)cogMethod))); - if (result != 0) { - errCode = result; - goto l7; - } - - /* In both CMMethod and CMBlock cases find the start of the map and - skip forward to the bytecode pc map entry for the stack check. */ - bcpc = startbcpc; - if (((cogBlockMethod->cmType)) == CMMethod) { - /* begin cmIsFullBlock */ - isInBlock = (cogBlockMethod->cpicHasMNUCaseOrCMIsFullBlock); - homeMethod = ((CogMethod *) cogBlockMethod); - assert(startbcpc == (startPCOfMethodHeader((homeMethod->methodHeader)))); - map = ((((usqInt)homeMethod)) + ((homeMethod->blockSize))) - 1; - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert((annotation == IsAbsPCReference) - || ((annotation == IsObjectReference) - || ((annotation == IsRelativeCall) - || (annotation == IsDisplacementX2N)))); - latestContinuation = startbcpc; - aMethodObj = (homeMethod->methodObject); - endbcpc = (numBytesOf(aMethodObj)) - 1; - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader) - ? 0x100 - : 0) -# else - 0 -# endif - ; - bcpc += deltaToSkipPrimAndErrorStoreInheader(aMethodObj, (homeMethod->methodHeader)); - } - else { - isInBlock = 1; - assert(bcpc == ((cogBlockMethod->startpc))); - homeMethod = cmHomeMethod(cogBlockMethod); - map = findMapLocationForMcpcinMethod((((usqInt)cogBlockMethod)) + (sizeof(CogBlockMethod)), homeMethod); - assert(map != 0); - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert(((((usqInt)(annotation)) >> AnnotationShift) == HasBytecodePC) - || ((((usqInt)(annotation)) >> AnnotationShift) == IsDisplacementX2N)); - while (((annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift)) != HasBytecodePC) { - map -= 1; - } - - /* skip fiducial; i.e. the map entry for the pc immediately following the method header. */ - map -= 1; - aMethodObj = (homeMethod->methodObject); - bcpc = startbcpc - ( -#if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet((homeMethod->methodHeader)) - ? AltBlockCreationBytecodeSize - : BlockCreationBytecodeSize) -#else // MULTIPLEBYTECODESETS - BlockCreationBytecodeSize -#endif - ); - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader1 = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader1) - ? 0x100 - : 0) -# else - 0 -# endif - ; - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - endbcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, -1, aMethodObj)) - : 0)); - bcpc = startbcpc; - } - nExts = 0; - while ((((usqInt)((byteAt(map)))) >> AnnotationShift) != HasBytecodePC) { - map -= 1; - } - map -= 1; - while (((mapByte = byteAt(map))) != MapEnd) { - - /* defensive; we exit on bcpc */ - if (mapByte >= FirstAnnotation) { - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if (annotation >= HasBytecodePC) { - if ((annotation == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - while (1) { - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - if (isInBlock) { - if (bcpc >= endbcpc) { - errCode = 0; - goto l7; - } - } - else { - if (((descriptor->isReturn)) - && (bcpc >= latestContinuation)) { - errCode = 0; - goto l7; - } - if ((isBranch(descriptor)) - || ((descriptor->isBlockCreation))) { - /* begin latestContinuationPCFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj); - targetPC = (bcpc + ((descriptor->numBytes))) + (((distance < 0) ? 0 : distance)); - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - /* latestContinuation = */ latestContinuation; - } - nextBcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) - : 0)); - if (((descriptor->isMapped)) - || (isInBlock - && ((descriptor->isMappedInBlock)))) break; - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - isBackwardBranch = (isBranch(descriptor)) - && ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) < 0)); - result = collectCogConstituentForAnnotationMcpcBcpcMethod(descriptor, ((isBackwardBranch - ? (((sqInt)((usqInt)(annotation) << 1))) + 1 - : ((sqInt)((usqInt)(annotation) << 1)))), (((char *) mcpc)), ((isBackwardBranch - ? bcpc - (2 * nExts) - : bcpc)), (((void *)cogMethod))); - if (result != 0) { - errCode = result; - goto l7; - } - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - } - else { - assert(((((usqInt)(mapByte)) >> AnnotationShift) == IsDisplacementX2N) - || ((((usqInt)(mapByte)) >> AnnotationShift) == IsAnnotationExtension)); - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - errCode = 0; - l7: /* end mapFor:bcpc:performUntil:arg: */; - if (errCode != 0) { - popRemappableOop(); - return null; - } - if (cogConstituentIndex < nSlots) { - shortentoIndexableSize(topRemappableOop(), cogConstituentIndex); - } - return popRemappableOop(); -} - - /* Cogit>>#compactCogCompiledCode */ -void -compactCogCompiledCode(void) -{ - assertValidDualZone(); - assert(noCogMethodsMaximallyMarked()); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - markActiveMethodsAndReferents(); - freeOlderMethodsForCompaction(); - compactPICsWithFreedTargets(); - planCompaction(); - updateStackZoneReferencesToCompiledCodePreCompaction(); - relocateMethodsPreCompaction(); - assertValidDualZone(); - compactCompiledCode(); - stopsFromto(backEnd, freeStart(), (youngReferrers()) - 1); - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), ((usqInt)(youngReferrers()))); - assert(allMethodsHaveCorrectHeader()); - assert(kosherYoungReferrers()); - assertValidDualZone(); -} - - /* Cogit>>#compactPICsWithFreedTargets */ -static void -compactPICsWithFreedTargets(void) -{ - CogMethod *cogMethod; - sqInt count; - - cogMethod = ((CogMethod *) methodZoneBase); - count = 0; - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) == CMClosedPIC) - && (cPICCompactAndIsNowEmpty(cogMethod))) { - ((((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)))->cmType = CMFree); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - count += 1; - } - assert(count == (numMethods())); -} - - -/* The start of a CogMethod has a call to a run-time abort routine that - either handles an in-line cache failure or a stack overflow. The routine - selects the - path depending on ReceiverResultReg; if zero it takes the stack overflow - path; if nonzero the in-line cache miss path. Neither of these paths - returns. The abort routine must be called; In the callee the method is - located by - adding the relevant offset to the return address of the call. - - N.B. This code must match that in compilePICAbort: so that the offset of - the return address of the call is the same in methods and closed PICs. */ - - /* Cogit>>#compileAbort */ -static AbstractInstruction * -compileAbort(void) -{ - AbstractInstruction *anInstruction; - sqInt callTarget; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 0, ReceiverResultReg); - stackOverflowCall = anInstruction; - - /* If there is a link register it must be saved (pushed onto the stack) before it - is smashed by the abort call, and hence needs to be manually handled here */ - sendMiss = genoperand(PushR, LinkReg); - /* begin Call: */ - callTarget = methodAbortTrampolineFor(methodOrBlockNumArgs); - return genoperand(Call, callTarget); -} - - /* Cogit>>#compileBlockDispatchFrom:to: */ -static sqInt NoDbgRegParms -compileBlockDispatchFromto(sqInt lowBlockStartIndex, sqInt highBlockStartIndex) -{ - AbstractInstruction *anInstruction; - BlockStart *blockStart; - sqInt halfWay; - AbstractInstruction *jmp; - - if (lowBlockStartIndex == highBlockStartIndex) { - blockStart = blockStartAt(lowBlockStartIndex); - genoperand(Jump, ((sqInt)((blockStart->entryLabel)))); - return null; - } - halfWay = (highBlockStartIndex + lowBlockStartIndex) / 2; - assert(((halfWay >= lowBlockStartIndex) && (halfWay <= highBlockStartIndex))); - - /* N.B. FLAGS := TempReg - startpc */ - blockStart = blockStartAt(halfWay); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)(((blockStart->startpc)) + 1) << 1) | 1); - anInstruction = genoperandoperand(CmpCqR, (((usqInt)(((blockStart->startpc)) + 1) << 1) | 1), TempReg); - if (lowBlockStartIndex == halfWay) { - genConditionalBranchoperand(JumpLessOrEqual, ((sqInt)((blockStart->entryLabel)))); - compileBlockDispatchFromto(halfWay + 1, highBlockStartIndex); - return null; - } - if ((halfWay + 1) == highBlockStartIndex) { - blockStart = blockStartAt(highBlockStartIndex); - genConditionalBranchoperand(JumpGreater, ((sqInt)((blockStart->entryLabel)))); - return compileBlockDispatchFromto(lowBlockStartIndex, halfWay); - } - jmp = genConditionalBranchoperand(JumpGreater, ((sqInt)0)); - compileBlockDispatchFromto(lowBlockStartIndex, halfWay); - if (halfWay == highBlockStartIndex) { - blockStart = blockStartAt(highBlockStartIndex); - jmpTarget(jmp, (blockStart->entryLabel)); - } - else { - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileBlockDispatchFromto(halfWay + 1, highBlockStartIndex); - } - return 0; -} - - -/* Compile a block's entry. This looks like a dummy CogBlockMethod header - (for frame parsing) - followed by either a frame build, if a frame is required, or nothing. The - CogMethodHeader's objectHeader field is a back pointer to the method, but - this can't be filled in until code generation. */ - - /* Cogit>>#compileBlockEntry: */ -static void NoDbgRegParms -compileBlockEntry(BlockStart *blockStart) -{ - AbstractInstruction *abstractInstruction; - sqInt alignment; - - /* begin AlignmentNops: */ - alignment = blockAlignment(); - genoperand(AlignmentNops, alignment); - (blockStart->fakeHeader = genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - switch (sizeof(CogBlockMethod)) { - case 8: - genoperand(Fill32, 0); - genoperand(Fill32, 0); - break; - case 12: - genoperand(Fill32, 0); - genoperand(Fill32, 0); - genoperand(Fill32, 0); - break; - case 16: - genoperand(Fill32, 0); - genoperand(Fill32, 0); - genoperand(Fill32, 0); - genoperand(Fill32, 0); - break; - default: - error("Case not found and no otherwise clause"); - } - (blockStart->entryLabel = genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (needsFrame) { - compileBlockFrameBuild(blockStart); - if (recordBlockTrace()) { - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceTraceBlockActivationTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - } - } - else { - compileBlockFramelessEntry(blockStart); - } -} - - -/* Generate a call to aRoutine with up to 4 arguments. If resultRegOrNone is - not NoReg assign the C result to resultRegOrNone. If saveRegs, save all - registers. Hack: a negative arg value indicates an abstract register, a - non-negative value - indicates a constant. */ - - /* Cogit>>#compileCallFor:numArgs:arg:arg:arg:arg:floatResultReg:regsToSave: */ -static void NoDbgRegParms -compileCallFornumArgsargargargargfloatResultRegregsToSave(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt resultRegOrNone, sqInt regMask) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - sqInt delta; - sqInt numRegsPushed; - usqInt regMaskCopy; - sqInt regsToSave; - sqInt wordsPushedModAlignment; - - regsToSave = (resultRegOrNone == NoReg - ? regMask - : ((regMask | (1U << resultRegOrNone)) - (1U << resultRegOrNone))); - if (cStackAlignment > BytesPerWord) { - /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ - regMaskCopy = ((usqInt)regsToSave); - numRegsPushed = 0; - while (regMaskCopy != 0) { - numRegsPushed += regMaskCopy & 1; - regMaskCopy = ((regMaskCopy) >> 1); - } - if ((numRegsPushed == 0) - && ((numIntRegArgs(((AbstractInstruction *) backEnd))) >= numArgs)) { - goto l1; - } - wordsPushedModAlignment = (numRegsPushed + ((((numArgs - (numIntRegArgs(((AbstractInstruction *) backEnd)))) < 0) ? 0 : (numArgs - (numIntRegArgs(((AbstractInstruction *) backEnd))))))) % (cStackAlignment / BytesPerWord); - if (wordsPushedModAlignment != 0) { - delta = (cStackAlignment / BytesPerWord) - wordsPushedModAlignment; - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, delta * BytesPerWord, SPReg); - } - l1: /* end genAlignCStackSavingRegisters:numArgs:wordAlignment: */; - } - genSaveRegs(backEnd, regsToSave); - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - if (numArgs == 0) { - goto l13; - } - if (regOrConst0 < NoReg) { - /* begin MoveCq:R: */ - anInstruction4 = genoperandoperand(MoveCqR, -2 - regOrConst0, A0); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, regOrConst0, A0); - } - if (numArgs == 1) { - goto l13; - } - if (regOrConst1 < NoReg) { - /* begin MoveCq:R: */ - anInstruction11 = genoperandoperand(MoveCqR, -2 - regOrConst1, A1); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, regOrConst1, A1); - } - if (numArgs == 2) { - goto l13; - } - if (regOrConst2 < NoReg) { - /* begin MoveCq:R: */ - anInstruction21 = genoperandoperand(MoveCqR, -2 - regOrConst2, A2); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, regOrConst2, A2); - } - if (numArgs == 3) { - goto l13; - } - if (regOrConst3 < NoReg) { - /* begin MoveCq:R: */ - anInstruction3 = genoperandoperand(MoveCqR, -2 - regOrConst3, A3); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, regOrConst3, A3); - } - l13: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin checkLiteral:forInstruction: */ - anInstruction2 = genoperand(CallFull, ((usqInt)aRoutine)); - if (resultRegOrNone != NoReg) { - cFloatResultToRd(backEnd, resultRegOrNone); - } - assert(numArgs <= 4); - genRestoreRegs(backEnd, regsToSave); -} - - -/* Generate a call to aRoutine with up to 4 arguments. If resultRegOrNone is - not NoReg assign the C result to resultRegOrNone. If saveRegs, save all - registers. Hack: a negative arg value indicates an abstract register, a - non-negative value - indicates a constant. */ - - /* Cogit>>#compileCallFor:numArgs:arg:arg:arg:arg:resultReg:regsToSave: */ -static void NoDbgRegParms -compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt resultRegOrNone, sqInt regMask) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - sqInt delta; - sqInt numRegsPushed; - usqInt regMaskCopy; - sqInt regsToSave; - sqInt wordsPushedModAlignment; - - regsToSave = (resultRegOrNone == NoReg - ? regMask - : ((regMask | (1U << resultRegOrNone)) - (1U << resultRegOrNone))); - if (cStackAlignment > BytesPerWord) { - /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ - regMaskCopy = ((usqInt)regsToSave); - numRegsPushed = 0; - while (regMaskCopy != 0) { - numRegsPushed += regMaskCopy & 1; - regMaskCopy = ((regMaskCopy) >> 1); - } - if ((numRegsPushed == 0) - && ((numIntRegArgs(((AbstractInstruction *) backEnd))) >= numArgs)) { - goto l1; - } - wordsPushedModAlignment = (numRegsPushed + ((((numArgs - (numIntRegArgs(((AbstractInstruction *) backEnd)))) < 0) ? 0 : (numArgs - (numIntRegArgs(((AbstractInstruction *) backEnd))))))) % (cStackAlignment / BytesPerWord); - if (wordsPushedModAlignment != 0) { - delta = (cStackAlignment / BytesPerWord) - wordsPushedModAlignment; - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, delta * BytesPerWord, SPReg); - } - l1: /* end genAlignCStackSavingRegisters:numArgs:wordAlignment: */; - } - genSaveRegs(backEnd, regsToSave); - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - if (numArgs == 0) { - goto l13; - } - if (regOrConst0 < NoReg) { - /* begin MoveCq:R: */ - anInstruction4 = genoperandoperand(MoveCqR, -2 - regOrConst0, A0); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, regOrConst0, A0); - } - if (numArgs == 1) { - goto l13; - } - if (regOrConst1 < NoReg) { - /* begin MoveCq:R: */ - anInstruction11 = genoperandoperand(MoveCqR, -2 - regOrConst1, A1); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, regOrConst1, A1); - } - if (numArgs == 2) { - goto l13; - } - if (regOrConst2 < NoReg) { - /* begin MoveCq:R: */ - anInstruction21 = genoperandoperand(MoveCqR, -2 - regOrConst2, A2); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, regOrConst2, A2); - } - if (numArgs == 3) { - goto l13; - } - if (regOrConst3 < NoReg) { - /* begin MoveCq:R: */ - anInstruction3 = genoperandoperand(MoveCqR, -2 - regOrConst3, A3); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, regOrConst3, A3); - } - l13: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin checkLiteral:forInstruction: */ - anInstruction2 = genoperand(CallFull, ((usqInt)aRoutine)); - genWriteCResultIntoReg(backEnd, resultRegOrNone); - assert(numArgs <= 4); - genRestoreRegs(backEnd, regsToSave); -} - - -/* Generate a call to aRoutine with up to 4 arguments. If resultRegOrNone is - not NoReg assign the C result to resultRegOrNone. If saveRegs, save all - registers. Hack: a negative arg value indicates an abstract register, a - non-negative value - indicates a constant. */ - - /* Cogit>>#compileCallFor:numArgs:arg:arg:arg:arg:resultReg:resultReg:regsToSave: */ -static void NoDbgRegParms -compileCallFornumArgsargargargargresultRegresultRegregsToSave(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt resultRegOrNone, sqInt resultReg2OrNone, sqInt regMask) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - sqInt delta; - sqInt numRegsPushed; - usqInt regMaskCopy; - sqInt regsToSave; - sqInt wordsPushedModAlignment; - - regsToSave = (resultRegOrNone == NoReg - ? regMask - : ((regMask | (1U << resultRegOrNone)) - (1U << resultRegOrNone))); - if (cStackAlignment > BytesPerWord) { - /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ - regMaskCopy = ((usqInt)regsToSave); - numRegsPushed = 0; - while (regMaskCopy != 0) { - numRegsPushed += regMaskCopy & 1; - regMaskCopy = ((regMaskCopy) >> 1); - } - if ((numRegsPushed == 0) - && ((numIntRegArgs(((AbstractInstruction *) backEnd))) >= numArgs)) { - goto l1; - } - wordsPushedModAlignment = (numRegsPushed + ((((numArgs - (numIntRegArgs(((AbstractInstruction *) backEnd)))) < 0) ? 0 : (numArgs - (numIntRegArgs(((AbstractInstruction *) backEnd))))))) % (cStackAlignment / BytesPerWord); - if (wordsPushedModAlignment != 0) { - delta = (cStackAlignment / BytesPerWord) - wordsPushedModAlignment; - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, delta * BytesPerWord, SPReg); - } - l1: /* end genAlignCStackSavingRegisters:numArgs:wordAlignment: */; - } - genSaveRegs(backEnd, regsToSave); - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - if (numArgs == 0) { - goto l13; - } - if (regOrConst0 < NoReg) { - /* begin MoveCq:R: */ - anInstruction4 = genoperandoperand(MoveCqR, -2 - regOrConst0, A0); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, regOrConst0, A0); - } - if (numArgs == 1) { - goto l13; - } - if (regOrConst1 < NoReg) { - /* begin MoveCq:R: */ - anInstruction11 = genoperandoperand(MoveCqR, -2 - regOrConst1, A1); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, regOrConst1, A1); - } - if (numArgs == 2) { - goto l13; - } - if (regOrConst2 < NoReg) { - /* begin MoveCq:R: */ - anInstruction21 = genoperandoperand(MoveCqR, -2 - regOrConst2, A2); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, regOrConst2, A2); - } - if (numArgs == 3) { - goto l13; - } - if (regOrConst3 < NoReg) { - /* begin MoveCq:R: */ - anInstruction3 = genoperandoperand(MoveCqR, -2 - regOrConst3, A3); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, regOrConst3, A3); - } - l13: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin checkLiteral:forInstruction: */ - anInstruction2 = genoperand(CallFull, ((usqInt)aRoutine)); - genWriteCResultIntoReg(backEnd, resultRegOrNone); - genWriteCSecondResultIntoReg(backEnd, resultReg2OrNone); - assert(numArgs <= 4); - genRestoreRegs(backEnd, regsToSave); -} - - -/* Generate a call to aRoutine with up to 4 arguments. If resultRegOrNone is - not NoReg assign the C result to resultRegOrNone. If saveRegs, save all - registers. Hack: a negative arg value indicates an abstract register, a - non-negative value - indicates a constant. */ - - /* Cogit>>#compileCallFor:numArgs:floatArg:floatArg:floatArg:floatArg:resultReg:regsToSave: */ -static void NoDbgRegParms -compileCallFornumArgsfloatArgfloatArgfloatArgfloatArgresultRegregsToSave(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt resultRegOrNone, sqInt regMask) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction2; - sqInt delta; - sqInt numRegsPushed; - usqInt regMaskCopy; - sqInt regsToSave; - sqInt wordsPushedModAlignment; - - regsToSave = (resultRegOrNone == NoReg - ? regMask - : ((regMask | (1U << resultRegOrNone)) - (1U << resultRegOrNone))); - if (cStackAlignment > BytesPerWord) { - /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ - regMaskCopy = ((usqInt)regsToSave); - numRegsPushed = 0; - while (regMaskCopy != 0) { - numRegsPushed += regMaskCopy & 1; - regMaskCopy = ((regMaskCopy) >> 1); - } - if ((numRegsPushed == 0) - && ((numIntRegArgs(((AbstractInstruction *) backEnd))) >= numArgs)) { - goto l1; - } - wordsPushedModAlignment = (numRegsPushed + ((((numArgs - (numIntRegArgs(((AbstractInstruction *) backEnd)))) < 0) ? 0 : (numArgs - (numIntRegArgs(((AbstractInstruction *) backEnd))))))) % (cStackAlignment / BytesPerWord); - if (wordsPushedModAlignment != 0) { - delta = (cStackAlignment / BytesPerWord) - wordsPushedModAlignment; - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, delta * BytesPerWord, SPReg); - } - l1: /* end genAlignCStackSavingRegisters:numArgs:wordAlignment: */; - } - genSaveRegs(backEnd, regsToSave); - genMarshallNArgsfloatArgfloatArgfloatArgfloatArg(backEnd, numArgs, regOrConst0, regOrConst1, regOrConst2, regOrConst3); - /* begin checkLiteral:forInstruction: */ - anInstruction2 = genoperand(CallFull, ((usqInt)aRoutine)); - genWriteCResultIntoReg(backEnd, resultRegOrNone); - genRemoveNFloatArgsFromStack(backEnd, numArgs); - genRestoreRegs(backEnd, regsToSave); -} - - -/* Compile the cache tag computation and the first comparison. Answer the - address of that comparison. */ - - /* Cogit>>#compileCPICEntry */ -static AbstractInstruction * -compileCPICEntry(void) -{ - entry = genGetInlineCacheClassTagFromintoforEntry(ReceiverResultReg, TempReg, 1); - /* begin CmpR:R: */ - assert(!((ClassReg == SPReg))); - genoperandoperand(CmpRR, ClassReg, TempReg); - return genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -} - - -/* Compile the abstract instructions for the entire full block method. */ - - /* Cogit>>#compileEntireFullBlockMethod: */ -static sqInt NoDbgRegParms -compileEntireFullBlockMethod(sqInt numCopied) -{ - sqInt result; - - /* begin preenMethodLabel */ - (((((AbstractInstruction *) methodLabel))->operands))[1] = 0; - compileFullBlockEntry(); - compileFullBlockMethodFrameBuild(numCopied); - if (((result = compileMethodBody())) < 0) { - return result; - } - assert(blockCount == 0); - return 0; -} - - -/* The entry code to a method checks that the class of the current receiver - matches that in the inline cache. Other non-obvious elements are that its - alignment must be - different from the alignment of the noCheckEntry so that the method map - machinery can distinguish normal and super sends (super sends bind to the - noCheckEntry). */ - - /* Cogit>>#compileEntry */ -static void -compileEntry(void) -{ - AbstractInstruction *anInstruction1; - AbstractInstruction * inst; - - entry = genGetInlineCacheClassTagFromintoforEntry(ReceiverResultReg, TempReg, 1); - /* begin CmpR:R: */ - assert(!((ClassReg == SPReg))); - genoperandoperand(CmpRR, ClassReg, TempReg); - genConditionalBranchoperand(JumpNonZero, ((sqInt)sendMiss)); - noCheckEntry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - if (((traceFlags & 0x100) == 0x100)) { - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - /* begin checkLiteral:forInstruction: */ - anInstruction1 = genoperand(CallFull, ceTraceLinkedSendTrampoline); - /* begin PopR: */ - genoperand(PopR, LinkReg); - } -} - - -/* Compile the abstract instructions for the entire method, including blocks. */ -/* Abort for stack overflow on full block activation (no inline cache miss - possible). The flag is SendNumArgsReg. */ - - /* Cogit>>#compileFullBlockEntry */ -static sqInt -compileFullBlockEntry(void) -{ - sqInt alignment; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt callTarget; - AbstractInstruction * jumpNoContextSwitch; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 0, ReceiverResultReg); - stackOverflowCall = anInstruction; - /* begin PushR: */ - genoperand(PushR, LinkReg); - /* begin Call: */ - callTarget = methodAbortTrampolineFor(methodOrBlockNumArgs); - genoperand(Call, callTarget); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, 0, SendNumArgsReg); - fullBlockNoContextSwitchEntry = anInstruction1; - jumpNoContextSwitch = genoperand(Jump, ((sqInt)0)); - /* begin AlignmentNops: */ - alignment = ((BytesPerWord < 8) ? 8 : BytesPerWord); - genoperand(AlignmentNops, alignment); - fullBlockEntry = genoperandoperand(MoveRR, ReceiverResultReg, SendNumArgsReg); - jmpTarget(jumpNoContextSwitch, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - -/* Compile the top-level method body. */ - - /* Cogit>>#compileMethodBody */ -static sqInt -compileMethodBody(void) -{ - if (endPC < initialPC) { - return 0; - } - return compileAbstractInstructionsFromthrough(initialPC + (deltaToSkipPrimAndErrorStoreInheader(methodObj, methodHeader)), endPC); -} - - -/* The start of a PIC has a call to a run-time abort routine that either - handles a dispatch to an - interpreted method or a dispatch of an MNU case. The routine selects the - path by testing - ClassReg, which holds the inline cache tag; if equal to the - picAbortDiscriminatorValue (zero) - it takes the MNU path; if nonzero the dispatch to interpreter path. - Neither of these paths - returns. The abort routine must be called; In the callee the PIC is - located by adding the - relevant offset to the return address of the call. - - N.B. This code must match that in compileAbort so that the offset of the - return address of - the call is the same in methods and closed PICs. */ - - /* Cogit>>#compilePICAbort: */ -static sqInt NoDbgRegParms -compilePICAbort(sqInt numArgs) -{ - AbstractInstruction *anInstruction; - sqInt callTarget; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 0 /* picAbortDiscriminatorValue */, ClassReg); - picMNUAbort = anInstruction; - - /* If there is a link register it must be saved (pushed onto the stack) before it - is smashed by the abort call, and hence needs to be manually handled here */ - picInterpretAbort = genoperand(PushR, LinkReg); - /* begin Call: */ - callTarget = picAbortTrampolineFor(numArgs); - genoperand(Call, callTarget); - return 0; -} - - -/* Compile the compare of stackLimit against the stack pointer, jumping to - the stackOverflowCall if - the stack pointer is below the limit. Answer a bytecode annotated label - that follows the sequence. - - The stack check functions both as a genuine stack limit check to prevent - calls overflowing stack pages, - and as an event/context-switch break out. To cause an event check - (including a check for a required - context switch), stackLimit is set to the highest possible value, and - hence all stack limit checks will - fail. A path in the stack overflow abort then arranges to call event - checking if it has been requested. - - Certain block activations (e.g. valueNoContextSwitch:) must not context - switch, and in that - case, SendNumArgs is set to zero to communicate to the stack overflow - abort that it should - not perform event/context-switch (yet). */ - - /* Cogit>>#compileStackOverflowCheck: */ -static AbstractInstruction * NoDbgRegParms -compileStackOverflowCheck(sqInt canContextSwitch) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction * jumpSkip; - AbstractInstruction * label; - - /* begin checkLiteral:forInstruction: */ - stackLimitAddress(); - anInstruction1 = genoperandoperand(MoveAwR, stackLimitAddress(), TempReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, SPReg); - if (canContextSwitch) { - genConditionalBranchoperand(JumpBelow, ((sqInt)stackOverflowCall)); - label = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - else { - jumpSkip = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 0, SendNumArgsReg); - genoperand(Jump, ((sqInt)stackOverflowCall)); - jmpTarget(jumpSkip, (label = genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - } - /* begin annotateBytecode: */ - (label->annotation = HasBytecodePC); - return label; -} - - -/* Generate a trampoline with up to four arguments. Generate either a call or - a jump to aRoutine - as requested by callJumpBar. If generating a call and resultRegOrNone is - not NoReg pass the C - result back in resultRegOrNone. - Hack: a negative value indicates an abstract register, a non-negative - value indicates a constant. */ - - /* Cogit>>#compileTrampolineFor:numArgs:arg:arg:arg:arg:regsToSave:pushLinkReg:floatResultReg: */ -static void NoDbgRegParms -compileTrampolineFornumArgsargargargargregsToSavepushLinkRegfloatResultReg(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone) -{ - genSmalltalkToCStackSwitch(pushLinkReg); - compileCallFornumArgsargargargargfloatResultRegregsToSave(aRoutine, numArgs, regOrConst0, regOrConst1, regOrConst2, regOrConst3, resultRegOrNone, regMask); - genLoadStackPointers(backEnd); - genTrampolineReturn(pushLinkReg); -} - - -/* Generate a trampoline with up to four arguments. Generate either a call or - a jump to aRoutine - as requested by callJumpBar. If generating a call and resultRegOrNone is - not NoReg pass the C - result back in resultRegOrNone. - Hack: a negative value indicates an abstract register, a non-negative - value indicates a constant. */ - - /* Cogit>>#compileTrampolineFor:numArgs:arg:arg:arg:arg:regsToSave:pushLinkReg:resultReg: */ -static void NoDbgRegParms -compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone) -{ - genSmalltalkToCStackSwitch(pushLinkReg); - compileCallFornumArgsargargargargresultRegregsToSave(aRoutine, numArgs, regOrConst0, regOrConst1, regOrConst2, regOrConst3, resultRegOrNone, regMask); - genLoadStackPointers(backEnd); - genTrampolineReturn(pushLinkReg); -} - - -/* Generate a trampoline with up to four arguments. Generate either a call or - a jump to aRoutine - as requested by callJumpBar. If generating a call and resultRegOrNone is - not NoReg pass the C - result back in resultRegOrNone. - Hack: a negative value indicates an abstract register, a non-negative - value indicates a constant. */ - - /* Cogit>>#compileTrampolineFor:numArgs:arg:arg:arg:arg:regsToSave:pushLinkReg:resultReg:resultReg: */ -static void NoDbgRegParms -compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultRegresultReg(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone, sqInt resultReg2OrNone) -{ - genSmalltalkToCStackSwitch(pushLinkReg); - compileCallFornumArgsargargargargresultRegresultRegregsToSave(aRoutine, numArgs, regOrConst0, regOrConst1, regOrConst2, regOrConst3, resultRegOrNone, resultReg2OrNone, regMask); - genLoadStackPointers(backEnd); - genTrampolineReturn(pushLinkReg); -} - - -/* Generate a trampoline with up to four arguments. Generate either a call or - a jump to aRoutine - as requested by callJumpBar. If generating a call and resultRegOrNone is - not NoReg pass the C - result back in resultRegOrNone. - Hack: a negative value indicates an abstract register, a non-negative - value indicates a constant. */ - - /* Cogit>>#compileTrampolineFor:numArgs:floatArg:floatArg:floatArg:floatArg:regsToSave:pushLinkReg:resultReg: */ -static void NoDbgRegParms -compileTrampolineFornumArgsfloatArgfloatArgfloatArgfloatArgregsToSavepushLinkRegresultReg(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone) -{ - genSmalltalkToCStackSwitch(pushLinkReg); - compileCallFornumArgsfloatArgfloatArgfloatArgfloatArgresultRegregsToSave(aRoutine, numArgs, regOrConst0, regOrConst1, regOrConst2, regOrConst3, resultRegOrNone, regMask); - genLoadStackPointers(backEnd); - genTrampolineReturn(pushLinkReg); -} - - -/* Generate the entry code for a method to determine cmEntryOffset and - cmNoCheckEntryOffset. We - need cmNoCheckEntryOffset up front to be able to generate the map starting - from cmNoCheckEntryOffset */ -/* stack allocate the various collections so that they - are effectively garbage collected on return. */ - - /* Cogit>>#computeEntryOffsets */ -static void -computeEntryOffsets(void) -{ - sqInt fixupSize; - sqInt opcodeSize; - AbstractInstruction *sendMissCall; - - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 24; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - methodOrBlockNumArgs = 0; - sendMissCall = compileAbort(); - compileEntry(); - computeMaximumSizes(); - generateInstructionsAt(methodZoneBase + (sizeof(CogMethod))); - cmEntryOffset = ((entry->address)) - methodZoneBase; - cmNoCheckEntryOffset = ((noCheckEntry->address)) - methodZoneBase; - missOffset = (((sendMissCall->address)) + ((sendMissCall->machineCodeSize))) - methodZoneBase; - entryPointMask = BytesPerWord - 1; - while ((cmEntryOffset & entryPointMask) == (cmNoCheckEntryOffset & entryPointMask)) { - entryPointMask = (entryPointMask + entryPointMask) + 1; - } - if (entryPointMask >= (roundUpToMethodAlignment(backEnd(), 1))) { - error("cannot differentiate checked and unchecked entry-points with current cog method alignment"); - } - checkedEntryAlignment = cmEntryOffset & entryPointMask; - uncheckedEntryAlignment = cmNoCheckEntryOffset & entryPointMask; - assert(checkedEntryAlignment != uncheckedEntryAlignment); -} - - -/* Generate the entry code for a method to determine cmEntryOffset and - cmNoCheckEntryOffset. We - need cmNoCheckEntryOffset up front to be able to generate the map starting - from cmNoCheckEntryOffset */ -/* stack allocate the various collections so that they - are effectively garbage collected on return. */ - - /* Cogit>>#computeFullBlockEntryOffsets */ -static void -computeFullBlockEntryOffsets(void) -{ - sqInt fixupSize; - sqInt opcodeSize; - - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 24; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - methodOrBlockNumArgs = 0; - compileFullBlockEntry(); - computeMaximumSizes(); - generateInstructionsAt(methodZoneBase + (sizeof(CogMethod))); - cbEntryOffset = ((fullBlockEntry->address)) - methodZoneBase; - cbNoSwitchEntryOffset = ((fullBlockNoContextSwitchEntry->address)) - methodZoneBase; -} - - -/* While we order variables in the CoInterpreter in order of dynamic - frequency, and hence - expect that stackPointer will be output first, C optimizers and linkers - may get their own - ideas and ``improve upon'' this ordering. So we cannot depend on - stackPointer being - at the lowest address of the variables we want to access through - VarBaseReg. Here we - choose the minimum amongst a set to try to choose a varBaseAddress that is - just less - than but iwht in range of all variables we want to access through it. */ - - /* Cogit>>#computeGoodVarBaseAddress */ -static usqInt -computeGoodVarBaseAddress(void) -{ - usqInt minAddress; - - - /* stackLimit is e.g. lowest using the clang toolchain on MacOS X */ - minAddress = stackLimitAddress(); - if ((stackPointerAddress()) < minAddress) { - minAddress = stackPointerAddress(); - } - if ((framePointerAddress()) < minAddress) { - minAddress = framePointerAddress(); - } - if ((instructionPointerAddress()) < minAddress) { - minAddress = instructionPointerAddress(); - } - if ((argumentCountAddress()) < minAddress) { - minAddress = argumentCountAddress(); - } - if ((primFailCodeAddress()) < minAddress) { - minAddress = primFailCodeAddress(); - } - return minAddress; -} - - -/* This pass assigns maximum sizes to all abstract instructions and - eliminates jump fixups. - It hence assigns the maximum address an instruction will occur at which - allows the next - pass to conservatively size jumps. */ - - /* Cogit>>#computeMaximumSizes */ -static void -computeMaximumSizes(void) -{ - AbstractInstruction *abstractInstruction; - sqInt i; - sqInt relativeAddress; - - relativeAddress = 0; - for (i = 0; i < opcodeIndex; i += 1) { - maybeBreakGeneratingInstructionWithIndex(i); - abstractInstruction = abstractInstructionAt(i); - (abstractInstruction->address = relativeAddress); - (abstractInstruction->maxSize = computeMaximumSize(abstractInstruction)); - relativeAddress += (abstractInstruction->maxSize); - } -} - - -/* Configure a copy of the prototype CPIC for a two-case PIC for - case0CogMethod and - case1Method - case1Tag. - The tag for case0CogMethod is at the send site and so doesn't need to be - generated. case1Method may be any of - - a Cog method; jump to its unchecked entry-point - - a CompiledMethod; jump to the ceInterpretFromPIC trampoline - - nil; call ceMNUFromPIC - addDelta is the address change from the prototype to the new CPIC - location, needed - because the loading of the CPIC label at the end may use a literal instead - of a pc relative load. */ -/* self disassembleFrom: cPIC asInteger + (self sizeof: CogMethod) to: cPIC - asInteger + closedPICSize - */ - - /* Cogit>>#configureCPIC:Case0:Case1Method:tag:isMNUCase:numArgs:delta: */ -static sqInt NoDbgRegParms -configureCPICCase0Case1MethodtagisMNUCasenumArgsdelta(CogMethod *cPIC, CogMethod *case0CogMethod, sqInt case1Method, sqInt case1Tag, sqInt isMNUCase, sqInt numArgs, sqInt addrDelta) -{ - sqInt caseEndAddress; - int operand; - sqInt targetEntry; - - assert(case1Method != null); - rewriteCallAttarget(backEnd, (((sqInt)cPIC)) + missOffset, picAbortTrampolineFor(numArgs)); - assert(!(inlineCacheTagIsYoung(case1Tag))); - if ((!isMNUCase) - && (methodHasCogMethod(case1Method))) { - operand = 0; - targetEntry = (((sqInt)(cogMethodOf(case1Method)))) + cmNoCheckEntryOffset; - } - else { - - /* We do not scavenge PICs, hence we cannot cache the MNU method if it is in new space. */ - operand = ((case1Method == null) - || (isYoungObject(case1Method)) - ? 0 - : case1Method); - targetEntry = (case1Method == null - ? (((sqInt)cPIC)) + (sizeof(CogMethod)) - : (((sqInt)cPIC)) + (picInterpretAbortOffset())); - } - rewriteJumpLongAttarget(backEnd, (((sqInt)cPIC)) + firstCPICCaseOffset, (((sqInt)case0CogMethod)) + cmNoCheckEntryOffset); - - /* update the cpic case */ - caseEndAddress = addressOfEndOfCaseinCPIC(2, cPIC); - rewriteCPICCaseAttagobjReftarget(caseEndAddress, case1Tag, operand, ((sqInt)((isMNUCase - ? (((sqInt)cPIC)) + (sizeof(CogMethod)) - : targetEntry)))); - relocateMethodReferenceBeforeAddressby(backEnd, ((((sqInt)cPIC)) + cPICEndOfCodeOffset) - (jumpLongByteSize(backEnd)), addrDelta); - rewriteJumpLongAttarget(backEnd, (((sqInt)cPIC)) + cPICEndOfCodeOffset, cPICMissTrampolineFor(numArgs)); - return 0; -} - - -/* Configure a copy of the prototype CPIC for a one-case MNU CPIC that calls - ceMNUFromPIC for - case0Tag The tag for case0 is at the send site and so doesn't need to be - generated. addDelta is the address change from the prototype to the new - CPIC location, needed - because the loading of the CPIC label at the end may be a literal instead - of a pc-relative load. */ -/* adjust the jump at missOffset, the ceAbortXArgs */ - - /* Cogit>>#configureMNUCPIC:methodOperand:numArgs:delta: */ -static sqInt NoDbgRegParms -configureMNUCPICmethodOperandnumArgsdelta(CogMethod *cPIC, sqInt methodOperand, sqInt numArgs, sqInt addrDelta) -{ - int operand; - sqInt target; - - rewriteCallAttarget(backEnd, (((sqInt)cPIC)) + missOffset, picAbortTrampolineFor(numArgs)); - - /* set the jump to the case0 method */ - operand = ((methodOperand == null) - || (isYoungObject(methodOperand)) - ? 0 - : methodOperand); - rewriteJumpLongAttarget(backEnd, (((sqInt)cPIC)) + firstCPICCaseOffset, (((sqInt)cPIC)) + (sizeof(CogMethod))); - storeLiteralbeforeFollowingAddress(backEnd, operand, ((((sqInt)cPIC)) + firstCPICCaseOffset) - (jumpLongByteSize(backEnd))); - rewriteJumpLongAttarget(backEnd, (((sqInt)cPIC)) + cPICEndOfCodeOffset, cPICMissTrampolineFor(numArgs)); - relocateMethodReferenceBeforeAddressby(backEnd, ((((sqInt)cPIC)) + cPICEndOfCodeOffset) - (jumpLongByteSize(backEnd)), addrDelta); - /* begin rewriteCPIC:caseJumpTo: */ - target = addressOfEndOfCaseinCPIC(2, cPIC); - rewriteCPICJumpAttarget(backEnd, (((((sqInt)cPIC)) + firstCPICCaseOffset) - (jumpLongByteSize(backEnd))) - 8 /* loadLiteralByteSize */, target); - return 0; -} - - -/* Scan the CPIC for target methods that have been freed and eliminate them. - Since the first entry cannot be eliminated, answer that the PIC should be - freed if the first entry is to a free target. Answer if the PIC is now - empty or should be freed. */ - - /* Cogit>>#cPICCompactAndIsNowEmpty: */ -static sqInt NoDbgRegParms -cPICCompactAndIsNowEmpty(CogMethod *cPIC) -{ - sqInt entryPoint; - sqInt followingAddress; - sqInt i; - sqInt methods[MaxCPICCases]; - sqInt pc; - int tags[MaxCPICCases]; - CogMethod *targetMethod; - sqInt targets[MaxCPICCases]; - sqInt used; - sqInt valid; - - used = 0; - for (i = 1; i <= ((cPIC->cPICNumCases)); i += 1) { - pc = addressOfEndOfCaseinCPIC(i, cPIC); - entryPoint = (i == 1 - ? jumpLongTargetBeforeFollowingAddress(backEnd, pc) - : jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc)); - - /* Collect all target triples except for triples whose entry-point is a freed method */ - valid = 1; - if (!(((((usqInt)cPIC)) <= (((usqInt)entryPoint))) - && (((((usqInt)cPIC)) + ((cPIC->blockSize))) >= (((usqInt)entryPoint))))) { - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - assert((((targetMethod->cmType)) == CMMethod) - || (((targetMethod->cmType)) == CMFree)); - if (((targetMethod->cmType)) == CMFree) { - if (i == 1) { - return 1; - } - valid = 0; - } - } - if (valid) { - tags[used] = ((i > 1 - ? (/* begin literal32BeforeFollowingAddress: */ - (followingAddress = pc - 16 /* jumpLongConditionalByteSize */), - literalBeforeFollowingAddress(((AbstractInstruction *) backEnd), followingAddress)) - : 0)); - targets[used] = entryPoint; - methods[used] = (literalBeforeFollowingAddress(backEnd, pc - ((i == 1 - ? jumpLongByteSize(backEnd) - : 24)))); - used += 1; - } - } - if (used == ((cPIC->cPICNumCases))) { - return 0; - } - if (used == 0) { - return 1; - } - ((((CogMethod *) ((((usqInt)cPIC)) + codeToDataDelta)))->cPICNumCases = used); - if (used == 1) { - pc = addressOfEndOfCaseinCPIC(2, cPIC); - /* begin rewriteCPIC:caseJumpTo: */ - rewriteCPICJumpAttarget(backEnd, (((((sqInt)cPIC)) + firstCPICCaseOffset) - (jumpLongByteSize(backEnd))) - 8 /* loadLiteralByteSize */, pc); - return 0; - } - for (i = 1; i < used; i += 1) { - pc = addressOfEndOfCaseinCPIC(i + 1, cPIC); - rewriteCPICCaseAttagobjReftarget(pc, tags[i], methods[i], targets[i]); - } - /* begin rewriteCPIC:caseJumpTo: */ - rewriteCPICJumpAttarget(backEnd, (((((sqInt)cPIC)) + firstCPICCaseOffset) - (jumpLongByteSize(backEnd))) - 8 /* loadLiteralByteSize */, pc - cPICCaseSize); - return 0; -} - - -/* The first case in a CPIC doesn't have a class reference so we need only - step over actually usd subsequent cases. - */ - - /* Cogit>>#cPICHasForwardedClass: */ -static sqInt NoDbgRegParms -cPICHasForwardedClass(CogMethod *cPIC) -{ - usqInt classIndex; - sqInt i; - sqInt pc; - - - /* start by finding the address of the topmost case, the cPICNumCases'th one */ - pc = (addressOfEndOfCaseinCPIC((cPIC->cPICNumCases), cPIC)) - 16 /* jumpLongConditionalByteSize */; - for (i = 2; i <= ((cPIC->cPICNumCases)); i += 1) { - /* begin literal32BeforeFollowingAddress: */ - classIndex = literalBeforeFollowingAddress(((AbstractInstruction *) backEnd), pc); - if (isForwardedClassIndex(classIndex)) { - return 1; - } - pc += cPICCaseSize; - } - return 0; -} - - -/* scan the CPIC for target methods that have been freed. */ - - /* Cogit>>#cPICHasFreedTargets: */ -static sqInt NoDbgRegParms -cPICHasFreedTargets(CogMethod *cPIC) -{ - sqInt entryPoint; - sqInt i; - sqInt pc; - CogMethod *targetMethod; - - for (i = 1; i <= ((cPIC->cPICNumCases)); i += 1) { - pc = addressOfEndOfCaseinCPIC(i, cPIC); - - /* Find target from jump. Ignore jumps to the interpret and MNU calls within this PIC */ - entryPoint = (i == 1 - ? jumpLongTargetBeforeFollowingAddress(backEnd, pc) - : jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc)); - if (!(((((usqInt)cPIC)) <= (((usqInt)entryPoint))) - && (((((usqInt)cPIC)) + ((cPIC->blockSize))) >= (((usqInt)entryPoint))))) { - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - assert((((targetMethod->cmType)) == CMMethod) - || (((targetMethod->cmType)) == CMFree)); - if (((targetMethod->cmType)) == CMFree) { - return 1; - } - } - } - return 0; -} - - -/* Whimsey; we want 16rCA5E10 + cPICPrototypeCaseOffset to be somewhere in - the middle of the zone. - */ - - /* Cogit>>#cPICPrototypeCaseOffset */ -static usqInt -cPICPrototypeCaseOffset(void) -{ - return ((methodZoneBase + (youngReferrers())) / 2) - 13262352; -} - - -/* Are any of the jumps from this CPIC to targetMethod? */ - - /* Cogit>>#cPIC:HasTarget: */ -static sqInt NoDbgRegParms -cPICHasTarget(CogMethod *cPIC, CogMethod *targetMethod) -{ - sqInt i; - sqInt pc; - sqInt target; - - target = (((usqInt)targetMethod)) + cmNoCheckEntryOffset; - - /* Since this is a fast test doing simple compares we don't need to care that some - cases have nonsense addresses in there. Just zip on through. */ - /* First jump is unconditional; subsequent ones are conditional */ - pc = (((sqInt)cPIC)) + firstCPICCaseOffset; - if (target == (jumpLongTargetBeforeFollowingAddress(backEnd, pc))) { - return 1; - } - for (i = 2; i <= MaxCPICCases; i += 1) { - pc += cPICCaseSize; - if (target == (jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc))) { - return 1; - } - } - return 0; -} - - -/* Answer an Array of the PIC's selector, followed by class and - targetMethod/doesNotUnderstand: for each entry in the PIC. - */ - - /* Cogit>>#createCPICData: */ -static sqInt NoDbgRegParms -createCPICData(CogMethod *cPIC) -{ - sqInt class; - usqInt entryPoint; - sqInt i; - sqInt pc; - sqInt picData; - sqInt target; - CogMethod *targetMethod; - - assert((((cPIC->methodObject)) == 0) - || (addressCouldBeOop((cPIC->methodObject)))); - picData = instantiateClassindexableSize(classArray(), (((cPIC->cPICNumCases)) * 2) + 1); - if (!picData) { - return picData; - } - storePointerUncheckedofObjectwithValue(0, picData, (cPIC->selector)); - for (i = 1; i <= ((cPIC->cPICNumCases)); i += 1) { - pc = addressOfEndOfCaseinCPIC(i, cPIC); - if (i == 1) { - - /* first case may have been collected and stored here by collectCogConstituentFor:Annotation:Mcpc:Bcpc:Method: */ - class = (cPIC->methodObject); - if (class == 0) { - class = nilObject(); - } - entryPoint = jumpLongTargetBeforeFollowingAddress(backEnd, pc); - } - else { - class = classForInlineCacheTag(literalBeforeFollowingAddress(backEnd, pc - 16 /* jumpLongConditionalByteSize */)); - entryPoint = jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc); - } - if (((((usqInt)cPIC)) <= (((usqInt)entryPoint))) - && (((((usqInt)cPIC)) + ((cPIC->blockSize))) >= (((usqInt)entryPoint)))) { - target = splObj(SelectorDoesNotUnderstand); - } - else { - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - assert(((targetMethod->cmType)) == CMMethod); - target = (targetMethod->methodObject); - } - storePointerUncheckedofObjectwithValue((i * 2) - 1, picData, class); - storePointerUncheckedofObjectwithValue(i * 2, picData, target); - } - beRootIfOld(picData); - (cPIC->methodObject = 0); - return picData; -} - - -/* Division is a little weird on some processors. Defer to the backEnd - to allow it to generate any special code it may need to. */ - - /* Cogit>>#DivR:R:Quo:Rem: */ -static AbstractInstruction * NoDbgRegParms -gDivRRQuoRem(sqInt rDivisor, sqInt rDividend, sqInt rQuotient, sqInt rRemainder) -{ - genDivRRQuoRem(backEnd, rDivisor, rDividend, rQuotient, rRemainder); - return abstractInstructionAt(opcodeIndex - 1); -} - - -/* Return the default number of bytes to allocate for native code at startup. - The actual value can be set via vmParameterAt: and/or a preference in the - ini file. */ - - /* Cogit>>#defaultCogCodeSize */ -sqInt -defaultCogCodeSize(void) -{ - return 0x180000; -} - - -/* Answer the number of bytecodes to skip to get to the first bytecode - past the primitive call and any store of the error code. */ - - /* Cogit>>#deltaToSkipPrimAndErrorStoreIn:header: */ -static sqInt NoDbgRegParms -deltaToSkipPrimAndErrorStoreInheader(sqInt aMethodObj, sqInt aMethodHeader) -{ - return (((primitiveIndexOfMethodheader(aMethodObj, aMethodHeader)) > 0) - && ((longStoreBytecodeForHeader(aMethodHeader)) == (fetchByteofObject((startPCOfMethod(aMethodObj)) + (sizeOfCallPrimitiveBytecode(aMethodHeader)), aMethodObj))) - ? (sizeOfCallPrimitiveBytecode(aMethodHeader)) + (sizeOfLongStoreTempBytecode(aMethodHeader)) - : 0); -} - - /* Cogit>>#endPCOf: */ -static sqInt NoDbgRegParms -endPCOf(sqInt aMethod) -{ - sqInt bsOffset; - sqInt byte; - BytecodeDescriptor *descriptor; - sqInt distance; - sqInt end; - sqInt latestContinuation; - sqInt nExts; - sqInt pc; - sqInt prim; - sqInt targetPC; - - pc = (latestContinuation = startPCOfMethod(aMethod)); - if (((prim = primitiveIndexOf(aMethod))) > 0) { - if (isQuickPrimitiveIndex(prim)) { - return pc - 1; - } - } - /* begin bytecodeSetOffsetFor: */ - bsOffset = -# if MULTIPLEBYTECODESETS - (methodUsesAlternateBytecodeSet(aMethod) - ? 0x100 - : 0) -# else - (assert(!((methodUsesAlternateBytecodeSet(aMethod)))), - 0) -# endif - ; - nExts = 0; - end = numBytesOf(aMethod); - while (pc <= end) { - byte = fetchByteofObject(pc, aMethod); - descriptor = generatorAt(byte + bsOffset); - if (((descriptor->isReturn)) - && (pc >= latestContinuation)) { - end = pc; - } - if ((isBranch(descriptor)) - || ((descriptor->isBlockCreation))) { - distance = ((descriptor->spanFunction))(descriptor, pc, nExts, aMethod); - targetPC = (pc + ((descriptor->numBytes))) + distance; - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - if ((descriptor->isBlockCreation)) { - pc += distance; - } - } - else { - /* latestContinuation = */ latestContinuation; - } - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - pc += (descriptor->numBytes); - } - return end; -} - - -/* This is a static version of ceEnterCogCodePopReceiverReg - for break-pointing when debugging in C. */ -/* This exists only for break-pointing. */ - - /* Cogit>>#enterCogCodePopReceiver */ -void -enterCogCodePopReceiver(void) -{ - realCEEnterCogCodePopReceiverReg(); - error("what??"); -} - - -/* Answer if the entryPoint's tag is expected to be a selector reference, as - opposed to a class tag. - */ - - /* Cogit>>#entryPointTagIsSelector: */ -static sqInt NoDbgRegParms -entryPointTagIsSelector(sqInt entryPoint) -{ - return (entryPoint < methodZoneBase) - || (((entryPoint & entryPointMask) == uncheckedEntryAlignment) - || (((entryPoint & entryPointMask) == checkedEntryAlignment) - && ((((((CogMethod *) (entryPoint - cmEntryOffset)))->cmType)) == CMOpenPIC))); -} - - -/* Use asserts to check if the ClosedPICPrototype is as expected from - compileClosedPICPrototype, and can be updated as required via - rewriteCPICCaseAt:tag:objRef:target:. If all asserts pass, answer - 0, otherwise answer a bit mask identifying all the errors. */ -/* self disassembleFrom: methodZoneBase + (self sizeof: CogMethod) to: - methodZoneBase + closedPICSize - */ - - /* Cogit>>#expectedClosedPICPrototype: */ -static sqInt NoDbgRegParms -expectedClosedPICPrototype(CogMethod *cPIC) -{ - usqInt classTag; - sqInt classTagPC; - usqInt entryPoint; - sqInt errors; - sqInt i; - sqInt methodObjPC; - usqInt object; - sqInt pc; - - errors = 0; - - /* First jump is unconditional; subsequent ones are conditional */ - pc = (((usqInt)cPIC)) + firstCPICCaseOffset; - object = literalBeforeFollowingAddress(backEnd, pc - (jumpLongByteSize(backEnd))); - if (!(asserta(object == (firstPrototypeMethodOop())))) { - errors = 1; - } - entryPoint = jumpLongTargetBeforeFollowingAddress(backEnd, pc); - if (!(asserta(entryPoint == ((cPICPrototypeCaseOffset()) + 13262352)))) { - errors += 2; - } - for (i = 1; i < MaxCPICCases; i += 1) { - - /* verify information in case is as expected. */ - pc += cPICCaseSize; - methodObjPC = (pc - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */; - object = literalBeforeFollowingAddress(backEnd, methodObjPC); - if (!(asserta(object == ((subsequentPrototypeMethodOop()) + i)))) { - errors = errors | 4; - } - classTagPC = pc - 16 /* jumpLongConditionalByteSize */; - /* begin literal32BeforeFollowingAddress: */ - classTag = literalBeforeFollowingAddress(((AbstractInstruction *) backEnd), classTagPC); - if (!(asserta(classTag == (3133021973U + i)))) { - errors = errors | 8; - } - entryPoint = jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc); - if (!(asserta(entryPoint == (((cPICPrototypeCaseOffset()) + 13262352) + (i * 16))))) { - errors = errors | 16; - } - rewriteCPICCaseAttagobjReftarget(pc, classTag ^ 0x5A5A5A5A, object ^ 0xA5A5A5A5U, entryPoint ^ 0x55AA50); - object = literalBeforeFollowingAddress(backEnd, methodObjPC); - if (!(asserta(object == (((subsequentPrototypeMethodOop()) + i) ^ 0xA5A5A5A5U)))) { - errors = errors | 32; - } - /* begin literal32BeforeFollowingAddress: */ - classTag = literalBeforeFollowingAddress(((AbstractInstruction *) backEnd), classTagPC); - if (!(asserta(classTag == ((3133021973U + i) ^ 0x5A5A5A5A)))) { - errors = errors | 64; - } - entryPoint = jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc); - if (!(asserta(entryPoint == ((((cPICPrototypeCaseOffset()) + 13262352) + (i * 16)) ^ 0x55AA50)))) { - errors = errors | 128; - } - rewriteCPICCaseAttagobjReftarget(pc, classTag ^ 0x5A5A5A5A, object ^ 0xA5A5A5A5U, entryPoint ^ 0x55AA50); - } - entryPoint = jumpLongTargetBeforeFollowingAddress(backEnd, (((usqInt)cPIC)) + cPICEndOfCodeOffset); - if (!(asserta(entryPoint == (cPICMissTrampolineFor(0))))) { - errors += 0x100; - } - return errors; -} - - -/* 224 11100000 aaaaaaaa Extend A (Ext A = Ext A prev * 256 + Ext A) */ - - /* Cogit>>#extABytecode */ -static sqInt -extABytecode(void) -{ - extA = ((((sqInt)((usqInt)(extA) << 8)))) + byte1; - return 0; -} - - -/* 225 11100001 sbbbbbbb Extend B (Ext B = Ext B prev * 256 + Ext B) */ - - /* Cogit>>#extBBytecode */ -static sqInt -extBBytecode(void) -{ - extB = ((numExtB == 0) - && (byte1 > 0x7F) - ? byte1 - 0x100 - : ((((sqInt)((usqInt)(extB) << 8)))) + byte1); - numExtB += 1; - return 0; -} - - -/* Fill in the block headers now we know the exact layout of the code. */ - - /* Cogit>>#fillInBlockHeadersAt: */ -static sqInt NoDbgRegParms -fillInBlockHeadersAt(sqInt startAddress) -{ - sqInt aCogMethodOrInteger; - CogBlockMethod *blockHeader; - BlockStart *blockStart; - sqInt i; - - if (!(needsFrame - && (blockCount > 0))) { - return null; - } - if (blockNoContextSwitchOffset == null) { - blockNoContextSwitchOffset = ((blockEntryLabel->address)) - ((blockEntryNoContextSwitch->address)); - } - else { - assert(blockNoContextSwitchOffset == (((blockEntryLabel->address)) - ((blockEntryNoContextSwitch->address)))); - } - for (i = 0; i < blockCount; i += 1) { - blockStart = blockStartAt(i); - /* begin writableBlockMethodFor: */ - aCogMethodOrInteger = (((blockStart->fakeHeader))->address); - blockHeader = ((CogBlockMethod *) ((((usqInt)aCogMethodOrInteger)) + codeToDataDelta)); - (blockHeader->homeOffset = ((((blockStart->fakeHeader))->address)) - startAddress); - (blockHeader->startpc = (blockStart->startpc)); - (blockHeader->cmType = CMBlock); - (blockHeader->cmNumArgs = (blockStart->numArgs)); - (blockHeader->cbUsesInstVars = (blockStart->hasInstVarRef)); - (blockHeader->stackCheckOffset = (((blockStart->stackCheckLabel)) == null - ? 0 - : ((((blockStart->stackCheckLabel))->address)) - ((((blockStart->fakeHeader))->address)))); - } - return 0; -} - - -/* Fill in the header for theCogMehtod method. This may be located at the - writable mapping. */ - - /* Cogit>>#fillInMethodHeader:size:selector: */ -static void NoDbgRegParms -fillInMethodHeadersizeselector(CogMethod *method, sqInt size, sqInt selector) -{ - sqInt actualMethodLocation; - CogMethod *originalMethod; - sqInt rawHeader; - - actualMethodLocation = (((usqInt)method)) - codeToDataDelta; - (method->cmType = CMMethod); - (method->objectHeader = nullHeaderForMachineCodeMethod()); - (method->blockSize = size); - (method->methodObject = methodObj); - - /* If the method has already been cogged (e.g. Newspeak accessors) then - leave the original method attached to its cog method, but get the right header. */ - rawHeader = rawHeaderOf(methodObj); - if (isCogMethodReference(rawHeader)) { - originalMethod = ((CogMethod *) rawHeader); - assert(((originalMethod->blockSize)) == size); - assert(methodHeader == ((originalMethod->methodHeader))); - } - else { - rawHeaderOfput(methodObj, actualMethodLocation); - } - (method->methodHeader = methodHeader); - (method->selector = selector); - (method->cmNumArgs = argumentCountOfMethodHeader(methodHeader)); - (method->cmHasMovableLiteral = hasMovableLiteral); - if ((method->cmRefersToYoung = hasYoungReferent)) { - addToYoungReferrers(method); - } - (method->cmUsageCount = initialMethodUsageCount()); - /* begin cpicHasMNUCase: */ - ((((CogBlockMethod *) method))->cpicHasMNUCaseOrCMIsFullBlock) = 0; - (method->cmUsesPenultimateLit = maxLitIndex >= ((literalCountOfMethodHeader(methodHeader)) - 2)); - (method->blockEntryOffset = (blockEntryLabel != null - ? ((blockEntryLabel->address)) - actualMethodLocation - : 0)); - if (needsFrame) { - if (!((((stackCheckLabel->address)) - actualMethodLocation) <= MaxStackCheckOffset)) { - error("too much code for stack check offset"); - } - } - (method->stackCheckOffset = (needsFrame - ? ((stackCheckLabel->address)) - actualMethodLocation - : 0)); - assert((callTargetFromReturnAddress(backEnd, actualMethodLocation + missOffset)) == (methodAbortTrampolineFor((method->cmNumArgs)))); - assert(size == (roundUpLength(size))); - /* begin assertValidDualZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, actualMethodLocation + cmNoCheckEntryOffset, codeToDataDelta); -# endif - /* begin maybeEnableSingleStep */ -} - - /* Cogit>>#findBackwardBranch:IsBackwardBranch:Mcpc:Bcpc:MatchingBcpc: */ -static sqInt NoDbgRegParms -findBackwardBranchIsBackwardBranchMcpcBcpcMatchingBcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *targetBcpc) -{ - return ((((isBackwardBranchAndAnnotation & 1) != 0)) - && ((((sqInt)targetBcpc)) == bcpc) - ? ((sqInt)mcpc) - : 0); -} - - /* Cogit>>#findBlockMethodWithEntry:startBcpc: */ -static usqInt NoDbgRegParms -findBlockMethodWithEntrystartBcpc(sqInt blockEntryMcpc, sqInt startBcpc) -{ - CogBlockMethod *cogBlockMethod; - - cogBlockMethod = ((CogBlockMethod *) (blockEntryMcpc - (sizeof(CogBlockMethod)))); - if (((cogBlockMethod->startpc)) == startBcpc) { - return ((usqInt)cogBlockMethod); - } - return 0; -} - - /* Cogit>>#findMapLocationForMcpc:inMethod: */ -static usqInt NoDbgRegParms -findMapLocationForMcpcinMethod(usqInt targetMcpc, CogMethod *cogMethod) -{ - sqInt annotation; - usqInt map; - sqInt mapByte; - sqInt mcpc; - - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - if (mcpc == targetMcpc) { - return map; - } - while (((mapByte = byteAt(map))) != MapEnd) { - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - if (annotation != IsAnnotationExtension) { - mcpc += 4 /* codeGranularity */ * ((annotation == IsDisplacementX2N - ? ((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift)) - : mapByte & DisplacementMask)); - } - if (mcpc >= targetMcpc) { - assert(mcpc == targetMcpc); - if (annotation == IsDisplacementX2N) { - map -= 1; - mapByte = byteAt(map); - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - assert(annotation > IsAnnotationExtension); - } - return map; - } - map -= 1; - } - return 0; -} - - -/* Find the CMMethod or CMBlock that has zero-relative startbcpc as its first - bytecode pc. - As this is for cannot resume processing and/or conversion to machine-code - on backward - branch, it doesn't have to be fast. Enumerate block returns and map to - bytecode pcs. */ - - /* Cogit>>#findMethodForStartBcpc:inHomeMethod: */ -CogBlockMethod * -findMethodForStartBcpcinHomeMethod(sqInt startbcpc, CogMethod *cogMethod) -{ - assert(((cogMethod->cmType)) == CMMethod); - if (startbcpc == (startPCOfMethodHeader((cogMethod->methodHeader)))) { - return ((CogBlockMethod *) cogMethod); - } - assert(((cogMethod->blockEntryOffset)) != 0); - return ((CogBlockMethod *) (blockDispatchTargetsForperformarg(cogMethod, findBlockMethodWithEntrystartBcpc, startbcpc))); -} - - -/* Machine code addresses map to the following bytecode for all bytecodes - except backward branches, where they map to the backward branch itself. - This is so that loops continue, rather than terminate prematurely. */ - - /* Cogit>>#find:IsBackwardBranch:Mcpc:Bcpc:MatchingMcpc: */ -static sqInt NoDbgRegParms -findIsBackwardBranchMcpcBcpcMatchingMcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *targetMcpc) -{ - return (targetMcpc == mcpc - ? ((descriptor == null) - || (((isBackwardBranchAndAnnotation & 1) != 0)) - ? bcpc - : bcpc + ((descriptor->numBytes))) - : 0); -} - - /* Cogit>>#firstMappedPCFor: */ -static sqInt NoDbgRegParms -firstMappedPCFor(CogMethod *cogMethod) -{ - return ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); -} - - -/* Answer a fake value for the first method oop in the PIC prototype. - Since we use MoveUniqueCw:R: it must not be confused with a - method-relative address. */ - - /* Cogit>>#firstPrototypeMethodOop */ -static sqInt -firstPrototypeMethodOop(void) -{ - return (addressIsInCurrentCompilation(99282957) - ? 212332557 - : 99282957); -} - - /* Cogit>>#fixupAt: */ -static BytecodeFixup * NoDbgRegParms -fixupAt(sqInt fixupPC) -{ - return fixupAtIndex(fixupPC - initialPC); -} - - /* Cogit>>#followForwardedLiteralsIn: */ -void -followForwardedLiteralsIn(CogMethod *cogMethod) -{ - sqInt annotation; - sqInt hasYoungObj; - sqInt hasYoungObjPtr; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - CogMethod * writableCogMethod; - - assert((((cogMethod->cmType)) != CMMethod) - || (!(isForwarded((cogMethod->methodObject))))); - writableCogMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - hasYoungObj = isYoung((cogMethod->methodObject)); - if (shouldRemapOop((cogMethod->selector))) { - (writableCogMethod->selector = remapObj((cogMethod->selector))); - if (isYoung((cogMethod->selector))) { - hasYoungObj = 1; - } - } - hasYoungObjPtr = ((sqInt)((&hasYoungObj))); - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = remapIfObjectRefpchasYoung(annotation, (((char *) mcpc)), (((void *)hasYoungObjPtr))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - if (hasYoungObj) { - ensureInYoungReferrers(cogMethod); - } - else { - (writableCogMethod->cmRefersToYoung = 0); - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - /* Cogit>>#followForwardedMethods */ -void -followForwardedMethods(void) -{ - CogMethod * cogMethod; - sqInt freedPIC; - - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - freedPIC = 0; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - if (isForwarded((cogMethod->methodObject))) { - (cogMethod->methodObject = followForwarded((cogMethod->methodObject))); - if (isYoungObject((cogMethod->methodObject))) { - ensureInYoungReferrers(cogMethod); - } - } - } - if (((cogMethod->cmType)) == CMClosedPIC) { - if (followMethodReferencesInClosedPIC(cogMethod)) { - freedPIC = 1; - freeMethod(cogMethod); - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (freedPIC) { - unlinkSendsToFree(); - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - -/* Follow a potential object reference from a closed PIC. - This may be a method reference or null. - Answer if the followed literal is young. - 'mcpc' refers to the jump/branch instruction at the end of - each cpic case */ - - /* Cogit>>#followMaybeObjRefInClosedPICAt: */ -static sqInt NoDbgRegParms -followMaybeObjRefInClosedPICAt(sqInt mcpc) -{ - usqInt object; - sqInt subject; - - object = literalBeforeFollowingAddress(backEnd, mcpc); - if (!(couldBeObject(object))) { - return 0; - } - if (!(isForwarded(object))) { - return isYoungObject(object); - } - subject = followForwarded(object); - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - storeLiteralbeforeFollowingAddress(backEnd, subject, mcpc); - return isYoungObject(subject); -} - - -/* Remap all object references in the closed PIC. Answer if any references - are young. - Set codeModified if any modifications are made. */ - - /* Cogit>>#followMethodReferencesInClosedPIC: */ -static sqInt NoDbgRegParms -followMethodReferencesInClosedPIC(CogMethod *cPIC) -{ - sqInt i; - sqInt pc; - sqInt refersToYoung; - - - /* first we check the potential method oop load at the beginning of the CPIC */ - pc = addressOfEndOfCaseinCPIC(1, cPIC); - - /* We find the end address of the cPICNumCases'th case and can then just step forward by the case size thereafter */ - refersToYoung = followMaybeObjRefInClosedPICAt(pc - (jumpLongByteSize(backEnd))); - - /* Next we check the potential potential method oop load for each case. */ - pc = addressOfEndOfCaseinCPIC((cPIC->cPICNumCases), cPIC); - for (i = 2; i <= ((cPIC->cPICNumCases)); i += 1) { - if (followMaybeObjRefInClosedPICAt((pc - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */)) { - refersToYoung = 1; - } - pc += cPICCaseSize; - } - return refersToYoung; -} - - -/* To avoid runtime checks on literal variable and literal accesses in == and - ~~, - we follow literals in methods having movable literals in the postBecome - action. To avoid scanning every method, we annotate cogMethods with the - cmHasMovableLiteral flag. */ - - /* Cogit>>#followMovableLiteralsAndUpdateYoungReferrers */ -void -followMovableLiteralsAndUpdateYoungReferrers(void) -{ - CogMethod *cogMethod; - - assert(kosherYoungReferrers()); - codeModified = 0; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - if ((cogMethod->cmHasMovableLiteral)) { - followForwardedLiteralsIn(cogMethod); - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - pruneYoungReferrers(); - if (codeModified) { - - /* After updating oops in inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)codeBase), freeStart()); - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - /* Cogit>>#freeCogMethod: */ -void -freeCogMethod(CogMethod *cogMethod) -{ - freeMethod(cogMethod); - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - -/* Free machine-code methods whose compiled methods are unmarked - and open PICs whose selectors are not marked, and closed PICs that - refer to unmarked objects. */ - - /* Cogit>>#freeUnmarkedMachineCode */ -void -freeUnmarkedMachineCode(void) -{ - CogMethod *cogMethod; - sqInt freedMethod; - - freedMethod = 0; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) == CMMethod) - && (!(isMarked((cogMethod->methodObject))))) { - freedMethod = 1; - freeMethod(cogMethod); - } - if ((((cogMethod->cmType)) == CMOpenPIC) - && ((!(isImmediate((cogMethod->selector)))) - && (!(isMarked((cogMethod->selector)))))) { - freedMethod = 1; - freeMethod(cogMethod); - } - if ((((cogMethod->cmType)) == CMClosedPIC) - && (closedPICRefersToUnmarkedObject(cogMethod))) { - freedMethod = 1; - freeMethod(cogMethod); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (freedMethod) { - unlinkSendsToFree(); - } -} - - -/* Call ceSendMustBeBooleanTo: via the relevant trampoline. */ - - /* Cogit>>#genCallMustBeBooleanFor: */ -static AbstractInstruction * NoDbgRegParms -genCallMustBeBooleanFor(sqInt boolean) -{ - AbstractInstruction *abstractInstruction; - sqInt callTarget; - - /* begin CallRT: */ - callTarget = (boolean == (falseObject()) - ? ceSendMustBeBooleanAddFalseTrampoline - : ceSendMustBeBooleanAddTrueTrampoline); - /* begin annotateCall: */ - abstractInstruction = genoperand(Call, callTarget); - (abstractInstruction->annotation = IsRelativeCall); - return abstractInstruction; -} - - /* Cogit>>#genConditionalBranch:operand: */ -static AbstractInstruction * NoDbgRegParms -genConditionalBranchoperand(sqInt opcode, sqInt operandOne) -{ - return noteFollowingConditionalBranch(previousInstruction(), genoperand(opcode, operandOne)); -} - - -/* An enilopmart (the reverse of a trampoline) is a piece of code that makes - the system-call-like transition from the C runtime into generated machine - code. The desired arguments and entry-point are pushed on a stackPage's - stack. The enilopmart pops off the values to be loaded into registers and - then executes a return instruction to pop off the entry-point and jump to - it. - BEFORE AFTER (stacks grow down) - whatever stackPointer -> whatever - target address => reg1 = reg1val, etc - reg1val pc = target address - reg2val - stackPointer -> reg3val */ - - /* Cogit>>#genEnilopmartFor:and:and:forCall:called: */ -static void (*genEnilopmartForandandforCallcalled(sqInt regArg1, sqInt regArg2OrNone, sqInt regArg3OrNone, sqInt forCall, char *trampolineName))(void) - -{ - AbstractInstruction *anInstruction; - sqInt endAddress; - usqInt enilopmart; - sqInt quickConstant; - sqInt size; - - zeroOpcodeIndex(); - /* begin MoveCq:R: */ - quickConstant = varBaseAddress(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - genLoadStackPointers(backEnd); - if (regArg3OrNone != NoReg) { - genoperand(PopR, regArg3OrNone); - } - if (regArg2OrNone != NoReg) { - genoperand(PopR, regArg2OrNone); - } - genoperand(PopR, regArg1); - genEnilopmartReturn(forCall); - computeMaximumSizes(); - size = generateInstructionsAt(methodZoneBase); - endAddress = outputInstructionsAt(methodZoneBase); - assert((methodZoneBase + size) == endAddress); - enilopmart = methodZoneBase; - methodZoneBase = alignUptoRoutineBoundary(endAddress); - stopsFromto(backEnd, endAddress, methodZoneBase - 1); - recordGeneratedRunTimeaddress(trampolineName, enilopmart); - return ((void (*)(void)) enilopmart); -} - - -/* An enilopmart (the reverse of a trampoline) is a piece of code that makes - the system-call-like transition from the C runtime into generated machine - code. At the point the enilopmart enters machine code via a return - instruction, any argument registers have been loaded with their values and - the stack, if - for call, looks like - ret pc - stackPointer -> target address - - and if not for call, looks like - whatever - stackPointer -> target address - - If forCall and running on a CISC, ret pc must be left on the stack. If - forCall and - running on a RISC, ret pc must be popped into LinkReg. In either case, - target address must be removed from the stack and jumped/returned to. */ - - /* Cogit>>#genEnilopmartReturn: */ -static void NoDbgRegParms -genEnilopmartReturn(sqInt forCall) -{ - if (forCall) { - genoperand(PopR, RISCTempReg); - genoperand(PopR, LinkReg); - genoperand(JumpR, RISCTempReg); - } - else { - genoperand(PopR, RISCTempReg); - genoperand(JumpR, RISCTempReg); - } -} - - -/* Generate the routine that writes the current values of the C frame and - stack pointers into - variables. These are used to establish the C stack in trampolines back - into the C run-time. - This routine assumes the system's frame pointer is the same as that used - in generated code. */ - - /* Cogit>>#generateCaptureCStackPointers: */ -static void NoDbgRegParms NeverInline -generateCaptureCStackPointers(sqInt captureFramePointer) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - sqInt callerSavedReg; - sqInt fixupSize; - sqInt offset; - sqInt opcodeSize; - sqInt pushedVarBaseReg; - sqInt quickConstant; - usqInt startAddress; - - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 32; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - - /* Must happen first; value may be used in accessing any of the following addresses */ - startAddress = methodZoneBase; - callerSavedReg = 0; - pushedVarBaseReg = 0; - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { - - /* VarBaseReg is not caller-saved; must save and restore it, either by using an available caller-saved reg or push/pop. */ - - /* TempReg used below */ - callerSavedReg = availableRegisterOrNoneIn(((ABICallerSavedRegisterMask | (1U << TempReg)) - (1U << TempReg))); - if (callerSavedReg == NoReg) { - gNativePushR(VarBaseReg); - pushedVarBaseReg = 1; - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, VarBaseReg, callerSavedReg); - } - } - /* begin MoveCq:R: */ - quickConstant = varBaseAddress(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - if (captureFramePointer) { - /* begin checkLiteral:forInstruction: */ - cFramePointerAddress(); - anInstruction1 = genoperandoperand(MoveRAw, FPReg, cFramePointerAddress()); - } - if (pushedVarBaseReg) { - /* begin LoadEffectiveAddressMw:r:R: */ - offset = (pushedVarBaseReg - ? 0 /* leafCallStackPointerDelta */ + BytesPerWord - : 0 /* leafCallStackPointerDelta */); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(LoadEffectiveAddressMwrR, offset, NativeSPReg, TempReg); - /* begin checkLiteral:forInstruction: */ - cStackPointerAddress(); - anInstruction3 = genoperandoperand(MoveRAw, TempReg, cStackPointerAddress()); - } - else { - /* begin checkLiteral:forInstruction: */ - cStackPointerAddress(); - anInstruction4 = genoperandoperand(MoveRAw, NativeSPReg, cStackPointerAddress()); - } - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { - if (pushedVarBaseReg) { - gNativePopR(VarBaseReg); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, callerSavedReg, VarBaseReg); - } - } - gNativeRetN(0); - outputInstructionsForGeneratedRuntimeAt(startAddress); - flushICacheFromto(backEnd, ((usqInt)startAddress), ((usqInt)methodZoneBase)); - recordGeneratedRunTimeaddress("ceCaptureCStackPointers", startAddress); - ceCaptureCStackPointers = ((void (*)(void)) startAddress); -} - - -/* Generate the prototype ClosedPIC to determine how much space a full closed - PIC takes. - When we first allocate a closed PIC it only has one or two cases and we - want to grow it. - So we have to determine how big a full one is before hand. */ -/* stack allocate the various collections so that they - are effectively garbage collected on return. */ - - /* Cogit>>#generateClosedPICPrototype */ -static void -generateClosedPICPrototype(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - CogMethod * cPIC; - AbstractInstruction * cPICEndOfCodeLabel; - sqInt endAddress; - AbstractInstruction * endCPICCase1; - sqInt fixupSize; - sqInt h; - AbstractInstruction *jumpNext; - sqInt jumpTarget; - sqInt jumpTarget1; - sqInt jumpTarget2; - sqInt numArgs; - sqInt opcode; - sqInt opcodeSize; - sqInt wordConstant; - sqInt wordConstant1; - - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = MaxCPICCases * 9; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - (methodLabel->address = methodZoneBase); - (methodLabel->dependent = null); - /* begin compileClosedPICPrototype */ - compilePICAbort((numArgs = 0)); - - /* At the end of the entry code we need to jump to the first case code, which is actually the last chunk. - On each entension we must update this jump to move back one case. */ - jumpNext = compileCPICEntry(); - /* begin MoveUniqueCw:R: */ - wordConstant1 = firstPrototypeMethodOop(); - /* begin uniqueLiteral:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCwR, wordConstant1, SendNumArgsReg); - /* begin JumpLong: */ - jumpTarget1 = (((methodZoneBase + (youngReferrers())) / 2) - 13262352) + 13262352; - genoperand(JumpLong, jumpTarget1); - endCPICCase0 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - for (h = 1; h < MaxCPICCases; h += 1) { - if (h == (MaxCPICCases - 1)) { - jmpTarget(jumpNext, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - /* begin MoveUniqueCw:R: */ - wordConstant = (subsequentPrototypeMethodOop()) + h; - /* begin uniqueLiteral:forInstruction: */ - anInstruction = genoperandoperand(MoveCwR, wordConstant, SendNumArgsReg); - /* begin gen:literal32:operand: */ - opcode = CmpCwR; - /* begin checkLiteral32:forInstruction: */ - anInstruction1 = genoperandoperand(opcode, 3133021973U + h, TempReg); - /* begin JumpLongZero: */ - jumpTarget = ((((methodZoneBase + (youngReferrers())) / 2) - 13262352) + 13262352) + (h * 16); - genConditionalBranchoperand(JumpLongZero, ((sqInt)jumpTarget)); - if (h == 1) { - endCPICCase1 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - } - /* begin checkLiteral:forInstruction: */ - (methodLabel->address); - anInstruction3 = genoperandoperand(MoveCwR, (methodLabel->address), ClassReg); - /* begin JumpLong: */ - jumpTarget2 = cPICMissTrampolineFor(numArgs); - genoperand(JumpLong, jumpTarget2); - cPICEndOfCodeLabel = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - computeMaximumSizes(); - cPIC = ((CogMethod *) methodZoneBase); - closedPICSize = (sizeof(CogMethod)) + (generateInstructionsAt(methodZoneBase + (sizeof(CogMethod)))); - endAddress = outputInstructionsAt(methodZoneBase + (sizeof(CogMethod))); - assert((methodZoneBase + closedPICSize) == endAddress); - firstCPICCaseOffset = ((endCPICCase0->address)) - methodZoneBase; - cPICEndOfCodeOffset = ((cPICEndOfCodeLabel->address)) - methodZoneBase; - cPICCaseSize = ((endCPICCase1->address)) - ((endCPICCase0->address)); - cPICEndSize = closedPICSize - (((MaxCPICCases - 1) * cPICCaseSize) + firstCPICCaseOffset); - closedPICSize = roundUpToMethodAlignment(backEnd(), closedPICSize); - assert(((picInterpretAbort->address)) == (((methodLabel->address)) + (picInterpretAbortOffset()))); - assert((expectedClosedPICPrototype(cPIC)) == 0); - storeLiteralbeforeFollowingAddress(backEnd, 0, ((endCPICCase0->address)) - (jumpLongByteSize(backEnd))); - methodZoneBase = alignUptoRoutineBoundary(endAddress); - cPICPrototype = cPIC; -} - - -/* We handle jump sizing simply. First we make a pass that asks each - instruction to compute its maximum size. Then we make a pass that - sizes jumps based on the maxmimum sizes. Then we make a pass - that fixes up jumps. When fixing up a jump the jump is not allowed to - choose a smaller offset but must stick to the size set in the second pass. */ - - /* Cogit>>#generateCogFullBlock */ -static CogMethod * -generateCogFullBlock(void) -{ - sqInt codeSize; - usqIntptr_t headerSize; - sqInt mapSize; - CogMethod *method; - sqInt result; - usqInt startAddress; - sqInt totalSize; - - headerSize = sizeof(CogMethod); - (methodLabel->address = freeStart()); - computeMaximumSizes(); - concretizeAt(methodLabel, freeStart()); - codeSize = generateInstructionsAt(((methodLabel->address)) + headerSize); - mapSize = generateMapAtstart(null, ((methodLabel->address)) + cbNoSwitchEntryOffset); - totalSize = roundUpToMethodAlignment(backEnd(), (headerSize + codeSize) + mapSize); - if (totalSize > MaxMethodSize) { - return ((CogMethod *) MethodTooBig); - } - startAddress = allocate(totalSize); - if (startAddress == 0) { - return ((CogMethod *) InsufficientCodeSpace); - } - assert((startAddress + cbEntryOffset) == ((fullBlockEntry->address))); - assert((startAddress + cbNoSwitchEntryOffset) == ((fullBlockNoContextSwitchEntry->address))); - result = outputInstructionsAt(startAddress + headerSize); - assert(((startAddress + headerSize) + codeSize) == result); - padIfPossibleWithStopsFromto(backEnd, result, ((startAddress + totalSize) - mapSize) - 1); - generateMapAtstart((startAddress + totalSize) - 1, startAddress + cbNoSwitchEntryOffset); - flag("TOCHECK"); - method = ((CogMethod *) ((((usqInt)startAddress)) + codeToDataDelta)); - fillInMethodHeadersizeselector(method, totalSize, nilObject()); - (method->cpicHasMNUCaseOrCMIsFullBlock = 1); - flushICacheFromto(backEnd, startAddress, startAddress + totalSize); - return ((CogMethod *) startAddress); -} - - -/* We handle jump sizing simply. First we make a pass that asks each - instruction to compute its maximum size. Then we make a pass that - sizes jumps based on the maxmimum sizes. Then we make a pass - that fixes up jumps. When fixing up a jump the jump is not allowed to - choose a smaller offset but must stick to the size set in the second pass. */ - - /* Cogit>>#generateCogMethod: */ -static CogMethod * NoDbgRegParms -generateCogMethod(sqInt selector) -{ - sqInt codeSize; - usqIntptr_t headerSize; - sqInt mapSize; - sqInt result; - usqInt startAddress; - sqInt totalSize; - - headerSize = sizeof(CogMethod); - (methodLabel->address = freeStart()); - computeMaximumSizes(); - concretizeAt(methodLabel, freeStart()); - codeSize = generateInstructionsAt(((methodLabel->address)) + headerSize); - mapSize = generateMapAtstart(null, ((methodLabel->address)) + cmNoCheckEntryOffset); - totalSize = roundUpToMethodAlignment(backEnd(), (headerSize + codeSize) + mapSize); - if (totalSize > MaxMethodSize) { - return ((CogMethod *) MethodTooBig); - } - startAddress = allocate(totalSize); - if (startAddress == 0) { - return ((CogMethod *) InsufficientCodeSpace); - } - assert((startAddress + cmEntryOffset) == ((entry->address))); - assert((startAddress + cmNoCheckEntryOffset) == ((noCheckEntry->address))); - result = outputInstructionsAt(startAddress + headerSize); - assert(((startAddress + headerSize) + codeSize) == result); - padIfPossibleWithStopsFromto(backEnd, result, ((startAddress + totalSize) - mapSize) - 1); - generateMapAtstart((startAddress + totalSize) - 1, startAddress + cmNoCheckEntryOffset); - fillInBlockHeadersAt(startAddress); - fillInMethodHeadersizeselector(((CogMethod *) ((((usqInt)startAddress)) + codeToDataDelta)), totalSize, selector); - flushICacheFromto(backEnd, startAddress, startAddress + totalSize); - return ((CogMethod *) startAddress); -} - - -/* Generate the method map at addressrNull (or compute it if addressOrNull is - null). Answer the length of the map in byes. Each entry in the map is in - two parts. In the - least signficant bits are a displacement of how far from the start or - previous entry, - unless it is an IsAnnotationExtension byte, in which case those bits are - the extension. - In the most signficant bits are the type of annotation at the point - reached. A null - byte ends the map. */ - - /* Cogit>>#generateMapAt:start: */ -static sqInt NoDbgRegParms -generateMapAtstart(usqInt addressOrNull, usqInt startAddress) -{ - unsigned char annotation; - sqInt delta; - sqInt i; - AbstractInstruction *instruction; - sqInt length; - usqInt location; - sqInt mapEntry; - sqInt maxDelta; - usqInt mcpc; - - length = 0; - location = startAddress; - for (i = 0; i < opcodeIndex; i += 1) { - instruction = abstractInstructionAt(i); - annotation = (instruction->annotation); - if (!(annotation == null)) { - /* begin mapEntryAddress */ - mcpc = ((instruction->address)) + ((instruction->machineCodeSize)); - while (((delta = (mcpc - location) / 4 /* codeGranularity */)) > DisplacementMask) { - maxDelta = (((((delta < MaxX2NDisplacement) ? delta : MaxX2NDisplacement)) | DisplacementMask) - DisplacementMask); - assert((((usqInt)(maxDelta)) >> AnnotationShift) <= DisplacementMask); - if (!(addressOrNull == null)) { - /* begin addToMap:instruction:byte:at:for: */ - codeByteAtput(addressOrNull - length, (((usqInt)(maxDelta)) >> AnnotationShift) + DisplacementX2N); - } - location += maxDelta * 4 /* codeGranularity */; - length += 1; - } - if (!(addressOrNull == null)) { - mapEntry = delta + (((sqInt)((usqInt)((((annotation < IsSendCall) ? annotation : IsSendCall))) << AnnotationShift))); - /* begin addToMap:instruction:byte:at:for: */ - codeByteAtput(addressOrNull - length, mapEntry); - } - location += delta * 4 /* codeGranularity */; - length += 1; - if (annotation > IsSendCall) { - - /* Add the necessary IsAnnotationExtension */ - if (!(addressOrNull == null)) { - mapEntry = (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift))) + (annotation - IsSendCall); - /* begin addToMap:instruction:byte:at:for: */ - codeByteAtput(addressOrNull - length, mapEntry); - } - length += 1; - } - } - } - if (!(addressOrNull == null)) { - /* begin addToMap:instruction:byte:at:for: */ - codeByteAtput(addressOrNull - length, MapEnd); - } - return length + 1; -} - - -/* Generate the prototype OpenPIC to determine how much space an open PIC - takes. - */ -/* stack allocate the various collections so that they - are effectively garbage collected on return. */ - - /* Cogit>>#generateOpenPICPrototype */ -static void -generateOpenPICPrototype(void) -{ - sqInt codeSize; - sqInt fixupSize; - sqInt mapSize; - sqInt opcodeSize; - - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 100; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - (methodLabel->address = methodZoneBase); - (methodLabel->dependent = null); - compileOpenPICnumArgs(specialSelector(0), 2 /* numRegArgs */); - computeMaximumSizes(); - concretizeAt(methodLabel, methodZoneBase); - codeSize = generateInstructionsAt(methodZoneBase + (sizeof(CogMethod))); - mapSize = generateMapAtstart(null, methodZoneBase + cmNoCheckEntryOffset); - openPICSize = (roundUpLength((sizeof(CogMethod)) + codeSize)) + (roundUpToMethodAlignment(backEnd(), mapSize)); -} - - -/* Generate the run-time entries at the base of the native code zone and - update the base. - */ - - /* Cogit>>#generateRunTimeTrampolines */ -static void -generateRunTimeTrampolines(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction2; - - ceSendMustBeBooleanAddFalseTrampoline = genMustBeBooleanTrampolineForcalled(falseObject(), "ceSendMustBeBooleanAddFalseTrampoline"); - ceSendMustBeBooleanAddTrueTrampoline = genMustBeBooleanTrampolineForcalled(trueObject(), "ceSendMustBeBooleanAddTrueTrampoline"); - /* begin genNonLocalReturnTrampoline */ - zeroOpcodeIndex(); - /* begin checkLiteral:forInstruction: */ - instructionPointerAddress(); - anInstruction2 = genoperandoperand(MoveRAw, LinkReg, instructionPointerAddress()); - ceNonLocalReturnTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNonLocalReturn, "ceNonLocalReturnTrampoline", 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 0, NoReg, 1); - /* begin genCheckForInterruptsTrampoline */ - zeroOpcodeIndex(); - /* begin checkLiteral:forInstruction: */ - instructionPointerAddress(); - anInstruction = genoperandoperand(MoveRAw, LinkReg, instructionPointerAddress()); - ceCheckForInterruptTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceCheckForInterrupt, "ceCheckForInterruptTrampoline", 0, null, null, null, null, 0 /* emptyRegisterMask */, 0, NoReg, 1); - ceFetchContextInstVarTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceContextinstVar, "ceFetchContextInstVarTrampoline", 2, ReceiverResultReg, SendNumArgsReg, null, null, 0 /* emptyRegisterMask */, 1, SendNumArgsReg, 0); - ceStoreContextInstVarTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceContextinstVarvalue, "ceStoreContextInstVarTrampoline", 3, ReceiverResultReg, SendNumArgsReg, ClassReg, null, 0 /* emptyRegisterMask */, 1, ReceiverResultReg, 0); - - /* ceInvokeInterpreter is an optimization and a work-around. Historically we used setjmp/longjmp to reenter the - interpreter at the current C stack base. The C stack base is set at start-up and on each callback enter and - callback return. The interpreter must be invoked whenever a non-machine-code method must be run. That might - be when invoking an interpreter method from one of the send linking routines (ceSend:...), or on continuing from - an evaluation primitive such as primitiveExecuteMethod. The problem here is that such primitives could have - been invoked by the interpreter or by machine code. So some form of non-local jump is required. But at least as - early as MSVC Community 2017, the Microshaft longjmp performs stack unwinding which gets hoplessly confused - (bless its little heart) by any stack switch between machine code and C stack, and raises a spurious - Stack cookie instrumentation code detected a stack-based buffer overrun - error from the bowels of gs_report.c _GSHandlerCheck. - Since the CoInterpreter maintains the base of the C stack in CFramePointer & CStackPointer, it is straight-forward - for us to simply call interpret after doing the switch to the C stack, avoiding the stack unwind issue altogether. */ - ceCannotResumeTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceCannotResume, "ceCannotResumeTrampoline", 0, null, null, null, null, 0 /* emptyRegisterMask */, 1, NoReg, 0); - - /* These two are unusual; they are reached by return instructions. */ - ceInvokeInterpret = genInvokeInterpretTrampoline(); - ceReturnToInterpreterTrampoline = genReturnToInterpreterTrampoline(); - ceBaseFrameReturnTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceBaseFrameReturn, "ceBaseFrameReturnTrampoline", 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 0, NoReg, 0); - ceFFICalloutTrampoline = genFFICalloutTrampoline(); - ceMallocTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceMalloc, "ceMallocTrampoline", 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, TempReg, 0); - ceFreeTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceFree, "ceFreeTrampoline", 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, NoReg, 0); -} - - -/* Generate a routine ceCaptureCStackPointers that will capture the C stack - pointer, and, if it is in use, the C frame pointer. These are used in - trampolines to call - run-time routines in the interpreter from machine-code. */ - - /* Cogit>>#generateStackPointerCapture */ -static void -generateStackPointerCapture(void) -{ - usqInt oldMethodZoneBase; - sqInt oldTrampolineTableIndex; - - - /* For the benefit of the following assert, assume the minimum at first. */ - cFramePointerInUse = 0; - assertCStackWellAligned(); - oldMethodZoneBase = methodZoneBase; - oldTrampolineTableIndex = trampolineTableIndex; - generateCaptureCStackPointers(1); - ceCaptureCStackPointers(); - if (!((cFramePointerInUse = checkIfCFramePointerInUse()))) { - methodZoneBase = oldMethodZoneBase; - trampolineTableIndex = oldTrampolineTableIndex; - generateCaptureCStackPointers(0); - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - assertCStackWellAligned(); -} - - -/* Generate the run-time entries and exits at the base of the native code - zone and update the base. - Read the class-side method trampolines for documentation on the various - trampolines - */ - - /* Cogit>>#generateTrampolines */ -static void -generateTrampolines(void) -{ - sqInt fixupSize; - usqInt methodZoneStart; - sqInt opcodeSize; - - methodZoneStart = methodZoneBase; - (methodLabel->address = methodZoneStart); - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 80; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - setHasYoungReferent(0); - generateSendTrampolines(); - generateMissAbortTrampolines(); - generateObjectRepresentationTrampolines(); - generateRunTimeTrampolines(); - generateEnilopmarts(); - generateTracingTrampolines(); - recordGeneratedRunTimeaddress("methodZoneBase", methodZoneBase); -} - - /* Cogit>>#generatorForPC: */ -static BytecodeDescriptor * NoDbgRegParms -generatorForPC(sqInt pc) -{ - return generatorAt(bytecodeSetOffset + (fetchByteofObject(pc, methodObj))); -} - - /* Cogit>>#genFFICalloutTrampoline */ -static usqInt -genFFICalloutTrampoline(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction2; - usqInt startAddress; - - zeroOpcodeIndexForNewOpcodes(); - /* begin checkLiteral:forInstruction: */ - instructionPointerAddress(); - anInstruction = genoperandoperand(MoveRAw, LinkReg, instructionPointerAddress()); - /* begin CallR: */ - genoperand(CallR, TempReg); - /* begin checkLiteral:forInstruction: */ - instructionPointerAddress(); - anInstruction2 = genoperandoperand(MoveAwR, instructionPointerAddress(), LinkReg); - genoperand(RetN, 0); - startAddress = methodZoneBase; - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress("ceFFICalloutTrampoline", startAddress); - recordRunTimeObjectReferences(); - return startAddress; -} - - -/* Generate a pair of routines that answer the frame pointer, and the stack - pointer immediately - after a leaf call, used for checking stack pointer alignment, frame - pointer usage, etc. N.B. - these are exported to the CoInterpreter et al via Cogit - class>>mustBeGlobal:. - */ - - /* Cogit>>#genGetLeafCallStackPointers */ -static void -genGetLeafCallStackPointers(void) -{ - sqInt fixupSize; - sqInt opcodeSize; - usqInt startAddress; - - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 4; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - startAddress = methodZoneBase; - genoperandoperand(MoveRR, FPReg, ABIResultReg); - genoperand(RetN, 0); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress("ceGetFP", startAddress); - ceGetFP = ((usqIntptr_t (*)(void)) startAddress); - startAddress = methodZoneBase; - zeroOpcodeIndex(); - genoperandoperand(MoveRR, NativeSPReg, ABIResultReg); - genoperand(RetN, 0); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress("ceGetSP", startAddress); - ceGetSP = ((usqIntptr_t (*)(void)) startAddress); -} - - -/* Generate the abort for a PIC. This abort performs either a call of - ceInterpretMethodFromPIC:receiver: to handle invoking an uncogged target - or a call of ceMNUFromPICMNUMethod:receiver: to handle an MNU dispatch - in a closed PIC. It distinguishes the two by testing ClassReg. If the - register is zero then this is an MNU. - - This poses a problem in 32-bit Spur, where zero is the cache tag for - immediate characters (tag pattern 2r10) because SmallIntegers have tag - patterns 2r11 - and 2r01, so anding with 1 reduces these to 0 & 1. We solve the ambiguity - by patching send sites with a 0 cache tag to open PICs instead of closed - PICs. */ - - /* Cogit>>#genInnerPICAbortTrampoline: */ -static usqInt NoDbgRegParms -genInnerPICAbortTrampoline(char *name) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *jumpMNUCase; - - /* begin CmpCq:R: */ - anInstruction = genoperandoperand(CmpCqR, 0 /* picAbortDiscriminatorValue */, ClassReg); - jumpMNUCase = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(ceInterpretMethodFromPICreceiver, 2, SendNumArgsReg, ReceiverResultReg, null, null, 0 /* emptyRegisterMask */, 0, NoReg); - jmpTarget(jumpMNUCase, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceMNUFromPICMNUMethodreceiver, name, 2, SendNumArgsReg, ReceiverResultReg, null, null, 0 /* emptyRegisterMask */, 0, NoReg, 1); -} - - -/* Switch to the C stack (do *not* save the Smalltalk stack pointers; - this is the caller's responsibility), and invoke interpret PDQ. */ - - /* Cogit>>#genInvokeInterpretTrampoline */ -static void (*genInvokeInterpretTrampoline(void))(void) - -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - sqInt quickConstant; - usqInt startAddress; - - startAddress = methodZoneBase; - zeroOpcodeIndex(); - /* begin MoveCq:R: */ - quickConstant = varBaseAddress(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - if (cFramePointerInUse) { - genLoadCStackPointers(backEnd); - } - else { - genLoadCStackPointer(backEnd); - } - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l16; - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction5 = genoperandoperand(MoveCqR, -2 - null, A0); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A0); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction11 = genoperandoperand(MoveCqR, -2 - null, A1); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A1); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction21 = genoperandoperand(MoveCqR, -2 - null, A2); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A2); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction31 = genoperandoperand(MoveCqR, -2 - null, A3); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A3); - } - l16: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin checkLiteral:forInstruction: */ - cReturnAddressAddress(); - anInstruction1 = genoperandoperand(MoveAwR, cReturnAddressAddress(), LinkReg); - /* begin checkLiteral:forInstruction: */ - ((sqInt)(((usqInt)interpret))); - anInstruction4 = genoperand(JumpFull, ((sqInt)(((usqInt)interpret)))); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress("ceInvokeInterpret", startAddress); - return ((void (*)(void)) startAddress); -} - - -/* The in-line cache for a send is implemented as a constant load into - ClassReg. We always use a 32-bit load, even in 64-bits. - - In the initial (unlinked) state the in-line cache is notionally loaded - with the selector. - But since in 64-bits an arbitrary selector oop won't fit in a 32-bit - constant load, we - instead load the cache with the selector's index, either into the literal - frame of the - current method, or into the special selector array. Negative values are - 1-relative indices into the special selector array. - - When a send is linked, the load of the selector, or selector index, is - overwritten with a - load of the receiver's class, or class tag. Hence, the 64-bit VM is - currently constrained - to use class indices as cache tags. If out-of-line literals are used, - distinct caches /must - not/ share acche locations, for if they do, send cacheing will be confused - by the sharing. - Hence we use the MoveUniqueC32:R: instruction that will not share literal - locations. */ - - /* Cogit>>#genLoadInlineCacheWithSelector: */ -static void NoDbgRegParms -genLoadInlineCacheWithSelector(sqInt selectorIndex) -{ - AbstractInstruction *anInstruction; - sqInt cacheValue; - sqInt opcode; - sqInt selector; - - assert((selectorIndex < 0 - ? (((-selectorIndex) >= 1) && ((-selectorIndex) <= (numSpecialSelectors()))) - : ((selectorIndex >= 0) && (selectorIndex <= ((literalCountOf(methodObj)) - 1))))); - selector = (selectorIndex < 0 - ? specialSelector(-1 - selectorIndex) - : getLiteral(selectorIndex)); - assert(addressCouldBeOop(selector)); - if (isNonImmediate(selector)) { - setHasMovableLiteral(1); - } - if (isYoung(selector)) { - setHasYoungReferent(1); - } - cacheValue = selector; - /* begin gen:uniqueLiteral32:operand: */ - opcode = MoveCwR; - /* begin uniqueLiteral32:forInstruction: */ - anInstruction = genoperandoperand(opcode, cacheValue, ClassReg); -} - - /* Cogit>>#genReturnToInterpreterTrampoline */ -static usqInt -genReturnToInterpreterTrampoline(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - usqInt startAddress; - - startAddress = methodZoneBase; - zeroOpcodeIndex(); - genoperand(PushR, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperandoperand(MoveMwrR, FoxIFSavedIP, FPReg, TempReg); - /* begin checkLiteral:forInstruction: */ - instructionPointerAddress(); - anInstruction5 = genoperandoperand(MoveRAw, TempReg, instructionPointerAddress()); - genSmalltalkToCStackSwitch(0); - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l17; - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction6 = genoperandoperand(MoveCqR, -2 - null, A0); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A0); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction11 = genoperandoperand(MoveCqR, -2 - null, A1); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A1); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction21 = genoperandoperand(MoveCqR, -2 - null, A2); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A2); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction31 = genoperandoperand(MoveCqR, -2 - null, A3); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A3); - } - l17: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin checkLiteral:forInstruction: */ - cReturnAddressAddress(); - anInstruction = genoperandoperand(MoveAwR, cReturnAddressAddress(), LinkReg); - /* begin checkLiteral:forInstruction: */ - ((sqInt)(((usqInt)interpret))); - anInstruction3 = genoperand(JumpFull, ((sqInt)(((usqInt)interpret)))); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress("ceReturnToInterpreterTrampoline", startAddress); - return startAddress; -} - - -/* If the client requires, then on an ARM-like RISC processor, the return - address needs to - be pushed to the stack so that the interpreter sees the same stack layout - as on CISC. - */ - - /* Cogit>>#genSmalltalkToCStackSwitch: */ -static sqInt NoDbgRegParms -genSmalltalkToCStackSwitch(sqInt pushLinkReg) -{ - if (pushLinkReg) { - genoperand(PushR, LinkReg); - } - genSaveStackPointers(backEnd); - if (cFramePointerInUse) { - genLoadCStackPointers(backEnd); - } - else { - genLoadCStackPointer(backEnd); - } - return 0; -} - - -/* Generate a trampoline with one argument that answers a result. - Hack: a negative value indicates an abstract register, a non-negative - value indicates a constant. */ - - /* Cogit>>#genTrampolineFor:called:arg:floatResult: */ -static usqInt NoDbgRegParms -genTrampolineForcalledargfloatResult(void *aRoutine, char *aString, sqInt regOrConst0, sqInt resultReg) -{ - return genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegfloatResultRegappendOpcodes(aRoutine, aString, 1, regOrConst0, null, null, null, 0 /* emptyRegisterMask */, 1, resultReg, 0); -} - - -/* Generate a trampoline with one argument that answers a result. - Hack: a negative value indicates an abstract register, a non-negative - value indicates a constant. */ - - /* Cogit>>#genTrampolineFor:called:arg:result:result: */ -static usqInt NoDbgRegParms -genTrampolineForcalledargresultresult(void *aRoutine, char *aString, sqInt regOrConst0, sqInt resultReg, sqInt resultReg2) -{ - return genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegresultRegappendOpcodes(aRoutine, aString, 1, regOrConst0, null, null, null, 0 /* emptyRegisterMask */, 1, resultReg, resultReg2, 0); -} - - -/* Generate a trampoline with one argument that answers a result. - Hack: a negative value indicates an abstract register, a non-negative - value indicates a constant. */ - - /* Cogit>>#genTrampolineFor:called:floatArg:result: */ -static usqInt NoDbgRegParms -genTrampolineForcalledfloatArgresult(void *aRoutine, char *aString, sqInt regOrConst0, sqInt resultReg) -{ - return genTrampolineForcallednumArgsfloatArgfloatArgfloatArgfloatArgregsToSavepushLinkRegresultRegappendOpcodes(aRoutine, aString, 1, regOrConst0, null, null, null, 0 /* emptyRegisterMask */, 1, resultReg, 0); -} - - -/* Generate a trampoline with up to four arguments. Generate either a call or - a jump to aRoutineOrNil - as requested by callJumpBar. If generating a call and resultRegOrNone is - not NoReg pass the C result - back in resultRegOrNone. - Hack: a negative value indicates an abstract register, a non-negative - value indicates a constant. */ - - /* Cogit>>#genTrampolineFor:called:numArgs:arg:arg:arg:arg:regsToSave:pushLinkReg:floatResultReg:appendOpcodes: */ -static usqInt NoDbgRegParms -genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegfloatResultRegappendOpcodes(void *aRoutine, char *trampolineName, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone, sqInt appendBoolean) -{ - usqInt startAddress; - - startAddress = methodZoneBase; - if (!appendBoolean) { - zeroOpcodeIndex(); - } - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegfloatResultReg(aRoutine, numArgs, regOrConst0, regOrConst1, regOrConst2, regOrConst3, regMask, pushLinkReg, resultRegOrNone); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress(trampolineName, startAddress); - recordRunTimeObjectReferences(); - return startAddress; -} - - -/* Generate a trampoline with up to four arguments. Generate either a call or - a jump to aRoutineOrNil - as requested by callJumpBar. If generating a call and resultRegOrNone is - not NoReg pass the C result - back in resultRegOrNone. - Hack: a negative value indicates an abstract register, a non-negative - value indicates a constant. */ - - /* Cogit>>#genTrampolineFor:called:numArgs:arg:arg:arg:arg:regsToSave:pushLinkReg:resultReg:appendOpcodes: */ -static usqInt NoDbgRegParms -genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(void *aRoutine, char *trampolineName, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone, sqInt appendBoolean) -{ - usqInt startAddress; - - startAddress = methodZoneBase; - if (!appendBoolean) { - zeroOpcodeIndex(); - } - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(aRoutine, numArgs, regOrConst0, regOrConst1, regOrConst2, regOrConst3, regMask, pushLinkReg, resultRegOrNone); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress(trampolineName, startAddress); - recordRunTimeObjectReferences(); - /* begin assertValidDualZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, codeBase + cmNoCheckEntryOffset, codeToDataDelta); -# endif - return startAddress; -} - - -/* Generate a trampoline with up to four arguments. Generate either a call or - a jump to aRoutineOrNil - as requested by callJumpBar. If generating a call and resultRegOrNone is - not NoReg pass the C result - back in resultRegOrNone. - Hack: a negative value indicates an abstract register, a non-negative - value indicates a constant. */ - - /* Cogit>>#genTrampolineFor:called:numArgs:arg:arg:arg:arg:regsToSave:pushLinkReg:resultReg:resultReg:appendOpcodes: */ -static usqInt NoDbgRegParms -genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegresultRegappendOpcodes(void *aRoutine, char *trampolineName, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone, sqInt resultReg2OrNone, sqInt appendBoolean) -{ - usqInt startAddress; - - startAddress = methodZoneBase; - if (!appendBoolean) { - zeroOpcodeIndex(); - } - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultRegresultReg(aRoutine, numArgs, regOrConst0, regOrConst1, regOrConst2, regOrConst3, regMask, pushLinkReg, resultRegOrNone, resultReg2OrNone); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress(trampolineName, startAddress); - recordRunTimeObjectReferences(); - return startAddress; -} - - -/* Generate a trampoline with up to four arguments. Generate either a call or - a jump to aRoutineOrNil - as requested by callJumpBar. If generating a call and resultRegOrNone is - not NoReg pass the C result - back in resultRegOrNone. - Hack: a negative value indicates an abstract register, a non-negative - value indicates a constant. */ - - /* Cogit>>#genTrampolineFor:called:numArgs:floatArg:floatArg:floatArg:floatArg:regsToSave:pushLinkReg:resultReg:appendOpcodes: */ -static usqInt NoDbgRegParms -genTrampolineForcallednumArgsfloatArgfloatArgfloatArgfloatArgregsToSavepushLinkRegresultRegappendOpcodes(void *aRoutine, char *trampolineName, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone, sqInt appendBoolean) -{ - usqInt startAddress; - - startAddress = methodZoneBase; - if (!appendBoolean) { - zeroOpcodeIndex(); - } - compileTrampolineFornumArgsfloatArgfloatArgfloatArgfloatArgregsToSavepushLinkRegresultReg(aRoutine, numArgs, regOrConst0, regOrConst1, regOrConst2, regOrConst3, regMask, pushLinkReg, resultRegOrNone); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress(trampolineName, startAddress); - recordRunTimeObjectReferences(); - return startAddress; -} - - -/* To return from a trampoline call we have to take the return address off - the stack, - iof it has been saved */ - - /* Cogit>>#genTrampolineReturn: */ -static void NoDbgRegParms -genTrampolineReturn(sqInt lnkRegWasPushed) -{ - if (lnkRegWasPushed - && (1)) { - genoperand(PopR, LinkReg); - genoperand(RetN, 0); - } - else { - genoperand(RetN, 0); - } -} - - -/* */ - - /* Cogit>>#gen: */ -static AbstractInstruction * NoDbgRegParms -gen(sqInt opcode) -{ - AbstractInstruction *abstractInstruction; - - assert(opcodeIndex < numAbstractOpcodes); - abstractInstruction = abstractInstructionAt(opcodeIndex); - opcodeIndex += 1; - (abstractInstruction->opcode = opcode); - return abstractInstruction; -} - - -/* */ -/* */ - - /* Cogit>>#gen:operand: */ -static AbstractInstruction * NoDbgRegParms -genoperand(sqInt opcode, sqInt operand) -{ - AbstractInstruction *abstractInstruction; - - assert(opcodeIndex < numAbstractOpcodes); - abstractInstruction = abstractInstructionAt(opcodeIndex); - opcodeIndex += 1; - (abstractInstruction->opcode = opcode); - ((abstractInstruction->operands))[0] = operand; - return abstractInstruction; -} - - -/* */ -/* */ -/* */ - - /* Cogit>>#gen:operand:operand: */ -static AbstractInstruction * NoDbgRegParms -genoperandoperand(sqInt opcode, sqInt operandOne, sqInt operandTwo) -{ - AbstractInstruction *abstractInstruction; - - assert(opcodeIndex < numAbstractOpcodes); - abstractInstruction = abstractInstructionAt(opcodeIndex); - opcodeIndex += 1; - (abstractInstruction->opcode = opcode); - ((abstractInstruction->operands))[0] = operandOne; - ((abstractInstruction->operands))[1] = operandTwo; - return abstractInstruction; -} - - -/* */ -/* */ -/* */ -/* */ - - /* Cogit>>#gen:operand:operand:operand: */ -static AbstractInstruction * NoDbgRegParms -genoperandoperandoperand(sqInt opcode, sqInt operandOne, sqInt operandTwo, sqInt operandThree) -{ - AbstractInstruction *abstractInstruction; - - assert(opcodeIndex < numAbstractOpcodes); - abstractInstruction = abstractInstructionAt(opcodeIndex); - opcodeIndex += 1; - (abstractInstruction->opcode = opcode); - ((abstractInstruction->operands))[0] = operandOne; - ((abstractInstruction->operands))[1] = operandTwo; - ((abstractInstruction->operands))[2] = operandThree; - return abstractInstruction; -} - - /* Cogit>>#getLiteral: */ -static sqInt NoDbgRegParms -getLiteral(sqInt litIndex) -{ - if (maxLitIndex < litIndex) { - maxLitIndex = litIndex; - } - return literalofMethod(litIndex, methodObj); -} - - /* Cogit>>#incrementUsageOfTargetIfLinkedSend:mcpc:ignored: */ -static sqInt NoDbgRegParms -incrementUsageOfTargetIfLinkedSendmcpcignored(sqInt annotation, char *mcpc, sqInt superfluity) -{ - sqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - - if (annotation >= IsSendCall) { - assert(annotation != IsNSSendCall); - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (((targetMethod1->cmUsageCount)) < (CMMaxUsageCount / 2)) { - ((((CogMethod *) ((((usqInt)targetMethod1)) + codeToDataDelta)))->cmUsageCount = ((targetMethod1->cmUsageCount)) + 1); - } - } - } - return 0; -} - - -/* Answer a usage count that reflects likely long-term usage. */ - - /* Cogit>>#initialClosedPICUsageCount */ -static sqInt -initialClosedPICUsageCount(void) -{ - return CMMaxUsageCount / 2; -} - - /* Cogit>>#initializeBackend */ -static void -initializeBackend(void) -{ - (methodLabel->machineCodeSize = 0); - (methodLabel->opcode = Label); - ((methodLabel->operands))[0] = 0; - ((methodLabel->operands))[1] = 0; - assert((!((registerMaskFor(VarBaseReg)) & CallerSavedRegisterMask))); - varBaseAddress = computeGoodVarBaseAddress(); - assert((stackLimitAddress()) >= varBaseAddress); - assert((cStackPointerAddress()) >= varBaseAddress); - assert((cFramePointerAddress()) >= varBaseAddress); - assert((cReturnAddressAddress()) >= varBaseAddress); - assert((nextProfileTickAddress()) >= varBaseAddress); - } - - /* Cogit>>#initializeCodeZoneFrom:upTo: */ -void -initializeCodeZoneFromupTo(sqInt startAddress, sqInt endAddress) -{ - sqInt fixupSize; - sqInt numberOfAbstractOpcodes; - sqInt opcodeSize; - usqInt startAddress1; - - initializeBackend(); - sqMakeMemoryExecutableFromToCodeToDataDelta(startAddress, endAddress, -# if DUAL_MAPPED_CODE_ZONE - (&codeToDataDelta) -# else - null -# endif - ); - stopsFromto(backEnd, startAddress, endAddress - 1); - codeBase = (methodZoneBase = startAddress); - minValidCallAddress = (((((codeBase < (interpretAddress())) ? codeBase : (interpretAddress()))) < (primitiveFailAddress())) ? (((codeBase < (interpretAddress())) ? codeBase : (interpretAddress()))) : (primitiveFailAddress())); - /* begin manageFrom:to: */ - mzFreeStart = (baseAddress = methodZoneBase); - youngReferrers = (limitAddress = endAddress); - openPICList = null; - methodBytesFreedSinceLastCompaction = 0; - methodCount = 0; - /* begin computeAllocationThreshold */ - allocationThreshold = ((((((usqInt)((limitAddress - baseAddress) * thresholdRatio))) + (7)) & ~7)) + baseAddress; - assertValidDualZone(); - /* begin maybeGenerateCacheFlush */ - /* begin generateVMOwnerLockFunctions */ -# if COGMTVM - /* begin allocateOpcodes:bytecodes: */ - numberOfAbstractOpcodes = numLowLevelLockOpcodes(backEnd); - numAbstractOpcodes = numberOfAbstractOpcodes; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - zeroOpcodeIndex(); - startAddress1 = methodZoneBase; - generateLowLevelTryLock(backEnd, vmOwnerAddress()); - outputInstructionsForGeneratedRuntimeAt(startAddress1); - recordGeneratedRunTimeaddress("ceTryLockVMOwner", startAddress1); - ceTryLockVMOwner = ((usqIntptr_t (*)(usqIntptr_t)) startAddress1); -# endif // COGMTVM - genGetLeafCallStackPointers(); - generateStackPointerCapture(); - generateTrampolines(); - computeEntryOffsets(); - computeFullBlockEntryOffsets(); - generateClosedPICPrototype(); - alignMethodZoneBase(); - flushICacheFromto(backEnd, startAddress, ((usqInt)methodZoneBase)); - /* begin maybeFlushWritableZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - if (codeToDataDelta > 0) { - flushDCacheFromto(backEnd, startAddress, ((usqInt)methodZoneBase)); - } -# endif - /* begin manageFrom:to: */ - mzFreeStart = (baseAddress = methodZoneBase); - youngReferrers = (limitAddress = endAddress); - openPICList = null; - methodBytesFreedSinceLastCompaction = 0; - methodCount = 0; - /* begin computeAllocationThreshold */ - allocationThreshold = ((((((usqInt)((limitAddress - baseAddress) * thresholdRatio))) + (7)) & ~7)) + baseAddress; - generateOpenPICPrototype(); -} - - -/* Answer a usage count that reflects likely long-term usage. - Answer 1 for non-primitives or quick primitives (inst var accessors), - 2 for methods with interpreter primitives, and 3 for compiled primitives. */ - - /* Cogit>>#initialMethodUsageCount */ -static sqInt -initialMethodUsageCount(void) -{ - if ((primitiveIndex == 1) - || (isQuickPrimitiveIndex(primitiveIndex))) { - return 1; - } - if (!(primitiveGeneratorOrNil())) { - return 2; - } - return 3; -} - - -/* Answer a usage count that reflects likely long-term usage. */ - - /* Cogit>>#initialOpenPICUsageCount */ -static sqInt -initialOpenPICUsageCount(void) -{ - return CMMaxUsageCount - 1; -} - - /* Cogit>>#inverseBranchFor: */ -static sqInt NoDbgRegParms -inverseBranchFor(sqInt opcode) -{ - switch (opcode) { - case JumpLongZero: - return JumpLongNonZero; - - case JumpLongNonZero: - return JumpLongZero; - - case JumpZero: - return JumpNonZero; - - case JumpNonZero: - return JumpZero; - - case JumpNegative: - return JumpNonNegative; - - case JumpNonNegative: - return JumpNegative; - - case JumpOverflow: - return JumpNoOverflow; - - case JumpNoOverflow: - return JumpOverflow; - - case JumpCarry: - return JumpNoCarry; - - case JumpNoCarry: - return JumpCarry; - - case JumpLess: - return JumpGreaterOrEqual; - - case JumpGreaterOrEqual: - return JumpLess; - - case JumpGreater: - return JumpLessOrEqual; - - case JumpLessOrEqual: - return JumpGreater; - - case JumpBelow: - return JumpAboveOrEqual; - - case JumpAboveOrEqual: - return JumpBelow; - - case JumpAbove: - return JumpBelowOrEqual; - - case JumpBelowOrEqual: - return JumpAbove; - - default: - error("Case not found and no otherwise clause"); - } - error("invalid opcode for inverse"); - return 0; -} - - -/* See Cogit class>>initializeAnnotationConstants */ - - /* Cogit>>#isPCMappedAnnotation: */ -static sqInt NoDbgRegParms -isPCMappedAnnotation(sqInt annotation) -{ - return annotation >= HasBytecodePC; -} - - /* Cogit>>#isPCWithinMethodZone: */ -sqInt -isPCWithinMethodZone(void *address) -{ - return (((((usqInt)address)) >= methodZoneBase) && ((((usqInt)address)) <= (freeStart()))); -} - - -/* Answer if the instruction preceding retpc is a call instruction. */ - - /* Cogit>>#isSendReturnPC: */ -sqInt -isSendReturnPC(sqInt retpc) -{ - usqInt target; - - if (!(isCallPrecedingReturnPC(backEnd, retpc))) { - return 0; - } - target = callTargetFromReturnAddress(backEnd, retpc); - return (((target >= firstSend) && (target <= lastSend))) - || (((target >= methodZoneBase) && (target <= (freeStart())))); -} - - -/* Floating-point jumps are a little weird on some processors. Defer to - the backEnd to allow it to generate any special code it may need to. */ - - /* Cogit>>#JumpFPEqual: */ -static AbstractInstruction * NoDbgRegParms -gJumpFPEqual(void *jumpTarget) -{ - /* begin genJumpFPEqual: */ - return genoperand(JumpFPEqual, ((sqInt)jumpTarget)); -} - - -/* Floating-point jumps are a little weird on some processors. Defer to - the backEnd to allow it to generate any special code it may need to. */ - - /* Cogit>>#JumpFPGreaterOrEqual: */ -static AbstractInstruction * NoDbgRegParms -gJumpFPGreaterOrEqual(void *jumpTarget) -{ - /* begin genJumpFPGreaterOrEqual: */ - return genoperand(JumpFPGreaterOrEqual, ((sqInt)jumpTarget)); -} - - -/* Floating-point jumps are a little weird on some processors. Defer to - the backEnd to allow it to generate any special code it may need to. */ - - /* Cogit>>#JumpFPGreater: */ -static AbstractInstruction * NoDbgRegParms -gJumpFPGreater(void *jumpTarget) -{ - /* begin genJumpFPGreater: */ - return genoperand(JumpFPGreater, ((sqInt)jumpTarget)); -} - - -/* Floating-point jumps are a little weird on some processors. Defer to - the backEnd to allow it to generate any special code it may need to. */ - - /* Cogit>>#JumpFPLessOrEqual: */ -static AbstractInstruction * NoDbgRegParms -gJumpFPLessOrEqual(void *jumpTarget) -{ - /* begin genJumpFPLessOrEqual: */ - return genoperand(JumpFPLessOrEqual, ((sqInt)jumpTarget)); -} - - -/* Floating-point jumps are a little weird on some processors. Defer to - the backEnd to allow it to generate any special code it may need to. */ - - /* Cogit>>#JumpFPLess: */ -static AbstractInstruction * NoDbgRegParms -gJumpFPLess(void *jumpTarget) -{ - /* begin genJumpFPLess: */ - return genoperand(JumpFPLess, ((sqInt)jumpTarget)); -} - - -/* Floating-point jumps are a little weird on some processors. Defer to - the backEnd to allow it to generate any special code it may need to. */ - - /* Cogit>>#JumpFPNotEqual: */ -static AbstractInstruction * NoDbgRegParms -gJumpFPNotEqual(void *jumpTarget) -{ - /* begin genJumpFPNotEqual: */ - return genoperand(JumpFPNotEqual, ((sqInt)jumpTarget)); -} - - /* Cogit>>#LogicalShiftLeftCq:R: */ -static AbstractInstruction * NoDbgRegParms -gLogicalShiftLeftCqR(sqInt quickConstant, sqInt reg) -{ - return genoperandoperand(LogicalShiftLeftCqR, quickConstant, reg); -} - - -/* destReg := srcReg << quickConstant */ - - /* Cogit>>#LogicalShiftLeftCq:R:R: */ -static AbstractInstruction * NoDbgRegParms -gLogicalShiftLeftCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) -{ - AbstractInstruction * first; - - return genoperandoperandoperand(LogicalShiftLeftCqRR, quickConstant, srcReg, destReg); - first = genoperandoperand(MoveRR, srcReg, destReg); - genoperandoperand(LogicalShiftLeftCqR, quickConstant, destReg); - return first; -} - - -/* destReg := (unsigned)srcReg >> quickConstant */ - - /* Cogit>>#LogicalShiftRightCq:R:R: */ -static AbstractInstruction * NoDbgRegParms -gLogicalShiftRightCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) -{ - AbstractInstruction * first; - - return genoperandoperandoperand(LogicalShiftRightCqRR, quickConstant, srcReg, destReg); - first = genoperandoperand(MoveRR, srcReg, destReg); - genoperandoperand(LogicalShiftRightCqR, quickConstant, destReg); - return first; -} - - /* Cogit>>#lastOpcode */ -static AbstractInstruction * -lastOpcode(void) -{ - assert(opcodeIndex > 0); - return abstractInstructionAt(opcodeIndex - 1); -} - - /* Cogit>>#linkSendAt:in:to:offset:receiver: */ -void -linkSendAtintooffsetreceiver(sqInt callSiteReturnAddress, CogMethod *sendingMethod, CogMethod *targetMethod, sqInt theEntryOffset, sqInt receiver) -{ - sqInt extent; - sqInt inlineCacheTag; - - assert((theEntryOffset == cmEntryOffset) - || (theEntryOffset == cmNoCheckEntryOffset)); - assert(((callSiteReturnAddress >= methodZoneBase) && (callSiteReturnAddress <= (freeStart())))); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - if (theEntryOffset == cmNoCheckEntryOffset) { - - /* no need to change selector cache tag */ - extent = rewriteCallAttarget(backEnd, callSiteReturnAddress, (((sqInt)targetMethod)) + cmNoCheckEntryOffset); - } - else { - inlineCacheTag = inlineCacheTagForInstance(receiver); - extent = rewriteInlineCacheAttagtarget(backEnd, callSiteReturnAddress, inlineCacheTag, (((sqInt)targetMethod)) + theEntryOffset); - } - flushICacheFromto(backEnd, (((usqInt)callSiteReturnAddress)) - extent, ((usqInt)callSiteReturnAddress)); -} - - /* Cogit>>#loadBytesAndGetDescriptor */ -static BytecodeDescriptor * -loadBytesAndGetDescriptor(void) -{ - BytecodeDescriptor *descriptor; - - byte0 = (fetchByteofObject(bytecodePC, methodObj)) + bytecodeSetOffset; - descriptor = generatorAt(byte0); - loadSubsequentBytesForDescriptorat(descriptor, bytecodePC); - return descriptor; -} - - /* Cogit>>#loadSubsequentBytesForDescriptor:at: */ -static void NoDbgRegParms -loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc) -{ - if (((descriptor->numBytes)) > 1) { - byte1 = fetchByteofObject(pc + 1, methodObj); - if (((descriptor->numBytes)) > 2) { - byte2 = fetchByteofObject(pc + 2, methodObj); - if (((descriptor->numBytes)) > 3) { - byte3 = fetchByteofObject(pc + 3, methodObj); - if (((descriptor->numBytes)) > 4) { - notYetImplemented(); - } - } - } - } -} - - /* Cogit>>#MoveCw:R: */ -static AbstractInstruction * NoDbgRegParms -gMoveCwR(sqInt wordConstant, sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkLiteral:forInstruction: */ - anInstruction = genoperandoperand(MoveCwR, wordConstant, reg); - return anInstruction; -} - - -/* Answer the address of the null byte at the end of the method map. */ - - /* Cogit>>#mapEndFor: */ -static usqInt NoDbgRegParms -mapEndFor(CogMethod *cogMethod) -{ - usqInt end; - - end = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while ((byteAt(end)) != MapEnd) { - end -= 1; - assert(end > (firstMappedPCFor(cogMethod))); - } - return end; -} - - -/* Unlinking/GC/Disassembly support */ -/* most of the time arg is a CogMethod... */ - - /* Cogit>>#mapFor:performUntil:arg: */ -static sqInt NoDbgRegParms -mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg) -{ - sqInt annotation; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - - /* begin firstMappedPCFor: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = functionSymbol(annotation, (((char *) mcpc)), arg); - if (result != 0) { - return result; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - return 0; -} - - -/* Remap all object references in the closed PIC. Answer if any references - are young. - Set codeModified if any modifications are made. */ - - /* Cogit>>#mapObjectReferencesInClosedPIC: */ -static sqInt NoDbgRegParms -mapObjectReferencesInClosedPIC(CogMethod *cPIC) -{ - sqInt i; - sqInt pc; - sqInt refersToYoung; - - - /* first we check the potential method oop load at the beginning of the CPIC */ - pc = addressOfEndOfCaseinCPIC(1, cPIC); - - /* We find the end address of the cPICNumCases'th case and can then just step forward by the case size thereafter */ - refersToYoung = remapMaybeObjRefInClosedPICAt(pc - (jumpLongByteSize(backEnd))); - - /* Next we check the potential class ref in the compare instruction, and the potential method oop load for each case. */ - pc = addressOfEndOfCaseinCPIC((cPIC->cPICNumCases), cPIC); - for (i = 2; i <= ((cPIC->cPICNumCases)); i += 1) { - if (remapMaybeObjRefInClosedPICAt((pc - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */)) { - refersToYoung = 1; - } - pc += cPICCaseSize; - } - return refersToYoung; -} - - -/* Update all references to objects in the generated runtime. */ - - /* Cogit>>#mapObjectReferencesInGeneratedRuntime */ -static void -mapObjectReferencesInGeneratedRuntime(void) -{ - sqInt i; - usqInt literal; - sqInt mappedLiteral; - usqInt mcpc; - - for (i = 0; i < runtimeObjectRefIndex; i += 1) { - mcpc = objectReferencesInRuntime[i]; - literal = literalBeforeFollowingAddress(backEnd, mcpc); - mappedLiteral = remapObject(literal); - if (mappedLiteral != literal) { - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - storeLiteralbeforeFollowingAddress(backEnd, mappedLiteral, mcpc); - } - } -} - - -/* Update all references to objects in machine code for a become. - Unlike incrementalGC or fullGC a method that does not refer to young may - refer to young as a result of the become operation. Unlike incrementalGC - or fullGC the reference from a Cog method to its methodObject *must not* - change since the two are two halves of the same object. */ - - /* Cogit>>#mapObjectReferencesInMachineCodeForBecome */ -static void -mapObjectReferencesInMachineCodeForBecome(void) -{ - sqInt annotation; - CogMethod * cogMethod; - sqInt freedPIC; - sqInt hasYoungObj; - sqInt hasYoungObjPtr; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt remappedMethod; - sqInt result; - CogMethod * writableCogMethod; - - hasYoungObj = 0; - hasYoungObjPtr = ((sqInt)((&hasYoungObj))); - codeModified = (freedPIC = 0); - mapObjectReferencesInGeneratedRuntime(); - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - assert(!hasYoungObj); - if (((cogMethod->cmType)) != CMFree) { - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - writableCogMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - (writableCogMethod->selector = remapOop((cogMethod->selector))); - if (((cogMethod->cmType)) == CMClosedPIC) { - if ((isYoung((cogMethod->selector))) - || (mapObjectReferencesInClosedPIC(cogMethod))) { - freedPIC = 1; - freeMethod(cogMethod); - } - } - else { - if (isYoung((cogMethod->selector))) { - hasYoungObj = 1; - } - if (((cogMethod->cmType)) == CMMethod) { - assert(((cogMethod->objectHeader)) == (nullHeaderForMachineCodeMethod())); - remappedMethod = remapOop((cogMethod->methodObject)); - if (remappedMethod != ((cogMethod->methodObject))) { - if (methodHasCogMethod(remappedMethod)) { - error("attempt to become two cogged methods"); - } - if (!(withoutForwardingOnandwithsendToCogit((cogMethod->methodObject), remappedMethod, (cogMethod->cmUsesPenultimateLit), methodhasSameCodeAscheckPenultimate))) { - error("attempt to become cogged method into different method"); - } - if ((rawHeaderOf((cogMethod->methodObject))) == (((sqInt)cogMethod))) { - rawHeaderOfput((cogMethod->methodObject), (cogMethod->methodHeader)); - (writableCogMethod->methodHeader = rawHeaderOf(remappedMethod)); - (writableCogMethod->methodObject = remappedMethod); - rawHeaderOfput(remappedMethod, ((sqInt)cogMethod)); - } - else { - assert((noAssertMethodClassAssociationOf((cogMethod->methodObject))) == (nilObject())); - (writableCogMethod->methodHeader = rawHeaderOf(remappedMethod)); - (writableCogMethod->methodObject = remappedMethod); - } - } - if (isYoung((cogMethod->methodObject))) { - hasYoungObj = 1; - } - } - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = remapIfObjectRefpchasYoung(annotation, (((char *) mcpc)), (((CogMethod *) hasYoungObjPtr))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - if (hasYoungObj) { - ensureInYoungReferrers(cogMethod); - hasYoungObj = 0; - } - else { - (cogMethod->cmRefersToYoung = 0); - } - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - pruneYoungReferrers(); - if (freedPIC) { - unlinkSendsToFree(); - } - if (codeModified) { - - /* After updating oops in inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)codeBase), freeStart()); - } -} - - -/* Update all references to objects in machine code for a full gc. Since - the current (New)ObjectMemory GC makes everything old in a full GC - a method not referring to young will not refer to young afterwards */ - - /* Cogit>>#mapObjectReferencesInMachineCodeForFullGC */ -static void -mapObjectReferencesInMachineCodeForFullGC(void) -{ - sqInt annotation; - CogMethod * cogMethod; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - CogMethod * writableCogMethod; - - codeModified = 0; - mapObjectReferencesInGeneratedRuntime(); - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - writableCogMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - (writableCogMethod->selector = remapOop((cogMethod->selector))); - if (((cogMethod->cmType)) == CMClosedPIC) { - assert(!((cogMethod->cmRefersToYoung))); - mapObjectReferencesInClosedPIC(cogMethod); - } - else { - if (((cogMethod->cmType)) == CMMethod) { - assert(((cogMethod->objectHeader)) == (nullHeaderForMachineCodeMethod())); - (writableCogMethod->methodObject = remapOop((cogMethod->methodObject))); - } - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = remapIfObjectRefpchasYoung(annotation, (((char *) mcpc)), 0); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - pruneYoungReferrers(); - if (codeModified) { - - /* After updating oops in inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)codeBase), freeStart()); - } -} - - -/* Update all references to objects in machine code for either a Spur - scavenging gc - or a Squeak V3 incremental GC. Avoid scanning all code by using the - youngReferrers list. In a young gc a method referring to young may no - longer refer to young, but a - method not referring to young cannot and will not refer to young - afterwards. */ - - /* Cogit>>#mapObjectReferencesInMachineCodeForYoungGC */ -static void -mapObjectReferencesInMachineCodeForYoungGC(void) -{ - sqInt annotation; - CogMethod * cogMethod; - sqInt hasYoungObj; - sqInt hasYoungObjPtr; - usqInt map; - sqInt mapByte; - sqInt mcpc; - usqInt pointer; - sqInt result; - CogMethod * writableCogMethod; - sqInt zoneIsWritable; - - codeModified = (zoneIsWritable = (hasYoungObj = 0)); - hasYoungObjPtr = ((sqInt)((&hasYoungObj))); - pointer = youngReferrers(); - while (pointer < limitAddress) { - assert(!hasYoungObj); - cogMethod = ((CogMethod *) (longAt(pointer))); - if (((cogMethod->cmType)) == CMFree) { - assert(!((cogMethod->cmRefersToYoung))); - } - else { - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - if ((cogMethod->cmRefersToYoung)) { - assert((((cogMethod->cmType)) == CMMethod) - || (((cogMethod->cmType)) == CMOpenPIC)); - if (!zoneIsWritable) { - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - zoneIsWritable = 1; - } - writableCogMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - (writableCogMethod->selector = remapOop((cogMethod->selector))); - if (isYoung((cogMethod->selector))) { - hasYoungObj = 1; - } - if (((cogMethod->cmType)) == CMMethod) { - assert(((cogMethod->objectHeader)) == (nullHeaderForMachineCodeMethod())); - (writableCogMethod->methodObject = remapOop((cogMethod->methodObject))); - if (isYoung((cogMethod->methodObject))) { - hasYoungObj = 1; - } - } - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = remapIfObjectRefpchasYoung(annotation, (((char *) mcpc)), (((void *)hasYoungObjPtr))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - if (hasYoungObj) { - hasYoungObj = 0; - } - else { - (writableCogMethod->cmRefersToYoung = 0); - } - } - } - pointer += BytesPerWord; - } - pruneYoungReferrers(); - if (codeModified) { - - /* After updating oops in inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } -} - - -/* Update all references to objects in machine code. */ - - /* Cogit>>#mapObjectReferencesInMachineCode: */ -void -mapObjectReferencesInMachineCode(sqInt gcMode) -{ - switch (gcMode) { - case GCModeNewSpace: - - /* N.B. do *not* ensureWritableCodeZone for every scavenge. */ - mapObjectReferencesInMachineCodeForYoungGC(); - break; - case GCModeFull: - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - mapObjectReferencesInMachineCodeForFullGC(); - break; - case GCModeBecome: - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - mapObjectReferencesInMachineCodeForBecome(); - break; - default: - error("Case not found and no otherwise clause"); - } - if (!(asserta((freeStart()) <= (youngReferrers())))) { - error("youngReferrers list overflowed"); - } -} - - -/* Mark objects in machine-code of marked methods (or open PICs with marked - selectors). - */ - - /* Cogit>>#markAndTraceMachineCodeOfMarkedMethods */ -void -markAndTraceMachineCodeOfMarkedMethods(void) -{ - sqInt annotation; - sqInt annotation1; - CogMethod *cogMethod; - usqInt map; - usqInt map1; - sqInt mapByte; - sqInt mapByte1; - sqInt mcpc; - sqInt mcpc1; - sqInt result; - sqInt result1; - - if (leakCheckFullGC()) { - asserta(allMachineCodeObjectReferencesValid()); - } - codeModified = 0; - markAndTraceObjectReferencesInGeneratedRuntime(); - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) == CMMethod) - && (isMarked((cogMethod->methodObject)))) { - /* begin markAndTraceLiteralsIn: */ - assert(((((cogMethod->cmType)) == CMMethod) - && (isMarked((cogMethod->methodObject)))) - || ((((cogMethod->cmType)) == CMOpenPIC) - && ((isImmediate((cogMethod->selector))) - || (isMarked((cogMethod->selector)))))); - markAndTraceLiteralinat((cogMethod->selector), cogMethod, (&((cogMethod->selector)))); - /* begin maybeMarkIRCsIn: */ - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = markLiteralspcmethod(annotation, (((char *) mcpc)), cogMethod); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - if ((((cogMethod->cmType)) == CMOpenPIC) - && ((isImmediate((cogMethod->selector))) - || (isMarked((cogMethod->selector))))) { - /* begin markAndTraceLiteralsIn: */ - assert(((((cogMethod->cmType)) == CMMethod) - && (isMarked((cogMethod->methodObject)))) - || ((((cogMethod->cmType)) == CMOpenPIC) - && ((isImmediate((cogMethod->selector))) - || (isMarked((cogMethod->selector)))))); - markAndTraceLiteralinat((cogMethod->selector), cogMethod, (&((cogMethod->selector)))); - /* begin maybeMarkIRCsIn: */ - /* begin mapFor:performUntil:arg: */ - mcpc1 = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map1 = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte1 = byteAt(map1))) != MapEnd) { - if (mapByte1 >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc1 += (mapByte1 & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation1 = ((usqInt)(mapByte1)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte1 = byteAt(map1 - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation1 += mapByte1 & DisplacementMask; - map1 -= 1; - } - result1 = markLiteralspcmethod(annotation1, (((char *) mcpc1)), cogMethod); - if (result1 != 0) { - goto l4; - } - } - else { - if (mapByte1 < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc1 += (((sqInt)((usqInt)((mapByte1 - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map1 -= 1; - } - l4: /* end mapFor:performUntil:arg: */; - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (leakCheckFullGC()) { - asserta(allMachineCodeObjectReferencesValid()); - } - if (codeModified) { - - /* After updating oops in inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } -} - - -/* Mark and trace any object references in the generated run-time. */ - - /* Cogit>>#markAndTraceObjectReferencesInGeneratedRuntime */ -static void -markAndTraceObjectReferencesInGeneratedRuntime(void) -{ - sqInt i; - usqInt literal; - usqInt mcpc; - - for (i = 0; i < runtimeObjectRefIndex; i += 1) { - mcpc = objectReferencesInRuntime[i]; - literal = literalBeforeFollowingAddress(backEnd, mcpc); - markAndTraceLiteralinatpc(literal, ((CogMethod *) null), ((usqInt)mcpc)); - } -} - - -/* Mark and trace objects in the argument and free if it is appropriate. - Answer if the method has been freed. firstVisit is a hint used to avoid - scanning methods we've already seen. False positives are fine. - For a CMMethod this - frees if the bytecode method isnt marked, - marks and traces object literals and selectors, - unlinks sends to targets that should be freed. - For a CMClosedPIC this - frees if it refers to anything that should be freed or isn't marked. - For a CMOpenPIC this - frees if the selector isn't marked. */ -/* this recurses at most one level down */ - - /* Cogit>>#markAndTraceOrFreeCogMethod:firstVisit: */ -static sqInt NoDbgRegParms -markAndTraceOrFreeCogMethodfirstVisit(CogMethod *cogMethod, sqInt firstVisit) -{ - sqInt annotation; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - - if (((cogMethod->cmType)) == CMFree) { - return 1; - } - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - if (((cogMethod->cmType)) == CMMethod) { - if (!(isMarked((cogMethod->methodObject)))) { - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - freeMethod(cogMethod); - return 1; - } - if (firstVisit) { - /* begin markLiteralsAndUnlinkUnmarkedSendsIn: */ - assert(((cogMethod->cmType)) == CMMethod); - assert(isMarked((cogMethod->methodObject))); - markAndTraceLiteralinat((cogMethod->selector), cogMethod, (&((cogMethod->selector)))); - /* begin maybeMarkIRCsIn: */ - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = markLiteralsAndUnlinkIfUnmarkedSendpcmethod(annotation, (((char *) mcpc)), cogMethod); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - return 0; - } - if (((cogMethod->cmType)) == CMClosedPIC) { - if (!(closedPICRefersToUnmarkedObject(cogMethod))) { - return 0; - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - freeMethod(cogMethod); - return 1; - } - if (((cogMethod->cmType)) == CMOpenPIC) { - if (isMarked((cogMethod->selector))) { - return 0; - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - freeMethod(cogMethod); - return 1; - } - assert((((cogMethod->cmType)) == CMMethod) - || ((((cogMethod->cmType)) == CMClosedPIC) - || (((cogMethod->cmType)) == CMOpenPIC))); - return 0; -} - - -/* If entryPoint is that of some method, then mark and trace objects in it - and free if it is appropriate. - Answer if the method has been freed. */ - - /* Cogit>>#markAndTraceOrFreePICTarget:in: */ -static sqInt NoDbgRegParms -markAndTraceOrFreePICTargetin(sqInt entryPoint, CogMethod *cPIC) -{ - CogMethod *targetMethod; - - assert((entryPoint > methodZoneBase) - && (entryPoint < (freeStart()))); - if (((((usqInt)cPIC)) <= (((usqInt)entryPoint))) - && (((((usqInt)cPIC)) + ((cPIC->blockSize))) >= (((usqInt)entryPoint)))) { - return 0; - } - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - assert((((targetMethod->cmType)) == CMMethod) - || (((targetMethod->cmType)) == CMFree)); - return markAndTraceOrFreeCogMethodfirstVisit(targetMethod, (((usqInt)targetMethod)) > (((usqInt)cPIC))); -} - - -/* Mark and trace literals. Unlink sends that have unmarked cache tags or - targets. - */ - - /* Cogit>>#markLiteralsAndUnlinkIfUnmarkedSend:pc:method: */ -static sqInt NoDbgRegParms -markLiteralsAndUnlinkIfUnmarkedSendpcmethod(sqInt annotation, char *mcpc, sqInt cogMethod) -{ - usqInt cacheTag1; - sqInt cacheTagMarked; - usqInt entryPoint1; - usqInt literal; - sqInt offset1; - sqInt *sendTable1; - sqInt tagCouldBeObj1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - literal = 0; - if (annotation == IsObjectReference) { - literal = literalBeforeFollowingAddress(backEnd, ((usqInt)mcpc)); - if (markAndTraceLiteralinatpc(literal, ((CogMethod *) cogMethod), ((usqInt)mcpc))) { - codeModified = 1; - } - } - if (annotation >= IsSendCall) { - /* begin entryCacheTagAndCouldBeObjectAt:annotation:into: */ - cacheTag1 = inlineCacheTagAt(backEnd, ((sqInt)mcpc)); - - /* in-line cache tags are the selectors of sends if sends are unlinked, - the selectors of super sends (entry offset = cmNoCheckEntryOffset), - the selectors of open PIC sends (entry offset = cmEntryOffset, target is an Open PIC) - or in-line cache tags (classes, class indices, immediate bit patterns, etc). - Note that selectors can be immediate so there is no guarantee that they - are markable/remappable objects. */ - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - tagCouldBeObj1 = entryPointTagIsSelector(entryPoint1); - cacheTagMarked = tagCouldBeObj1 - && (1); - if (entryPoint1 > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint1 - offset1)); - if ((!cacheTagMarked) - || (markAndTraceOrFreeCogMethodfirstVisit(targetMethod1, (((usqInt)targetMethod1)) > (((usqInt)mcpc))))) { - - /* Either the cacheTag is unmarked (e.g. new class) or the target - has been freed (because it is unmarked), so unlink the send. */ - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - markAndTraceLiteralinat((targetMethod1->selector), targetMethod1, (&((targetMethod1->selector)))); - } - } - else { - - /* cacheTag is selector */ - if (markAndTraceCacheTagLiteralinatpc(cacheTag1, ((CogMethod *) cogMethod), ((usqInt)mcpc))) { - codeModified = 1; - } - } - } - return 0; -} - - -/* Mark and trace literals. - Additionally in Newspeak, void push implicits that have unmarked classes. */ - - /* Cogit>>#markLiterals:pc:method: */ -static sqInt NoDbgRegParms -markLiteralspcmethod(sqInt annotation, char *mcpc, CogMethod *cogMethod) -{ - usqInt cacheTag1; - usqInt entryPoint1; - usqInt literal; - sqInt tagCouldBeObj1; - - literal = 0; - if (annotation == IsObjectReference) { - literal = literalBeforeFollowingAddress(backEnd, ((usqInt)mcpc)); - if (markAndTraceLiteralinatpc(literal, cogMethod, ((usqInt)mcpc))) { - codeModified = 1; - } - } - if (annotation >= IsSendCall) { - /* begin entryCacheTagAndCouldBeObjectAt:annotation:into: */ - cacheTag1 = inlineCacheTagAt(backEnd, ((sqInt)mcpc)); - - /* in-line cache tags are the selectors of sends if sends are unlinked, - the selectors of super sends (entry offset = cmNoCheckEntryOffset), - the selectors of open PIC sends (entry offset = cmEntryOffset, target is an Open PIC) - or in-line cache tags (classes, class indices, immediate bit patterns, etc). - Note that selectors can be immediate so there is no guarantee that they - are markable/remappable objects. */ - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - tagCouldBeObj1 = entryPointTagIsSelector(entryPoint1); - if (tagCouldBeObj1 - && (markAndTraceCacheTagLiteralinatpc(cacheTag1, cogMethod, ((usqInt)mcpc)))) { - - /* cacheTag is selector */ - codeModified = 1; - } - } - return 0; -} - - /* Cogit>>#markMethodAndReferents: */ -void -markMethodAndReferents(CogBlockMethod *aCogMethod) -{ - sqInt annotation; - CogMethod * cogMethod; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - CogMethod * writableMethod; - - assert((((aCogMethod->cmType)) == CMMethod) - || (((aCogMethod->cmType)) == CMBlock)); - cogMethod = (((aCogMethod->cmType)) == CMMethod - ? ((CogMethod *) aCogMethod) - : cmHomeMethod(aCogMethod)); - writableMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - (writableMethod->cmUsageCount = CMMaxUsageCount); - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = incrementUsageOfTargetIfLinkedSendmcpcignored(annotation, (((char *) mcpc)), 0); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; -} - - /* Cogit>>#maxCogMethodAddress */ -usqInt -maxCogMethodAddress(void) -{ - return ((usqInt)(limitZony())); -} - - -/* If this is the Newspeak VM and the objectRepresentation supports pinning - then allocate space for the implicit receiver caches on the heap. */ - - /* Cogit>>#maybeAllocAndInitIRCs */ -static sqInt -maybeAllocAndInitIRCs(void) -{ - return 1; -} - - -/* Check that the header fields are consistent with the type. - Answer 0 if it is ok, otherwise answer a code for the error. */ - - /* Cogit>>#maybeFreeCogMethodDoesntLookKosher: */ -static sqInt NoDbgRegParms -maybeFreeCogMethodDoesntLookKosher(CogMethod *cogMethod) -{ - sqInt result; - - result = cogMethodDoesntLookKosher(cogMethod); - return (result == 2 - ? 0 - : result); -} - - /* Cogit>>#mclassIsSmallInteger */ -static sqInt -mclassIsSmallInteger(void) -{ - return (receiverTags & 1); -} - - -/* Answer the absolute machine code pc matching the zero-relative - bytecode pc of a backward branch in cogMethod, given the start - of the bytecodes for cogMethod's block or method object. */ - - /* Cogit>>#mcPCForBackwardBranch:startBcpc:in: */ -usqInt -mcPCForBackwardBranchstartBcpcin(sqInt bcpc, sqInt startbcpc, CogBlockMethod *cogMethod) -{ - sqInt aMethodHeader; - sqInt aMethodHeader1; - sqInt aMethodObj; - sqInt annotation; - sqInt bcpc1; - sqInt bsOffset; - sqInt byte; - BytecodeDescriptor *descriptor; - sqInt distance; - sqInt endbcpc; - CogMethod *homeMethod; - sqInt isBackwardBranch; - sqInt isInBlock; - sqInt latestContinuation; - usqInt map; - sqInt mapByte; - usqInt mcpc; - sqInt nExts; - sqInt nextBcpc; - sqInt result; - sqInt targetPC; - - latestContinuation = 0; - /* begin mapFor:bcpc:performUntil:arg: */ - assert(((cogMethod->stackCheckOffset)) > 0); - - /* The stack check maps to the start of the first bytecode, - the first bytecode being effectively after frame build. */ - mcpc = (((usqInt)cogMethod)) + ((cogMethod->stackCheckOffset)); - result = (((((0 + (((int)((usqInt)(HasBytecodePC) << 1)))) & 1) != 0)) - && ((((sqInt)(((void *)bcpc)))) == startbcpc) - ? ((sqInt)(((char *) mcpc))) - : 0); - if (result != 0) { - return result; - } - - /* In both CMMethod and CMBlock cases find the start of the map and - skip forward to the bytecode pc map entry for the stack check. */ - bcpc1 = startbcpc; - if (((cogMethod->cmType)) == CMMethod) { - /* begin cmIsFullBlock */ - isInBlock = (cogMethod->cpicHasMNUCaseOrCMIsFullBlock); - homeMethod = ((CogMethod *) cogMethod); - assert(startbcpc == (startPCOfMethodHeader((homeMethod->methodHeader)))); - map = ((((usqInt)homeMethod)) + ((homeMethod->blockSize))) - 1; - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert((annotation == IsAbsPCReference) - || ((annotation == IsObjectReference) - || ((annotation == IsRelativeCall) - || (annotation == IsDisplacementX2N)))); - latestContinuation = startbcpc; - aMethodObj = (homeMethod->methodObject); - endbcpc = (numBytesOf(aMethodObj)) - 1; - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader) - ? 0x100 - : 0) -# else - 0 -# endif - ; - bcpc1 += deltaToSkipPrimAndErrorStoreInheader(aMethodObj, (homeMethod->methodHeader)); - } - else { - isInBlock = 1; - assert(bcpc1 == ((cogMethod->startpc))); - homeMethod = cmHomeMethod(cogMethod); - map = findMapLocationForMcpcinMethod((((usqInt)cogMethod)) + (sizeof(CogBlockMethod)), homeMethod); - assert(map != 0); - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert(((((usqInt)(annotation)) >> AnnotationShift) == HasBytecodePC) - || ((((usqInt)(annotation)) >> AnnotationShift) == IsDisplacementX2N)); - while (((annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift)) != HasBytecodePC) { - map -= 1; - } - - /* skip fiducial; i.e. the map entry for the pc immediately following the method header. */ - map -= 1; - aMethodObj = (homeMethod->methodObject); - bcpc1 = startbcpc - ( -#if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet((homeMethod->methodHeader)) - ? AltBlockCreationBytecodeSize - : BlockCreationBytecodeSize) -#else // MULTIPLEBYTECODESETS - BlockCreationBytecodeSize -#endif - ); - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader1 = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader1) - ? 0x100 - : 0) -# else - 0 -# endif - ; - byte = (fetchByteofObject(bcpc1, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - endbcpc = (bcpc1 + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc1, -1, aMethodObj)) - : 0)); - bcpc1 = startbcpc; - } - nExts = 0; - while ((((usqInt)((byteAt(map)))) >> AnnotationShift) != HasBytecodePC) { - map -= 1; - } - map -= 1; - while (((mapByte = byteAt(map))) != MapEnd) { - - /* defensive; we exit on bcpc */ - if (mapByte >= FirstAnnotation) { - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if (annotation >= HasBytecodePC) { - if ((annotation == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - while (1) { - byte = (fetchByteofObject(bcpc1, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - if (isInBlock) { - if (bcpc1 >= endbcpc) { - return 0; - } - } - else { - if (((descriptor->isReturn)) - && (bcpc1 >= latestContinuation)) { - return 0; - } - if ((isBranch(descriptor)) - || ((descriptor->isBlockCreation))) { - /* begin latestContinuationPCFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, bcpc1, nExts, aMethodObj); - targetPC = (bcpc1 + ((descriptor->numBytes))) + (((distance < 0) ? 0 : distance)); - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - /* latestContinuation = */ latestContinuation; - } - nextBcpc = (bcpc1 + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc1, nExts, aMethodObj)) - : 0)); - if (((descriptor->isMapped)) - || (isInBlock - && ((descriptor->isMappedInBlock)))) break; - bcpc1 = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - isBackwardBranch = (isBranch(descriptor)) - && ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, bcpc1, nExts, aMethodObj)) < 0)); - result = findBackwardBranchIsBackwardBranchMcpcBcpcMatchingBcpc(descriptor, ((isBackwardBranch - ? (((sqInt)((usqInt)(annotation) << 1))) + 1 - : ((sqInt)((usqInt)(annotation) << 1)))), (((char *) mcpc)), ((isBackwardBranch - ? bcpc1 - (2 * nExts) - : bcpc1)), (((void *)bcpc))); - if (result != 0) { - return result; - } - bcpc1 = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - } - else { - assert(((((usqInt)(mapByte)) >> AnnotationShift) == IsDisplacementX2N) - || ((((usqInt)(mapByte)) >> AnnotationShift) == IsAnnotationExtension)); - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - return 0; -} - - -/* For the purposes of become: see if the two methods are similar, i.e. can - be safely becommed. - This is pretty strict. All literals and bytecodes must be identical. Only - trailer bytes and header - flags can differ. */ - - /* Cogit>>#method:hasSameCodeAs:checkPenultimate: */ -static sqInt NoDbgRegParms -methodhasSameCodeAscheckPenultimate(sqInt methodA, sqInt methodB, sqInt comparePenultimateLiteral) -{ - sqInt bi; - sqInt endPCA; - sqInt headerA; - sqInt headerB; - sqInt li; - sqInt numLitsA; - - headerA = methodHeaderOf(methodA); - headerB = methodHeaderOf(methodB); - numLitsA = literalCountOfMethodHeader(headerA); - endPCA = endPCOf(methodA); - if (((argumentCountOfMethodHeader(headerA)) != (argumentCountOfMethodHeader(headerB))) - || (((temporaryCountOfMethodHeader(headerA)) != (temporaryCountOfMethodHeader(headerB))) - || (((primitiveIndexOfMethodheader(methodA, headerA)) != (primitiveIndexOfMethodheader(methodB, headerB))) - || ((numLitsA != (literalCountOfMethodHeader(headerB))) - || (endPCA > (numBytesOf(methodB))))))) { - return 0; - } - for (li = 1; li < numLitsA; li += 1) { - if ((fetchPointerofObject(li, methodA)) != (fetchPointerofObject(li, methodB))) { - if ((li < (numLitsA - 1)) - || (comparePenultimateLiteral)) { - return 0; - } - } - } - for (bi = (startPCOfMethod(methodA)); bi <= endPCA; bi += 1) { - if ((fetchByteofObject(bi, methodA)) != (fetchByteofObject(bi, methodB))) { - return 0; - } - } - return 1; -} - - /* Cogit>>#mnuOffset */ -sqInt -mnuOffset(void) -{ - return missOffset; -} - - /* Cogit>>#NativePopR: */ -static AbstractInstruction * NoDbgRegParms -gNativePopR(sqInt reg) -{ - return genoperand(PopR, reg); -} - - /* Cogit>>#NativePushR: */ -static AbstractInstruction * NoDbgRegParms -gNativePushR(sqInt reg) -{ - return genoperand(PushR, reg); -} - - /* Cogit>>#NativeRetN: */ -static AbstractInstruction * NoDbgRegParms -gNativeRetN(sqInt offset) -{ - return genoperand(RetN, offset); -} - - /* Cogit>>#needsFrameIfImmutability: */ -static sqInt NoDbgRegParms -needsFrameIfImmutability(sqInt stackDelta) -{ - return IMMUTABILITY; -} - - /* Cogit>>#needsFrameIfInBlock: */ -static sqInt NoDbgRegParms -needsFrameIfInBlock(sqInt stackDelta) -{ - return inBlock > 0; -} - - /* Cogit>>#needsFrameNever: */ -static sqInt NoDbgRegParms -needsFrameNever(sqInt stackDelta) -{ - return 0; -} - - /* Cogit>>#noAssertMethodClassAssociationOf: */ -static sqInt NoDbgRegParms -noAssertMethodClassAssociationOf(sqInt methodPointer) -{ - return literalofMethod((literalCountOfMethodHeader(noAssertHeaderOf(methodPointer))) - 1, methodPointer); -} - - -/* Check that no method is maximally marked. A maximal mark is an indication - the method has been scanned to increase the usage count of its referent - methods. */ - - /* Cogit>>#noCogMethodsMaximallyMarked */ -static sqInt -noCogMethodsMaximallyMarked(void) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) != CMFree) - && (((cogMethod->cmUsageCount)) == CMMaxUsageCount)) { - return 0; - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return 1; -} - - -/* Answer if all targets in the PIC are in-use methods. */ - - /* Cogit>>#noTargetsFreeInClosedPIC: */ -static sqInt NoDbgRegParms -noTargetsFreeInClosedPIC(CogMethod *cPIC) -{ - return !(cPICHasFreedTargets(cPIC)); -} - - /* Cogit>>#OrCq:R:R: */ -static AbstractInstruction * NoDbgRegParms -gOrCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction * first; - - /* begin gen:quickConstant:operand:operand: */ - anInstruction = genoperandoperandoperand(OrCqRR, quickConstant, srcReg, destReg); - return anInstruction; - if (srcReg == destReg) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(OrCqR, quickConstant, destReg); - return anInstruction1; - } - first = genoperandoperand(MoveRR, srcReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(OrCqR, quickConstant, destReg); - return first; -} - - -/* Store the generated machine code, answering the last address */ - - /* Cogit>>#outputInstructionsAt: */ -static sqInt NoDbgRegParms -outputInstructionsAt(sqInt startAddress) -{ - sqInt absoluteAddress; - AbstractInstruction * abstractInstruction; - sqInt i; - sqInt j; - - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - absoluteAddress = startAddress; - for (i = 0; i < opcodeIndex; i += 1) { - maybeBreakGeneratingInstructionWithIndex(i); - abstractInstruction = abstractInstructionAt(i); - assert(((abstractInstruction->address)) == absoluteAddress); - /* begin outputMachineCodeAt: */ - for (j = 0; j < ((abstractInstruction->machineCodeSize)); j += 4) { - longAtput(absoluteAddress + j, ((abstractInstruction->machineCode))[j / 4]); - } - absoluteAddress += (abstractInstruction->machineCodeSize); - } - return absoluteAddress; -} - - -/* Output instructions generated for one of the generated run-time routines, - a trampoline, etc - */ - - /* Cogit>>#outputInstructionsForGeneratedRuntimeAt: */ -static sqInt NoDbgRegParms -outputInstructionsForGeneratedRuntimeAt(sqInt startAddress) -{ - sqInt endAddress; - sqInt size; - - computeMaximumSizes(); - (methodLabel->address = startAddress); - size = generateInstructionsAt(startAddress); - endAddress = outputInstructionsAt(startAddress); - assert((startAddress + size) == endAddress); - methodZoneBase = alignUptoRoutineBoundary(endAddress); - stopsFromto(backEnd, endAddress, methodZoneBase - 1); - return startAddress; -} - - /* Cogit>>#PushCw: */ -static AbstractInstruction * NoDbgRegParms -gPushCw(sqInt wordConstant) -{ - AbstractInstruction *anInstruction; - - /* begin checkLiteral:forInstruction: */ - anInstruction = genoperand(PushCw, wordConstant); - return anInstruction; -} - - -/* Code entry closed PIC full or miss to an instance of a young class or to a - young target method. - Attempt to patch the send site to an open PIC. Answer if the attempt - succeeded; in fact it will - only return if the attempt failed. - The stack looks like: - receiver - args - sp=> sender return address */ - - /* Cogit>>#patchToOpenPICFor:numArgs:receiver: */ -sqInt -patchToOpenPICFornumArgsreceiver(sqInt selector, sqInt numArgs, sqInt receiver) -{ - sqInt extent; - CogMethod *oPIC; - sqInt outerReturn; - - - /* See if an Open PIC is already available. */ - outerReturn = stackTop(); - oPIC = openPICWithSelector(selector); - if (!oPIC) { - - /* otherwise attempt to create an Open PIC. */ - oPIC = cogOpenPICSelectornumArgs(selector, numArgs); - if ((((((sqInt)oPIC)) >= MaxNegativeErrorCode) && ((((sqInt)oPIC)) <= -1))) { - - /* For some reason the PIC couldn't be generated, most likely a lack of code memory. */ - if ((((sqInt)oPIC)) == InsufficientCodeSpace) { - callForCogCompiledCodeCompaction(); - } - return 0; - } - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - extent = rewriteInlineCacheAttagtarget(backEnd, outerReturn, inlineCacheValueForSelectorin(backEnd, selector, mframeHomeMethodExport()), (((sqInt)oPIC)) + cmEntryOffset); - flushICacheFromto(backEnd, (((usqInt)outerReturn)) - extent, ((usqInt)outerReturn)); - flushICacheFromto(backEnd, ((usqInt)oPIC), (((usqInt)oPIC)) + openPICSize); - executeCogMethodfromLinkedSendWithReceiver(oPIC, receiver); - return 1; -} - - -/* This value is used to decide between MNU processing - or interpretation in the closed PIC aborts. */ - - /* Cogit>>#picAbortDiscriminatorValue */ -static sqInt -picAbortDiscriminatorValue(void) -{ - return 0; -} - - -/* Answer the start of the abort sequence for invoking the interpreter in a - closed PIC. - */ - - /* Cogit>>#picInterpretAbortOffset */ -static sqInt -picInterpretAbortOffset(void) -{ - return (interpretOffset()) - (8 /* pushLinkRegisterByteSize */ + (callInstructionByteSize(backEnd))); -} - - /* Cogit>>#previousInstruction */ -static AbstractInstruction * -previousInstruction(void) -{ - assert(opcodeIndex > 0); - return abstractInstructionAt(opcodeIndex - 1); -} - - /* Cogit>>#printCogMethodFor: */ -void -printCogMethodFor(void *address) -{ - CogMethod * cogMethod; - - cogMethod = methodFor(address); - if (cogMethod == null) { - if ((codeEntryFor(address)) == null) { - print("not a method"); - cr(); - } - else { - print("trampoline "); - print(codeEntryNameFor(address)); - cr(); - } - } - else { - printCogMethod(cogMethod); - } -} - - /* Cogit>>#printTrampolineTable */ -void -printTrampolineTable(void) -{ - sqInt i; - - for (i = 0; i < trampolineTableIndex; i += 2) { - printHex(((sqInt)(trampolineAddresses[i + 1]))); - print(": "); - print(((char *) (trampolineAddresses[i]))); - cr(); - } -} - - /* Cogit>>#processorHasDivQuoRemAndMClassIsSmallInteger */ -static sqInt -processorHasDivQuoRemAndMClassIsSmallInteger(void) -{ - return mclassIsSmallInteger(); -} - - /* Cogit>>#processorHasMultiplyAndMClassIsSmallInteger */ -static sqInt -processorHasMultiplyAndMClassIsSmallInteger(void) -{ - return 0; -} - - /* Cogit>>#recordGeneratedRunTime:address: */ -static void NoDbgRegParms -recordGeneratedRunTimeaddress(char *aString, sqInt address) -{ - assert((trampolineTableIndex + 2) <= (NumTrampolines * 2)); - trampolineAddresses[trampolineTableIndex] = aString; - trampolineAddresses[trampolineTableIndex + 1] = (((char *) address)); - - /* self printTrampolineTable */ - trampolineTableIndex += 2; -} - - -/* This one for C support code. */ - - /* Cogit>>#recordPrimTraceFunc */ -sqInt -recordPrimTraceFunc(void) -{ - return recordPrimTrace(); -} - - /* Cogit>>#recordRunTimeObjectReferences */ -static void -recordRunTimeObjectReferences(void) -{ - sqInt i; - AbstractInstruction *instruction; - - for (i = 0; i < opcodeIndex; i += 1) { - instruction = abstractInstructionAt(i); - if (((instruction->annotation)) == IsObjectReference) { - assert(runtimeObjectRefIndex < NumObjRefsInRuntime); - assert(!hasYoungReferent); - if (hasYoungReferent) { - error("attempt to generate run-time routine containing young object reference. Cannot initialize Cogit run-time."); - } - objectReferencesInRuntime[runtimeObjectRefIndex] = (((usqInt)(((instruction->address)) + ((instruction->machineCodeSize))))); - runtimeObjectRefIndex += 1; - } - } -} - - /* Cogit>>#registerMaskFor: */ -static sqInt NoDbgRegParms -registerMaskFor(sqInt reg) -{ - return 1U << reg; -} - - /* Cogit>>#registerMaskFor:and:and: */ -static sqInt NoDbgRegParms -registerMaskForandand(sqInt reg1, sqInt reg2, sqInt reg3) -{ - return ((1U << reg1) | (1U << reg2)) | (1U << reg3); -} - - /* Cogit>>#relocateCallsAndSelfReferencesInMethod: */ -static void NoDbgRegParms -relocateCallsAndSelfReferencesInMethod(CogMethod *cogMethod) -{ - sqInt annotation; - sqInt callDelta; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqLong refDelta; - sqInt result; - - refDelta = (cogMethod->objectHeader); - callDelta = 0; - assert((((cogMethod->cmType)) == CMMethod) - || (((cogMethod->cmType)) == CMOpenPIC)); - assert((callTargetFromReturnAddress(backEnd, (((sqInt)cogMethod)) + missOffset)) == ((((cogMethod->cmType)) == CMMethod - ? methodAbortTrampolineFor((cogMethod->cmNumArgs)) - : picAbortTrampolineFor((cogMethod->cmNumArgs))))); - relocateCallBeforeReturnPCby(backEnd, (((sqInt)cogMethod)) + missOffset, -callDelta); - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = relocateIfCallOrMethodReferencemcpcdelta(annotation, (((char *) mcpc)), (((void *)refDelta))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; -} - - /* Cogit>>#relocateCallsInClosedPIC: */ -static void NoDbgRegParms -relocateCallsInClosedPIC(CogMethod *cPIC) -{ - sqInt callDelta; - sqInt entryPoint; - sqInt i; - sqInt pc; - sqLong refDelta; - CogMethod *targetMethod; - - refDelta = (cPIC->objectHeader); - callDelta = 0; - assert((callTargetFromReturnAddress(backEnd, (((sqInt)cPIC)) + missOffset)) == (picAbortTrampolineFor((cPIC->cmNumArgs)))); - relocateCallBeforeReturnPCby(backEnd, (((sqInt)cPIC)) + missOffset, -callDelta); - pc = (((sqInt)cPIC)) + firstCPICCaseOffset; - for (i = 1; i <= ((cPIC->cPICNumCases)); i += 1) { - pc = addressOfEndOfCaseinCPIC(i, cPIC); - entryPoint = (i == 1 - ? jumpLongTargetBeforeFollowingAddress(backEnd, pc) - : jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc)); - if (((((usqInt)cPIC)) <= (((usqInt)entryPoint))) - && (((((usqInt)cPIC)) + ((cPIC->blockSize))) >= (((usqInt)entryPoint)))) { - - /* Interpret/MNU */ - if (i == 1) { - relocateJumpLongBeforeFollowingAddressby(backEnd, pc, refDelta); - } - else { - relocateJumpLongConditionalBeforeFollowingAddressby(backEnd, pc, refDelta); - } - } - else { - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - assert(((targetMethod->cmType)) == CMMethod); - if (i == 1) { - relocateJumpLongBeforeFollowingAddressby(backEnd, pc, -(callDelta - ((targetMethod->objectHeader)))); - } - else { - relocateJumpLongConditionalBeforeFollowingAddressby(backEnd, pc, -(callDelta - ((targetMethod->objectHeader)))); - } - } - } - assert(((cPIC->cPICNumCases)) > 0); - relocateMethodReferenceBeforeAddressby(backEnd, (addressOfEndOfCaseinCPIC(2, cPIC)) + 8 /* loadLiteralByteSize */, refDelta); - relocateJumpLongBeforeFollowingAddressby(backEnd, (((sqInt)cPIC)) + cPICEndOfCodeOffset, -callDelta); -} - - -/* To placate the C static type system... */ - - /* Cogit>>#relocateIfCallOrMethodReference:mcpc:delta: */ -static sqInt NoDbgRegParms -relocateIfCallOrMethodReferencemcpcdelta(sqInt annotation, char *mcpc, CogMethod *refDeltaArg) -{ - sqInt callDelta; - sqInt entryPoint; - sqInt offset1; - sqInt refDelta; - sqInt *sendTable1; - CogMethod *targetMethod; - sqInt unlinkedRoutine; - - refDelta = ((sqInt) refDeltaArg); - callDelta = 0; - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint <= methodZoneBase) { - - /* send is not linked; just relocate */ - relocateCallBeforeReturnPCby(backEnd, ((sqInt)mcpc), -callDelta); - return 0; - } - /* begin offsetAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod = ((CogMethod *) (entryPoint - offset1)); - if (((targetMethod->cmType)) != CMFree) { - - /* send target not freed; just relocate. */ - relocateCallBeforeReturnPCby(backEnd, ((sqInt)mcpc), -(callDelta - ((targetMethod->objectHeader)))); - - /* See comment in planCompaction */ - restorePICUsageCount(targetMethod); - return 0; - } - unlinkedRoutine = sendTable1[((((targetMethod->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod->cmNumArgs)) : (NumSendTrampolines - 1))]; - unlinkedRoutine -= callDelta; - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod->selector), enumeratingCogMethod), unlinkedRoutine); - return 0; - } - if (annotation == IsRelativeCall) { - relocateCallBeforeReturnPCby(backEnd, ((sqInt)mcpc), -callDelta); - return 0; - } - if (annotation == IsAbsPCReference) { - relocateMethodReferenceBeforeAddressby(backEnd, ((sqInt)mcpc), refDelta); - } - return 0; -} - - -/* to placate the C static type system... */ - - /* Cogit>>#remapIfObjectRef:pc:hasYoung: */ -static sqInt NoDbgRegParms -remapIfObjectRefpchasYoung(sqInt annotation, char *mcpc, CogMethod *hasYoungPtr) -{ - usqInt cacheTag1; - usqInt entryPoint1; - usqInt literal; - sqInt mappedCacheTag; - sqInt mappedLiteral; - sqInt offset1; - sqInt *sendTable1; - sqInt tagCouldBeObj1; - CogMethod *targetMethod1; - - if (annotation == IsObjectReference) { - literal = literalBeforeFollowingAddress(backEnd, ((usqInt)mcpc)); - if (couldBeObject(literal)) { - mappedLiteral = remapObject(literal); - if (literal != mappedLiteral) { - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - storeLiteralbeforeFollowingAddress(backEnd, mappedLiteral, ((usqInt)mcpc)); - } - if ((hasYoungPtr != 0) - && (isYoung(mappedLiteral))) { - (*((sqInt *) hasYoungPtr) = 1); - } - } - } - if (annotation >= IsSendCall) { - /* begin entryCacheTagAndCouldBeObjectAt:annotation:into: */ - cacheTag1 = inlineCacheTagAt(backEnd, ((sqInt)mcpc)); - - /* in-line cache tags are the selectors of sends if sends are unlinked, - the selectors of super sends (entry offset = cmNoCheckEntryOffset), - the selectors of open PIC sends (entry offset = cmEntryOffset, target is an Open PIC) - or in-line cache tags (classes, class indices, immediate bit patterns, etc). - Note that selectors can be immediate so there is no guarantee that they - are markable/remappable objects. */ - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - tagCouldBeObj1 = entryPointTagIsSelector(entryPoint1); - if (tagCouldBeObj1 - && (couldBeObject(cacheTag1))) { - mappedCacheTag = remapObject(cacheTag1); - if (cacheTag1 != mappedCacheTag) { - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheTagat(backEnd, mappedCacheTag, ((usqInt)mcpc)); - } - if ((hasYoungPtr != 0) - && (isYoung(mappedCacheTag))) { - (*((sqInt *) hasYoungPtr) = 1); - } - } - if (hasYoungPtr != 0) { - - /* Since the unlinking routines may rewrite the cacheTag to the send's selector, and - since they don't have the cogMethod to hand and can't add it to youngReferrers, - the method must remain in youngReferrers if the targetMethod's selector is young. */ - if (entryPoint1 > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint1 - offset1)); - if (isYoung((targetMethod1->selector))) { - (*((sqInt *) hasYoungPtr) = 1); - } - } - } - } - return 0; -} - - -/* Remap a potential object reference from a closed PIC. - This may be an object reference, an inline cache tag or null. - Answer if the updated literal is young. - mcpc is the address of the next instruction following either - the load of the method literal or the compare of the class tag. */ - - /* Cogit>>#remapMaybeObjRefInClosedPICAt: */ -static sqInt NoDbgRegParms -remapMaybeObjRefInClosedPICAt(sqInt mcpc) -{ - usqInt object; - sqInt subject; - - object = literalBeforeFollowingAddress(backEnd, mcpc); - if (!(couldBeObject(object))) { - return 0; - } - subject = remapOop(object); - if (object != subject) { - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - storeLiteralbeforeFollowingAddress(backEnd, subject, mcpc); - } - return isYoungObject(subject); -} - - -/* Rewrite the three values involved in a CPIC case. Used by the initialize & - extend CPICs. - c.f. expectedClosedPICPrototype: */ -/* write the obj ref/operand via the second ldr */ - - /* Cogit>>#rewriteCPICCaseAt:tag:objRef:target: */ -static void NoDbgRegParms -rewriteCPICCaseAttagobjReftarget(sqInt followingAddress, sqInt newTag, sqInt newObjRef, sqInt newTarget) -{ - sqInt classTagPC; - sqInt methodObjPC; - - methodObjPC = (followingAddress - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */; - storeLiteralbeforeFollowingAddress(backEnd, newObjRef, methodObjPC); - - /* rewite the tag via the first ldr */ - classTagPC = followingAddress - 16 /* jumpLongConditionalByteSize */; - /* begin storeLiteral32:beforeFollowingAddress: */ - storeLiteralbeforeFollowingAddress(((AbstractInstruction *) backEnd), newTag, classTagPC); - rewriteConditionalJumpLongAttarget(backEnd, followingAddress, newTarget); -} - - -/* destReg := fromReg - subReg */ - - /* Cogit>>#SubR:R:R: */ -static AbstractInstruction * NoDbgRegParms -gSubRRR(sqInt subReg, sqInt fromReg, sqInt destReg) -{ - AbstractInstruction * first; - - return genoperandoperandoperand(SubRRR, subReg, fromReg, destReg); - assert(subReg != destReg); - first = genoperandoperand(MoveRR, fromReg, destReg); - genoperandoperand(SubRR, subReg, destReg); - return first; -} - - -/* Answer the number of clean blocks found in the literal frame */ - - /* Cogit>>#scanForCleanBlocks */ -static sqInt -scanForCleanBlocks(void) -{ - sqInt i; - sqInt iLimiT; - sqInt lit; - sqInt numCleanBlocks; - sqInt startPCOrNil; - - numCleanBlocks = 0; - for (i = 1, iLimiT = (literalCountOf(methodObj)); i <= iLimiT; i += 1) { - lit = fetchPointerofObject(i, methodObj); - startPCOrNil = startPCOrNilOfLiteralin(lit, methodObj); - if (!(startPCOrNil == null)) { - numCleanBlocks += 1; - } - } - return numCleanBlocks; -} - - /* Cogit>>#setBreakMethod: */ -void -setBreakMethod(sqInt anObj) -{ - breakMethod = anObj; -} - - -/* If a method is compiled to machine code via a block entry it won't have a - selector. A subsequent send can find the method and hence fill in the - selector. - */ -/* self disassembleMethod: cogMethod */ - - /* Cogit>>#setSelectorOf:to: */ -void -setSelectorOfto(CogMethod *cogMethod, sqInt aSelectorOop) -{ - compilationBreakpointisMNUCase(aSelectorOop, 0); - assert(((cogMethod->cmType)) == CMMethod); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - ((((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)))->selector = aSelectorOop); - if (isYoung(aSelectorOop)) { - ensureInYoungReferrers(cogMethod); - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - /* Cogit>>#spanForCleanBlockStartingAt: */ -static sqInt NoDbgRegParms -spanForCleanBlockStartingAt(sqInt startPC) -{ - BytecodeDescriptor *descriptor; - sqInt end; - sqInt pc; - - pc = startPC; - end = numBytesOf(methodObj); - while (pc <= end) { - /* begin generatorForPC: */ - descriptor = generatorAt(bytecodeSetOffset + (fetchByteofObject(pc, methodObj))); - pc += (descriptor->numBytes); - if ((descriptor->isReturn)) { - return pc - startPC; - } - } - error("couldn't locate end of clean block"); - return 0; -} - - /* Cogit>>#stackCheckOffsetOfBlockAt:isMcpc: */ -static usqInt NoDbgRegParms -stackCheckOffsetOfBlockAtisMcpc(sqInt blockEntryMcpc, sqInt mcpc) -{ - CogBlockMethod *cogBlockMethod; - - cogBlockMethod = ((CogBlockMethod *) (blockEntryMcpc - (sizeof(CogBlockMethod)))); - if (((((sqInt)cogBlockMethod)) + ((cogBlockMethod->stackCheckOffset))) == mcpc) { - return ((usqInt)cogBlockMethod); - } - return 0; -} - - -/* Answer a fake value for the method oop in other than the first case in the - PIC prototype. - Since we use MoveUniqueCw:R: it must not be confused with a - method-relative address. - */ - - /* Cogit>>#subsequentPrototypeMethodOop */ -static sqInt -subsequentPrototypeMethodOop(void) -{ - return (addressIsInCurrentCompilation(0xBADA550) - ? 0xDEADEAD - : 0xBADA550); -} - - /* Cogit>>#traceLinkedSendOffset */ -sqInt -traceLinkedSendOffset(void) -{ - return (cmNoCheckEntryOffset + (callFullInstructionByteSize(backEnd))) + (8 /* pushLinkRegisterByteSize */); -} - - -/* Encode true and false and 0 to N such that they can't be confused for - register numbers (including NoReg) - and can be tested for by isTrampolineArgConstant: and decoded by - trampolineArgValue: - */ - - /* Cogit>>#trampolineArgConstant: */ -static sqInt NoDbgRegParms -trampolineArgConstant(sqInt booleanOrInteger) -{ - assert(booleanOrInteger >= 0); - return -2 - booleanOrInteger; -} - - /* Cogit>>#trampolineName:numArgs: */ -static char * NoDbgRegParms -trampolineNamenumArgs(char *routinePrefix, sqInt numArgs) -{ - char *theString; - - /* begin trampolineName:numArgs:limit: */ - theString = malloc((strlen(routinePrefix)) + 6); - sprintf(theString, "%s%cArgs", routinePrefix, (numArgs <= (NumSendTrampolines - 2) - ? '0' + numArgs - : 'N')); - return theString; -} - - -/* Malloc a string with the contents for the trampoline table */ - - /* Cogit>>#trampolineName:numArgs:limit: */ -static char * NoDbgRegParms -trampolineNamenumArgslimit(char *routinePrefix, int numArgs, sqInt argsLimit) -{ - char *theString; - - theString = malloc((strlen(routinePrefix)) + 6); - sprintf(theString, "%s%cArgs", routinePrefix, (numArgs <= argsLimit - ? '0' + numArgs - : 'N')); - return theString; -} - - /* Cogit>>#trampolineName:numRegArgs: */ -static char * NoDbgRegParms -trampolineNamenumRegArgs(char *routinePrefix, sqInt numArgs) -{ - sqInt argsLimit; - char *theString; - - /* begin trampolineName:numArgs:limit: */ - argsLimit = 2 /* numRegArgs */; - theString = malloc((strlen(routinePrefix)) + 6); - sprintf(theString, "%s%cArgs", routinePrefix, (numArgs <= argsLimit - ? '0' + numArgs - : 'N')); - return theString; -} - - /* Cogit>>#unknownBytecode */ -static sqInt -unknownBytecode(void) -{ - return EncounteredUnknownBytecode; -} - - -/* Unlink all sends in cog methods. */ - - /* Cogit>>#unlinkAllSends */ -void -unlinkAllSends(void) -{ - sqInt annotation; - CogMethod *cogMethod; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - - if (!methodZoneBase) { - return; - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - cogMethod = ((CogMethod *) methodZoneBase); - voidOpenPICList(); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfLinkedSendpcignored(annotation, (((char *) mcpc)), 0); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - else { - if (((cogMethod->cmType)) != CMFree) { - freeMethod(cogMethod); - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); -} - - -/* To placate the C static type system... */ - - /* Cogit>>#unlinkIfFreeOrLinkedSend:pc:of: */ -static sqInt NoDbgRegParms -unlinkIfFreeOrLinkedSendpcof(sqInt annotation, char *mcpc, CogMethod *theSelector) -{ - sqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if ((((targetMethod1->cmType)) == CMFree) - || (((targetMethod1->selector)) == (((sqInt) theSelector)))) { - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - } - return 0; -} - - /* Cogit>>#unlinkIfInvalidClassSend:pc:ignored: */ -static sqInt NoDbgRegParms -unlinkIfInvalidClassSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity) -{ - usqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send, but maybe a super send or linked to an OpenPIC, in which case the cache tag will be a selector.... */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (!(((annotation == IsSuperSend) - || (((annotation >= IsDirectedSuperSend) && (annotation <= IsDirectedSuperBindingSend)))) - || (((targetMethod1->cmType)) == CMOpenPIC))) { - if (!(isValidClassTag(inlineCacheTagAt(backEnd, ((sqInt)mcpc))))) { - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - } - } - return 0; -} - - /* Cogit>>#unlinkIfLinkedSendToFree:pc:ignored: */ -static sqInt NoDbgRegParms -unlinkIfLinkedSendToFreepcignored(sqInt annotation, char *mcpc, sqInt superfluity) -{ - sqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (((targetMethod1->cmType)) == CMFree) { - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - } - return 0; -} - - -/* To placate the C static type system... */ - - /* Cogit>>#unlinkIfLinkedSend:pc:if: */ -static sqInt NoDbgRegParms -unlinkIfLinkedSendpcif(sqInt annotation, char *mcpc, CogMethod *criterionArg) -{ - sqInt (*criterion)(CogMethod *); - sqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - criterion = ((void *)criterionArg); - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (criterion(targetMethod1)) { - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - } - return 0; -} - - /* Cogit>>#unlinkIfLinkedSend:pc:ignored: */ -static sqInt NoDbgRegParms -unlinkIfLinkedSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity) -{ - usqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - return 0; -} - - /* Cogit>>#unlinkIfLinkedSend:pc:to: */ -static sqInt NoDbgRegParms -unlinkIfLinkedSendpcto(sqInt annotation, char *mcpc, sqInt theCogMethod) -{ - sqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if ((((sqInt)targetMethod1)) == theCogMethod) { - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - } - return 0; -} - - -/* Unlink all sends in cog methods whose class tag is that of a forwarded - class. - */ - - /* Cogit>>#unlinkSendsLinkedForInvalidClasses */ -void -unlinkSendsLinkedForInvalidClasses(void) -{ - sqInt annotation; - CogMethod *cogMethod; - sqInt freedPIC; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - - if (!methodZoneBase) { - return; - } - cogMethod = ((CogMethod *) methodZoneBase); - codeModified = (freedPIC = 0); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfInvalidClassSendpcignored(annotation, (((char *) mcpc)), 0); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - else { - if ((((cogMethod->cmType)) == CMClosedPIC) - && (cPICHasForwardedClass(cogMethod))) { - freeMethod(cogMethod); - freedPIC = 1; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (freedPIC) { - unlinkSendsToFree(); - } - else { - if (codeModified) { - - /* After possibly updating inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } - } -} - - -/* Unlink all sends in cog methods. Free all Closed PICs with the selector, - or with an MNU case if isMNUSelector. First check if any method actually - has the selector; if not there can't be any linked send to it. This - routine (including descendents) is performance critical. It contributes - perhaps 30% of entire execution time in Compiler recompileAll. */ - - /* Cogit>>#unlinkSendsOf:isMNUSelector: */ -void -unlinkSendsOfisMNUSelector(sqInt selector, sqInt isMNUSelector) -{ - sqInt annotation; - CogMethod *cogMethod; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt mustScanAndUnlink; - sqInt result; - - if (!methodZoneBase) { - return; - } - cogMethod = ((CogMethod *) methodZoneBase); - mustScanAndUnlink = 0; - if (isMNUSelector) { - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - if (((cogMethod->cpicHasMNUCaseOrCMIsFullBlock)) - && (((cogMethod->cmType)) == CMClosedPIC)) { - assert(((cogMethod->cmType)) == CMClosedPIC); - freeMethod(cogMethod); - mustScanAndUnlink = 1; - } - else { - if (((cogMethod->selector)) == selector) { - mustScanAndUnlink = 1; - if (((cogMethod->cmType)) == CMClosedPIC) { - freeMethod(cogMethod); - } - } - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - } - else { - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) != CMFree) - && (((cogMethod->selector)) == selector)) { - mustScanAndUnlink = 1; - if (((cogMethod->cmType)) == CMClosedPIC) { - freeMethod(cogMethod); - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - } - if (!mustScanAndUnlink) { - return; - } - codeModified = 0; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfFreeOrLinkedSendpcof(annotation, (((char *) mcpc)), (((CogMethod *) selector))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (codeModified) { - - /* After possibly updating inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - -/* Unlink all sends in cog methods to free methods and/or pics. */ - - /* Cogit>>#unlinkSendsToFree */ -void -unlinkSendsToFree(void) -{ - sqInt annotation; - CogMethod *cogMethod; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - - if (!methodZoneBase) { - return; - } - codeModified = 0; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfLinkedSendToFreepcignored(annotation, (((char *) mcpc)), 0); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - else { - if (((cogMethod->cmType)) == CMClosedPIC) { - assert(noTargetsFreeInClosedPIC(cogMethod)); - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (codeModified) { - - /* After possibly updating inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } -} - - -/* Unlink all sends in cog methods to methods with a machine code - primitive, and free machine code primitive methods if freeIfTrue. - To avoid having to scan PICs, free any and all PICs */ - - /* Cogit>>#unlinkSendsToMethodsSuchThat:AndFreeIf: */ -void -unlinkSendsToMethodsSuchThatAndFreeIf(sqInt (*criterion)(CogMethod *), sqInt freeIfTrue) -{ - sqInt annotation; - CogMethod *cogMethod; - sqInt freedSomething; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - - if (!methodZoneBase) { - return; - } - codeModified = (freedSomething = 0); - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - if (freeIfTrue - && (criterion(cogMethod))) { - freeMethod(cogMethod); - freedSomething = 1; - } - else { - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfLinkedSendpcif(annotation, (((char *) mcpc)), (((CogMethod *) criterion))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - } - else { - if (((cogMethod->cmType)) == CMClosedPIC) { - freeMethod(cogMethod); - freedSomething = 1; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (freedSomething) { - unlinkSendsToFree(); - } - else { - if (codeModified) { - - /* After possibly updating inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } - } -} - - -/* Unlink all sends in cog methods to a particular target method. - If targetMethodObject isn't actually a method (perhaps being - used via invokeAsMethod) then there's nothing to do. */ - - /* Cogit>>#unlinkSendsTo:andFreeIf: */ -void -unlinkSendsToandFreeIf(sqInt targetMethodObject, sqInt freeIfTrue) -{ - sqInt annotation; - CogMethod *cogMethod; - sqInt freedPIC; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - CogMethod *targetMethod; - - if (!((isOopCompiledMethod(targetMethodObject)) - && (methodHasCogMethod(targetMethodObject)))) { - return; - } - targetMethod = cogMethodOf(targetMethodObject); - if (!methodZoneBase) { - return; - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - codeModified = (freedPIC = 0); - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfLinkedSendpcto(annotation, (((char *) mcpc)), targetMethod); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - else { - if ((((cogMethod->cmType)) == CMClosedPIC) - && (cPICHasTarget(cogMethod, targetMethod))) { - freeMethod(cogMethod); - freedPIC = 1; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (freeIfTrue) { - freeMethod(targetMethod); - } - if (freedPIC) { - unlinkSendsToFree(); - } - else { - if (codeModified) { - - /* After possibly updating inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - /* Cogit>>#voidCogCompiledCode */ -void -voidCogCompiledCode(void) -{ - CogMethod *cogMethod; - - /* begin clearCogCompiledCode */ - cogMethod = ((CogMethod *) baseAddress); - while ((((usqInt)cogMethod)) < mzFreeStart) { - if (((cogMethod->cmType)) == CMMethod) { - freeMethod(cogMethod); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - /* begin manageFrom:to: */ - mzFreeStart = (/* baseAddress = */ baseAddress); - youngReferrers = (/* limitAddress = */ limitAddress); - openPICList = null; - methodBytesFreedSinceLastCompaction = 0; - methodCount = 0; - /* begin computeAllocationThreshold */ - allocationThreshold = ((((((usqInt)((limitAddress - baseAddress) * thresholdRatio))) + (7)) & ~7)) + baseAddress; - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - -/* Access for the object representations when they need to prepend code to - trampolines. - */ -/* Eliminate stale dependent info. */ - - /* Cogit>>#zeroOpcodeIndex */ -static void -zeroOpcodeIndex(void) -{ - sqInt i; - - for (i = 0; i < opcodeIndex; i += 1) { - ((abstractOpcodes[i]).dependent = null); - } - zeroOpcodeIndexForNewOpcodes(); -} - - -/* Access for the object representations when they need to prepend code to - trampolines. - */ - - /* Cogit>>#zeroOpcodeIndexForNewOpcodes */ -static void -zeroOpcodeIndexForNewOpcodes(void) -{ - opcodeIndex = 0; -} - - /* CogMethod>>#counters */ -static sqInt NoDbgRegParms -counters(CogMethod * self_in_counters) -{ - return 0; -} - - /* CogMethodZone>>#addToOpenPICList: */ -static void NoDbgRegParms -addToOpenPICList(CogMethod *anOpenPIC) -{ - assert(((anOpenPIC->cmType)) == CMOpenPIC); - assert((openPICList == null) - || (((openPICList->cmType)) == CMOpenPIC)); - assertValidDualZoneWriteAddress(anOpenPIC); - (anOpenPIC->nextOpenPIC = ((usqInt)openPICList)); - openPICList = ((CogMethod *) ((((usqInt)anOpenPIC)) - (getCodeToDataDelta()))); -} - - /* CogMethodZone>>#addToYoungReferrers: */ -static void NoDbgRegParms -addToYoungReferrers(CogMethod *cogMethod) -{ - assertValidDualZoneWriteAddress(cogMethod); - assert((occurrencesInYoungReferrers(cogMethod)) == 0); - assert((cogMethod->cmRefersToYoung)); - assert((youngReferrers <= limitAddress) - && (youngReferrers >= (limitAddress - (methodCount * BytesPerWord)))); - if (!(asserta((limitAddress - (methodCount * BytesPerWord)) >= mzFreeStart))) { - error("no room on youngReferrers list"); - } - youngReferrers -= BytesPerWord; - codeLongAtput(youngReferrers, (((usqInt)cogMethod)) - (getCodeToDataDelta())); -} - - /* CogMethodZone>>#allocate: */ -static usqInt NoDbgRegParms -allocate(sqInt numBytes) -{ - usqInt allocation; - sqInt roundedBytes; - - roundedBytes = (numBytes + 7) & -8; - if ((mzFreeStart + roundedBytes) >= ((((limitAddress - (methodCount * BytesPerWord)) < allocationThreshold) ? (limitAddress - (methodCount * BytesPerWord)) : allocationThreshold))) { - return 0; - } - allocation = mzFreeStart; - mzFreeStart += roundedBytes; - methodCount += 1; - return allocation; -} - - -/* Answer the method containing mcpc for the purposes of code zone - compaction, where mcpc is actually the value of instructionPointer at the - time of a compaction. */ - - /* CogMethodZone>>#cogMethodContaining: */ -CogMethod * -cogMethodContaining(usqInt mcpc) -{ - CogMethod * cogMethod; - CogMethod * prevMethod; - - if (mcpc > limitAddress) { - return null; - } - if (mcpc < baseAddress) { - /* begin assertMcpcIsPrimReturn: */ - assert((mcpc == cePrimReturnEnterCogCode) - || (mcpc == cePrimReturnEnterCogCodeProfiling)); - return null; - } - assert(mcpc < (freeStart())); - cogMethod = ((CogMethod *) baseAddress); - while ((((usqInt)cogMethod)) < mcpc) { - prevMethod = cogMethod; - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - assert((prevMethod != null) - && ((mcpc == ((((usqInt)prevMethod)) + ((prevMethod->stackCheckOffset)))) - || ((mcpcisAtStackCheckOfBlockMethodIn(mcpc, prevMethod)) - || (((primitiveIndexOfMethodheader((prevMethod->methodObject), (prevMethod->methodHeader))) > 0) - || ((isCallPrecedingReturnPC(backEnd(), mcpc)) - && ((callTargetFromReturnAddress(backEnd(), mcpc)) == (ceCheckForInterruptTrampoline()))))))); - return prevMethod; -} - - /* CogMethodZone>>#compactCompiledCode */ -static void -compactCompiledCode(void) -{ - unsigned short bytes; - CogMethod *dest; - sqLong objectHeaderValue; - CogMethod *source; - CogMethod * writableVersion; - - compactionInProgress = 1; - methodCount = 0; - objectHeaderValue = nullHeaderForMachineCodeMethod(); - source = ((CogMethod *) baseAddress); - voidOpenPICList(); - voidUnpairedMethodList(); - while ((source < (limitZony())) - && (((source->cmType)) != CMFree)) { - assert((cogMethodDoesntLookKosher(source)) == 0); - /* begin writableMethodFor: */ - writableVersion = ((CogMethod *) ((((usqInt)source)) + codeToDataDelta)); - (writableVersion->objectHeader = objectHeaderValue); - if (((source->cmUsageCount)) > 0) { - (writableVersion->cmUsageCount = ((source->cmUsageCount)) / 2); - } - /* begin maybeLinkOnUnpairedMethodList: */ - /* begin clearSavedPICUsageCount: */ - if (((writableVersion->cmType)) == CMClosedPIC) { - (writableVersion->blockEntryOffset = 0); - } - if (((source->cmType)) == CMOpenPIC) { - addToOpenPICList(writableVersion); - } - methodCount += 1; - source = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)source)) + ((source->blockSize))))); - } - if (source >= (limitZony())) { - haltmsg("no free methods; cannot compact."); - return; - } - dest = source; - while (source < (limitZony())) { - assert((maybeFreeCogMethodDoesntLookKosher(source)) == 0); - bytes = (source->blockSize); - if (((source->cmType)) != CMFree) { - methodCount += 1; - codeMemmove(dest, source, bytes); - /* begin maybeFlushWritableZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - if (codeToDataDelta > 0) { - flushDCacheFromto(backEnd, ((usqInt)dest), (((usqInt)dest)) + bytes); - } -# endif - ((writableVersion = ((CogMethod *) ((((usqInt)dest)) + codeToDataDelta)))->objectHeader = objectHeaderValue); - if (((dest->cmType)) == CMMethod) { - - /* For non-Newspeak there should be a one-to-one mapping between bytecoded and - cog methods. For Newspeak not necessarily, but only for anonymous accessors. */ - /* Only update the original method's header if it is referring to this CogMethod. */ - if ((((sqInt)(rawHeaderOf((dest->methodObject))))) == (((sqInt)source))) { - rawHeaderOfput((dest->methodObject), ((sqInt)dest)); - } - else { - assert((noAssertMethodClassAssociationOf((dest->methodObject))) == (nilObject())); - /* begin linkOnUnpairedMethodList: */ - } - } - else { - /* begin clearSavedPICUsageCount: */ - if (((writableVersion->cmType)) == CMClosedPIC) { - (writableVersion->blockEntryOffset = 0); - } - if (((dest->cmType)) == CMOpenPIC) { - addToOpenPICList(writableVersion); - } - } - if (((dest->cmUsageCount)) > 0) { - (writableVersion->cmUsageCount = ((dest->cmUsageCount)) / 2); - } - /* begin maybeFlushWritableZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - if (codeToDataDelta > 0) { - flushDCacheFromto(backEnd, ((usqInt)dest), ((usqInt)(dest + 1))); - } -# endif - dest = ((CogMethod *) ((((usqInt)dest)) + bytes)); - } - source = ((CogMethod *) ((((usqInt)source)) + bytes)); - } - mzFreeStart = ((usqInt)dest); - methodBytesFreedSinceLastCompaction = 0; - compactionInProgress = 0; -} - - /* CogMethodZone>>#ensureInYoungReferrers: */ -static void NoDbgRegParms -ensureInYoungReferrers(CogMethod *cogMethod) -{ - CogMethod * writableMethod; - - assertValidDualZoneReadAddress(cogMethod); - if (!((cogMethod->cmRefersToYoung))) { - assert((occurrencesInYoungReferrers(cogMethod)) == 0); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - ((writableMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)))->cmRefersToYoung = 1); - addToYoungReferrers(writableMethod); - } -} - - /* CogMethodZone>>#followForwardedLiteralsInOpenPICList */ -static void -followForwardedLiteralsInOpenPICList(void) -{ - CogMethod *openPIC; - - openPIC = openPICList; - while (openPIC != null) { - followForwardedLiteralsIn(openPIC); - openPIC = ((CogMethod *) ((openPIC->nextOpenPIC))); - } - pruneYoungReferrers(); -} - - /* CogMethodZone>>#freeMethod: */ -static void NoDbgRegParms -freeMethod(CogMethod *cogMethod) -{ - CogMethod * writableMethod; - - assert(((cogMethod->cmType)) != CMFree); - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - if (((cogMethod->cmType)) == CMMethod) { - - /* For non-Newspeak there should be a one-to-one mapping between bytecoded and - cog methods. For Newspeak not necessarily, but only for anonymous accessors. */ - /* Only reset the original method's header if it is referring to this CogMethod. */ - if ((((sqInt)(rawHeaderOf((cogMethod->methodObject))))) == (((sqInt)cogMethod))) { - rawHeaderOfput((cogMethod->methodObject), (cogMethod->methodHeader)); - } - else { - assert((noAssertMethodClassAssociationOf((cogMethod->methodObject))) == (nilObject())); - } - } - if (((cogMethod->cmType)) == CMOpenPIC) { - removeFromOpenPICList(cogMethod); - } - /* begin writableMethodFor: */ - writableMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - (writableMethod->cmRefersToYoung = 0); - (writableMethod->cmType = CMFree); - methodBytesFreedSinceLastCompaction += (cogMethod->blockSize); -} - - -/* Free methods, preferring older methods for compaction, up to some - fraction, currently a quarter. - */ - - /* CogMethodZone>>#freeOlderMethodsForCompaction */ -static void -freeOlderMethodsForCompaction(void) -{ - sqInt amountToFree; - CogMethod *cogMethod; - sqInt freeableUsage; - sqInt freedSoFar; - sqInt initialFreeSpace; - sqInt zoneSize; - - zoneSize = ((((limitAddress) < allocationThreshold) ? (limitAddress) : allocationThreshold)) - baseAddress; - initialFreeSpace = (((((limitAddress) < allocationThreshold) ? (limitAddress) : allocationThreshold)) - mzFreeStart) + methodBytesFreedSinceLastCompaction; - freedSoFar = initialFreeSpace; - - /* 4 needs to be e.g. a start-up parameter */ - amountToFree = zoneSize / 4; - freeableUsage = 0; - do { - cogMethod = ((CogMethod *) baseAddress); - while (((((usqInt)cogMethod)) < mzFreeStart) - && (freedSoFar < amountToFree)) { - if ((((cogMethod->cmType)) == CMMethod - ? ((cogMethod->cmUsageCount)) <= freeableUsage - : (((cogMethod->cmType)) != CMFree) - && (((cogMethod->cmUsageCount)) == 0))) { - freeMethod(cogMethod); - freedSoFar += (cogMethod->blockSize); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - } while((freedSoFar < amountToFree) - && (((freeableUsage += 1)) < CMMaxUsageCount)); -} - - -/* Answer that all entries in youngReferrers are in-use and have the - cmRefersToYoung flag set. - Used to check that the youngreferrers pruning routines work correctly. */ - - /* CogMethodZone>>#kosherYoungReferrers */ -sqInt -kosherYoungReferrers(void) -{ - CogMethod * cogMethod; - usqInt pointer; - CogMethod * prevMethod; - - if ((youngReferrers > limitAddress) - || (youngReferrers < mzFreeStart)) { - return 0; - } - pointer = youngReferrers; - while (pointer < limitAddress) { - cogMethod = ((CogMethod *) (longAt(pointer))); - if (((cogMethod->cmType)) != CMFree) { - if (!((cogMethod->cmRefersToYoung))) { - return 0; - } - if ((occurrencesInYoungReferrers(cogMethod)) != 1) { - return 0; - } - } - pointer += BytesPerWord; - } - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - prevMethod = cogMethod; - if (((cogMethod->cmType)) != CMFree) { - if ((occurrencesInYoungReferrers(cogMethod)) != (((cogMethod->cmRefersToYoung) - ? 1 - : 0))) { - return 0; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - if (cogMethod == prevMethod) { - return 0; - } - } - return 1; -} - - -/* For assert checking... */ - - /* CogMethodZone>>#mcpc:isAtStackCheckOfBlockMethodIn: */ -static sqInt NoDbgRegParms -mcpcisAtStackCheckOfBlockMethodIn(sqInt mcpc, CogMethod *cogMethod) -{ - if (((cogMethod->blockEntryOffset)) == 0) { - return 0; - } - return (blockDispatchTargetsForperformarg(cogMethod, stackCheckOffsetOfBlockAtisMcpc, mcpc)) != 0; -} - - /* CogMethodZone>>#methodFor: */ -CogMethod * -methodFor(void *address) -{ - CogMethod * cogMethod; - CogMethod * nextMethod; - - cogMethod = ((CogMethod *) baseAddress); - while ((cogMethod < (limitZony())) - && ((((usqInt)cogMethod)) <= (((usqInt)address)))) { - /* begin methodAfter: */ - nextMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - if (nextMethod == cogMethod) { - return null; - } - if (((((usqInt)address)) >= (((usqInt)cogMethod))) - && ((((usqInt)address)) < (((usqInt)nextMethod)))) { - return cogMethod; - } - cogMethod = nextMethod; - } - return null; -} - - /* CogMethodZone>>#methodsCompiledToMachineCodeInto: */ -sqInt -methodsCompiledToMachineCodeInto(sqInt arrayObj) -{ - CogMethod *cogMethod; - sqInt methodIndex; - - methodIndex = 0; - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - storePointerUncheckedofObjectwithValue(methodIndex, arrayObj, (cogMethod->methodObject)); - methodIndex += 1; - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return methodIndex; -} - - /* CogMethodZone>>#numMethods */ -sqInt -numMethods(void) -{ - return methodCount; -} - - /* CogMethodZone>>#numMethodsOfType: */ -sqInt -numMethodsOfType(sqInt cogMethodType) -{ - CogMethod *cogMethod; - sqInt n; - - n = 0; - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == cogMethodType) { - n += 1; - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return n; -} - - /* CogMethodZone>>#occurrencesInYoungReferrers: */ -static sqInt NoDbgRegParms -occurrencesInYoungReferrers(CogMethod *cogMethod) -{ - sqInt count; - usqInt pointer; - - assert(youngReferrers <= limitAddress); - count = 0; - pointer = youngReferrers; - while (pointer < limitAddress) { - if ((((sqInt)cogMethod)) == (longAt(pointer))) { - count += 1; - } - pointer += BytesPerWord; - } - return count; -} - - /* CogMethodZone>>#openPICWithSelector: */ -static CogMethod * NoDbgRegParms -openPICWithSelector(sqInt aSelector) -{ - CogMethod *openPIC; - - openPIC = openPICList; - do { - if ((openPIC == null) - || (((openPIC->selector)) == aSelector)) { - return openPIC; - } - openPIC = ((CogMethod *) ((openPIC->nextOpenPIC))); - } while(1); - return 0; -} - - -/* Some methods have been freed. Compute how much each survivor needs to - move during the ensuing compaction and record it in the objectHeader - field. - For Sista, where we want PICs to last so they can be observed, we need to - keep PICs unless - they are definitely unused. So we need to identify unused PICs. So in - planCompact, zero the - usage counts of all PICs, saving the actual usage count in - blockEntryOffset. Then in - relocateMethodsPreCompaction (actually in - relocateIfCallOrMethodReference:mcpc:delta:) restore the usage counts of - used PICs. Finally in compactCompiledCode, clear the blockEntryOffset - of the unused PICs; they will then have a zero count and be reclaimed in - the next code compaction. */ - - /* CogMethodZone>>#planCompaction */ -static void -planCompaction(void) -{ - CogMethod *cogMethod; - sqInt delta; - - delta = 0; - cogMethod = ((CogMethod *) baseAddress); - while ((((usqInt)cogMethod)) < mzFreeStart) { - if (((cogMethod->cmType)) == CMFree) { - delta -= (cogMethod->blockSize); - } - else { - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - ((((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)))->objectHeader = delta); - savePICUsageCount(cogMethod); - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* CogMethodZone>>#printCogMethods */ -void -printCogMethods(void) -{ - CogMethod *cogMethod; - sqInt nc; - sqInt nf; - sqInt nm; - sqInt no; - sqInt nu; - - /* begin printCogMethodsSummarizing: */ - nm = (nc = (no = (nf = (nu = 0)))); - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - printCogMethod(cogMethod); - switch ((cogMethod->cmType)) { - case CMFree: - nf += 1; - break; - case CMMethod: - nm += 1; - break; - case CMClosedPIC: - nc += 1; - break; - case CMOpenPIC: - no += 1; - break; - default: - nu += 1; - - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - print("CMMethod "); - printNum(nm); - print(" CMClosedPIC "); - printNum(nc); - print(" CMOpenPIC "); - printNum(no); - print(" CMFree "); - printNum(nf); - if (nu > 0) { - print(" UNKNOWN "); - printNum(nu); - } - print(" total "); - printNum((((nm + nc) + no) + nf) + nu); - cr(); -} - - /* CogMethodZone>>#printCogMethodsOfType: */ -void -printCogMethodsOfType(sqInt cmType) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == cmType) { - printCogMethod(cogMethod); - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* CogMethodZone>>#printCogMethodsWithMethod: */ -void -printCogMethodsWithMethod(sqInt methodOop) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) != CMFree) - && (((cogMethod->methodObject)) == methodOop)) { - printCogMethod(cogMethod); - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* CogMethodZone>>#printCogMethodsWithPrimitive: */ -void -printCogMethodsWithPrimitive(sqInt primIdx) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) == CMMethod) - && (primIdx == (primitiveIndexOfMethodheader((cogMethod->methodObject), (cogMethod->methodHeader))))) { - printCogMethod(cogMethod); - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* CogMethodZone>>#printCogMethodsWithSelector: */ -void -printCogMethodsWithSelector(sqInt selectorOop) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) != CMFree) - && (((cogMethod->selector)) == selectorOop)) { - printCogMethod(cogMethod); - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* CogMethodZone>>#printCogYoungReferrers */ -void -printCogYoungReferrers(void) -{ - CogMethod *cogMethod; - usqInt pointer; - - pointer = youngReferrers; - while (pointer < limitAddress) { - cogMethod = ((CogMethod *) (longAt(pointer))); - if (!((cogMethod->cmRefersToYoung))) { - print("*"); - } - if (((cogMethod->cmType)) == CMFree) { - print("!"); - } - if (!(((cogMethod->cmRefersToYoung)) - && (((cogMethod->cmType)) != CMFree))) { - print(" "); - } - printCogMethod(cogMethod); - pointer += BytesPerWord; - } -} - - /* CogMethodZone>>#printOpenPICList */ -sqInt -printOpenPICList(void) -{ - sqInt n; - CogMethod *openPIC; - - /* begin printOpenPICListSummarizing: */ - n = 0; - openPIC = openPICList; - while (!(openPIC == null)) { - n += 1; - printCogMethod(openPIC); - openPIC = ((CogMethod *) ((openPIC->nextOpenPIC))); - } - return n; -} - - /* CogMethodZone>>#pruneYoungReferrers */ -sqInt -pruneYoungReferrers(void) -{ - usqInt dest; - usqInt next; - usqInt source; - - assert(youngReferrers <= limitAddress); - if (youngReferrers == limitAddress) { - return null; - } - dest = limitAddress; - while (1) { - next = dest - BytesPerWord; - if (!((next >= youngReferrers) - && (((((CogMethod *) (longAt(next))))->cmRefersToYoung)))) break; - dest = next; - } - assert(dest >= youngReferrers); - source = dest - BytesPerWord; - while (source >= youngReferrers) { - if (((((CogMethod *) (longAt(source))))->cmRefersToYoung)) { - assert(source < (dest - BytesPerWord)); - if (!(next == null)) { - - /* convenient first-time flag */ - next = null; - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - } - codeLongAtput((dest -= BytesPerWord), longAt(source)); - } - source -= BytesPerWord; - } - youngReferrers = dest; - assert(kosherYoungReferrers()); - return 0; -} - - /* CogMethodZone>>#relocateAndPruneYoungReferrers */ -static sqInt -relocateAndPruneYoungReferrers(void) -{ - CogMethod *cogMethod; - usqInt dest; - usqInt next; - usqInt source; - - assert(youngReferrers <= limitAddress); - if (youngReferrers == limitAddress) { - return null; - } - dest = limitAddress; - while (1) { - next = dest - BytesPerWord; - if (!((next >= youngReferrers) - && (((((cogMethod = ((CogMethod *) (longAt(next))))->cmType)) != CMFree) - && ((cogMethod->cmRefersToYoung))))) break; - if (((cogMethod->objectHeader)) != 0) { - codeLongAtput(next, (((sqInt)cogMethod)) + ((cogMethod->objectHeader))); - } - dest = next; - } - assert(dest >= youngReferrers); - source = dest - BytesPerWord; - while (source >= youngReferrers) { - cogMethod = ((CogMethod *) (longAt(source))); - if ((((cogMethod->cmType)) != CMFree) - && ((cogMethod->cmRefersToYoung))) { - assert(source < (dest - BytesPerWord)); - if (((cogMethod->objectHeader)) != 0) { - cogMethod = ((CogMethod *) ((((sqInt)cogMethod)) + (((sqInt)((cogMethod->objectHeader)))))); - } - codeLongAtput((dest -= BytesPerWord), ((sqInt)cogMethod)); - } - source -= BytesPerWord; - } - youngReferrers = dest; - return 0; -} - - -/* All surviving methods have had the amount they are going to relocate by - stored in their objectHeader fields. Relocate all relative calls so that - after the compaction of both the method containing each call and the call - target the calls invoke the same target. */ - - /* CogMethodZone>>#relocateMethodsPreCompaction */ -static sqInt -relocateMethodsPreCompaction(void) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) baseAddress); - while ((((usqInt)cogMethod)) < mzFreeStart) { - if (((cogMethod->cmType)) != CMFree) { - if (((cogMethod->cmType)) == CMClosedPIC) { - relocateCallsInClosedPIC(cogMethod); - } - else { - relocateCallsAndSelfReferencesInMethod(cogMethod); - } - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - relocateAndPruneYoungReferrers(); - return 1; -} - - /* CogMethodZone>>#removeFromOpenPICList: */ -static sqInt NoDbgRegParms -removeFromOpenPICList(CogMethod *anOpenPIC) -{ - CogMethod *prevPIC; - - assert(((anOpenPIC->cmType)) == CMOpenPIC); - if (!openPICList) { - return null; - } - assert((((openPICList->cmType)) == CMOpenPIC) - && ((((openPICList->nextOpenPIC)) == null) - || ((((((CogMethod *) ((openPICList->nextOpenPIC))))->cmType)) == CMOpenPIC))); - if (anOpenPIC == openPICList) { - - /* N.B. Use self rather than coInterpreter to avoid attempting to cast nil. - Conversion to CogMethod done in the nextOpenPIC accessor. */ - openPICList = ((CogMethod *) ((anOpenPIC->nextOpenPIC))); - return null; - } - prevPIC = openPICList; - do { - assert((prevPIC != null) - && (((prevPIC->cmType)) == CMOpenPIC)); - if (((prevPIC->nextOpenPIC)) == (((usqInt)anOpenPIC))) { - ((((CogMethod *) ((((usqInt)prevPIC)) + codeToDataDelta)))->nextOpenPIC = (anOpenPIC->nextOpenPIC)); - return null; - } - prevPIC = ((CogMethod *) ((prevPIC->nextOpenPIC))); - } while(1); - return 0; -} - - -/* For Sista, where we want PICs to last so they can be observed, we need to - keep PICs unless - they are definitely unused. So we need to identify unused PICs. So in - planCompact, zero the - usage counts of all PICs, saving the actual usage count in - blockEntryOffset. Then in - relocateMethodsPreCompaction (actually in - relocateIfCallOrMethodReference:mcpc:delta:) restore the usage counts of - used PICs. Finally in compactCompiledCode, clear the blockEntryOffset - of the unused PICs; they will then have a zero count and be reclaimed in - the next code compaction. */ - - /* CogMethodZone>>#restorePICUsageCount: */ -static void NoDbgRegParms -restorePICUsageCount(CogMethod *cogMethod) -{ - if ((((cogMethod->cmType)) == CMClosedPIC) - && (((cogMethod->blockEntryOffset)) != 0)) { - (cogMethod->cmUsageCount = (cogMethod->blockEntryOffset)); - (cogMethod->blockEntryOffset = 0); - } -} - - -/* Determine the default alignment for the start of a CogMethod, which in - turn determines the size of the mask used to distinguish the checked and - unchecked entry-points, used to distinguish normal and super sends on - method unlinking. - This is passed onto the backEnd to allow processors with coarse - instructions (ARM) to increase the alignment if required. */ - - /* CogMethodZone>>#roundUpLength: */ -static sqInt NoDbgRegParms -roundUpLength(sqInt numBytes) -{ - return roundUpToMethodAlignment(backEnd(), numBytes); -} - - -/* For Sista, where we want PICs to last so they can be observed, we need to - keep PICs unless - they are definitely unused. So we need to identify unused PICs. So in - planCompact, zero the - usage counts of all PICs, saving the actual usage count in - blockEntryOffset. Then in - relocateMethodsPreCompaction (actually in - relocateIfCallOrMethodReference:mcpc:delta:) restore the usage counts of - used PICs. Finally in compactCompiledCode, clear the blockEntryOffset - of the unused PICs; they will then have a zero count and be reclaimed in - the next code compaction. */ - - /* CogMethodZone>>#savePICUsageCount: */ -static void NoDbgRegParms -savePICUsageCount(CogMethod *cogMethod) -{ - if (((cogMethod->cmType)) == CMClosedPIC) { - (cogMethod->blockEntryOffset = (cogMethod->cmUsageCount)); - (cogMethod->cmUsageCount = 0); - } -} - - /* CogMethodZone>>#voidOpenPICList */ -static void -voidOpenPICList(void) -{ - openPICList = null; -} - - /* CogMethodZone>>#voidUnpairedMethodList */ -static void -voidUnpairedMethodList(void) -{ - } - - /* CogMethodZone>>#voidYoungReferrersPostTenureAll */ -static void -voidYoungReferrersPostTenureAll(void) -{ - CogMethod *cogMethod; - usqInt pointer; - - assert(youngReferrers <= limitAddress); - pointer = youngReferrers; - while (pointer < limitAddress) { - cogMethod = ((CogMethod *) (longAt(pointer))); - if (((cogMethod->cmType)) != CMFree) { - (cogMethod->cmRefersToYoung = 0); - } - pointer += BytesPerWord; - } - youngReferrers = limitAddress; -} - - -/* useful for VM debugging; use export: so it will be accessible on win32 */ - - /* CogMethodZone>>#whereIsMaybeCodeThing: */ -EXPORT(char *) -whereIsMaybeCodeThing(sqInt anOop) -{ - if (oopisGreaterThanOrEqualToandLessThan(anOop, codeBase, limitAddress)) { - if (oopisLessThan(anOop, minCogMethodAddress())) { - return " is in generated runtime"; - } - if (oopisLessThan(anOop, mzFreeStart)) { - return " is in generated methods"; - } - if (oopisLessThan(anOop, youngReferrers)) { - return " is in code zone"; - } - return " is in young referrers"; - } - return null; -} - - /* CogMIPSELCompiler>>#addiuR:R:C: */ -static sqInt NoDbgRegParms -addiuRRC(AbstractInstruction * self_in_addiuRRC, sqInt destReg, sqInt srcReg, sqInt imm) -{ - return itypersrtsignedImmediate(self_in_addiuRRC, ADDIU, srcReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#adduR:R:R: */ -static sqInt NoDbgRegParms -adduRRR(AbstractInstruction * self_in_adduRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_adduRRR, SPECIAL, leftReg, rightReg, destReg, 0, ADDU); -} - - /* CogMIPSELCompiler>>#andiR:R:C: */ -static sqInt NoDbgRegParms -andiRRC(AbstractInstruction * self_in_andiRRC, sqInt destReg, sqInt srcReg, sqInt imm) -{ - return itypersrteitherImmediate(self_in_andiRRC, ANDI, srcReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#andR:R:R: */ -static sqInt NoDbgRegParms -andRRR(AbstractInstruction * self_in_andRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_andRRR, SPECIAL, leftReg, rightReg, destReg, 0, AND); -} - - /* CogMIPSELCompiler>>#beqR:R:offset: */ -static sqInt NoDbgRegParms -beqRRoffset(AbstractInstruction * self_in_beqRRoffset, sqInt leftReg, sqInt rightReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_beqRRoffset, BEQ, leftReg, rightReg, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#bgezR:offset: */ -static sqInt NoDbgRegParms -bgezRoffset(AbstractInstruction * self_in_bgezRoffset, sqInt cmpReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_bgezRoffset, REGIMM, cmpReg, BGEZ, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#bgtzR:offset: */ -static sqInt NoDbgRegParms -bgtzRoffset(AbstractInstruction * self_in_bgtzRoffset, sqInt cmpReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_bgtzRoffset, BGTZ, cmpReg, 0, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#blezR:offset: */ -static sqInt NoDbgRegParms -blezRoffset(AbstractInstruction * self_in_blezRoffset, sqInt cmpReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_blezRoffset, BLEZ, cmpReg, 0, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#bltzR:offset: */ -static sqInt NoDbgRegParms -bltzRoffset(AbstractInstruction * self_in_bltzRoffset, sqInt cmpReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_bltzRoffset, REGIMM, cmpReg, BLTZ, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#bneR:R:offset: */ -static sqInt NoDbgRegParms -bneRRoffset(AbstractInstruction * self_in_bneRRoffset, sqInt leftReg, sqInt rightReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_bneRRoffset, BNE, leftReg, rightReg, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#callInstructionByteSize */ -static sqInt NoDbgRegParms -callInstructionByteSize(AbstractInstruction * self_in_callInstructionByteSize) -{ - flag("todo"); - return 16; -} - - -/* csra - 16: lui t9, high - csra - 12: ori t9, low - csra - 8: jalr t9 - csra - 4: nop (delay slot) */ - - /* CogMIPSELCompiler>>#callTargetFromReturnAddress: */ -static usqInt NoDbgRegParms -callTargetFromReturnAddress(AbstractInstruction * self_in_callTargetFromReturnAddress, sqInt callSiteReturnAddress) -{ - assert((opcodeAtAddress(self_in_callTargetFromReturnAddress, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_callTargetFromReturnAddress, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_callTargetFromReturnAddress, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_callTargetFromReturnAddress, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_callTargetFromReturnAddress))); - return literalAtAddress(self_in_callTargetFromReturnAddress, callSiteReturnAddress - 12); -} - - -/* NOTE: the right reg (rt) MUST equal dest reg (rd) or behavior is undefined */ - - /* CogMIPSELCompiler>>#clzR:R:R: */ -static sqInt NoDbgRegParms -clzRRR(AbstractInstruction * self_in_clzRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_clzRRR, SPECIAL, leftReg, rightReg, destReg, 0, 32); -} - - /* CogMIPSELCompiler>>#cmpC32RTempByteSize */ -static sqInt NoDbgRegParms -cmpC32RTempByteSize(AbstractInstruction * self_in_cmpC32RTempByteSize) -{ - return 8; -} - - -/* Each MIPS instruction has 4 bytes. Many abstract opcodes need more than - one instruction. Instructions that refer to constants and/or literals - depend on literals - being stored in-line or out-of-line. - - N.B. The ^N forms are to get around the bytecode compiler's long branch - limits which are exceeded when each case jumps around the otherwise. */ - - /* CogMIPSELCompiler>>#computeMaximumSize */ -static sqInt NoDbgRegParms -computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize) -{ - switch ((self_in_computeMaximumSize->opcode)) { - case BrEqualRR: - case BrNotEqualRR: - case JumpR: - case Jump: - case JumpZero: - case JumpNonZero: - case JumpNegative: - case JumpNonNegative: - case JumpOverflow: - case JumpNoOverflow: - case JumpCarry: - case JumpNoCarry: - case JumpLess: - case JumpGreaterOrEqual: - case JumpGreater: - case JumpLessOrEqual: - case JumpBelow: - case JumpAboveOrEqual: - case JumpAbove: - case JumpBelowOrEqual: - case JumpFPEqual: - case JumpFPNotEqual: - case JumpFPLess: - case JumpFPGreaterOrEqual: - case JumpFPGreater: - case JumpFPLessOrEqual: - case JumpFPOrdered: - case JumpFPUnordered: - case RetN: - case MoveCwR: - case MoveXbrRR: - case MoveRXbrR: - case PopR: - case PushR: - case ConvertRRd: - return 8; - - case BrUnsignedLessRR: - case BrUnsignedLessEqualRR: - case BrUnsignedGreaterRR: - case BrUnsignedGreaterEqualRR: - case BrSignedLessRR: - case BrSignedLessEqualRR: - case BrSignedGreaterRR: - case BrSignedGreaterEqualRR: - case XorCqR: - case AddCwR: - case AndCwR: - case OrCwR: - case SubCwR: - case XorCwR: - case MoveXwrRR: - case MoveRXwrR: - case PrefetchAw: - return 12; - - case BrLongEqualRR: - case BrLongNotEqualRR: - case PushCw: - case PushCq: - return 16; - - case MulRR: - case DivRR: - case MoveLowR: - case MoveHighR: - case Literal: - case Fill32: - case Nop: - case Stop: - case AddRR: - case AndRR: - case OrRR: - case XorRR: - case SubRR: - case NegateR: - case AddRRR: - case SubRRR: - case LogicalShiftLeftCqR: - case LogicalShiftRightCqR: - case ArithmeticShiftRightCqR: - case LogicalShiftLeftRR: - case LogicalShiftRightRR: - case ArithmeticShiftRightRR: - case AddRdRd: - case CmpRdRd: - case SubRdRd: - case MulRdRd: - case DivRdRd: - case SqrtRd: - case ClzRR: - case MoveRR: - case MoveRdRd: - case MoveRMwr: - case MoveMbrR: - case MoveRMbr: - case MoveM16rR: - case MoveRM16r: - return 4; - - case Label: - return 0; - - case AlignmentNops: - return (((self_in_computeMaximumSize->operands))[0]) - 4; - - case Call: - case CallFull: - case JumpFull: - case JumpLong: - case JumpLongZero: - case JumpLongNonZero: - return 16; - - case AddCqR: - case OrCqR: - case OrCqRR: - case SubCqR: - case TstCqR: - case LoadEffectiveAddressMwrR: - return (isShortOffset(self_in_computeMaximumSize, ((self_in_computeMaximumSize->operands))[0]) - ? 4 - : 12); - - case AndCqR: - case AndCqRR: - return ((((((self_in_computeMaximumSize->operands))[0]) >= 0) && ((((self_in_computeMaximumSize->operands))[0]) <= 0xFFFF)) - ? 4 - : 12); - - case CmpCqR: - case CmpCwR: - case AddCheckOverflowCqR: - case SubCheckOverflowCqR: - return 28; - - case CmpRR: - case AddCheckOverflowRR: - case SubCheckOverflowRR: - case MulCheckOverflowRR: - return 20; - - case MoveCqR: - return (isShortOffset(self_in_computeMaximumSize, ((self_in_computeMaximumSize->operands))[0]) - ? 4 - : 8); - - case MoveAwR: - case MoveAbR: - return (((((self_in_computeMaximumSize->operands))[0]) != null) - && ((((varBaseAddress()) - (0x8000)) < (((self_in_computeMaximumSize->operands))[0])) - && ((((self_in_computeMaximumSize->operands))[0]) < ((varBaseAddress()) + (0x8000)))) - ? 4 - : 12); - - case MoveRAw: - case MoveRAb: - return (((((self_in_computeMaximumSize->operands))[1]) != null) - && ((((varBaseAddress()) - (0x8000)) < (((self_in_computeMaximumSize->operands))[1])) - && ((((self_in_computeMaximumSize->operands))[1]) < ((varBaseAddress()) + (0x8000)))) - ? 4 - : 12); - - case MoveRdM64r: - case MoveM64rRd: - return 12; - - case MoveMwrR: - return (isShortOffset(self_in_computeMaximumSize, ((self_in_computeMaximumSize->operands))[0]) - ? 4 - : 16); - - default: - error("Case not found and no otherwise clause"); - } - return 0; -} - - /* CogMIPSELCompiler>>#concretizeAddCheckOverflowCqR */ -static sqInt NoDbgRegParms -concretizeAddCheckOverflowCqR(AbstractInstruction * self_in_concretizeAddCheckOverflowCqR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - sqInt aWord4; - sqInt aWord5; - sqInt aWord6; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeAddCheckOverflowCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAddCheckOverflowCqR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeAddCheckOverflowCqR, AT, high16BitsOf(self_in_concretizeAddCheckOverflowCqR, rightImm)); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeAddCheckOverflowCqR, AT, AT, low16BitsOf(self_in_concretizeAddCheckOverflowCqR, rightImm)); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = adduRRR(self_in_concretizeAddCheckOverflowCqR, OverflowTemp1, leftReg, ZR); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = adduRRR(self_in_concretizeAddCheckOverflowCqR, destReg, leftReg, AT); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[12 / 4] = aWord3; - /* begin machineCodeAt:put: */ - aWord4 = xorRRR(self_in_concretizeAddCheckOverflowCqR, OverflowTemp2, destReg, AT); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[16 / 4] = aWord4; - /* begin machineCodeAt:put: */ - aWord5 = xorRRR(self_in_concretizeAddCheckOverflowCqR, OverflowTemp1, destReg, OverflowTemp1); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[20 / 4] = aWord5; - /* begin machineCodeAt:put: */ - aWord6 = andRRR(self_in_concretizeAddCheckOverflowCqR, Overflow, OverflowTemp1, OverflowTemp2); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[24 / 4] = aWord6; - return 28; -} - - /* CogMIPSELCompiler>>#concretizeAddCheckOverflowRR */ -static sqInt NoDbgRegParms -concretizeAddCheckOverflowRR(AbstractInstruction * self_in_concretizeAddCheckOverflowRR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - sqInt aWord4; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeAddCheckOverflowRR->operands))[0]; - - /* Save original LHS */ - destReg = (leftReg = ((self_in_concretizeAddCheckOverflowRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeAddCheckOverflowRR, OverflowTemp1, leftReg, ZR); - ((self_in_concretizeAddCheckOverflowRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = adduRRR(self_in_concretizeAddCheckOverflowRR, destReg, leftReg, rightReg); - ((self_in_concretizeAddCheckOverflowRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = xorRRR(self_in_concretizeAddCheckOverflowRR, OverflowTemp2, destReg, rightReg); - ((self_in_concretizeAddCheckOverflowRR->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = xorRRR(self_in_concretizeAddCheckOverflowRR, OverflowTemp1, destReg, OverflowTemp1); - ((self_in_concretizeAddCheckOverflowRR->machineCode))[12 / 4] = aWord3; - /* begin machineCodeAt:put: */ - aWord4 = andRRR(self_in_concretizeAddCheckOverflowRR, Overflow, OverflowTemp1, OverflowTemp2); - ((self_in_concretizeAddCheckOverflowRR->machineCode))[16 / 4] = aWord4; - return 20; -} - - /* CogMIPSELCompiler>>#concretizeAddCqR */ -static sqInt NoDbgRegParms -concretizeAddCqR(AbstractInstruction * self_in_concretizeAddCqR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeAddCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAddCqR->operands))[1]); - if (!(isShortOffset(self_in_concretizeAddCqR, rightImm))) { - return concretizeAddCwR(self_in_concretizeAddCqR); - } - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizeAddCqR, destReg, leftReg, rightImm); - ((self_in_concretizeAddCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeAddCwR */ -static sqInt NoDbgRegParms -concretizeAddCwR(AbstractInstruction * self_in_concretizeAddCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeAddCwR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAddCwR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeAddCwR, AT, high16BitsOf(self_in_concretizeAddCwR, rightImm)); - ((self_in_concretizeAddCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeAddCwR, AT, AT, low16BitsOf(self_in_concretizeAddCwR, rightImm)); - ((self_in_concretizeAddCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = adduRRR(self_in_concretizeAddCwR, destReg, leftReg, AT); - ((self_in_concretizeAddCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeAddRRDest: */ -static sqInt NoDbgRegParms -concretizeAddRRDest(AbstractInstruction * self_in_concretizeAddRRDest, sqInt destReg) -{ - sqInt aWord; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeAddRRDest->operands))[0]; - leftReg = ((self_in_concretizeAddRRDest->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeAddRRDest, destReg, leftReg, rightReg); - ((self_in_concretizeAddRRDest->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeAlignmentNops */ -static usqInt NoDbgRegParms -concretizeAlignmentNops(AbstractInstruction * self_in_concretizeAlignmentNops) -{ - sqInt p; - - assert((((self_in_concretizeAlignmentNops->machineCodeSize)) % 4) == 0); - for (p = 0; p < ((self_in_concretizeAlignmentNops->machineCodeSize)); p += 4) { - /* begin machineCodeAt:put: */ - ((self_in_concretizeAlignmentNops->machineCode))[p / 4] = 0 /* nop */; - } - return (self_in_concretizeAlignmentNops->machineCodeSize); -} - - /* CogMIPSELCompiler>>#concretizeAndCqR */ -static sqInt NoDbgRegParms -concretizeAndCqR(AbstractInstruction * self_in_concretizeAndCqR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeAndCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAndCqR->operands))[1]); - if (!(isShortOffset(self_in_concretizeAndCqR, rightImm))) { - return concretizeAndCwR(self_in_concretizeAndCqR); - } - /* begin machineCodeAt:put: */ - aWord = andiRRC(self_in_concretizeAndCqR, destReg, leftReg, rightImm); - ((self_in_concretizeAndCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeAndCqRDest: */ -static sqInt NoDbgRegParms -concretizeAndCqRDest(AbstractInstruction * self_in_concretizeAndCqRDest, sqInt destReg) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt srcReg; - usqInt value; - - value = ((self_in_concretizeAndCqRDest->operands))[0]; - srcReg = ((self_in_concretizeAndCqRDest->operands))[1]; - if (((value >= 0) && (value <= 0xFFFF))) { - /* begin machineCodeAt:put: */ - aWord = andiRRC(self_in_concretizeAndCqRDest, destReg, srcReg, value); - ((self_in_concretizeAndCqRDest->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeAndCqRDest, AT, high16BitsOf(self_in_concretizeAndCqRDest, value)); - ((self_in_concretizeAndCqRDest->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeAndCqRDest, AT, AT, low16BitsOf(self_in_concretizeAndCqRDest, value)); - ((self_in_concretizeAndCqRDest->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = andRRR(self_in_concretizeAndCqRDest, destReg, srcReg, AT); - ((self_in_concretizeAndCqRDest->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeAndCwR */ -static sqInt NoDbgRegParms -concretizeAndCwR(AbstractInstruction * self_in_concretizeAndCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeAndCwR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAndCwR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeAndCwR, AT, high16BitsOf(self_in_concretizeAndCwR, rightImm)); - ((self_in_concretizeAndCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeAndCwR, AT, AT, low16BitsOf(self_in_concretizeAndCwR, rightImm)); - ((self_in_concretizeAndCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = andRRR(self_in_concretizeAndCwR, destReg, leftReg, AT); - ((self_in_concretizeAndCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeAndRR */ -static sqInt NoDbgRegParms -concretizeAndRR(AbstractInstruction * self_in_concretizeAndRR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeAndRR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAndRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = andRRR(self_in_concretizeAndRR, destReg, leftReg, rightReg); - ((self_in_concretizeAndRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeArithmeticShiftRightCqR */ -static sqInt NoDbgRegParms -concretizeArithmeticShiftRightCqR(AbstractInstruction * self_in_concretizeArithmeticShiftRightCqR) -{ - sqInt aWord; - sqInt distance; - usqInt reg; - - distance = (((((self_in_concretizeArithmeticShiftRightCqR->operands))[0]) < 0x1F) ? (((self_in_concretizeArithmeticShiftRightCqR->operands))[0]) : 0x1F); - reg = ((self_in_concretizeArithmeticShiftRightCqR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = sraRRC(self_in_concretizeArithmeticShiftRightCqR, reg, reg, distance); - ((self_in_concretizeArithmeticShiftRightCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeArithmeticShiftRightRR */ -static sqInt NoDbgRegParms -concretizeArithmeticShiftRightRR(AbstractInstruction * self_in_concretizeArithmeticShiftRightRR) -{ - sqInt aWord; - usqInt destReg; - usqInt distReg; - - distReg = ((self_in_concretizeArithmeticShiftRightRR->operands))[0]; - destReg = ((self_in_concretizeArithmeticShiftRightRR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = sravRRR(self_in_concretizeArithmeticShiftRightRR, destReg, destReg, distReg); - ((self_in_concretizeArithmeticShiftRightRR->machineCode))[0 / 4] = aWord; - return 4; -} - - -/* Generate concrete machine code for the instruction at actualAddress, - setting machineCodeSize, and answer the following address. */ -/* Generate concrete machine code for the instruction at actualAddress, - setting machineCodeSize, and answer the following address. */ - - /* CogMIPSELCompiler>>#concretizeAt: */ -static sqInt NoDbgRegParms -concretizeAt(AbstractInstruction * self_in_concretizeAt, sqInt actualAddress) -{ - assert((actualAddress % 4) == 0); - (self_in_concretizeAt->address) = actualAddress; - (self_in_concretizeAt->machineCodeSize) = dispatchConcretize(self_in_concretizeAt); - assert((((self_in_concretizeAt->maxSize)) == null) - || (((self_in_concretizeAt->maxSize)) >= ((self_in_concretizeAt->machineCodeSize)))); - return actualAddress + ((self_in_concretizeAt->machineCodeSize)); -} - - /* CogMIPSELCompiler>>#concretizeBrEqualRR */ -static sqInt NoDbgRegParms -concretizeBrEqualRR(AbstractInstruction * self_in_concretizeBrEqualRR) -{ - sqInt aWord; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrEqualRR->address)) + 4))); - leftReg = ((self_in_concretizeBrEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrEqualRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = beqRRoffset(self_in_concretizeBrEqualRR, leftReg, rightReg, offset); - ((self_in_concretizeBrEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrEqualRR->machineCode))[4 / 4] = 0 /* nop */; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeBrLongEqualRR */ -static sqInt NoDbgRegParms -concretizeBrLongEqualRR(AbstractInstruction * self_in_concretizeBrLongEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - usqInt jumpTargetAddr; - AbstractInstruction *jumpTargetInstruction; - usqInt leftReg; - usqInt rightReg; - - /* begin longJumpTargetAddress */ - jumpTarget = ((AbstractInstruction *) (((self_in_concretizeBrLongEqualRR->operands))[0])); - if ((addressIsInInstructions(jumpTarget)) - || (jumpTarget == (methodLabel()))) { - jumpTarget = ((AbstractInstruction *) ((jumpTarget->address))); - } - assert(jumpTarget != 0); - jumpTargetInstruction = jumpTarget; - flag("todo"); - jumpTargetAddr = (((usqInt)jumpTargetInstruction)) & 0xFFFFFFF; - leftReg = ((self_in_concretizeBrLongEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrLongEqualRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = bneRRoffset(self_in_concretizeBrLongEqualRR, leftReg, rightReg, 12); - ((self_in_concretizeBrLongEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrLongEqualRR->machineCode))[4 / 4] = 0 /* nop */; - /* begin machineCodeAt:put: */ - aWord1 = jA(self_in_concretizeBrLongEqualRR, jumpTargetAddr); - ((self_in_concretizeBrLongEqualRR->machineCode))[8 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrLongEqualRR->machineCode))[12 / 4] = 0 /* nop */; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeBrLongNotEqualRR */ -static sqInt NoDbgRegParms -concretizeBrLongNotEqualRR(AbstractInstruction * self_in_concretizeBrLongNotEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - usqInt jumpTargetAddr; - AbstractInstruction *jumpTargetInstruction; - usqInt leftReg; - usqInt rightReg; - - /* begin longJumpTargetAddress */ - jumpTarget = ((AbstractInstruction *) (((self_in_concretizeBrLongNotEqualRR->operands))[0])); - if ((addressIsInInstructions(jumpTarget)) - || (jumpTarget == (methodLabel()))) { - jumpTarget = ((AbstractInstruction *) ((jumpTarget->address))); - } - assert(jumpTarget != 0); - jumpTargetInstruction = jumpTarget; - flag("todo"); - jumpTargetAddr = (((usqInt)jumpTargetInstruction)) & 0xFFFFFFF; - leftReg = ((self_in_concretizeBrLongNotEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrLongNotEqualRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = beqRRoffset(self_in_concretizeBrLongNotEqualRR, leftReg, rightReg, 12); - ((self_in_concretizeBrLongNotEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrLongNotEqualRR->machineCode))[4 / 4] = 0 /* nop */; - /* begin machineCodeAt:put: */ - aWord1 = jA(self_in_concretizeBrLongNotEqualRR, jumpTargetAddr); - ((self_in_concretizeBrLongNotEqualRR->machineCode))[8 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrLongNotEqualRR->machineCode))[12 / 4] = 0 /* nop */; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeBrNotEqualRR */ -static sqInt NoDbgRegParms -concretizeBrNotEqualRR(AbstractInstruction * self_in_concretizeBrNotEqualRR) -{ - sqInt aWord; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrNotEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrNotEqualRR->address)) + 4))); - leftReg = ((self_in_concretizeBrNotEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrNotEqualRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = bneRRoffset(self_in_concretizeBrNotEqualRR, leftReg, rightReg, offset); - ((self_in_concretizeBrNotEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrNotEqualRR->machineCode))[4 / 4] = 0 /* nop */; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeBrSignedGreaterEqualRR */ -static sqInt NoDbgRegParms -concretizeBrSignedGreaterEqualRR(AbstractInstruction * self_in_concretizeBrSignedGreaterEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrSignedGreaterEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrSignedGreaterEqualRR->address)) + 8))); - leftReg = ((self_in_concretizeBrSignedGreaterEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrSignedGreaterEqualRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltRRR(self_in_concretizeBrSignedGreaterEqualRR, BranchTemp, leftReg, rightReg); - ((self_in_concretizeBrSignedGreaterEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = beqRRoffset(self_in_concretizeBrSignedGreaterEqualRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrSignedGreaterEqualRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrSignedGreaterEqualRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrSignedGreaterRR */ -static sqInt NoDbgRegParms -concretizeBrSignedGreaterRR(AbstractInstruction * self_in_concretizeBrSignedGreaterRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrSignedGreaterRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrSignedGreaterRR->address)) + 8))); - leftReg = ((self_in_concretizeBrSignedGreaterRR->operands))[1]; - rightReg = ((self_in_concretizeBrSignedGreaterRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltRRR(self_in_concretizeBrSignedGreaterRR, BranchTemp, rightReg, leftReg); - ((self_in_concretizeBrSignedGreaterRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = bneRRoffset(self_in_concretizeBrSignedGreaterRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrSignedGreaterRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrSignedGreaterRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrSignedLessEqualRR */ -static sqInt NoDbgRegParms -concretizeBrSignedLessEqualRR(AbstractInstruction * self_in_concretizeBrSignedLessEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrSignedLessEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrSignedLessEqualRR->address)) + 8))); - leftReg = ((self_in_concretizeBrSignedLessEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrSignedLessEqualRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltRRR(self_in_concretizeBrSignedLessEqualRR, BranchTemp, rightReg, leftReg); - ((self_in_concretizeBrSignedLessEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = beqRRoffset(self_in_concretizeBrSignedLessEqualRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrSignedLessEqualRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrSignedLessEqualRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrSignedLessRR */ -static sqInt NoDbgRegParms -concretizeBrSignedLessRR(AbstractInstruction * self_in_concretizeBrSignedLessRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrSignedLessRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrSignedLessRR->address)) + 8))); - leftReg = ((self_in_concretizeBrSignedLessRR->operands))[1]; - rightReg = ((self_in_concretizeBrSignedLessRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltRRR(self_in_concretizeBrSignedLessRR, BranchTemp, leftReg, rightReg); - ((self_in_concretizeBrSignedLessRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = bneRRoffset(self_in_concretizeBrSignedLessRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrSignedLessRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrSignedLessRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrUnsignedGreaterEqualRR */ -static sqInt NoDbgRegParms -concretizeBrUnsignedGreaterEqualRR(AbstractInstruction * self_in_concretizeBrUnsignedGreaterEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrUnsignedGreaterEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrUnsignedGreaterEqualRR->address)) + 8))); - leftReg = ((self_in_concretizeBrUnsignedGreaterEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrUnsignedGreaterEqualRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltuRRR(self_in_concretizeBrUnsignedGreaterEqualRR, BranchTemp, leftReg, rightReg); - ((self_in_concretizeBrUnsignedGreaterEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = beqRRoffset(self_in_concretizeBrUnsignedGreaterEqualRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrUnsignedGreaterEqualRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrUnsignedGreaterEqualRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrUnsignedGreaterRR */ -static sqInt NoDbgRegParms -concretizeBrUnsignedGreaterRR(AbstractInstruction * self_in_concretizeBrUnsignedGreaterRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrUnsignedGreaterRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrUnsignedGreaterRR->address)) + 8))); - leftReg = ((self_in_concretizeBrUnsignedGreaterRR->operands))[1]; - rightReg = ((self_in_concretizeBrUnsignedGreaterRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltuRRR(self_in_concretizeBrUnsignedGreaterRR, BranchTemp, rightReg, leftReg); - ((self_in_concretizeBrUnsignedGreaterRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = bneRRoffset(self_in_concretizeBrUnsignedGreaterRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrUnsignedGreaterRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrUnsignedGreaterRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrUnsignedLessEqualRR */ -static sqInt NoDbgRegParms -concretizeBrUnsignedLessEqualRR(AbstractInstruction * self_in_concretizeBrUnsignedLessEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrUnsignedLessEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrUnsignedLessEqualRR->address)) + 8))); - leftReg = ((self_in_concretizeBrUnsignedLessEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrUnsignedLessEqualRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltuRRR(self_in_concretizeBrUnsignedLessEqualRR, BranchTemp, rightReg, leftReg); - ((self_in_concretizeBrUnsignedLessEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = beqRRoffset(self_in_concretizeBrUnsignedLessEqualRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrUnsignedLessEqualRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrUnsignedLessEqualRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrUnsignedLessRR */ -static sqInt NoDbgRegParms -concretizeBrUnsignedLessRR(AbstractInstruction * self_in_concretizeBrUnsignedLessRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrUnsignedLessRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrUnsignedLessRR->address)) + 8))); - leftReg = ((self_in_concretizeBrUnsignedLessRR->operands))[1]; - rightReg = ((self_in_concretizeBrUnsignedLessRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltuRRR(self_in_concretizeBrUnsignedLessRR, BranchTemp, leftReg, rightReg); - ((self_in_concretizeBrUnsignedLessRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = bneRRoffset(self_in_concretizeBrUnsignedLessRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrUnsignedLessRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrUnsignedLessRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - -/* Call is used only for calls within code-space, See CallFull for general - anywhere in address space calling - */ -/* Relative branches in MIPS have a displacement of +/- 131kB (signed 18 - bits), which is too small to cover - the method zone. */ - - /* CogMIPSELCompiler>>#concretizeCall */ -static sqInt NoDbgRegParms -concretizeCall(AbstractInstruction * self_in_concretizeCall) -{ - return concretizeCallFull(self_in_concretizeCall); -} - - /* CogMIPSELCompiler>>#concretizeCallFull */ -static sqInt NoDbgRegParms -concretizeCallFull(AbstractInstruction * self_in_concretizeCallFull) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - AbstractInstruction *jumpTarget; - usqInt jumpTargetAddr; - AbstractInstruction *jumpTargetInstruction; - - /* begin longJumpTargetAddress */ - jumpTarget = ((AbstractInstruction *) (((self_in_concretizeCallFull->operands))[0])); - if ((addressIsInInstructions(jumpTarget)) - || (jumpTarget == (methodLabel()))) { - jumpTarget = ((AbstractInstruction *) ((jumpTarget->address))); - } - assert(jumpTarget != 0); - jumpTargetInstruction = jumpTarget; - jumpTargetAddr = ((usqInt)jumpTargetInstruction); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeCallFull, TargetReg, high16BitsOf(self_in_concretizeCallFull, jumpTargetAddr)); - ((self_in_concretizeCallFull->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeCallFull, TargetReg, TargetReg, low16BitsOf(self_in_concretizeCallFull, jumpTargetAddr)); - ((self_in_concretizeCallFull->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = jalR(self_in_concretizeCallFull, TargetReg); - ((self_in_concretizeCallFull->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - ((self_in_concretizeCallFull->machineCode))[12 / 4] = 0 /* nop */; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeClzRR */ -static sqInt NoDbgRegParms -concretizeClzRR(AbstractInstruction * self_in_concretizeClzRR) -{ - sqInt aWord; - usqInt destReg; - usqInt maskReg; - usqInt rightReg; - - maskReg = ((self_in_concretizeClzRR->operands))[0]; - destReg = (rightReg = ((self_in_concretizeClzRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = clzRRR(self_in_concretizeClzRR, destReg, maskReg, rightReg); - ((self_in_concretizeClzRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeCmpCqR */ -static sqInt NoDbgRegParms -concretizeCmpCqR(AbstractInstruction * self_in_concretizeCmpCqR) -{ - return concretizeCmpCwR(self_in_concretizeCmpCqR); -} - - /* CogMIPSELCompiler>>#concretizeCmpCwR */ -static sqInt NoDbgRegParms -concretizeCmpCwR(AbstractInstruction * self_in_concretizeCmpCwR) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeCmpRR */ -static sqInt NoDbgRegParms -concretizeCmpRR(AbstractInstruction * self_in_concretizeCmpRR) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeDivRR */ -static sqInt NoDbgRegParms -concretizeDivRR(AbstractInstruction * self_in_concretizeDivRR) -{ - sqInt aWord; - usqInt dividendReg; - usqInt divisorReg; - - dividendReg = ((self_in_concretizeDivRR->operands))[0]; - divisorReg = ((self_in_concretizeDivRR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = divRR(self_in_concretizeDivRR, dividendReg, divisorReg); - ((self_in_concretizeDivRR->machineCode))[0 / 4] = aWord; - return 4; -} - - -/* fill with operand 0 according to the processor's endianness. - You might think this is bogus and we should fill with stop instrurctions - instead, but this is used to leave room for a CMBlock header before the - code for a block; - the gaps get filled in by fillInBlockHeadersAt: after code has been - generated. */ - - /* CogMIPSELCompiler>>#concretizeFill32 */ -static sqInt NoDbgRegParms -concretizeFill32(AbstractInstruction * self_in_concretizeFill32) -{ - sqInt aWord; - - /* begin machineCodeAt:put: */ - aWord = ((self_in_concretizeFill32->operands))[0]; - ((self_in_concretizeFill32->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeJump */ -static sqInt NoDbgRegParms -concretizeJump(AbstractInstruction * self_in_concretizeJump) -{ - sqInt aWord; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - sqInt offset; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeJump->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeJump->address)) + 4))); - flag("BranchRange"); - /* begin machineCodeAt:put: */ - aWord = beqRRoffset(self_in_concretizeJump, ZR, ZR, offset); - ((self_in_concretizeJump->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeJump->machineCode))[4 / 4] = 0 /* nop */; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeJumpFull */ -static sqInt NoDbgRegParms -concretizeJumpFull(AbstractInstruction * self_in_concretizeJumpFull) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - AbstractInstruction *jumpTarget; - usqInt jumpTargetAddr; - AbstractInstruction *jumpTargetInstruction; - - /* begin longJumpTargetAddress */ - jumpTarget = ((AbstractInstruction *) (((self_in_concretizeJumpFull->operands))[0])); - if ((addressIsInInstructions(jumpTarget)) - || (jumpTarget == (methodLabel()))) { - jumpTarget = ((AbstractInstruction *) ((jumpTarget->address))); - } - assert(jumpTarget != 0); - jumpTargetInstruction = jumpTarget; - jumpTargetAddr = ((usqInt)jumpTargetInstruction); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeJumpFull, TargetReg, high16BitsOf(self_in_concretizeJumpFull, jumpTargetAddr)); - ((self_in_concretizeJumpFull->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeJumpFull, TargetReg, TargetReg, low16BitsOf(self_in_concretizeJumpFull, jumpTargetAddr)); - ((self_in_concretizeJumpFull->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = jR(self_in_concretizeJumpFull, TargetReg); - ((self_in_concretizeJumpFull->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - ((self_in_concretizeJumpFull->machineCode))[12 / 4] = 0 /* nop */; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeJumpLong */ -static sqInt NoDbgRegParms -concretizeJumpLong(AbstractInstruction * self_in_concretizeJumpLong) -{ - return concretizeJumpFull(self_in_concretizeJumpLong); -} - - /* CogMIPSELCompiler>>#concretizeJumpLongNonZero */ -static sqInt NoDbgRegParms -concretizeJumpLongNonZero(AbstractInstruction * self_in_concretizeJumpLongNonZero) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpLongZero */ -static sqInt NoDbgRegParms -concretizeJumpLongZero(AbstractInstruction * self_in_concretizeJumpLongZero) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpNonZero */ -static sqInt NoDbgRegParms -concretizeJumpNonZero(AbstractInstruction * self_in_concretizeJumpNonZero) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpNoOverflow */ -static sqInt NoDbgRegParms -concretizeJumpNoOverflow(AbstractInstruction * self_in_concretizeJumpNoOverflow) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpOverflow */ -static sqInt NoDbgRegParms -concretizeJumpOverflow(AbstractInstruction * self_in_concretizeJumpOverflow) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpR */ -static sqInt NoDbgRegParms -concretizeJumpR(AbstractInstruction * self_in_concretizeJumpR) -{ - sqInt aWord; - usqInt reg; - - flag("OABI"); - reg = ((self_in_concretizeJumpR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = jR(self_in_concretizeJumpR, reg); - ((self_in_concretizeJumpR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeJumpR->machineCode))[4 / 4] = 0 /* nop */; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeJumpSignedGreaterEqual */ -static sqInt NoDbgRegParms -concretizeJumpSignedGreaterEqual(AbstractInstruction * self_in_concretizeJumpSignedGreaterEqual) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpSignedGreaterThan */ -static sqInt NoDbgRegParms -concretizeJumpSignedGreaterThan(AbstractInstruction * self_in_concretizeJumpSignedGreaterThan) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpSignedLessEqual */ -static sqInt NoDbgRegParms -concretizeJumpSignedLessEqual(AbstractInstruction * self_in_concretizeJumpSignedLessEqual) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpSignedLessThan */ -static sqInt NoDbgRegParms -concretizeJumpSignedLessThan(AbstractInstruction * self_in_concretizeJumpSignedLessThan) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpUnsignedGreaterEqual */ -static sqInt NoDbgRegParms -concretizeJumpUnsignedGreaterEqual(AbstractInstruction * self_in_concretizeJumpUnsignedGreaterEqual) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpUnsignedGreaterThan */ -static sqInt NoDbgRegParms -concretizeJumpUnsignedGreaterThan(AbstractInstruction * self_in_concretizeJumpUnsignedGreaterThan) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpUnsignedLessEqual */ -static sqInt NoDbgRegParms -concretizeJumpUnsignedLessEqual(AbstractInstruction * self_in_concretizeJumpUnsignedLessEqual) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpUnsignedLessThan */ -static sqInt NoDbgRegParms -concretizeJumpUnsignedLessThan(AbstractInstruction * self_in_concretizeJumpUnsignedLessThan) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpZero */ -static sqInt NoDbgRegParms -concretizeJumpZero(AbstractInstruction * self_in_concretizeJumpZero) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeLoadEffectiveAddressMwrR */ -static sqInt NoDbgRegParms -concretizeLoadEffectiveAddressMwrR(AbstractInstruction * self_in_concretizeLoadEffectiveAddressMwrR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt baseReg; - usqInt destReg; - sqInt offset; - - offset = ((self_in_concretizeLoadEffectiveAddressMwrR->operands))[0]; - baseReg = ((self_in_concretizeLoadEffectiveAddressMwrR->operands))[1]; - destReg = ((self_in_concretizeLoadEffectiveAddressMwrR->operands))[2]; - if (isShortOffset(self_in_concretizeLoadEffectiveAddressMwrR, offset)) { - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizeLoadEffectiveAddressMwrR, destReg, baseReg, offset); - ((self_in_concretizeLoadEffectiveAddressMwrR->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeLoadEffectiveAddressMwrR, AT, high16BitsOf(self_in_concretizeLoadEffectiveAddressMwrR, offset)); - ((self_in_concretizeLoadEffectiveAddressMwrR->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeLoadEffectiveAddressMwrR, AT, AT, low16BitsOf(self_in_concretizeLoadEffectiveAddressMwrR, offset)); - ((self_in_concretizeLoadEffectiveAddressMwrR->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = adduRRR(self_in_concretizeLoadEffectiveAddressMwrR, destReg, baseReg, AT); - ((self_in_concretizeLoadEffectiveAddressMwrR->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeLogicalShiftLeftCqR */ -static sqInt NoDbgRegParms -concretizeLogicalShiftLeftCqR(AbstractInstruction * self_in_concretizeLogicalShiftLeftCqR) -{ - sqInt aWord; - sqInt distance; - usqInt reg; - - distance = (((((self_in_concretizeLogicalShiftLeftCqR->operands))[0]) < 0x1F) ? (((self_in_concretizeLogicalShiftLeftCqR->operands))[0]) : 0x1F); - reg = ((self_in_concretizeLogicalShiftLeftCqR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = sllRRC(self_in_concretizeLogicalShiftLeftCqR, reg, reg, distance); - ((self_in_concretizeLogicalShiftLeftCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeLogicalShiftLeftRR */ -static sqInt NoDbgRegParms -concretizeLogicalShiftLeftRR(AbstractInstruction * self_in_concretizeLogicalShiftLeftRR) -{ - sqInt aWord; - usqInt destReg; - usqInt distReg; - - distReg = ((self_in_concretizeLogicalShiftLeftRR->operands))[0]; - destReg = ((self_in_concretizeLogicalShiftLeftRR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = sllvRRR(self_in_concretizeLogicalShiftLeftRR, destReg, destReg, distReg); - ((self_in_concretizeLogicalShiftLeftRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeLogicalShiftRightCqR */ -static sqInt NoDbgRegParms -concretizeLogicalShiftRightCqR(AbstractInstruction * self_in_concretizeLogicalShiftRightCqR) -{ - sqInt aWord; - sqInt distance; - usqInt reg; - - distance = (((((self_in_concretizeLogicalShiftRightCqR->operands))[0]) < 0x1F) ? (((self_in_concretizeLogicalShiftRightCqR->operands))[0]) : 0x1F); - reg = ((self_in_concretizeLogicalShiftRightCqR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = srlRRC(self_in_concretizeLogicalShiftRightCqR, reg, reg, distance); - ((self_in_concretizeLogicalShiftRightCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeLogicalShiftRightRR */ -static sqInt NoDbgRegParms -concretizeLogicalShiftRightRR(AbstractInstruction * self_in_concretizeLogicalShiftRightRR) -{ - sqInt aWord; - usqInt destReg; - usqInt distReg; - - distReg = ((self_in_concretizeLogicalShiftRightRR->operands))[0]; - destReg = ((self_in_concretizeLogicalShiftRightRR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = srlvRRR(self_in_concretizeLogicalShiftRightRR, destReg, destReg, distReg); - ((self_in_concretizeLogicalShiftRightRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveAbR */ -static sqInt NoDbgRegParms -concretizeMoveAbR(AbstractInstruction * self_in_concretizeMoveAbR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt destReg; - usqInt srcAddr; - - srcAddr = ((self_in_concretizeMoveAbR->operands))[0]; - destReg = ((self_in_concretizeMoveAbR->operands))[1]; - if ((srcAddr != null) - && ((((varBaseAddress()) - (0x8000)) < srcAddr) - && (srcAddr < ((varBaseAddress()) + (0x8000))))) { - /* begin machineCodeAt:put: */ - aWord = lwRbaseoffset(self_in_concretizeMoveAbR, destReg, ConcreteVarBaseReg, srcAddr - (varBaseAddress())); - ((self_in_concretizeMoveAbR->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeMoveAbR, AT, high16BitsOf(self_in_concretizeMoveAbR, srcAddr)); - ((self_in_concretizeMoveAbR->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeMoveAbR, AT, AT, low16BitsOf(self_in_concretizeMoveAbR, srcAddr)); - ((self_in_concretizeMoveAbR->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = lbuRbaseoffset(self_in_concretizeMoveAbR, destReg, AT, 0); - ((self_in_concretizeMoveAbR->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMoveAwR */ -static sqInt NoDbgRegParms -concretizeMoveAwR(AbstractInstruction * self_in_concretizeMoveAwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt destReg; - usqInt srcAddr; - - srcAddr = ((self_in_concretizeMoveAwR->operands))[0]; - destReg = ((self_in_concretizeMoveAwR->operands))[1]; - if ((srcAddr != null) - && ((((varBaseAddress()) - (0x8000)) < srcAddr) - && (srcAddr < ((varBaseAddress()) + (0x8000))))) { - /* begin machineCodeAt:put: */ - aWord = lwRbaseoffset(self_in_concretizeMoveAwR, destReg, ConcreteVarBaseReg, srcAddr - (varBaseAddress())); - ((self_in_concretizeMoveAwR->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeMoveAwR, AT, high16BitsOf(self_in_concretizeMoveAwR, srcAddr)); - ((self_in_concretizeMoveAwR->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeMoveAwR, AT, AT, low16BitsOf(self_in_concretizeMoveAwR, srcAddr)); - ((self_in_concretizeMoveAwR->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = lwRbaseoffset(self_in_concretizeMoveAwR, destReg, AT, 0); - ((self_in_concretizeMoveAwR->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMoveCqR */ -static sqInt NoDbgRegParms -concretizeMoveCqR(AbstractInstruction * self_in_concretizeMoveCqR) -{ - sqInt aWord; - usqInt reg; - sqInt word; - - word = ((self_in_concretizeMoveCqR->operands))[0]; - reg = ((self_in_concretizeMoveCqR->operands))[1]; - if (!(isShortOffset(self_in_concretizeMoveCqR, word))) { - return concretizeMoveCwR(self_in_concretizeMoveCqR); - } - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizeMoveCqR, reg, ZR, word); - ((self_in_concretizeMoveCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveCwR */ -static sqInt NoDbgRegParms -concretizeMoveCwR(AbstractInstruction * self_in_concretizeMoveCwR) -{ - sqInt aWord; - sqInt aWord1; - usqInt reg; - sqInt word; - - word = ((self_in_concretizeMoveCwR->operands))[0]; - reg = ((self_in_concretizeMoveCwR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeMoveCwR, reg, high16BitsOf(self_in_concretizeMoveCwR, word)); - ((self_in_concretizeMoveCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeMoveCwR, reg, reg, low16BitsOf(self_in_concretizeMoveCwR, word)); - ((self_in_concretizeMoveCwR->machineCode))[4 / 4] = aWord1; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeMoveHighR */ -static sqInt NoDbgRegParms -concretizeMoveHighR(AbstractInstruction * self_in_concretizeMoveHighR) -{ - sqInt aWord; - usqInt destReg; - - destReg = ((self_in_concretizeMoveHighR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = mfhiR(self_in_concretizeMoveHighR, destReg); - ((self_in_concretizeMoveHighR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveLowR */ -static sqInt NoDbgRegParms -concretizeMoveLowR(AbstractInstruction * self_in_concretizeMoveLowR) -{ - sqInt aWord; - usqInt destReg; - - destReg = ((self_in_concretizeMoveLowR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = mfloR(self_in_concretizeMoveLowR, destReg); - ((self_in_concretizeMoveLowR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveM16rR */ -static sqInt NoDbgRegParms -concretizeMoveM16rR(AbstractInstruction * self_in_concretizeMoveM16rR) -{ - sqInt aWord; - usqInt destReg; - sqInt offset; - usqInt srcReg; - - offset = ((self_in_concretizeMoveM16rR->operands))[0]; - srcReg = ((self_in_concretizeMoveM16rR->operands))[1]; - destReg = ((self_in_concretizeMoveM16rR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = lhuRbaseoffset(self_in_concretizeMoveM16rR, destReg, srcReg, offset); - ((self_in_concretizeMoveM16rR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveMbrR */ -static sqInt NoDbgRegParms -concretizeMoveMbrR(AbstractInstruction * self_in_concretizeMoveMbrR) -{ - sqInt aWord; - usqInt destReg; - sqInt offset; - usqInt srcReg; - - offset = ((self_in_concretizeMoveMbrR->operands))[0]; - srcReg = ((self_in_concretizeMoveMbrR->operands))[1]; - destReg = ((self_in_concretizeMoveMbrR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = lbuRbaseoffset(self_in_concretizeMoveMbrR, destReg, srcReg, offset); - ((self_in_concretizeMoveMbrR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveMwrR */ -static sqInt NoDbgRegParms -concretizeMoveMwrR(AbstractInstruction * self_in_concretizeMoveMwrR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - sqInt aWord4; - usqInt baseReg; - usqInt destReg; - sqInt offset; - - offset = ((self_in_concretizeMoveMwrR->operands))[0]; - baseReg = ((self_in_concretizeMoveMwrR->operands))[1]; - destReg = ((self_in_concretizeMoveMwrR->operands))[2]; - if (isShortOffset(self_in_concretizeMoveMwrR, offset)) { - /* begin machineCodeAt:put: */ - aWord = lwRbaseoffset(self_in_concretizeMoveMwrR, destReg, baseReg, offset); - ((self_in_concretizeMoveMwrR->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeMoveMwrR, AT, high16BitsOf(self_in_concretizeMoveMwrR, offset)); - ((self_in_concretizeMoveMwrR->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeMoveMwrR, AT, AT, low16BitsOf(self_in_concretizeMoveMwrR, offset)); - ((self_in_concretizeMoveMwrR->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = adduRRR(self_in_concretizeMoveMwrR, AT, baseReg, AT); - ((self_in_concretizeMoveMwrR->machineCode))[8 / 4] = aWord3; - /* begin machineCodeAt:put: */ - aWord4 = lwRbaseoffset(self_in_concretizeMoveMwrR, destReg, AT, 0); - ((self_in_concretizeMoveMwrR->machineCode))[12 / 4] = aWord4; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeMoveRAb */ -static sqInt NoDbgRegParms -concretizeMoveRAb(AbstractInstruction * self_in_concretizeMoveRAb) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt destAddr; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRAb->operands))[0]; - destAddr = ((self_in_concretizeMoveRAb->operands))[1]; - if ((destAddr != null) - && ((((varBaseAddress()) - (0x8000)) < destAddr) - && (destAddr < ((varBaseAddress()) + (0x8000))))) { - /* begin machineCodeAt:put: */ - aWord = swRbaseoffset(self_in_concretizeMoveRAb, srcReg, ConcreteVarBaseReg, destAddr - (varBaseAddress())); - ((self_in_concretizeMoveRAb->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeMoveRAb, AT, high16BitsOf(self_in_concretizeMoveRAb, destAddr)); - ((self_in_concretizeMoveRAb->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeMoveRAb, AT, AT, low16BitsOf(self_in_concretizeMoveRAb, destAddr)); - ((self_in_concretizeMoveRAb->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = sbRbaseoffset(self_in_concretizeMoveRAb, srcReg, AT, 0); - ((self_in_concretizeMoveRAb->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMoveRAw */ -static sqInt NoDbgRegParms -concretizeMoveRAw(AbstractInstruction * self_in_concretizeMoveRAw) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt destAddr; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRAw->operands))[0]; - destAddr = ((self_in_concretizeMoveRAw->operands))[1]; - if ((destAddr != null) - && ((((varBaseAddress()) - (0x8000)) < destAddr) - && (destAddr < ((varBaseAddress()) + (0x8000))))) { - /* begin machineCodeAt:put: */ - aWord = swRbaseoffset(self_in_concretizeMoveRAw, srcReg, ConcreteVarBaseReg, destAddr - (varBaseAddress())); - ((self_in_concretizeMoveRAw->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeMoveRAw, AT, high16BitsOf(self_in_concretizeMoveRAw, destAddr)); - ((self_in_concretizeMoveRAw->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeMoveRAw, AT, AT, low16BitsOf(self_in_concretizeMoveRAw, destAddr)); - ((self_in_concretizeMoveRAw->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = swRbaseoffset(self_in_concretizeMoveRAw, srcReg, AT, 0); - ((self_in_concretizeMoveRAw->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMoveRM16r */ -static sqInt NoDbgRegParms -concretizeMoveRM16r(AbstractInstruction * self_in_concretizeMoveRM16r) -{ - sqInt aWord; - usqInt destReg; - sqInt offset; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRM16r->operands))[0]; - offset = ((self_in_concretizeMoveRM16r->operands))[1]; - destReg = ((self_in_concretizeMoveRM16r->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = shRbaseoffset(self_in_concretizeMoveRM16r, srcReg, destReg, offset); - ((self_in_concretizeMoveRM16r->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveRMbr */ -static sqInt NoDbgRegParms -concretizeMoveRMbr(AbstractInstruction * self_in_concretizeMoveRMbr) -{ - sqInt aWord; - usqInt destReg; - sqInt offset; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRMbr->operands))[0]; - offset = ((self_in_concretizeMoveRMbr->operands))[1]; - destReg = ((self_in_concretizeMoveRMbr->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = sbRbaseoffset(self_in_concretizeMoveRMbr, srcReg, destReg, offset); - ((self_in_concretizeMoveRMbr->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveRMwr */ -static sqInt NoDbgRegParms -concretizeMoveRMwr(AbstractInstruction * self_in_concretizeMoveRMwr) -{ - sqInt aWord; - usqInt baseReg; - sqInt offset; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRMwr->operands))[0]; - offset = ((self_in_concretizeMoveRMwr->operands))[1]; - baseReg = ((self_in_concretizeMoveRMwr->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = swRbaseoffset(self_in_concretizeMoveRMwr, srcReg, baseReg, offset); - ((self_in_concretizeMoveRMwr->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveRR */ -static sqInt NoDbgRegParms -concretizeMoveRR(AbstractInstruction * self_in_concretizeMoveRR) -{ - sqInt aWord; - usqInt destReg; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRR->operands))[0]; - destReg = ((self_in_concretizeMoveRR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeMoveRR, destReg, srcReg, ZR); - ((self_in_concretizeMoveRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveRXbrR */ -static sqInt NoDbgRegParms -concretizeMoveRXbrR(AbstractInstruction * self_in_concretizeMoveRXbrR) -{ - sqInt aWord; - sqInt aWord1; - usqInt baseReg; - usqInt indexReg; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRXbrR->operands))[0]; - indexReg = ((self_in_concretizeMoveRXbrR->operands))[1]; - baseReg = ((self_in_concretizeMoveRXbrR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeMoveRXbrR, AT, baseReg, indexReg); - ((self_in_concretizeMoveRXbrR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = sbRbaseoffset(self_in_concretizeMoveRXbrR, srcReg, AT, 0); - ((self_in_concretizeMoveRXbrR->machineCode))[4 / 4] = aWord1; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeMoveRXwrR */ -static sqInt NoDbgRegParms -concretizeMoveRXwrR(AbstractInstruction * self_in_concretizeMoveRXwrR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt baseReg; - usqInt indexReg; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRXwrR->operands))[0]; - indexReg = ((self_in_concretizeMoveRXwrR->operands))[1]; - baseReg = ((self_in_concretizeMoveRXwrR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = sllRRC(self_in_concretizeMoveRXwrR, AT, indexReg, 2); - ((self_in_concretizeMoveRXwrR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = adduRRR(self_in_concretizeMoveRXwrR, AT, baseReg, AT); - ((self_in_concretizeMoveRXwrR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = swRbaseoffset(self_in_concretizeMoveRXwrR, srcReg, AT, 0); - ((self_in_concretizeMoveRXwrR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMoveXbrRR */ -static sqInt NoDbgRegParms -concretizeMoveXbrRR(AbstractInstruction * self_in_concretizeMoveXbrRR) -{ - sqInt aWord; - sqInt aWord1; - usqInt baseReg; - usqInt destReg; - usqInt indexReg; - - - /* index is number of *bytes* */ - indexReg = ((self_in_concretizeMoveXbrRR->operands))[0]; - baseReg = ((self_in_concretizeMoveXbrRR->operands))[1]; - destReg = ((self_in_concretizeMoveXbrRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeMoveXbrRR, AT, baseReg, indexReg); - ((self_in_concretizeMoveXbrRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = lbuRbaseoffset(self_in_concretizeMoveXbrRR, destReg, AT, 0); - ((self_in_concretizeMoveXbrRR->machineCode))[4 / 4] = aWord1; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeMoveXwrRR */ -static sqInt NoDbgRegParms -concretizeMoveXwrRR(AbstractInstruction * self_in_concretizeMoveXwrRR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt baseReg; - usqInt destReg; - usqInt indexReg; - - indexReg = ((self_in_concretizeMoveXwrRR->operands))[0]; - baseReg = ((self_in_concretizeMoveXwrRR->operands))[1]; - destReg = ((self_in_concretizeMoveXwrRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = sllRRC(self_in_concretizeMoveXwrRR, AT, indexReg, 2); - ((self_in_concretizeMoveXwrRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = adduRRR(self_in_concretizeMoveXwrRR, AT, baseReg, AT); - ((self_in_concretizeMoveXwrRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = lwRbaseoffset(self_in_concretizeMoveXwrRR, destReg, AT, 0); - ((self_in_concretizeMoveXwrRR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMulCheckOverflowRR */ -static sqInt NoDbgRegParms -concretizeMulCheckOverflowRR(AbstractInstruction * self_in_concretizeMulCheckOverflowRR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeMulCheckOverflowRR->operands))[0]; - - /* Overflow occured if the sign bit of the low part is different from the high part. */ - destReg = (leftReg = ((self_in_concretizeMulCheckOverflowRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = multRR(self_in_concretizeMulCheckOverflowRR, leftReg, rightReg); - ((self_in_concretizeMulCheckOverflowRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = mfloR(self_in_concretizeMulCheckOverflowRR, destReg); - ((self_in_concretizeMulCheckOverflowRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = sraRRC(self_in_concretizeMulCheckOverflowRR, OverflowTemp1, destReg, 0x1F); - ((self_in_concretizeMulCheckOverflowRR->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = mfhiR(self_in_concretizeMulCheckOverflowRR, OverflowTemp2); - ((self_in_concretizeMulCheckOverflowRR->machineCode))[12 / 4] = aWord3; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeNegateR */ -static sqInt NoDbgRegParms -concretizeNegateR(AbstractInstruction * self_in_concretizeNegateR) -{ - sqInt aWord; - usqInt reg; - - reg = ((self_in_concretizeNegateR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = subuRRR(self_in_concretizeNegateR, reg, ZR, reg); - ((self_in_concretizeNegateR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeNop */ -static sqInt NoDbgRegParms -concretizeNop(AbstractInstruction * self_in_concretizeNop) -{ - /* begin machineCodeAt:put: */ - ((self_in_concretizeNop->machineCode))[0 / 4] = 0 /* nop */; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeOrCqR */ -static sqInt NoDbgRegParms -concretizeOrCqR(AbstractInstruction * self_in_concretizeOrCqR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeOrCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeOrCqR->operands))[1]); - if (!(((rightImm >= 0) && (rightImm <= 0xFFFF)))) { - return concretizeOrCwR(self_in_concretizeOrCqR); - } - /* begin machineCodeAt:put: */ - aWord = oriRRC(self_in_concretizeOrCqR, destReg, leftReg, rightImm); - ((self_in_concretizeOrCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeOrCqRR */ -static sqInt NoDbgRegParms -concretizeOrCqRR(AbstractInstruction * self_in_concretizeOrCqRR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt dstReg; - usqInt srcReg; - usqInt value; - - value = ((self_in_concretizeOrCqRR->operands))[0]; - srcReg = ((self_in_concretizeOrCqRR->operands))[1]; - dstReg = ((self_in_concretizeOrCqRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeOrCqRR, AT, high16BitsOf(self_in_concretizeOrCqRR, value)); - ((self_in_concretizeOrCqRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeOrCqRR, AT, AT, low16BitsOf(self_in_concretizeOrCqRR, value)); - ((self_in_concretizeOrCqRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = orRRR(self_in_concretizeOrCqRR, dstReg, srcReg, AT); - ((self_in_concretizeOrCqRR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeOrCwR */ -static sqInt NoDbgRegParms -concretizeOrCwR(AbstractInstruction * self_in_concretizeOrCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeOrCwR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeOrCwR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeOrCwR, AT, high16BitsOf(self_in_concretizeOrCwR, rightImm)); - ((self_in_concretizeOrCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeOrCwR, AT, AT, low16BitsOf(self_in_concretizeOrCwR, rightImm)); - ((self_in_concretizeOrCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = orRRR(self_in_concretizeOrCwR, destReg, leftReg, AT); - ((self_in_concretizeOrCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeOrRR */ -static sqInt NoDbgRegParms -concretizeOrRR(AbstractInstruction * self_in_concretizeOrRR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeOrRR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeOrRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = orRRR(self_in_concretizeOrRR, destReg, leftReg, rightReg); - ((self_in_concretizeOrRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizePopR */ -static sqInt NoDbgRegParms -concretizePopR(AbstractInstruction * self_in_concretizePopR) -{ - sqInt aWord; - sqInt aWord1; - usqInt destReg; - - destReg = ((self_in_concretizePopR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = lwRbaseoffset(self_in_concretizePopR, destReg, SP, 0); - ((self_in_concretizePopR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = addiuRRC(self_in_concretizePopR, SP, SP, 4); - ((self_in_concretizePopR->machineCode))[4 / 4] = aWord1; - return 8; -} - - /* CogMIPSELCompiler>>#concretizePrefetchAw */ -static sqInt NoDbgRegParms -concretizePrefetchAw(AbstractInstruction * self_in_concretizePrefetchAw) -{ - usqInt addressOperand; - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - - addressOperand = ((self_in_concretizePrefetchAw->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizePrefetchAw, AT, high16BitsOf(self_in_concretizePrefetchAw, addressOperand)); - ((self_in_concretizePrefetchAw->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizePrefetchAw, AT, AT, low16BitsOf(self_in_concretizePrefetchAw, addressOperand)); - ((self_in_concretizePrefetchAw->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = prefRoffsethint(self_in_concretizePrefetchAw, AT, 0, HintLoad); - ((self_in_concretizePrefetchAw->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizePushCq */ -static sqInt NoDbgRegParms -concretizePushCq(AbstractInstruction * self_in_concretizePushCq) -{ - return concretizePushCw(self_in_concretizePushCq); -} - - /* CogMIPSELCompiler>>#concretizePushCw */ -static sqInt NoDbgRegParms -concretizePushCw(AbstractInstruction * self_in_concretizePushCw) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt value; - - value = ((self_in_concretizePushCw->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizePushCw, AT, high16BitsOf(self_in_concretizePushCw, value)); - ((self_in_concretizePushCw->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizePushCw, AT, AT, low16BitsOf(self_in_concretizePushCw, value)); - ((self_in_concretizePushCw->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = addiuRRC(self_in_concretizePushCw, SP, SP, -4); - ((self_in_concretizePushCw->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = swRbaseoffset(self_in_concretizePushCw, AT, SP, 0); - ((self_in_concretizePushCw->machineCode))[12 / 4] = aWord3; - return 16; -} - - /* CogMIPSELCompiler>>#concretizePushR */ -static sqInt NoDbgRegParms -concretizePushR(AbstractInstruction * self_in_concretizePushR) -{ - sqInt aWord; - sqInt aWord1; - usqInt srcReg; - - srcReg = ((self_in_concretizePushR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizePushR, SP, SP, -4); - ((self_in_concretizePushR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = swRbaseoffset(self_in_concretizePushR, srcReg, SP, 0); - ((self_in_concretizePushR->machineCode))[4 / 4] = aWord1; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeRetN */ -static sqInt NoDbgRegParms -concretizeRetN(AbstractInstruction * self_in_concretizeRetN) -{ - sqInt aWord; - sqInt aWord1; - sqInt offset; - - offset = ((self_in_concretizeRetN->operands))[0]; - /* begin machineCodeAt:put: */ - aWord1 = jR(self_in_concretizeRetN, RA); - ((self_in_concretizeRetN->machineCode))[0 / 4] = aWord1; - if (offset == 0) { - /* begin machineCodeAt:put: */ - ((self_in_concretizeRetN->machineCode))[4 / 4] = 0 /* nop */; - } - else { - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizeRetN, SP, SP, offset); - ((self_in_concretizeRetN->machineCode))[4 / 4] = aWord; - } - return 8; -} - - /* CogMIPSELCompiler>>#concretizeStop */ -static sqInt NoDbgRegParms -concretizeStop(AbstractInstruction * self_in_concretizeStop) -{ - sqInt aWord; - - /* begin machineCodeAt:put: */ - aWord = stop(self_in_concretizeStop); - ((self_in_concretizeStop->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeSubCheckOverflowCqR */ -static sqInt NoDbgRegParms -concretizeSubCheckOverflowCqR(AbstractInstruction * self_in_concretizeSubCheckOverflowCqR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - sqInt aWord4; - sqInt aWord5; - sqInt aWord6; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeSubCheckOverflowCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeSubCheckOverflowCqR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeSubCheckOverflowCqR, AT, high16BitsOf(self_in_concretizeSubCheckOverflowCqR, rightImm)); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeSubCheckOverflowCqR, AT, AT, low16BitsOf(self_in_concretizeSubCheckOverflowCqR, rightImm)); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = adduRRR(self_in_concretizeSubCheckOverflowCqR, OverflowTemp1, leftReg, ZR); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = subuRRR(self_in_concretizeSubCheckOverflowCqR, destReg, leftReg, AT); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[12 / 4] = aWord3; - /* begin machineCodeAt:put: */ - aWord4 = xorRRR(self_in_concretizeSubCheckOverflowCqR, OverflowTemp2, destReg, AT); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[16 / 4] = aWord4; - /* begin machineCodeAt:put: */ - aWord5 = xorRRR(self_in_concretizeSubCheckOverflowCqR, OverflowTemp1, destReg, OverflowTemp1); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[20 / 4] = aWord5; - /* begin machineCodeAt:put: */ - aWord6 = andRRR(self_in_concretizeSubCheckOverflowCqR, Overflow, OverflowTemp1, OverflowTemp2); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[24 / 4] = aWord6; - return 28; -} - - /* CogMIPSELCompiler>>#concretizeSubCheckOverflowRR */ -static sqInt NoDbgRegParms -concretizeSubCheckOverflowRR(AbstractInstruction * self_in_concretizeSubCheckOverflowRR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - sqInt aWord4; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeSubCheckOverflowRR->operands))[0]; - - /* Save original LHS */ - destReg = (leftReg = ((self_in_concretizeSubCheckOverflowRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeSubCheckOverflowRR, OverflowTemp1, leftReg, ZR); - ((self_in_concretizeSubCheckOverflowRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = subuRRR(self_in_concretizeSubCheckOverflowRR, destReg, leftReg, rightReg); - ((self_in_concretizeSubCheckOverflowRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = xorRRR(self_in_concretizeSubCheckOverflowRR, OverflowTemp2, destReg, rightReg); - ((self_in_concretizeSubCheckOverflowRR->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = xorRRR(self_in_concretizeSubCheckOverflowRR, OverflowTemp1, destReg, OverflowTemp1); - ((self_in_concretizeSubCheckOverflowRR->machineCode))[12 / 4] = aWord3; - /* begin machineCodeAt:put: */ - aWord4 = andRRR(self_in_concretizeSubCheckOverflowRR, Overflow, OverflowTemp1, OverflowTemp2); - ((self_in_concretizeSubCheckOverflowRR->machineCode))[16 / 4] = aWord4; - return 20; -} - - /* CogMIPSELCompiler>>#concretizeSubCqR */ -static sqInt NoDbgRegParms -concretizeSubCqR(AbstractInstruction * self_in_concretizeSubCqR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeSubCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeSubCqR->operands))[1]); - if (!(isShortOffset(self_in_concretizeSubCqR, -rightImm))) { - return concretizeSubCwR(self_in_concretizeSubCqR); - } - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizeSubCqR, destReg, leftReg, -rightImm); - ((self_in_concretizeSubCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeSubCwR */ -static sqInt NoDbgRegParms -concretizeSubCwR(AbstractInstruction * self_in_concretizeSubCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeSubCwR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeSubCwR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeSubCwR, AT, high16BitsOf(self_in_concretizeSubCwR, rightImm)); - ((self_in_concretizeSubCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeSubCwR, AT, AT, low16BitsOf(self_in_concretizeSubCwR, rightImm)); - ((self_in_concretizeSubCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = subuRRR(self_in_concretizeSubCwR, destReg, leftReg, AT); - ((self_in_concretizeSubCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeSubRRDest: */ -static sqInt NoDbgRegParms -concretizeSubRRDest(AbstractInstruction * self_in_concretizeSubRRDest, sqInt destReg) -{ - sqInt aWord; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeSubRRDest->operands))[0]; - leftReg = ((self_in_concretizeSubRRDest->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = subuRRR(self_in_concretizeSubRRDest, destReg, leftReg, rightReg); - ((self_in_concretizeSubRRDest->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeTstCqR */ -static sqInt NoDbgRegParms -concretizeTstCqR(AbstractInstruction * self_in_concretizeTstCqR) -{ - sqInt aWord; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeTstCqR->operands))[0]; - leftReg = ((self_in_concretizeTstCqR->operands))[1]; - if (!(isShortOffset(self_in_concretizeTstCqR, rightImm))) { - return concretizeTstCwR(self_in_concretizeTstCqR); - } - /* begin machineCodeAt:put: */ - aWord = andiRRC(self_in_concretizeTstCqR, Cmp, leftReg, rightImm); - ((self_in_concretizeTstCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeTstCwR */ -static sqInt NoDbgRegParms -concretizeTstCwR(AbstractInstruction * self_in_concretizeTstCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeTstCwR->operands))[0]; - leftReg = ((self_in_concretizeTstCwR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeTstCwR, AT, high16BitsOf(self_in_concretizeTstCwR, rightImm)); - ((self_in_concretizeTstCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeTstCwR, AT, AT, low16BitsOf(self_in_concretizeTstCwR, rightImm)); - ((self_in_concretizeTstCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = andRRR(self_in_concretizeTstCwR, Cmp, leftReg, AT); - ((self_in_concretizeTstCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeUnimplemented */ -static sqInt NoDbgRegParms -concretizeUnimplemented(AbstractInstruction * self_in_concretizeUnimplemented) -{ - error("Unimplemented RTL instruction"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeXorCwR */ -static sqInt NoDbgRegParms -concretizeXorCwR(AbstractInstruction * self_in_concretizeXorCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeXorCwR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeXorCwR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeXorCwR, AT, high16BitsOf(self_in_concretizeXorCwR, rightImm)); - ((self_in_concretizeXorCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeXorCwR, AT, AT, low16BitsOf(self_in_concretizeXorCwR, rightImm)); - ((self_in_concretizeXorCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = xorRRR(self_in_concretizeXorCwR, destReg, leftReg, AT); - ((self_in_concretizeXorCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeXorRR */ -static sqInt NoDbgRegParms -concretizeXorRR(AbstractInstruction * self_in_concretizeXorRR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeXorRR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeXorRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = xorRRR(self_in_concretizeXorRR, destReg, leftReg, rightReg); - ((self_in_concretizeXorRR->machineCode))[0 / 4] = aWord; - return 4; -} - - -/* Attempt to generate concrete machine code for the instruction at address. - This is the inner dispatch of concretizeAt: actualAddress which exists - only to get around the branch size limits in the SqueakV3 (blue book - derived) bytecode set. */ - - /* CogMIPSELCompiler>>#dispatchConcretize */ -static sqInt NoDbgRegParms -dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) -{ - AbstractInstruction *dependentChain; - - switch ((self_in_dispatchConcretize->opcode)) { - case BrEqualRR: - return concretizeBrEqualRR(self_in_dispatchConcretize); - - case BrNotEqualRR: - return concretizeBrNotEqualRR(self_in_dispatchConcretize); - - case BrUnsignedLessRR: - return concretizeBrUnsignedLessRR(self_in_dispatchConcretize); - - case BrUnsignedLessEqualRR: - return concretizeBrUnsignedLessEqualRR(self_in_dispatchConcretize); - - case BrUnsignedGreaterRR: - return concretizeBrUnsignedGreaterRR(self_in_dispatchConcretize); - - case BrUnsignedGreaterEqualRR: - return concretizeBrUnsignedGreaterEqualRR(self_in_dispatchConcretize); - - case BrSignedLessRR: - return concretizeBrSignedLessRR(self_in_dispatchConcretize); - - case BrSignedLessEqualRR: - return concretizeBrSignedLessEqualRR(self_in_dispatchConcretize); - - case BrSignedGreaterRR: - return concretizeBrSignedGreaterRR(self_in_dispatchConcretize); - - case BrSignedGreaterEqualRR: - return concretizeBrSignedGreaterEqualRR(self_in_dispatchConcretize); - - case BrLongEqualRR: - return concretizeBrLongEqualRR(self_in_dispatchConcretize); - - case BrLongNotEqualRR: - return concretizeBrLongNotEqualRR(self_in_dispatchConcretize); - - case MulRR: - case JumpNegative: - case JumpNonNegative: - case JumpCarry: - case JumpNoCarry: - case JumpFPEqual: - case JumpFPNotEqual: - case JumpFPLess: - case JumpFPGreaterOrEqual: - case JumpFPGreater: - case JumpFPLessOrEqual: - case JumpFPOrdered: - case JumpFPUnordered: - case XorCqR: - case AddRdRd: - case CmpRdRd: - case DivRdRd: - case MulRdRd: - case SubRdRd: - case SqrtRd: - case MoveRMbr: - case MoveM64rRd: - case MoveRdM64r: - case ConvertRRd: - return concretizeUnimplemented(self_in_dispatchConcretize); - - case DivRR: - return concretizeDivRR(self_in_dispatchConcretize); - - case MoveLowR: - return concretizeMoveLowR(self_in_dispatchConcretize); - - case MoveHighR: - return concretizeMoveHighR(self_in_dispatchConcretize); - - case Label: - /* begin concretizeLabel */ - dependentChain = (self_in_dispatchConcretize->dependent); - while (!(dependentChain == null)) { - /* begin updateLabel: */ - assert((((dependentChain->opcode)) == MoveCwR) - || (((dependentChain->opcode)) == PushCw)); - ((dependentChain->operands))[0] = (((self_in_dispatchConcretize->address)) + (((self_in_dispatchConcretize->operands))[1])); - dependentChain = (dependentChain->dependent); - } - return 0; - - case AlignmentNops: - return concretizeAlignmentNops(self_in_dispatchConcretize); - - case Fill32: - return concretizeFill32(self_in_dispatchConcretize); - - case Nop: - return concretizeNop(self_in_dispatchConcretize); - - case Call: - return concretizeCall(self_in_dispatchConcretize); - - case CallFull: - return concretizeCallFull(self_in_dispatchConcretize); - - case JumpR: - return concretizeJumpR(self_in_dispatchConcretize); - - case JumpFull: - return concretizeJumpFull(self_in_dispatchConcretize); - - case JumpLong: - return concretizeJumpLong(self_in_dispatchConcretize); - - case JumpLongZero: - return concretizeJumpLongZero(self_in_dispatchConcretize); - - case JumpLongNonZero: - return concretizeJumpLongNonZero(self_in_dispatchConcretize); - - case Jump: - return concretizeJump(self_in_dispatchConcretize); - - case JumpZero: - return concretizeJumpZero(self_in_dispatchConcretize); - - case JumpNonZero: - return concretizeJumpNonZero(self_in_dispatchConcretize); - - case JumpOverflow: - return concretizeJumpOverflow(self_in_dispatchConcretize); - - case JumpNoOverflow: - return concretizeJumpNoOverflow(self_in_dispatchConcretize); - - case JumpLess: - return concretizeJumpSignedLessThan(self_in_dispatchConcretize); - - case JumpGreaterOrEqual: - return concretizeJumpSignedGreaterEqual(self_in_dispatchConcretize); - - case JumpGreater: - return concretizeJumpSignedGreaterThan(self_in_dispatchConcretize); - - case JumpLessOrEqual: - return concretizeJumpSignedLessEqual(self_in_dispatchConcretize); - - case JumpBelow: - return concretizeJumpUnsignedLessThan(self_in_dispatchConcretize); - - case JumpAboveOrEqual: - return concretizeJumpUnsignedGreaterEqual(self_in_dispatchConcretize); - - case JumpAbove: - return concretizeJumpUnsignedGreaterThan(self_in_dispatchConcretize); - - case JumpBelowOrEqual: - return concretizeJumpUnsignedLessEqual(self_in_dispatchConcretize); - - case RetN: - return concretizeRetN(self_in_dispatchConcretize); - - case Stop: - return concretizeStop(self_in_dispatchConcretize); - - case AddCqR: - return concretizeAddCqR(self_in_dispatchConcretize); - - case AndCqR: - return concretizeAndCqRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]); - - case AndCqRR: - return concretizeAndCqRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[2]); - - case OrCqRR: - return concretizeOrCqRR(self_in_dispatchConcretize); - - case CmpCqR: - return concretizeCmpCqR(self_in_dispatchConcretize); - - case OrCqR: - return concretizeOrCqR(self_in_dispatchConcretize); - - case SubCqR: - return concretizeSubCqR(self_in_dispatchConcretize); - - case TstCqR: - return concretizeTstCqR(self_in_dispatchConcretize); - - case AddCwR: - return concretizeAddCwR(self_in_dispatchConcretize); - - case AndCwR: - return concretizeAndCwR(self_in_dispatchConcretize); - - case CmpCwR: - return concretizeCmpCwR(self_in_dispatchConcretize); - - case OrCwR: - return concretizeOrCwR(self_in_dispatchConcretize); - - case SubCwR: - return concretizeSubCwR(self_in_dispatchConcretize); - - case XorCwR: - return concretizeXorCwR(self_in_dispatchConcretize); - - case AddRR: - return concretizeAddRRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]); - - case AndRR: - return concretizeAndRR(self_in_dispatchConcretize); - - case CmpRR: - return concretizeCmpRR(self_in_dispatchConcretize); - - case OrRR: - return concretizeOrRR(self_in_dispatchConcretize); - - case SubRR: - return concretizeSubRRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]); - - case XorRR: - return concretizeXorRR(self_in_dispatchConcretize); - - case AddRRR: - return concretizeAddRRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[2]); - - case SubRRR: - return concretizeSubRRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[2]); - - case NegateR: - return concretizeNegateR(self_in_dispatchConcretize); - - case LoadEffectiveAddressMwrR: - return concretizeLoadEffectiveAddressMwrR(self_in_dispatchConcretize); - - case ArithmeticShiftRightCqR: - return concretizeArithmeticShiftRightCqR(self_in_dispatchConcretize); - - case LogicalShiftRightCqR: - return concretizeLogicalShiftRightCqR(self_in_dispatchConcretize); - - case LogicalShiftLeftCqR: - return concretizeLogicalShiftLeftCqR(self_in_dispatchConcretize); - - case ArithmeticShiftRightRR: - return concretizeArithmeticShiftRightRR(self_in_dispatchConcretize); - - case LogicalShiftLeftRR: - return concretizeLogicalShiftLeftRR(self_in_dispatchConcretize); - - case LogicalShiftRightRR: - return concretizeLogicalShiftRightRR(self_in_dispatchConcretize); - - case ClzRR: - return concretizeClzRR(self_in_dispatchConcretize); - - case MoveCqR: - return concretizeMoveCqR(self_in_dispatchConcretize); - - case MoveCwR: - return concretizeMoveCwR(self_in_dispatchConcretize); - - case MoveRR: - return concretizeMoveRR(self_in_dispatchConcretize); - - case MoveAwR: - return concretizeMoveAwR(self_in_dispatchConcretize); - - case MoveRAw: - return concretizeMoveRAw(self_in_dispatchConcretize); - - case MoveAbR: - return concretizeMoveAbR(self_in_dispatchConcretize); - - case MoveRAb: - return concretizeMoveRAb(self_in_dispatchConcretize); - - case MoveMbrR: - return concretizeMoveMbrR(self_in_dispatchConcretize); - - case MoveM16rR: - return concretizeMoveM16rR(self_in_dispatchConcretize); - - case MoveRM16r: - return concretizeMoveRM16r(self_in_dispatchConcretize); - - case MoveMwrR: - return concretizeMoveMwrR(self_in_dispatchConcretize); - - case MoveXbrRR: - return concretizeMoveXbrRR(self_in_dispatchConcretize); - - case MoveRXbrR: - return concretizeMoveRXbrR(self_in_dispatchConcretize); - - case MoveXwrRR: - return concretizeMoveXwrRR(self_in_dispatchConcretize); - - case MoveRXwrR: - return concretizeMoveRXwrR(self_in_dispatchConcretize); - - case MoveRMwr: - return concretizeMoveRMwr(self_in_dispatchConcretize); - - case PopR: - return concretizePopR(self_in_dispatchConcretize); - - case PushR: - return concretizePushR(self_in_dispatchConcretize); - - case PushCq: - return concretizePushCq(self_in_dispatchConcretize); - - case PushCw: - return concretizePushCw(self_in_dispatchConcretize); - - case PrefetchAw: - return concretizePrefetchAw(self_in_dispatchConcretize); - - case AddCheckOverflowCqR: - return concretizeAddCheckOverflowCqR(self_in_dispatchConcretize); - - case AddCheckOverflowRR: - return concretizeAddCheckOverflowRR(self_in_dispatchConcretize); - - case SubCheckOverflowCqR: - return concretizeSubCheckOverflowCqR(self_in_dispatchConcretize); - - case SubCheckOverflowRR: - return concretizeSubCheckOverflowRR(self_in_dispatchConcretize); - - case MulCheckOverflowRR: - return concretizeMulCheckOverflowRR(self_in_dispatchConcretize); - - default: - error("Case not found and no otherwise clause"); - } - return 0; -} - - /* CogMIPSELCompiler>>#divR:R: */ -static sqInt NoDbgRegParms -divRR(AbstractInstruction * self_in_divRR, sqInt dividendReg, sqInt divisorReg) -{ - flag("todo"); - return rtypersrtrdsafunct(self_in_divRR, SPECIAL, dividendReg, divisorReg, 0, 0, DIV); -} - - -/* Answer if CallFull and/or JumpFull are relative and hence need relocating - on method - compation. If so, they are annotated with IsRelativeCall in methods and - relocated in - relocateIfCallOrMethodReference:mcpc:delta: */ - - /* CogMIPSELCompiler>>#fullCallsAreRelative */ -static sqInt NoDbgRegParms -fullCallsAreRelative(AbstractInstruction * self_in_fullCallsAreRelative) -{ - return 0; -} - - /* CogMIPSELCompiler>>#functionAtAddress: */ -static sqInt NoDbgRegParms -functionAtAddress(AbstractInstruction * self_in_functionAtAddress, sqInt mcpc) -{ - return (longAt(mcpc)) & 0x3F; -} - - /* CogMIPSELCompiler>>#genDivR:R:Quo:Rem: */ -static sqInt NoDbgRegParms -genDivRRQuoRem(AbstractInstruction * self_in_genDivRRQuoRem, sqInt abstractRegDivisor, sqInt abstractRegDividend, sqInt abstractRegQuotient, sqInt abstractRegRemainder) -{ - genoperandoperand(DivRR, abstractRegDividend, abstractRegDivisor); - genoperand(MoveLowR, abstractRegQuotient); - genoperand(MoveHighR, abstractRegRemainder); - return 0; -} - - /* CogMIPSELCompiler>>#genMulR:R: */ -static AbstractInstruction * NoDbgRegParms -genMulRR(AbstractInstruction * self_in_genMulRR, sqInt regSource, sqInt regDest) -{ - return genoperandoperand(MulRR, regSource, regDest); -} - - -/* Ensure that the register args are pushed before the outer and - inner retpcs at an entry miss for arity <= self numRegArgs. The - outer retpc is that of a call at a send site. The inner is the call - from a method or PIC abort/miss to the trampoline. */ -/* Putting the receiver and args above the return address means the - CoInterpreter has a single machine-code frame format which saves - us a lot of work. */ -/* Iff there are register args convert - sp -> outerRetpc (send site retpc) - linkReg = innerRetpc (PIC abort/miss retpc) - to - base -> receiver - (arg0) - (arg1) - sp -> outerRetpc (send site retpc) - sp -> linkReg/innerRetpc (PIC abort/miss retpc) */ - - /* CogMIPSELCompiler>>#genPushRegisterArgsForAbortMissNumArgs: */ -static void NoDbgRegParms -genPushRegisterArgsForAbortMissNumArgs(AbstractInstruction * self_in_genPushRegisterArgsForAbortMissNumArgs, sqInt numArgs) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - flag("inefficient"); - if (numArgs <= 2 /* numRegArgs */) { - assert((numRegArgs()) <= 2); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, SPReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveRMwr, ReceiverResultReg, 0, SPReg); - if (numArgs > 0) { - /* begin PushR: */ - genoperand(PushR, Arg0Reg); - if (numArgs > 1) { - /* begin PushR: */ - genoperand(PushR, Arg1Reg); - } - } - /* begin PushR: */ - genoperand(PushR, TempReg); - } - /* begin PushR: */ - genoperand(PushR, LinkReg); -} - - -/* Ensure that the register args are pushed before the retpc for arity <= - self numRegArgs. - */ -/* This is easy on a RISC like ARM because the return address is in the link - register. Putting - the receiver and args above the return address means the CoInterpreter has - a single - machine-code frame format which saves us a lot of work - NOTA BENE: we do NOT push the return address here, which means it must be - dealt with later. */ - - /* CogMIPSELCompiler>>#genPushRegisterArgsForNumArgs:scratchReg: */ -static void NoDbgRegParms -genPushRegisterArgsForNumArgsscratchReg(AbstractInstruction * self_in_genPushRegisterArgsForNumArgsscratchReg, sqInt numArgs, sqInt ignored) -{ - flag("inefficient"); - if (numArgs <= 2 /* numRegArgs */) { - assert((numRegArgs()) <= 2); - /* begin PushR: */ - genoperand(PushR, ReceiverResultReg); - if (numArgs > 0) { - /* begin PushR: */ - genoperand(PushR, Arg0Reg); - if (numArgs > 1) { - /* begin PushR: */ - genoperand(PushR, Arg1Reg); - } - } - } -} - - -/* This is a no-op on MIPS since the ABI passes up to 4 args in registers and - trampolines currently observe that limit. - */ - - /* CogMIPSELCompiler>>#genRemoveNArgsFromStack: */ -static sqInt NoDbgRegParms -genRemoveNArgsFromStack(AbstractInstruction * self_in_genRemoveNArgsFromStack, sqInt n) -{ - assert(n <= 4); - return 0; -} - - -/* Restore the registers in regMask as saved by genSaveRegs:. - We don't need to do anything because all of the abstract registers are - allocated to C preserved registers. But for the future... */ - - /* CogMIPSELCompiler>>#genRestoreRegs: */ -static sqInt NoDbgRegParms -genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask) -{ - sqInt reg; - - assert(regMask == 0); - assert(!((((regMask & (registerMaskForandand(SP, FP, RA))) != 0)))); - for (reg = R0; reg <= R28; reg += 1) { - if (((regMask & (1U << reg)) != 0)) { - /* begin PopR: */ - genoperand(PopR, reg); - } - } - return 0; -} - - -/* Save the registers in regMask for a call into the C run-time from a - trampoline. We don't need to do anything because all of the abstract - registers are - allocated to C preserved registers. But for the future... */ - - /* CogMIPSELCompiler>>#genSaveRegs: */ -static sqInt NoDbgRegParms -genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask) -{ - sqInt reg; - - assert(regMask == 0); - assert(!((((regMask & (registerMaskForandand(SP, FP, RA))) != 0)))); - for (reg = R28; reg >= R0; reg += -1) { - if (((regMask & (1U << reg)) != 0)) { - /* begin PushR: */ - genoperand(PushR, reg); - } - } - return 0; -} - - /* CogMIPSELCompiler>>#genSubstituteReturnAddress: */ -static AbstractInstruction * NoDbgRegParms -genSubstituteReturnAddress(AbstractInstruction * self_in_genSubstituteReturnAddress, sqInt retpc) -{ - AbstractInstruction *anInstruction; - - /* begin checkLiteral:forInstruction: */ - anInstruction = genoperandoperand(MoveCwR, retpc, RA); - return anInstruction; -} - - -/* Answer if the processor has a dedicated callee-saved register to point to - the base of commonly-accessed variables. */ - - /* CogMIPSELCompiler>>#hasVarBaseRegister */ -static sqInt NoDbgRegParms -hasVarBaseRegister(AbstractInstruction * self_in_hasVarBaseRegister) -{ - return 1; -} - - /* CogMIPSELCompiler>>#high16BitsOf: */ -static usqInt NoDbgRegParms -high16BitsOf(AbstractInstruction * self_in_high16BitsOf, usqInt word) -{ - return (word) >> 16; -} - - -/* Answer the inline cache tag for the return address of a send. */ -/* MoveCwR ClassReg selectorIndex/expectedClass - Call: unlinked send stub/expectedTarget - Push ReceiverResult <-- callSiteReturnAddress */ -/* lui s3, selector/tagHigh - ori s3, s3, selector/tagLow - lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jalr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#inlineCacheTagAt: */ -static usqInt NoDbgRegParms -inlineCacheTagAt(AbstractInstruction * self_in_inlineCacheTagAt, usqInt callSiteReturnAddress) -{ - assert((opcodeAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 24)) == LUI); - assert((opcodeAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 20)) == ORI); - assert((opcodeAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_inlineCacheTagAt))); - return literalAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 20); -} - - -/* Answer the instruction size at pc. */ - - /* CogMIPSELCompiler>>#instructionSizeAt: */ -static sqInt NoDbgRegParms -instructionSizeAt(AbstractInstruction * self_in_instructionSizeAt, sqInt pc) -{ - return 4; -} - - -/* Assuming mcpc is a send return pc answer if the instruction before it is a - call (not a CallFull). - */ -/* cogit disassembleFrom: mcpc - 8 to: mcpc. */ - - /* CogMIPSELCompiler>>#isCallPrecedingReturnPC: */ -static sqInt NoDbgRegParms -isCallPrecedingReturnPC(AbstractInstruction * self_in_isCallPrecedingReturnPC, sqInt mcpc) -{ - if ((opcodeAtAddress(self_in_isCallPrecedingReturnPC, mcpc - 8)) == JAL) { - return 1; - } - if (((opcodeAtAddress(self_in_isCallPrecedingReturnPC, mcpc - 8)) == SPECIAL) - && ((functionAtAddress(self_in_isCallPrecedingReturnPC, mcpc - 8)) == JALR)) { - return 1; - } - return 0; -} - - /* CogMIPSELCompiler>>#isJump */ -static sqInt NoDbgRegParms -isJump(AbstractInstruction * self_in_isJump) -{ - return (((((self_in_isJump->opcode)) >= FirstJump) && (((self_in_isJump->opcode)) <= LastJump))) - || (((((self_in_isJump->opcode)) >= BrEqualRR) && (((self_in_isJump->opcode)) <= BrLongNotEqualRR))); -} - - -/* cogit disassembleFrom: pc to: pc + 4. */ - - /* CogMIPSELCompiler>>#isJumpAt: */ -static sqInt NoDbgRegParms -isJumpAt(AbstractInstruction * self_in_isJumpAt, sqInt pc) -{ - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == J) { - return 1; - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == SPECIAL) { - if ((functionAtAddress(self_in_isJumpAt, pc)) == JR) { - return 1; - } - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == BEQ) { - return 1; - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == BNE) { - return 1; - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == BLEZ) { - return 1; - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == BGTZ) { - return 1; - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == REGIMM) { - if ((rtAtAddress(self_in_isJumpAt, pc)) == BLTZ) { - return 1; - } - if ((rtAtAddress(self_in_isJumpAt, pc)) == BGEZ) { - return 1; - } - } - return 0; -} - - -/* Answer if the receiver is a pc-dependent instruction. */ - - /* CogMIPSELCompiler>>#isPCDependent */ -static sqInt NoDbgRegParms -isPCDependent(AbstractInstruction * self_in_isPCDependent) -{ - return (isJump(self_in_isPCDependent)) - || (((self_in_isPCDependent->opcode)) == AlignmentNops); -} - - /* CogMIPSELCompiler>>#isShortOffset: */ -static sqInt NoDbgRegParms -isShortOffset(AbstractInstruction * self_in_isShortOffset, sqInt offset) -{ - return ((offset >= -32768) && (offset <= 0x7FFF)); -} - - /* CogMIPSELCompiler>>#itype:rs:rt:eitherImmediate: */ -static sqInt NoDbgRegParms -itypersrteitherImmediate(AbstractInstruction * self_in_itypersrteitherImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate) -{ - assert(((op >= 0) && (op <= 0x3F))); - assert(((rs >= 0) && (rs <= 0x1F))); - assert(((rt >= 0) && (rt <= 0x1F))); - return (((((sqInt)((usqInt)(op) << 26))) | (((sqInt)((usqInt)(rs) << 21)))) | (((sqInt)((usqInt)(rt) << 16)))) | (immediate & 0xFFFF); -} - - /* CogMIPSELCompiler>>#itype:rs:rt:signedImmediate: */ -static sqInt NoDbgRegParms -itypersrtsignedImmediate(AbstractInstruction * self_in_itypersrtsignedImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate) -{ - assert(((op >= 0) && (op <= 0x3F))); - assert(((rs >= 0) && (rs <= 0x1F))); - assert(((rt >= 0) && (rt <= 0x1F))); - assert(isShortOffset(self_in_itypersrtsignedImmediate, immediate)); - return (((((sqInt)((usqInt)(op) << 26))) | (((sqInt)((usqInt)(rs) << 21)))) | (((sqInt)((usqInt)(rt) << 16)))) | (immediate & 0xFFFF); -} - - /* CogMIPSELCompiler>>#itype:rs:rt:unsignedImmediate: */ -static sqInt NoDbgRegParms -itypersrtunsignedImmediate(AbstractInstruction * self_in_itypersrtunsignedImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate) -{ - assert(((op >= 0) && (op <= 0x3F))); - assert(((rs >= 0) && (rs <= 0x1F))); - assert(((rt >= 0) && (rt <= 0x1F))); - assert(((immediate >= 0) && (immediate <= 0xFFFF))); - return (((((sqInt)((usqInt)(op) << 26))) | (((sqInt)((usqInt)(rs) << 21)))) | (((sqInt)((usqInt)(rt) << 16)))) | immediate; -} - - /* CogMIPSELCompiler>>#jA: */ -static sqInt NoDbgRegParms -jA(AbstractInstruction * self_in_jA, sqInt target) -{ - assert((target & 3) == 0); - return jtypetarget(self_in_jA, J, ((usqInt)((target & 0xFFFFFFF))) >> 2); -} - - /* CogMIPSELCompiler>>#jalA: */ -static sqInt NoDbgRegParms -jalA(AbstractInstruction * self_in_jalA, sqInt target) -{ - assert((target & 3) == 0); - return jtypetarget(self_in_jalA, JAL, ((usqInt)((target & 0xFFFFFFF))) >> 2); -} - - /* CogMIPSELCompiler>>#jalR: */ -static sqInt NoDbgRegParms -jalR(AbstractInstruction * self_in_jalR, sqInt targetReg) -{ - return rtypersrtrdsafunct(self_in_jalR, SPECIAL, targetReg, 0, RA, 0, JALR); -} - - /* CogMIPSELCompiler>>#jR: */ -static sqInt NoDbgRegParms -jR(AbstractInstruction * self_in_jR, sqInt targetReg) -{ - return rtypersrtrdsafunct(self_in_jR, SPECIAL, targetReg, 0, 0, 0, JR); -} - - /* CogMIPSELCompiler>>#jtype:target: */ -static sqInt NoDbgRegParms -jtypetarget(AbstractInstruction * self_in_jtypetarget, sqInt op, sqInt target) -{ - assert(((op >= 0) && (op <= 0x3F))); - assert(((target >= 0) && (target <= 0x7FFFFFF))); - return (((sqInt)((usqInt)(op) << 26))) | target; -} - - /* CogMIPSELCompiler>>#jumpLongByteSize */ -static sqInt NoDbgRegParms -jumpLongByteSize(AbstractInstruction * self_in_jumpLongByteSize) -{ - flag("bogus"); - return 16; -} - - /* CogMIPSELCompiler>>#jumpLongConditionalByteSize */ -static sqInt NoDbgRegParms -jumpLongConditionalByteSize(AbstractInstruction * self_in_jumpLongConditionalByteSize) -{ - return 16; -} - - -/* mcpc - 16: beq/ne Cmp, ZR, +12 - mcpc - 12: nop (delay slot) - mcpc - 8: j psuedo-address - mcpc - 4: nop (delay slot) */ - - /* CogMIPSELCompiler>>#jumpLongConditionalTargetBeforeFollowingAddress: */ -static usqInt NoDbgRegParms -jumpLongConditionalTargetBeforeFollowingAddress(AbstractInstruction * self_in_jumpLongConditionalTargetBeforeFollowingAddress, sqInt mcpc) -{ - assert(((opcodeAtAddress(self_in_jumpLongConditionalTargetBeforeFollowingAddress, mcpc - 16)) == BEQ) - || ((opcodeAtAddress(self_in_jumpLongConditionalTargetBeforeFollowingAddress, mcpc - 16)) == BNE)); - assert((longAt(mcpc - 12)) == (nop(self_in_jumpLongConditionalTargetBeforeFollowingAddress))); - assert((opcodeAtAddress(self_in_jumpLongConditionalTargetBeforeFollowingAddress, mcpc - 8)) == J); - assert((longAt(mcpc - 4)) == (nop(self_in_jumpLongConditionalTargetBeforeFollowingAddress))); - return targetFromJTypeAtAddress(self_in_jumpLongConditionalTargetBeforeFollowingAddress, mcpc - 8); -} - - -/* Answer the target address for the long jump immediately preceding mcpc */ - - /* CogMIPSELCompiler>>#jumpLongTargetBeforeFollowingAddress: */ -static usqInt NoDbgRegParms -jumpLongTargetBeforeFollowingAddress(AbstractInstruction * self_in_jumpLongTargetBeforeFollowingAddress, sqInt mcpc) -{ - assert((longAt(mcpc - 4)) == (nop(self_in_jumpLongTargetBeforeFollowingAddress))); - assert((opcodeAtAddress(self_in_jumpLongTargetBeforeFollowingAddress, mcpc - 8)) == SPECIAL); - assert((functionAtAddress(self_in_jumpLongTargetBeforeFollowingAddress, mcpc - 8)) == JR); - return literalAtAddress(self_in_jumpLongTargetBeforeFollowingAddress, mcpc - 12); -} - - /* CogMIPSELCompiler>>#jumpShortByteSize */ -static sqInt NoDbgRegParms -jumpShortByteSize(AbstractInstruction * self_in_jumpShortByteSize) -{ - return 8; -} - - -/* cogit disassembleFrom: pc to: pc + 4. */ - - /* CogMIPSELCompiler>>#jumpTargetPCAt: */ -static usqInt NoDbgRegParms -jumpTargetPCAt(AbstractInstruction * self_in_jumpTargetPCAt, sqInt pc) -{ - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == J) { - return targetFromJTypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == BEQ) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == BNE) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == BLEZ) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == BGTZ) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == REGIMM) { - if ((rtAtAddress(self_in_jumpTargetPCAt, pc)) == BLTZ) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((rtAtAddress(self_in_jumpTargetPCAt, pc)) == BGEZ) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - } - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#lbR:base:offset: */ -static sqInt NoDbgRegParms -lbRbaseoffset(AbstractInstruction * self_in_lbRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_lbRbaseoffset, LB, baseReg, destReg, offset); -} - - /* CogMIPSELCompiler>>#lbuR:base:offset: */ -static sqInt NoDbgRegParms -lbuRbaseoffset(AbstractInstruction * self_in_lbuRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_lbuRbaseoffset, LBU, baseReg, destReg, offset); -} - - /* CogMIPSELCompiler>>#lhR:base:offset: */ -static sqInt NoDbgRegParms -lhRbaseoffset(AbstractInstruction * self_in_lhRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_lhRbaseoffset, LH, baseReg, destReg, offset); -} - - /* CogMIPSELCompiler>>#lhuR:base:offset: */ -static sqInt NoDbgRegParms -lhuRbaseoffset(AbstractInstruction * self_in_lhuRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_lhuRbaseoffset, LHU, baseReg, destReg, offset); -} - - /* CogMIPSELCompiler>>#literalAtAddress: */ -static usqInt NoDbgRegParms -literalAtAddress(AbstractInstruction * self_in_literalAtAddress, sqInt mcpc) -{ - usqInt high; - usqInt low; - - assert((opcodeAtAddress(self_in_literalAtAddress, mcpc)) == ORI); - assert((opcodeAtAddress(self_in_literalAtAddress, mcpc - 4)) == LUI); - low = (longAt(mcpc)) & 0xFFFF; - high = (longAt(mcpc - 4)) & 0xFFFF; - return (high << 16) | low; -} - - /* CogMIPSELCompiler>>#literalAtAddress:put: */ -static sqInt NoDbgRegParms -literalAtAddressput(AbstractInstruction * self_in_literalAtAddressput, sqInt mcpc, sqInt newLiteral) -{ - usqInt newLower; - usqInt newUpper; - usqInt oldLower; - usqInt oldUpper; - - assert((opcodeAtAddress(self_in_literalAtAddressput, mcpc - 4)) == LUI); - assert((opcodeAtAddress(self_in_literalAtAddressput, mcpc)) == ORI); - oldUpper = longAt(mcpc - 4); - newUpper = (oldUpper & 0xFFFF0000U) | (high16BitsOf(self_in_literalAtAddressput, newLiteral)); - longAtput(mcpc - 4, newUpper); - oldLower = longAt(mcpc); - newLower = (oldLower & 0xFFFF0000U) | (low16BitsOf(self_in_literalAtAddressput, newLiteral)); - longAtput(mcpc, newLower); - assert((opcodeAtAddress(self_in_literalAtAddressput, mcpc - 4)) == LUI); - assert((opcodeAtAddress(self_in_literalAtAddressput, mcpc)) == ORI); - assert((literalAtAddress(self_in_literalAtAddressput, mcpc)) == newLiteral); - return newLiteral; -} - - -/* Answer the literal embedded in the instruction immediately preceding - followingAddress. This is used in the MoveCwR, PushCw and CmpCwR cases. */ -/* Cmp/MoveCwR - pc-8 lui rx, uper - pc-4 ori rx, rx, lower */ - - /* CogMIPSELCompiler>>#literalBeforeFollowingAddress: */ -static usqInt NoDbgRegParms -literalBeforeFollowingAddress(AbstractInstruction * self_in_literalBeforeFollowingAddress, sqInt followingAddress) -{ - if ((opcodeAtAddress(self_in_literalBeforeFollowingAddress, followingAddress - 4)) == ORI) { - return literalAtAddress(self_in_literalBeforeFollowingAddress, followingAddress - 4); - } - if (((opcodeAtAddress(self_in_literalBeforeFollowingAddress, followingAddress - 4)) == SW) - && ((opcodeAtAddress(self_in_literalBeforeFollowingAddress, followingAddress - 8)) == ADDIU)) { - return literalAtAddress(self_in_literalBeforeFollowingAddress, followingAddress - 12); - } - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#loadLiteralByteSize */ -static sqInt NoDbgRegParms -loadLiteralByteSize(AbstractInstruction * self_in_loadLiteralByteSize) -{ - return 8; -} - - -/* Answer the byte size of a MoveCwR opcode's corresponding machine code - when the argument is a PIC. This is for the self-reference at the end of a - closed PIC. */ - - /* CogMIPSELCompiler>>#loadPICLiteralByteSize */ -static sqInt NoDbgRegParms -loadPICLiteralByteSize(AbstractInstruction * self_in_loadPICLiteralByteSize) -{ - /* begin loadLiteralByteSize */ - return 8; -} - - /* CogMIPSELCompiler>>#low16BitsOf: */ -static usqInt NoDbgRegParms -low16BitsOf(AbstractInstruction * self_in_low16BitsOf, usqInt word) -{ - return word & 0xFFFF; -} - - /* CogMIPSELCompiler>>#luiR:C: */ -static sqInt NoDbgRegParms -luiRC(AbstractInstruction * self_in_luiRC, sqInt destReg, sqInt imm) -{ - return itypersrteitherImmediate(self_in_luiRC, LUI, 0, destReg, imm); -} - - /* CogMIPSELCompiler>>#lwR:base:offset: */ -static sqInt NoDbgRegParms -lwRbaseoffset(AbstractInstruction * self_in_lwRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_lwRbaseoffset, LW, baseReg, destReg, offset); -} - - /* CogMIPSELCompiler>>#machineCodeBytes */ -static sqInt NoDbgRegParms -machineCodeBytes(AbstractInstruction * self_in_machineCodeBytes) -{ - return 28; -} - - -/* Answer the maximum number of words of machine code generated for any - abstract instruction. - e.g. AddCheckOverflowCqR */ - - /* CogMIPSELCompiler>>#machineCodeWords */ -static sqInt NoDbgRegParms -machineCodeWords(AbstractInstruction * self_in_machineCodeWords) -{ - return 7; -} - - /* CogMIPSELCompiler>>#mfhiR: */ -static sqInt NoDbgRegParms -mfhiR(AbstractInstruction * self_in_mfhiR, sqInt destReg) -{ - flag("todo"); - return rtypersrtrdsafunct(self_in_mfhiR, SPECIAL, 0, 0, destReg, 0, MFHI); -} - - /* CogMIPSELCompiler>>#mfloR: */ -static sqInt NoDbgRegParms -mfloR(AbstractInstruction * self_in_mfloR, sqInt destReg) -{ - flag("todo"); - return rtypersrtrdsafunct(self_in_mfloR, SPECIAL, 0, 0, destReg, 0, MFLO); -} - - /* CogMIPSELCompiler>>#mipsbreak: */ -static sqInt NoDbgRegParms -mipsbreak(AbstractInstruction * self_in_mipsbreak, sqInt code) -{ - assert(((code >= 0) && (code <= 0xFFFFF))); - return (((sqInt)((usqInt)(code) << 6))) | BREAK; -} - - /* CogMIPSELCompiler>>#multR:R: */ -static sqInt NoDbgRegParms -multRR(AbstractInstruction * self_in_multRR, sqInt leftReg, sqInt rightReg) -{ - flag("todo"); - return rtypersrtrdsafunct(self_in_multRR, SPECIAL, leftReg, rightReg, 0, 0, MULT); -} - - /* CogMIPSELCompiler>>#nop */ -static sqInt NoDbgRegParms -nop(AbstractInstruction * self_in_nop) -{ - return 0; -} - - -/* Support for processors without condition codes, such as the MIPS. - Answer the branch opcode. Modify the receiver and the branch to - implement a suitable conditional branch that doesn't depend on - condition codes being set by the receiver. */ - - /* CogMIPSELCompiler>>#noteFollowingConditionalBranch: */ -static AbstractInstruction * NoDbgRegParms -noteFollowingConditionalBranch(AbstractInstruction * self_in_noteFollowingConditionalBranch, AbstractInstruction *branch) -{ - usqInt newBranchLeft; - sqInt newBranchOpcode; - usqInt newBranchRight; - - if ((((branch->opcode)) == JumpOverflow) - || (((branch->opcode)) == JumpNoOverflow)) { - return noteFollowingOverflowBranch(self_in_noteFollowingConditionalBranch, branch); - } - switch ((branch->opcode)) { - case JumpZero: - newBranchOpcode = BrEqualRR; - break; - - case JumpNonZero: - newBranchOpcode = BrNotEqualRR; - break; - - case JumpBelow: - newBranchOpcode = BrUnsignedLessRR; - break; - - case JumpBelowOrEqual: - newBranchOpcode = BrUnsignedLessEqualRR; - break; - - case JumpAbove: - newBranchOpcode = BrUnsignedGreaterRR; - break; - - case JumpAboveOrEqual: - newBranchOpcode = BrUnsignedGreaterEqualRR; - break; - - case JumpLess: - case JumpNegative: - newBranchOpcode = BrSignedLessRR; - break; - - case JumpLessOrEqual: - newBranchOpcode = BrSignedLessEqualRR; - break; - - case JumpGreater: - newBranchOpcode = BrSignedGreaterRR; - break; - - case JumpGreaterOrEqual: - newBranchOpcode = BrSignedGreaterEqualRR; - break; - - case JumpLongZero: - newBranchOpcode = BrLongEqualRR; - break; - - case JumpLongNonZero: - newBranchOpcode = BrLongNotEqualRR; - break; - - default: - /* begin unreachable */ - error("UNREACHABLE"); - newBranchOpcode = 0;; - } - switch ((self_in_noteFollowingConditionalBranch->opcode)) { - case BrEqualRR: - case BrUnsignedLessRR: - - /* I.e., two jumps after a compare. */ - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[1]; - newBranchRight = ((self_in_noteFollowingConditionalBranch->operands))[2]; - break; - case CmpRR: - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[1]; - newBranchRight = ((self_in_noteFollowingConditionalBranch->operands))[0]; - (self_in_noteFollowingConditionalBranch->opcode) = Label; - break; - case CmpCqR: - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[1]; - newBranchRight = AT; - (self_in_noteFollowingConditionalBranch->opcode) = MoveCqR; - ((self_in_noteFollowingConditionalBranch->operands))[1] = AT; - break; - case CmpCwR: - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[1]; - newBranchRight = AT; - (self_in_noteFollowingConditionalBranch->opcode) = MoveCwR; - ((self_in_noteFollowingConditionalBranch->operands))[1] = AT; - break; - case TstCqR: - newBranchLeft = Cmp; - newBranchRight = ZR; - break; - case AndCqR: - case OrRR: - case XorRR: - case SubCwR: - case SubCqR: - case ArithmeticShiftRightCqR: - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[1]; - newBranchRight = ZR; - break; - case AndCqRR: - case OrCqRR: - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[2]; - newBranchRight = ZR; - break; - case ClzRR: - - /* we test if the destination register is zero */ - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[0]; - newBranchRight = ZR; - break; - default: - /* begin unreachable */ - error("UNREACHABLE"); - - } - /* begin rewriteOpcode:with:with: */ - (branch->opcode) = newBranchOpcode; - ((branch->operands))[1] = newBranchLeft; - ((branch->operands))[2] = newBranchRight; - return branch; -} - - -/* Support for processors without condition codes, such as the MIPS. - Answer the branch opcode. Modify the receiver and the branch to - implement a suitable conditional branch that doesn't depend on - condition codes being set by the receiver. */ - - /* CogMIPSELCompiler>>#noteFollowingOverflowBranch: */ -static AbstractInstruction * NoDbgRegParms -noteFollowingOverflowBranch(AbstractInstruction * self_in_noteFollowingOverflowBranch, AbstractInstruction *branch) -{ - sqInt newBranchOpcode; - - if (((self_in_noteFollowingOverflowBranch->opcode)) == MulRR) { - (self_in_noteFollowingOverflowBranch->opcode) = MulCheckOverflowRR; - switch ((branch->opcode)) { - case JumpOverflow: - newBranchOpcode = BrNotEqualRR; - break; - - case JumpNoOverflow: - newBranchOpcode = BrEqualRR; - break; - - default: - /* begin unreachable */ - error("UNREACHABLE"); - newBranchOpcode = 0;; - } - /* begin rewriteOpcode:with:with: */ - (branch->opcode) = newBranchOpcode; - ((branch->operands))[1] = OverflowTemp1; - ((branch->operands))[2] = OverflowTemp2; - return branch; - } - switch ((self_in_noteFollowingOverflowBranch->opcode)) { - case AddCqR: - (self_in_noteFollowingOverflowBranch->opcode) = AddCheckOverflowCqR; - break; - - case AddRR: - (self_in_noteFollowingOverflowBranch->opcode) = AddCheckOverflowRR; - break; - - case SubCqR: - (self_in_noteFollowingOverflowBranch->opcode) = SubCheckOverflowCqR; - break; - - case SubRR: - (self_in_noteFollowingOverflowBranch->opcode) = SubCheckOverflowRR; - break; - - default: - /* begin unreachable */ - error("UNREACHABLE"); - (self_in_noteFollowingOverflowBranch->opcode) = 0;; - } - switch ((branch->opcode)) { - case JumpOverflow: - newBranchOpcode = BrSignedLessRR; - break; - - case JumpNoOverflow: - newBranchOpcode = BrSignedGreaterEqualRR; - break; - - default: - /* begin unreachable */ - error("UNREACHABLE"); - newBranchOpcode = 0;; - } - /* begin rewriteOpcode:with:with: */ - (branch->opcode) = newBranchOpcode; - ((branch->operands))[1] = Overflow; - ((branch->operands))[2] = ZR; - return branch; -} - - /* CogMIPSELCompiler>>#numIntRegArgs */ -static sqInt NoDbgRegParms -numIntRegArgs(AbstractInstruction * self_in_numIntRegArgs) -{ - flag("OABI"); - return 4; -} - - /* CogMIPSELCompiler>>#opcodeAtAddress: */ -static sqInt NoDbgRegParms -opcodeAtAddress(AbstractInstruction * self_in_opcodeAtAddress, sqInt mcpc) -{ - return ((usqInt)((longAt(mcpc)))) >> 26; -} - - /* CogMIPSELCompiler>>#oriR:R:C: */ -static sqInt NoDbgRegParms -oriRRC(AbstractInstruction * self_in_oriRRC, sqInt destReg, sqInt srcReg, sqInt imm) -{ - return itypersrteitherImmediate(self_in_oriRRC, ORI, srcReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#orR:R:R: */ -static sqInt NoDbgRegParms -orRRR(AbstractInstruction * self_in_orRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_orRRR, SPECIAL, leftReg, rightReg, destReg, 0, OR); -} - - /* CogMIPSELCompiler>>#padIfPossibleWithStopsFrom:to: */ -static void NoDbgRegParms -padIfPossibleWithStopsFromto(AbstractInstruction * self_in_padIfPossibleWithStopsFromto, sqInt startAddr, sqInt endAddr) -{ - sqInt addr; - - for (addr = startAddr; addr < endAddr; addr += 4) { - longAtput(addr, stop(self_in_padIfPossibleWithStopsFromto)); - } -} - - /* CogMIPSELCompiler>>#prefR:offset:hint: */ -static sqInt NoDbgRegParms -prefRoffsethint(AbstractInstruction * self_in_prefRoffsethint, sqInt baseReg, sqInt offset, sqInt hint) -{ - flag("todo"); - assert((hint == HintLoad) - || (hint == HintStore)); - return itypersrtsignedImmediate(self_in_prefRoffsethint, PREF, baseReg, hint, offset); -} - - /* CogMIPSELCompiler>>#pushLinkRegisterByteSize */ -static sqInt NoDbgRegParms -pushLinkRegisterByteSize(AbstractInstruction * self_in_pushLinkRegisterByteSize) -{ - return 8; -} - - /* CogMIPSELCompiler>>#relocateCallBeforeReturnPC:by: */ -static AbstractInstruction * NoDbgRegParms -relocateCallBeforeReturnPCby(AbstractInstruction * self_in_relocateCallBeforeReturnPCby, sqInt retpc, sqInt delta) -{ - usqInt target; - - assert((delta % 4) == 0); - if (delta == 0) { - return self_in_relocateCallBeforeReturnPCby; - } - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 16)) == LUI); - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 12)) == ORI); - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 8)) == SPECIAL); - assert((functionAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 8)) == JALR); - assert((longAt(retpc - 4)) == (nop(self_in_relocateCallBeforeReturnPCby))); - target = literalAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 12); - target += delta; - literalAtAddressput(self_in_relocateCallBeforeReturnPCby, retpc - 12, target); - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 16)) == LUI); - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 12)) == ORI); - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 8)) == SPECIAL); - assert((functionAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 8)) == JALR); - assert((longAt(retpc - 4)) == (nop(self_in_relocateCallBeforeReturnPCby))); - return 0; -} - - -/* lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jr t9 - nop (delay slot) - ... <-- pc */ - - /* CogMIPSELCompiler>>#relocateJumpLongBeforeFollowingAddress:by: */ -static AbstractInstruction * NoDbgRegParms -relocateJumpLongBeforeFollowingAddressby(AbstractInstruction * self_in_relocateJumpLongBeforeFollowingAddressby, sqInt pc, sqInt delta) -{ - usqInt newTarget; - usqInt oldTarget; - - assert((delta % 4) == 0); - if (delta == 0) { - return self_in_relocateJumpLongBeforeFollowingAddressby; - } - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 16)) == LUI); - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 12)) == ORI); - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 8)) == SPECIAL); - assert((functionAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 8)) == JR); - assert((longAt(pc - 4)) == (nop(self_in_relocateJumpLongBeforeFollowingAddressby))); - oldTarget = literalAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 12); - newTarget = oldTarget + delta; - literalAtAddressput(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 12, newTarget); - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 16)) == LUI); - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 12)) == ORI); - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 8)) == SPECIAL); - assert((functionAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 8)) == JR); - assert((longAt(pc - 4)) == (nop(self_in_relocateJumpLongBeforeFollowingAddressby))); - return 0; -} - - -/* lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jalr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#relocateJumpLongConditionalBeforeFollowingAddress:by: */ -static void NoDbgRegParms -relocateJumpLongConditionalBeforeFollowingAddressby(AbstractInstruction * self_in_relocateJumpLongConditionalBeforeFollowingAddressby, sqInt pc, sqInt delta) -{ - assert((opcodeAtAddress(self_in_relocateJumpLongConditionalBeforeFollowingAddressby, pc - 16)) == BNE); - assert((longAt(pc - 12)) == (nop(self_in_relocateJumpLongConditionalBeforeFollowingAddressby))); - assert((opcodeAtAddress(self_in_relocateJumpLongConditionalBeforeFollowingAddressby, pc - 8)) == J); - assert((longAt(pc - 4)) == (nop(self_in_relocateJumpLongConditionalBeforeFollowingAddressby))); - rewriteJTypeAtAddressdelta(self_in_relocateJumpLongConditionalBeforeFollowingAddressby, pc - 8, delta); - assert((opcodeAtAddress(self_in_relocateJumpLongConditionalBeforeFollowingAddressby, pc - 16)) == BNE); - assert((longAt(pc - 12)) == (nop(self_in_relocateJumpLongConditionalBeforeFollowingAddressby))); - assert((opcodeAtAddress(self_in_relocateJumpLongConditionalBeforeFollowingAddressby, pc - 8)) == J); - assert((longAt(pc - 4)) == (nop(self_in_relocateJumpLongConditionalBeforeFollowingAddressby))); -} - - -/* cogit disassembleFrom: pc - 16 to: pc + 16 a StackToRegisterMappingCogit. */ - - /* CogMIPSELCompiler>>#relocateMethodReferenceBeforeAddress:by: */ -static AbstractInstruction * NoDbgRegParms -relocateMethodReferenceBeforeAddressby(AbstractInstruction * self_in_relocateMethodReferenceBeforeAddressby, sqInt pc, sqInt delta) -{ - usqInt newValue; - usqInt oldValue; - - if (((opcodeAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 8)) == ADDIU) - && ((opcodeAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 4)) == SW)) { - - /* PushCw */ - oldValue = literalAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 12); - newValue = oldValue + delta; - literalAtAddressput(self_in_relocateMethodReferenceBeforeAddressby, pc - 12, newValue); - assert((literalAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 12)) == newValue); - return self_in_relocateMethodReferenceBeforeAddressby; - } - oldValue = literalAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 4); - newValue = oldValue + delta; - literalAtAddressput(self_in_relocateMethodReferenceBeforeAddressby, pc - 4, newValue); - assert((literalAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 4)) == newValue); - return 0; -} - - -/* Rewrite a call instruction to call a different target. This variant is - used to link PICs - in ceSendMiss et al,. - Answer the extent of the code change which is used to compute the range of - the icache to flush. */ -/* lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jalr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#rewriteCallAt:target: */ -static sqInt NoDbgRegParms -rewriteCallAttarget(AbstractInstruction * self_in_rewriteCallAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress) -{ - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteCallAttarget))); - literalAtAddressput(self_in_rewriteCallAttarget, callSiteReturnAddress - 12, callTargetAddress); - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteCallAttarget))); - return 20; -} - - -/* Rewrite a jump instruction to call a different target. This variant is - used to reset the - jumps in the prototype CPIC to suit each use,. - Answer the extent of the code change which is used to compute the range of - the icache to flush. */ - - /* CogMIPSELCompiler>>#rewriteConditionalJumpLongAt:target: */ -static void NoDbgRegParms -rewriteConditionalJumpLongAttarget(AbstractInstruction * self_in_rewriteConditionalJumpLongAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress) -{ - assert((opcodeAtAddress(self_in_rewriteConditionalJumpLongAttarget, callSiteReturnAddress - 8)) == J); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteConditionalJumpLongAttarget))); - rewriteJTypeAtAddresstarget(self_in_rewriteConditionalJumpLongAttarget, callSiteReturnAddress - 8, callTargetAddress); - assert((opcodeAtAddress(self_in_rewriteConditionalJumpLongAttarget, callSiteReturnAddress - 8)) == J); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteConditionalJumpLongAttarget))); -} - - -/* Rewrite a jump instruction to call a different target. This variant is - used to reset the - jumps in the prototype CPIC to suit each use,. - Answer the extent of the code change which is used to compute the range of - the icache to flush. */ -/* self CmpR: ClassReg R: TempReg. - ^self JumpNonZero: 0 */ -/* bne s5, s3, +156 ; =BE7C - nop (delay slot) - .... <-- addressFollowingJump */ - - /* CogMIPSELCompiler>>#rewriteCPICJumpAt:target: */ -static void NoDbgRegParms -rewriteCPICJumpAttarget(AbstractInstruction * self_in_rewriteCPICJumpAttarget, usqInt addressFollowingJump, usqInt jumpTargetAddr) -{ - assert((opcodeAtAddress(self_in_rewriteCPICJumpAttarget, addressFollowingJump - 8)) == BNE); - assert((longAt(addressFollowingJump - 4)) == (nop(self_in_rewriteCPICJumpAttarget))); - rewriteITypeBranchAtAddresstarget(self_in_rewriteCPICJumpAttarget, addressFollowingJump - 8, jumpTargetAddr); - assert((opcodeAtAddress(self_in_rewriteCPICJumpAttarget, addressFollowingJump - 8)) == BNE); - assert((longAt(addressFollowingJump - 4)) == (nop(self_in_rewriteCPICJumpAttarget))); -} - - -/* Rewrite an inline cache to call a different target for a new tag. This - variant is used - to link unlinked sends in ceSend:to:numArgs: et al. Answer the extent of - the code - change which is used to compute the range of the icache to flush. */ -/* MoveCwR ClassReg selectorIndex/expectedClass - Call: unlinked send stub/expectedTarget - Push ReceiverResult <-- callSiteReturnAddress */ -/* lui s3, selector/tagHigh - ori s3, s3, selector/tagLow - lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jalr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#rewriteInlineCacheAt:tag:target: */ -static sqInt NoDbgRegParms -rewriteInlineCacheAttagtarget(AbstractInstruction * self_in_rewriteInlineCacheAttagtarget, usqInt callSiteReturnAddress, sqInt cacheTag, usqInt callTargetAddress) -{ - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 24)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 20)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteInlineCacheAttagtarget))); - literalAtAddressput(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 20, cacheTag); - literalAtAddressput(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 12, callTargetAddress); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 24)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 20)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteInlineCacheAttagtarget))); - return 24; -} - - -/* Rewrite an inline cache with a new tag. This variant is used - by the garbage collector. */ -/* MoveCwR ClassReg selectorIndex/expectedClass - Call: unlinked send stub/expectedTarget - Push ReceiverResult <-- callSiteReturnAddress */ -/* lui s3, selector/tagHigh - ori s3, s3, selector/tagLow - lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jalr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#rewriteInlineCacheTag:at: */ -static void NoDbgRegParms -rewriteInlineCacheTagat(AbstractInstruction * self_in_rewriteInlineCacheTagat, sqInt cacheTag, usqInt callSiteReturnAddress) -{ - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 24)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 20)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteInlineCacheTagat))); - literalAtAddressput(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 20, cacheTag); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 24)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 20)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteInlineCacheTagat))); -} - - /* CogMIPSELCompiler>>#rewriteITypeBranchAtAddress:target: */ -static void NoDbgRegParms -rewriteITypeBranchAtAddresstarget(AbstractInstruction * self_in_rewriteITypeBranchAtAddresstarget, sqInt mcpc, sqInt newTarget) -{ - sqInt newDisplacement; - unsigned int newInstruction; - sqInt oldInstruction; - - - /* Displacement is relative to delay slot. */ - newDisplacement = newTarget - (mcpc + 4); - - /* Displacement is in words. */ - newDisplacement = (newDisplacement) >> 2; - newDisplacement = newDisplacement & 0xFFFF; - oldInstruction = longAt(mcpc); - newInstruction = (oldInstruction & 0xFFFF0000U) | newDisplacement; - longAtput(mcpc, newInstruction); -} - - /* CogMIPSELCompiler>>#rewriteJTypeAtAddress:delta: */ -static void NoDbgRegParms -rewriteJTypeAtAddressdelta(AbstractInstruction * self_in_rewriteJTypeAtAddressdelta, sqInt mcpc, sqInt delta) -{ - usqInt newTarget; - usqInt oldTarget; - - oldTarget = targetFromJTypeAtAddress(self_in_rewriteJTypeAtAddressdelta, mcpc); - newTarget = oldTarget + delta; - rewriteJTypeAtAddresstarget(self_in_rewriteJTypeAtAddressdelta, mcpc, newTarget); -} - - /* CogMIPSELCompiler>>#rewriteJTypeAtAddress:target: */ -static void NoDbgRegParms -rewriteJTypeAtAddresstarget(AbstractInstruction * self_in_rewriteJTypeAtAddresstarget, sqInt mcpc, sqInt newTarget) -{ - sqInt regionMask; - - assert((opcodeAtAddress(self_in_rewriteJTypeAtAddresstarget, mcpc)) == J); - - /* mcpc + 4: relative to delay slot not j */ - regionMask = 0xF0000000U; - assert(((mcpc + 4) & regionMask) == (newTarget & regionMask)); - longAtput(mcpc, jA(self_in_rewriteJTypeAtAddresstarget, newTarget)); -} - - -/* Rewrite a jump instruction to call a different target. This variant is - used to reset the - jumps in the prototype CPIC to suit each use,. - Answer the extent of the code change which is used to compute the range of - the icache to flush. */ -/* lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#rewriteJumpLongAt:target: */ -static sqInt NoDbgRegParms -rewriteJumpLongAttarget(AbstractInstruction * self_in_rewriteJumpLongAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress) -{ - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 8)) == JR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteJumpLongAttarget))); - literalAtAddressput(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 12, callTargetAddress); - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 8)) == JR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteJumpLongAttarget))); - return 20; -} - - /* CogMIPSELCompiler>>#rtAtAddress: */ -static sqInt NoDbgRegParms -rtAtAddress(AbstractInstruction * self_in_rtAtAddress, sqInt mcpc) -{ - return (((usqInt)((longAt(mcpc)))) >> 16) & 0x1F; -} - - /* CogMIPSELCompiler>>#rtype:rs:rt:rd:sa:funct: */ -static sqInt NoDbgRegParms -rtypersrtrdsafunct(AbstractInstruction * self_in_rtypersrtrdsafunct, sqInt op, sqInt rs, sqInt rt, sqInt rd, sqInt sa, sqInt funct) -{ - assert(((op >= 0) && (op <= 0x3F))); - assert(((rs >= 0) && (rs <= 0x1F))); - assert(((rt >= 0) && (rt <= 0x1F))); - assert(((rd >= 0) && (rd <= 0x1F))); - assert(((sa >= 0) && (sa <= 0x1F))); - assert(((funct >= 0) && (funct <= 0x3F))); - return (((((((sqInt)((usqInt)(op) << 26))) | (((sqInt)((usqInt)(rs) << 21)))) | (((sqInt)((usqInt)(rt) << 16)))) | (((sqInt)((usqInt)(rd) << 11)))) | (((sqInt)((usqInt)(sa) << 6)))) | funct; -} - - /* CogMIPSELCompiler>>#sbR:base:offset: */ -static sqInt NoDbgRegParms -sbRbaseoffset(AbstractInstruction * self_in_sbRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_sbRbaseoffset, SB, baseReg, srcReg, offset); -} - - -/* Not really, but we can merge this in noteFollowingConditionalBranch:. */ - - /* CogMIPSELCompiler>>#setsConditionCodesFor: */ -static sqInt NoDbgRegParms -setsConditionCodesFor(AbstractInstruction * self_in_setsConditionCodesFor, sqInt aConditionalJumpOpcode) -{ - if (((self_in_setsConditionCodesFor->opcode)) == XorRR) { - return 1; - } - if (((self_in_setsConditionCodesFor->opcode)) == ArithmeticShiftRightCqR) { - return 1; - } - if ((((self_in_setsConditionCodesFor->opcode)) == ClzRR) - && (aConditionalJumpOpcode == JumpZero)) { - return 1; - } - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#shR:base:offset: */ -static sqInt NoDbgRegParms -shRbaseoffset(AbstractInstruction * self_in_shRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_shRbaseoffset, SH, baseReg, srcReg, offset); -} - - -/* Size a jump and set its address. The target may be another instruction - or an absolute address. On entry the address inst var holds our virtual - address. On exit address is set to eventualAbsoluteAddress, which is - where this instruction will be output. The span of a jump to a following - instruction is therefore between that instruction's address and this - instruction's address ((which are both still their virtual addresses), but - the span of a jump to a preceding instruction or to an absolute address is - between that instruction's address (which by now is its eventual absolute - address) or absolute address and eventualAbsoluteAddress. - - ARM is simple; the 26-bit call/jump range means no short jumps. This - routine only has to determine the targets of jumps, not determine sizes. */ - - /* CogMIPSELCompiler>>#sizePCDependentInstructionAt: */ -static usqInt NoDbgRegParms -sizePCDependentInstructionAt(AbstractInstruction * self_in_sizePCDependentInstructionAt, sqInt eventualAbsoluteAddress) -{ - usqInt alignment; - - if (((self_in_sizePCDependentInstructionAt->opcode)) == AlignmentNops) { - (self_in_sizePCDependentInstructionAt->address) = eventualAbsoluteAddress; - alignment = ((self_in_sizePCDependentInstructionAt->operands))[0]; - return ((self_in_sizePCDependentInstructionAt->machineCodeSize) = ((eventualAbsoluteAddress + (alignment - 1)) & (-alignment)) - eventualAbsoluteAddress); - } - assert((isJump(self_in_sizePCDependentInstructionAt)) - || ((((self_in_sizePCDependentInstructionAt->opcode)) == Call) - || (((self_in_sizePCDependentInstructionAt->opcode)) == CallFull))); - if (isJump(self_in_sizePCDependentInstructionAt)) { - resolveJumpTarget(self_in_sizePCDependentInstructionAt); - } - (self_in_sizePCDependentInstructionAt->address) = eventualAbsoluteAddress; - return ((self_in_sizePCDependentInstructionAt->machineCodeSize) = (self_in_sizePCDependentInstructionAt->maxSize)); -} - - /* CogMIPSELCompiler>>#sllR:R:C: */ -static sqInt NoDbgRegParms -sllRRC(AbstractInstruction * self_in_sllRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount) -{ - return rtypersrtrdsafunct(self_in_sllRRC, SPECIAL, 0, sourceReg, destReg, shiftAmount, SLL); -} - - /* CogMIPSELCompiler>>#sllvR:R:R: */ -static sqInt NoDbgRegParms -sllvRRR(AbstractInstruction * self_in_sllvRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_sllvRRR, SPECIAL, rightReg, leftReg, destReg, 0, SLLV); -} - - /* CogMIPSELCompiler>>#sltiR:R:C: */ -static sqInt NoDbgRegParms -sltiRRC(AbstractInstruction * self_in_sltiRRC, sqInt destReg, sqInt leftReg, sqInt imm) -{ - return itypersrtsignedImmediate(self_in_sltiRRC, SLTI, leftReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#sltiuR:R:C: */ -static sqInt NoDbgRegParms -sltiuRRC(AbstractInstruction * self_in_sltiuRRC, sqInt destReg, sqInt leftReg, sqInt imm) -{ - return itypersrtsignedImmediate(self_in_sltiuRRC, SLTIU, leftReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#sltR:R:R: */ -static sqInt NoDbgRegParms -sltRRR(AbstractInstruction * self_in_sltRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_sltRRR, SPECIAL, leftReg, rightReg, destReg, 0, SLT); -} - - /* CogMIPSELCompiler>>#sltuR:R:R: */ -static sqInt NoDbgRegParms -sltuRRR(AbstractInstruction * self_in_sltuRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_sltuRRR, SPECIAL, leftReg, rightReg, destReg, 0, SLTU); -} - - /* CogMIPSELCompiler>>#sraR:R:C: */ -static sqInt NoDbgRegParms -sraRRC(AbstractInstruction * self_in_sraRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount) -{ - return rtypersrtrdsafunct(self_in_sraRRC, SPECIAL, 0, sourceReg, destReg, shiftAmount, SRA); -} - - /* CogMIPSELCompiler>>#sravR:R:R: */ -static sqInt NoDbgRegParms -sravRRR(AbstractInstruction * self_in_sravRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_sravRRR, SPECIAL, rightReg, leftReg, destReg, 0, SRAV); -} - - /* CogMIPSELCompiler>>#srlR:R:C: */ -static sqInt NoDbgRegParms -srlRRC(AbstractInstruction * self_in_srlRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount) -{ - return rtypersrtrdsafunct(self_in_srlRRC, SPECIAL, 0, sourceReg, destReg, shiftAmount, SRL); -} - - /* CogMIPSELCompiler>>#srlvR:R:R: */ -static sqInt NoDbgRegParms -srlvRRR(AbstractInstruction * self_in_srlvRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_srlvRRR, SPECIAL, rightReg, leftReg, destReg, 0, SRLV); -} - - /* CogMIPSELCompiler>>#stop */ -static sqInt NoDbgRegParms -stop(AbstractInstruction * self_in_stop) -{ - return mipsbreak(self_in_stop, 0); -} - - /* CogMIPSELCompiler>>#stopsFrom:to: */ -static void NoDbgRegParms -stopsFromto(AbstractInstruction * self_in_stopsFromto, sqInt startAddr, sqInt endAddr) -{ - sqInt addr; - - assert((((endAddr - startAddr) + 1) % 4) == 0); - for (addr = startAddr; addr <= endAddr; addr += 4) { - codeLongAtput(addr, stop(self_in_stopsFromto)); - } -} - - -/* Rewrite the long constant loaded by a MoveCwR or PushCw before the given - address - */ - - /* CogMIPSELCompiler>>#storeLiteral:beforeFollowingAddress: */ -static sqInt NoDbgRegParms -storeLiteralbeforeFollowingAddress(AbstractInstruction * self_in_storeLiteralbeforeFollowingAddress, sqInt literal, sqInt followingAddress) -{ - flag("bogus"); - if ((opcodeAtAddress(self_in_storeLiteralbeforeFollowingAddress, followingAddress - 4)) == ORI) { - return literalAtAddressput(self_in_storeLiteralbeforeFollowingAddress, followingAddress - 4, literal); - } - if (((opcodeAtAddress(self_in_storeLiteralbeforeFollowingAddress, followingAddress - 4)) == SW) - && ((opcodeAtAddress(self_in_storeLiteralbeforeFollowingAddress, followingAddress - 8)) == ADDIU)) { - return literalAtAddressput(self_in_storeLiteralbeforeFollowingAddress, followingAddress - 12, literal); - } - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#subuR:R:R: */ -static sqInt NoDbgRegParms -subuRRR(AbstractInstruction * self_in_subuRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_subuRRR, SPECIAL, leftReg, rightReg, destReg, 0, SUBU); -} - - /* CogMIPSELCompiler>>#swR:base:offset: */ -static sqInt NoDbgRegParms -swRbaseoffset(AbstractInstruction * self_in_swRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_swRbaseoffset, SW, baseReg, srcReg, offset); -} - - /* CogMIPSELCompiler>>#targetFromITypeAtAddress: */ -static usqInt NoDbgRegParms -targetFromITypeAtAddress(AbstractInstruction * self_in_targetFromITypeAtAddress, usqInt mcpc) -{ - usqInt offset; - - offset = (longAt(mcpc)) & 0xFFFF; - offset = offset << 2; - return (mcpc + offset) + OneInstruction; -} - - /* CogMIPSELCompiler>>#targetFromJTypeAtAddress: */ -static usqInt NoDbgRegParms -targetFromJTypeAtAddress(AbstractInstruction * self_in_targetFromJTypeAtAddress, usqInt mcpc) -{ - sqInt targetLow; - - - /* mcpc + 4: relative to delay slot not j */ - targetLow = (longAt(mcpc)) & 0x3FFFFFF; - return ((mcpc + 4) & 0xF0000000U) + (((sqInt)((usqInt)(targetLow) << 2))); -} - - /* CogMIPSELCompiler>>#xoriR:R:C: */ -static sqInt NoDbgRegParms -xoriRRC(AbstractInstruction * self_in_xoriRRC, sqInt destReg, sqInt srcReg, sqInt imm) -{ - return itypersrteitherImmediate(self_in_xoriRRC, XORI, srcReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#xorR:R:R: */ -static sqInt NoDbgRegParms -xorRRR(AbstractInstruction * self_in_xorRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_xorRRR, SPECIAL, leftReg, rightReg, destReg, 0, XOR); -} - - -/* Answer if Call and JumpLong are relative and hence need to take the - caller's relocation delta into account during code compaction, rather than - just the - callee's delta. */ - - /* CogMIPSELCompiler>>#zoneCallsAreRelative */ -static sqInt NoDbgRegParms -zoneCallsAreRelative(AbstractInstruction * self_in_zoneCallsAreRelative) -{ - return 0; -} - - /* CogObjectRepresentation>>#checkValidObjectReference: */ -static sqInt NoDbgRegParms -checkValidObjectReference(sqInt anOop) -{ - return (!(isImmediate(anOop))) - && ((heapMapAtWord(pointerForOop(anOop))) != 0); -} - - /* CogObjectRepresentation>>#genCmpClassFloatCompactIndexR: */ -static AbstractInstruction * NoDbgRegParms -genCmpClassFloatCompactIndexR(sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, ClassFloatCompactIndex, reg); - return anInstruction; -} - - /* CogObjectRepresentation>>#genCmpClassMethodContextCompactIndexR: */ -static AbstractInstruction * NoDbgRegParms -genCmpClassMethodContextCompactIndexR(sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, reg); - return anInstruction; -} - - -/* Get the method header (first word) of a CompiledMethod into headerReg. - Deal with the method possibly being cogged. */ - - /* CogObjectRepresentation>>#genGetMethodHeaderOf:into:scratch: */ -static sqInt NoDbgRegParms -genGetMethodHeaderOfintoscratch(sqInt methodReg, sqInt headerReg, sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *jumpNotCogged; - sqInt offset; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, BaseHeaderSize, methodReg, headerReg); - jumpNotCogged = genJumpSmallInteger(headerReg); - /* begin MoveMw:r:R: */ - offset = offsetof(CogMethod, methodHeader); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, offset, headerReg, headerReg); - jmpTarget(jumpNotCogged, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - -/* TODO: Optimize this one avoiding the trampoline */ - - /* CogObjectRepresentation>>#genLcByteSizeOf:to: */ -static void NoDbgRegParms -genLcByteSizeOfto(sqInt oop, sqInt resultRegister) -{ - AbstractInstruction *abstractInstruction; - - if (oop != Arg0Reg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, oop, Arg0Reg); - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceByteSizeOfTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, resultRegister); - ssPushNativeRegister(resultRegister); -} - - /* CogObjectRepresentation>>#genLcFloat32:toOop: */ -static void NoDbgRegParms -genLcFloat32toOop(sqInt value, sqInt object) -{ - AbstractInstruction *abstractInstruction; - - /* begin ConvertRs:Rd: */ - genoperandoperand(ConvertRsRd, value, DPFPReg0); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceFloatObjectOfTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, object); - ssPushRegister(object); -} - - /* CogObjectRepresentation>>#genLcFloat64:toOop: */ -static void NoDbgRegParms -genLcFloat64toOop(sqInt value, sqInt object) -{ - AbstractInstruction *abstractInstruction; - - if (value != DPFPReg0) { - /* begin MoveRd:Rd: */ - genoperandoperand(MoveRdRd, value, DPFPReg0); - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceFloatObjectOfTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, object); - ssPushRegister(object); -} - - /* CogObjectRepresentation>>#genLcInstantiateOop: */ -static void NoDbgRegParms -genLcInstantiateOop(sqInt classOop) -{ - AbstractInstruction *abstractInstruction; - - if (classOop != ReceiverResultReg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, classOop, ReceiverResultReg); - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceInstantiateClassTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, classOop); - ssPushRegister(classOop); -} - - /* CogObjectRepresentation>>#genLcInstantiateOop:constantIndexableSize: */ -static void NoDbgRegParms -genLcInstantiateOopconstantIndexableSize(sqInt classOop, sqInt indexableSize) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - - if (classOop != Arg0Reg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, classOop, Arg0Reg); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, indexableSize, Arg1Reg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceInstantiateClassIndexableSizeTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, classOop); - ssPushRegister(classOop); -} - - /* CogObjectRepresentation>>#genLcInstantiateOop:indexableSize: */ -static void NoDbgRegParms -genLcInstantiateOopindexableSize(sqInt classOop, sqInt indexableSize) -{ - AbstractInstruction *abstractInstruction; - - if (classOop != Arg0Reg) { - if (indexableSize == Arg0Reg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, indexableSize, TempReg); - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, classOop, Arg0Reg); - } - if (indexableSize != Arg1Reg) { - if (indexableSize == Arg0Reg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, Arg1Reg); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, indexableSize, Arg1Reg); - } - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceInstantiateClassIndexableSizeTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, classOop); - ssPushRegister(classOop); -} - - /* CogObjectRepresentation>>#genLcInt64ToOop: */ -static void NoDbgRegParms -genLcInt64ToOop(sqInt value) -{ - AbstractInstruction *abstractInstruction; - - if (value != ReceiverResultReg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, value, ReceiverResultReg); - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceSigned64BitIntegerTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - ssPushRegister(ReceiverResultReg); -} - - -/* Put the arguments in the correct registers */ - - /* CogObjectRepresentation>>#genLcInt64ToOop:highPart: */ -static void NoDbgRegParms -genLcInt64ToOophighPart(sqInt valueLow, sqInt valueHigh) -{ - AbstractInstruction *abstractInstruction; - - if (valueLow != ReceiverResultReg) { - if (valueHigh == ReceiverResultReg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, valueHigh, TempReg); - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, valueLow, ReceiverResultReg); - } - if (valueHigh != Arg0Reg) { - if (valueHigh == ReceiverResultReg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, Arg0Reg); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, valueHigh, Arg0Reg); - } - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceSigned64BitIntegerTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - ssPushRegister(ReceiverResultReg); -} - - /* CogObjectRepresentation>>#genLcOopToInt64: */ -static void NoDbgRegParms -genLcOopToInt64(sqInt value) -{ - AbstractInstruction *abstractInstruction; - - if (value != ReceiverResultReg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, value, ReceiverResultReg); - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceSigned64BitValueOfTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - ssPushNativeRegister(ReceiverResultReg); -} - - -/* Assume this is always correct */ - - /* CogObjectRepresentation>>#genLcOopToPointer: */ -static void NoDbgRegParms -genLcOopToPointer(sqInt object) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, BaseHeaderSize, object, object); - ssPushNativeRegister(object); -} - - /* CogObjectRepresentation>>#genLcOopToUInt64: */ -static void NoDbgRegParms -genLcOopToUInt64(sqInt value) -{ - AbstractInstruction *abstractInstruction; - - if (value != ReceiverResultReg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, value, ReceiverResultReg); - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, cePositive64BitValueOfTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - ssPushNativeRegister(ReceiverResultReg); -} - - /* CogObjectRepresentation>>#genLcOop:toFloat32: */ -static void NoDbgRegParms -genLcOoptoFloat32(sqInt object, sqInt value) -{ - AbstractInstruction *abstractInstruction; - - if (object != ReceiverResultReg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, object, ReceiverResultReg); - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceFloatValueOfTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin ConvertRd:Rs: */ - genoperandoperand(ConvertRdRs, DPFPReg0, value); - ssPushNativeRegisterSingleFloat(value); -} - - /* CogObjectRepresentation>>#genLcOop:toFloat64: */ -static void NoDbgRegParms -genLcOoptoFloat64(sqInt object, sqInt value) -{ - AbstractInstruction *abstractInstruction; - - if (object != ReceiverResultReg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, object, ReceiverResultReg); - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceFloatValueOfTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - if (DPFPReg0 != value) { - /* begin MoveRd:Rd: */ - genoperandoperand(MoveRdRd, DPFPReg0, value); - } - ssPushNativeRegisterDoubleFloat(value); -} - - /* CogObjectRepresentation>>#genLcOop:toInt64:highPart: */ -static void NoDbgRegParms -genLcOoptoInt64highPart(sqInt object, sqInt valueLow, sqInt valueHigh) -{ - AbstractInstruction *abstractInstruction; - - if (object != ReceiverResultReg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, object, ReceiverResultReg); - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceSigned64BitValueOfTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - if (Arg0Reg != valueHigh) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, valueHigh); - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, valueLow); - ssPushNativeRegistersecondRegister(valueLow, valueHigh); -} - - /* CogObjectRepresentation>>#genLcOop:toUInt64:highPart: */ -static void NoDbgRegParms -genLcOoptoUInt64highPart(sqInt object, sqInt valueLow, sqInt valueHigh) -{ - AbstractInstruction *abstractInstruction; - - if (object != ReceiverResultReg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, object, ReceiverResultReg); - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, cePositive64BitValueOfTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - if (Arg0Reg != valueHigh) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, valueHigh); - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, valueLow); - ssPushNativeRegistersecondRegister(valueLow, valueHigh); -} - - /* CogObjectRepresentation>>#genLcPointerToOop:class: */ -static void NoDbgRegParms -genLcPointerToOopclass(sqInt pointer, sqInt pointerClass) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin PushR: */ - genoperand(PushR, pointer); - annotateobjRef(checkLiteralforInstruction(pointerClass, genoperandoperand(MoveCwR, pointerClass, Arg0Reg)), pointerClass); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, BytesPerOop, Arg1Reg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceInstantiateClassIndexableSizeTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin PopR: */ - genoperand(PopR, pointer); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveRMwr, pointer, BaseHeaderSize, TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, pointer); - ssPushRegister(pointer); -} - - /* CogObjectRepresentation>>#genLcUInt64ToOop: */ -static void NoDbgRegParms -genLcUInt64ToOop(sqInt value) -{ - AbstractInstruction *abstractInstruction; - - if (value != ReceiverResultReg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, value, ReceiverResultReg); - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, cePositive64BitIntegerTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - ssPushRegister(ReceiverResultReg); -} - - -/* Put the arguments in the correct registers */ - - /* CogObjectRepresentation>>#genLcUInt64ToOop:highPart: */ -static void NoDbgRegParms -genLcUInt64ToOophighPart(sqInt valueLow, sqInt valueHigh) -{ - AbstractInstruction *abstractInstruction; - - if (valueLow != ReceiverResultReg) { - if (valueHigh == ReceiverResultReg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, valueHigh, TempReg); - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, valueLow, ReceiverResultReg); - } - if (valueHigh != Arg0Reg) { - if (valueHigh == ReceiverResultReg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, Arg0Reg); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, valueHigh, Arg0Reg); - } - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, cePositive64BitIntegerTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - ssPushRegister(ReceiverResultReg); -} - - /* CogObjectRepresentation>>#genLoadSlot:sourceReg:destReg: */ -static sqInt NoDbgRegParms -genLoadSlotsourceRegdestReg(sqInt index, sqInt sourceReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, (index * BytesPerWord) + BaseHeaderSize, sourceReg, destReg); - return 0; -} - - /* CogObjectRepresentation>>#genPrimitiveAdd */ -static sqInt -genPrimitiveAdd(void) -{ - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpOvfl; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genRemoveSmallIntegerTagsInScratchReg(ClassReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, ReceiverResultReg, ClassReg); - /* begin JumpOverflow: */ - jumpOvfl = genConditionalBranchoperand(JumpOverflow, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpOvfl, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveBitAnd */ -static sqInt -genPrimitiveBitAnd(void) -{ - AbstractInstruction *jumpNotSI; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - /* begin AndR:R: */ - genoperandoperand(AndRR, Arg0Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveBitOr */ -static sqInt -genPrimitiveBitOr(void) -{ - AbstractInstruction *jumpNotSI; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - /* begin OrR:R: */ - genoperandoperand(OrRR, Arg0Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - -/* rTemp := rArg0 - rClass := tTemp - rTemp := rTemp & 1 - jz nonInt - rClass >>= 1 - cmp 0,rClass - jge neg - cmp 31,rClass // numSmallIntegerBits, jge for sign - jge tooBig - rTemp := rReceiver - rTemp <<= rClass - rTemp >>= rClass (arithmetic) - cmp rTemp,rReceiver - jnz ovfl - rReceiver := rReceiver - 1 - rReceiver := rReceiver <<= rClass - rReceiver := rReceiver + 1 - ret - neg: - rClass := 0 - rClass - cmp 31,rClass // numSmallIntegerBits - jge inRange - rClass := 31 - inRange - rReceiver := rReceiver >>= rClass. - rReceiver := rReceiver | smallIntegerTags. - ret - ovfl - tooBig - nonInt: - fail - */ - - /* CogObjectRepresentation>>#genPrimitiveBitShift */ -static sqInt -genPrimitiveBitShift(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *jumpInRange; - AbstractInstruction *jumpNegative; - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpOvfl; - AbstractInstruction *jumpTooBig; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genConvertSmallIntegerToIntegerInReg(ClassReg); - if (!(setsConditionCodesFor(lastOpcode(), JumpNegative))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, ClassReg); - } - /* begin JumpNegative: */ - jumpNegative = genConditionalBranchoperand(JumpNegative, ((sqInt)0)); - /* begin CmpCq:R: */ - anInstruction1 = genoperandoperand(CmpCqR, 0x1F /* numSmallIntegerBits */, ClassReg); - /* begin JumpGreaterOrEqual: */ - jumpTooBig = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - /* begin LogicalShiftLeftR:R: */ - genoperandoperand(LogicalShiftLeftRR, ClassReg, TempReg); - /* begin ArithmeticShiftRightR:R: */ - genoperandoperand(ArithmeticShiftRightRR, ClassReg, TempReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, ReceiverResultReg); - /* begin JumpNonZero: */ - jumpOvfl = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genRemoveSmallIntegerTagsInScratchReg(ReceiverResultReg); - /* begin LogicalShiftLeftR:R: */ - genoperandoperand(LogicalShiftLeftRR, ClassReg, ReceiverResultReg); - genAddSmallIntegerTagsTo(ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNegative, genoperand(NegateR, ClassReg)); - /* begin CmpCq:R: */ - anInstruction2 = genoperandoperand(CmpCqR, 0x1F /* numSmallIntegerBits */, ClassReg); - /* begin JumpLessOrEqual: */ - jumpInRange = genConditionalBranchoperand(JumpLessOrEqual, ((sqInt)0)); - /* begin MoveCq:R: */ - anInstruction3 = genoperandoperand(MoveCqR, 0x1F /* numSmallIntegerBits */, ClassReg); - jmpTarget(jumpInRange, genoperandoperand(ArithmeticShiftRightRR, ClassReg, ReceiverResultReg)); - genClearAndSetSmallIntegerTagsIn(ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotSI, jmpTarget(jumpTooBig, jmpTarget(jumpOvfl, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveBitXor */ -static sqInt -genPrimitiveBitXor(void) -{ - AbstractInstruction *jumpNotSI; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genRemoveSmallIntegerTagsInScratchReg(Arg0Reg); - /* begin XorR:R: */ - genoperandoperand(XorRR, Arg0Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveClass */ -static sqInt -genPrimitiveClass(void) -{ - sqInt reg; - - reg = ReceiverResultReg; - if (methodOrBlockNumArgs > 0) { - if (methodOrBlockNumArgs > 1) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - reg = Arg0Reg; - assert(0 < (numRegArgs())); - } - if ((genGetClassObjectOfintoscratchRegmayBeAForwarder(reg, ReceiverResultReg, TempReg, reg != ReceiverResultReg)) == BadRegisterSet) { - genGetClassObjectOfintoscratchRegmayBeAForwarder(reg, ClassReg, TempReg, reg != ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, ReceiverResultReg); - } - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - return UnfailingPrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveDiv */ -static sqInt -genPrimitiveDiv(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *convert; - AbstractInstruction *jumpExact; - AbstractInstruction *jumpIsSI; - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpSameSign; - AbstractInstruction *jumpZero; - - if (!(processorHasDivQuoRemAndMClassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, Arg1Reg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genShiftAwaySmallIntegerTagsInScratchReg(ClassReg); - if (!(setsConditionCodesFor(lastOpcode(), JumpZero))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, ClassReg); - } - /* begin JumpZero: */ - jumpZero = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - genShiftAwaySmallIntegerTagsInScratchReg(TempReg); - gDivRRQuoRem(ClassReg, TempReg, TempReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(CmpCqR, 0, ClassReg); - /* begin JumpZero: */ - jumpExact = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin XorR:R: */ - genoperandoperand(XorRR, ClassReg, Arg1Reg); - if (!(setsConditionCodesFor(lastOpcode(), JumpZero))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, Arg1Reg); - } - /* begin JumpGreaterOrEqual: */ - jumpSameSign = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(SubCqR, 1, TempReg); - jmpTarget(jumpSameSign, (convert = genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - genConvertIntegerInRegtoSmallIntegerInReg(TempReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpExact, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - jumpIsSI = genJumpIsSmallIntegerValuescratch(TempReg, Arg1Reg); - jmpTarget(jumpIsSI, convert); - jmpTarget(jumpZero, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveDivide */ -static sqInt -genPrimitiveDivide(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *jumpInexact; - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpOverflow; - AbstractInstruction *jumpZero; - - if (!(processorHasDivQuoRemAndMClassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genShiftAwaySmallIntegerTagsInScratchReg(ClassReg); - /* begin JumpZero: */ - jumpZero = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - genShiftAwaySmallIntegerTagsInScratchReg(TempReg); - gDivRRQuoRem(ClassReg, TempReg, TempReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, ClassReg); - /* begin JumpNonZero: */ - jumpInexact = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - jumpOverflow = genJumpNotSmallIntegerValuescratch(TempReg, Arg1Reg); - genConvertIntegerInRegtoSmallIntegerInReg(TempReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpOverflow, jmpTarget(jumpInexact, jmpTarget(jumpZero, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveEqual */ -static sqInt -genPrimitiveEqual(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpZero, gJumpFPEqual, 0) - : genSmallIntegerComparison(JumpZero)); -} - - /* CogObjectRepresentation>>#genPrimitiveGreaterOrEqual */ -static sqInt -genPrimitiveGreaterOrEqual(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpGreaterOrEqual, gJumpFPGreaterOrEqual, 0) - : genSmallIntegerComparison(JumpGreaterOrEqual)); -} - - /* CogObjectRepresentation>>#genPrimitiveGreaterThan */ -static sqInt -genPrimitiveGreaterThan(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpGreater, gJumpFPGreater, 0) - : genSmallIntegerComparison(JumpGreater)); -} - - -/* Implementation notes: there are two reasons to use TempReg - -1) if primitive fails, ReceiverResultReg must remain unchanged (we - CompletePrimitive) -2) CLZ/BSR only work on 64bits for registers R0-R7 on - Intel X64. But Win64 uses R9 - Normally, this should be backEnd dependent, but for now we have a single - 64bits target... - */ - - /* CogObjectRepresentation>>#genPrimitiveHighBit */ -static sqInt -genPrimitiveHighBit(void) -{ - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *jumpNegativeReceiver; - AbstractInstruction *jumpNegativeReceiver2; - - - /* remove excess tag bits from the receiver oop */ - - /* and use the abstract cogit facility for case of single tag-bit */ - /* begin genHighBitIn:ofSmallIntegerOopWithSingleTagBit: */ - /* begin genHighBitClzIn:ofSmallIntegerOopWithSingleTagBit: */ - genoperandoperand(ClzRR, ReceiverResultReg, TempReg); - if (!(setsConditionCodesFor(lastOpcode(), JumpZero))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(CmpCqR, 0, TempReg); - } - - /* Note the nice bit trick below: - highBit_1based_of_small_int_value = (BytesPerWord * 8) - leadingZeroCout_of_oop - 1 toAccountForTagBit. - This is like 2 complements (- reg - 1) on (BytesPerWord * 8) log2 bits, or exactly a bit invert operation... */ - jumpNegativeReceiver2 = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkLiteral:forInstruction: */ - anInstruction3 = genoperandoperand(XorCwR, (BytesPerWord * 8) - 1, TempReg); - jumpNegativeReceiver = jumpNegativeReceiver2; - goto l4; - l4: /* end genHighBitIn:ofSmallIntegerOopWithSingleTagBit: */; - if (jumpNegativeReceiver == 0) { - return UnimplementedPrimitive; - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - genConvertIntegerToSmallIntegerInReg(ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNegativeReceiver, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveIdentical */ -static sqInt -genPrimitiveIdentical(void) -{ - return genPrimitiveIdenticalOrNotIf(0); -} - - /* CogObjectRepresentation>>#genPrimitiveLessOrEqual */ -static sqInt -genPrimitiveLessOrEqual(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpLessOrEqual, gJumpFPGreaterOrEqual, 1) - : genSmallIntegerComparison(JumpLessOrEqual)); -} - - /* CogObjectRepresentation>>#genPrimitiveLessThan */ -static sqInt -genPrimitiveLessThan(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpLess, gJumpFPGreater, 1) - : genSmallIntegerComparison(JumpLess)); -} - - /* CogObjectRepresentation>>#genPrimitiveMod */ -static sqInt -genPrimitiveMod(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *jumpExact; - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpSameSign; - AbstractInstruction *jumpZero; - - if (!(processorHasDivQuoRemAndMClassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genRemoveSmallIntegerTagsInScratchReg(ClassReg); - /* begin JumpZero: */ - jumpZero = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, Arg1Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - genRemoveSmallIntegerTagsInScratchReg(TempReg); - gDivRRQuoRem(ClassReg, TempReg, TempReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, ClassReg); - /* begin JumpZero: */ - jumpExact = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin XorR:R: */ - genoperandoperand(XorRR, ClassReg, Arg1Reg); - if (!(setsConditionCodesFor(lastOpcode(), JumpZero))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, Arg1Reg); - } - /* begin JumpGreaterOrEqual: */ - jumpSameSign = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin XorR:R: */ - genoperandoperand(XorRR, ClassReg, Arg1Reg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg1Reg, ClassReg); - jmpTarget(jumpSameSign, jmpTarget(jumpExact, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - genSetSmallIntegerTagsIn(ClassReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpZero, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveMultiply */ -static sqInt -genPrimitiveMultiply(void) -{ - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpOvfl; - - if (!(processorHasMultiplyAndMClassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, Arg1Reg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genShiftAwaySmallIntegerTagsInScratchReg(ClassReg); - genRemoveSmallIntegerTagsInScratchReg(Arg1Reg); - /* begin MulOverflowR:R: */ - genMulRR(backEnd, Arg1Reg, ClassReg); - /* begin JumpOverflow: */ - jumpOvfl = genConditionalBranchoperand(JumpOverflow, ((sqInt)0)); - genSetSmallIntegerTagsIn(ClassReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpOvfl, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - -/* subclasses override if they can */ - - /* CogObjectRepresentation>>#genPrimitiveNewMethod */ -static sqInt -genPrimitiveNewMethod(void) -{ - return UnimplementedPrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveNotEqual */ -static sqInt -genPrimitiveNotEqual(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpNonZero, gJumpFPNotEqual, 0) - : genSmallIntegerComparison(JumpNonZero)); -} - - /* CogObjectRepresentation>>#genPrimitiveNotIdentical */ -static sqInt -genPrimitiveNotIdentical(void) -{ - return genPrimitiveIdenticalOrNotIf(1); -} - - /* CogObjectRepresentation>>#genPrimitiveQuo */ -static sqInt -genPrimitiveQuo(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *convert; - AbstractInstruction *jumpExact; - AbstractInstruction *jumpIsSI; - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpZero; - - if (!(processorHasDivQuoRemAndMClassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genShiftAwaySmallIntegerTagsInScratchReg(ClassReg); - if (!(setsConditionCodesFor(lastOpcode(), JumpZero))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, ClassReg); - } - /* begin JumpZero: */ - jumpZero = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - genShiftAwaySmallIntegerTagsInScratchReg(TempReg); - gDivRRQuoRem(ClassReg, TempReg, TempReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, ClassReg); - /* begin JumpZero: */ - jumpExact = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin Label */ - convert = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - genConvertIntegerInRegtoSmallIntegerInReg(TempReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpExact, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - jumpIsSI = genJumpIsSmallIntegerValuescratch(TempReg, Arg1Reg); - jmpTarget(jumpIsSI, convert); - jmpTarget(jumpZero, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveSubtract */ -static sqInt -genPrimitiveSubtract(void) -{ - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpOvfl; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, Arg0Reg, TempReg); - /* begin JumpOverflow: */ - jumpOvfl = genConditionalBranchoperand(JumpOverflow, ((sqInt)0)); - genAddSmallIntegerTagsTo(TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpOvfl, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genSmallIntegerComparison: */ -static sqInt NoDbgRegParms -genSmallIntegerComparison(sqInt jumpOpcode) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt constant; - AbstractInstruction *jumpFail; - AbstractInstruction *jumpTrue; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpFail = genJumpNotSmallInteger(Arg0Reg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, ReceiverResultReg); - jumpTrue = genConditionalBranchoperand(jumpOpcode, 0); - /* begin genMoveConstant:R: */ - constant = falseObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpTrue, (shouldAnnotateObjectReference(trueObject()) - ? annotateobjRef(checkLiteralforInstruction(trueObject(), genoperandoperand(MoveCwR, trueObject(), ReceiverResultReg)), trueObject()) - : (/* begin checkQuickConstant:forInstruction: */ - trueObject(), - (anInstruction1 = genoperandoperand(MoveCqR, trueObject(), ReceiverResultReg)), - anInstruction1))); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpFail, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - -/* Stack looks like - return address */ - - /* CogObjectRepresentation>>#genSmallIntegerComparison:orDoubleComparison:invert: */ -static sqInt NoDbgRegParms -genSmallIntegerComparisonorDoubleComparisoninvert(sqInt jumpOpcode, AbstractInstruction * NoDbgRegParms (*jumpFPOpcodeGenerator)(void *), sqInt invertComparison) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt constant; - AbstractInstruction *jumpCond; - AbstractInstruction * jumpFail; - AbstractInstruction * jumpNonInt; - sqInt r; - - jumpNonInt = ((AbstractInstruction *) 0); - r = genSmallIntegerComparison(jumpOpcode); - if (r < 0) { - return r; - } -# if defined(DPFPReg0) - - /* Fall through on non-SmallInteger argument. Argument may be a Float : let us check or fail */ - jumpNonInt = genJumpImmediate(Arg0Reg); - genGetCompactClassIndexNonImmOfinto(Arg0Reg, SendNumArgsReg); - genCmpClassFloatCompactIndexR(SendNumArgsReg); - /* begin JumpNonZero: */ - jumpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genConvertSmallIntegerToIntegerInReg(ReceiverResultReg); - /* begin ConvertR:Rd: */ - genoperandoperand(ConvertRRd, ReceiverResultReg, DPFPReg0); - genGetDoubleValueOfinto(Arg0Reg, DPFPReg1); - if (invertComparison) { - - /* May need to invert for NaNs */ - /* begin CmpRd:Rd: */ - genoperandoperand(CmpRdRd, DPFPReg0, DPFPReg1); - } - else { - /* begin CmpRd:Rd: */ - genoperandoperand(CmpRdRd, DPFPReg1, DPFPReg0); - } - - /* FP jumps are a little weird */ - jumpCond = jumpFPOpcodeGenerator(0); - /* begin genMoveConstant:R: */ - constant = falseObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpCond, (shouldAnnotateObjectReference(trueObject()) - ? annotateobjRef(checkLiteralforInstruction(trueObject(), genoperandoperand(MoveCwR, trueObject(), ReceiverResultReg)), trueObject()) - : (/* begin checkQuickConstant:forInstruction: */ - trueObject(), - (anInstruction1 = genoperandoperand(MoveCqR, trueObject(), ReceiverResultReg)), - anInstruction1))); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNonInt, jmpTarget(jumpFail, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); -# endif // defined(DPFPReg0) - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#isUnannotatableConstant: */ -static sqInt NoDbgRegParms -isUnannotatableConstant(CogSimStackEntry *simStackEntry) -{ - return (((simStackEntry->type)) == SSConstant) - && ((isImmediate((simStackEntry->constant))) - || (!(shouldAnnotateObjectReference((simStackEntry->constant))))); -} - - -/* Character gets mapped to zero. See inlineCacheTagForInstance:. */ - - /* CogObjectRepresentationFor32BitSpur>>#classForInlineCacheTag: */ -static sqInt NoDbgRegParms -classForInlineCacheTag(sqInt inlineCacheTag) -{ - return classOrNilAtIndex((inlineCacheTag == 0 - ? characterTag() - : inlineCacheTag)); -} - - /* CogObjectRepresentationFor32BitSpur>>#genAddSmallIntegerTagsTo: */ -static sqInt NoDbgRegParms -genAddSmallIntegerTagsTo(sqInt aRegister) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, 1, aRegister); - return 0; -} - - -/* Set the SmallInteger tag bits when the tag bits may be filled with - garbage. - */ - - /* CogObjectRepresentationFor32BitSpur>>#genClearAndSetSmallIntegerTagsIn: */ -static sqInt NoDbgRegParms -genClearAndSetSmallIntegerTagsIn(sqInt scratchReg) -{ - return genSetSmallIntegerTagsIn(scratchReg); -} - - -/* Convert the Character in reg to a SmallInteger, assuming - the Character's value is a valid character. */ -/* self assume: objectMemory smallIntegerTag = 1 */ - - /* CogObjectRepresentationFor32BitSpur>>#genConvertCharacterToSmallIntegerInReg: */ -static void NoDbgRegParms -genConvertCharacterToSmallIntegerInReg(sqInt reg) -{ - assert(((numCharacterBits()) + 1) == (numSmallIntegerBits())); - /* begin LogicalShiftRightCq:R: */ - genoperandoperand(LogicalShiftRightCqR, 1, reg); -} - - /* CogObjectRepresentationFor32BitSpur>>#genConvertIntegerInReg:toSmallIntegerInReg: */ -static sqInt NoDbgRegParms -genConvertIntegerInRegtoSmallIntegerInReg(sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - - gLogicalShiftLeftCqRR(1, srcReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, 1, destReg); - return 0; -} - - /* CogObjectRepresentationFor32BitSpur>>#genConvertIntegerToSmallIntegerInReg: */ -static sqInt NoDbgRegParms -genConvertIntegerToSmallIntegerInReg(sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, 1, reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, 1, reg); - return 0; -} - - -/* Convert the SmallInteger in reg to a Character, assuming - the SmallInteger's value is a valid character. */ -/* self assume: objectMemory smallIntegerTag = 1 */ - - /* CogObjectRepresentationFor32BitSpur>>#genConvertSmallIntegerToCharacterInReg: */ -static void NoDbgRegParms -genConvertSmallIntegerToCharacterInReg(sqInt reg) -{ - assert(((numCharacterBits()) + 1) == (numSmallIntegerBits())); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, 1, reg); -} - - /* CogObjectRepresentationFor32BitSpur>>#genConvertSmallIntegerToIntegerInReg: */ -static sqInt NoDbgRegParms -genConvertSmallIntegerToIntegerInReg(sqInt reg) -{ - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, 1, reg); - return 0; -} - - /* CogObjectRepresentationFor32BitSpur>>#generateLowcodeObjectTrampolines */ -static void -generateLowcodeObjectTrampolines(void) -{ - ceFloatObjectOfTrampoline = genTrampolineForcalledfloatArgresult(floatObjectOf, "ceFloatObjectOfTrampoline", DPFPReg0, TempReg); - ceFloatValueOfTrampoline = genTrampolineForcalledargfloatResult(floatValueOf, "ceFloatValueOfTrampoline", ReceiverResultReg, DPFPReg0); - /* begin genTrampolineFor:called:arg:arg:result: */ - ceInstantiateClassIndexableSizeTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(instantiateClassindexableSize, "ceInstantiateClassIndexableSizeTrampoline", 2, Arg0Reg, Arg1Reg, null, null, 0 /* emptyRegisterMask */, 1, TempReg, 0); - /* begin genTrampolineFor:called:arg:arg:result: */ - ceInstantiateClassTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(instantiateClassindexableSize, "ceInstantiateClassTrampoline", 2, ReceiverResultReg, 0, null, null, 0 /* emptyRegisterMask */, 1, TempReg, 0); - /* begin genTrampolineFor:called:arg:result: */ - ceByteSizeOfTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(byteSizeOf, "ceByteSizeOfTrampoline", 1, Arg0Reg, null, null, null, 0 /* emptyRegisterMask */, 1, TempReg, 0); - /* begin genTrampolineFor:called:arg:arg:result: */ - cePositive64BitIntegerTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(positive64BitIntegerFor, "cePositive64BitIntegerTrampoline", 2, ReceiverResultReg, Arg0Reg, null, null, 0 /* emptyRegisterMask */, 1, TempReg, 0); - cePositive64BitValueOfTrampoline = genTrampolineForcalledargresultresult(positive64BitValueOf, "cePositive64BitValueOfTrampoline", ReceiverResultReg, TempReg, Arg0Reg); - /* begin genTrampolineFor:called:arg:arg:result: */ - ceSigned64BitIntegerTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(signed64BitIntegerFor, "ceSigned64BitIntegerTrampoline", 2, ReceiverResultReg, Arg0Reg, null, null, 0 /* emptyRegisterMask */, 1, TempReg, 0); - ceSigned64BitValueOfTrampoline = genTrampolineForcalledargresultresult(signed64BitValueOf, "ceSigned64BitValueOfTrampoline", ReceiverResultReg, TempReg, Arg0Reg); - /* begin genTrampolineFor:called:arg:result: */ - cePositive32BitIntegerTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(positive32BitIntegerFor, "cePositive32BitIntegerTrampoline", 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, TempReg, 0); - /* begin genTrampolineFor:called:arg:result: */ - cePositive32BitValueOfTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(positive32BitValueOf, "cePositive32BitValueOfTrampoline", 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, TempReg, 0); - /* begin genTrampolineFor:called:arg:result: */ - ceSigned32BitIntegerTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(signed32BitIntegerFor, "ceSigned32BitIntegerTrampoline", 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, TempReg, 0); - /* begin genTrampolineFor:called:arg:result: */ - ceSigned32BitValueOfTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(signed32BitValueOf, "ceSigned32BitValueOfTrampoline", 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, TempReg, 0); -} - - -/* Fetch the instance's identity hash into destReg, encoded as a - SmallInteger. - */ -/* Get header word in scratchReg */ - - /* CogObjectRepresentationFor32BitSpur>>#genGetHashFieldNonImmOf:asSmallIntegerInto: */ -static sqInt NoDbgRegParms -genGetHashFieldNonImmOfasSmallIntegerInto(sqInt instReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 4, instReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - identityHashHalfWordMask(); - anInstruction1 = genoperandoperand(AndCqR, identityHashHalfWordMask(), destReg); - genConvertIntegerToSmallIntegerInReg(destReg); - return 0; -} - - -/* Fetch the instance's identity hash into destReg, unencoded. */ - - /* CogObjectRepresentationFor32BitSpur>>#genGetHashFieldNonImmOf:into: */ -static sqInt NoDbgRegParms -genGetHashFieldNonImmOfinto(sqInt instReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 4, instReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - identityHashHalfWordMask(); - anInstruction1 = genoperandoperand(AndCqR, identityHashHalfWordMask(), destReg); - return 0; -} - - -/* Extract the inline cache tag for the object in sourceReg into destReg. The - inline cache tag for a given object is the value loaded in inline caches - to distinguish - objects of different classes. In Spur this is either the tags for - immediates, (with - 1 & 3 collapsed to 1 for SmallIntegers, and 2 collapsed to 0 for - Characters), or - the receiver's classIndex. - If forEntry is true answer the entry label at which control is to enter - (cmEntryOffset). If forEntry is false, control enters at the start. - If forEntry is true, generate something like this: - Limm: - andl $0x1, rDest - j Lcmp - Lentry: - movl rSource, rDest - andl $0x3, rDest - jnz Limm - movl 0(%edx), rDest - andl $0x3fffff, rDest - Lcmp: - If forEntry is false, generate something like the following. - At least on a 2.2GHz Intel Core i7 the following is slightly faster than - the above, - 136m sends/sec vs 130m sends/sec for nfib in tinyBenchmarks - Lentry: - movl rSource, rDest - andl $0x3, rDest - jz LnotImm - andl $1, rDest - j Lcmp - LnotImm: - movl 0(%edx), rDest - andl $0x3fffff, rDest - Lcmp: - But we expect most SmallInteger arithmetic to be performed in-line and so - prefer the - version that is faster for non-immediates (because it branches for - immediates only). */ - - /* CogObjectRepresentationFor32BitSpur>>#genGetInlineCacheClassTagFrom:into:forEntry: */ -static AbstractInstruction * NoDbgRegParms -genGetInlineCacheClassTagFromintoforEntry(sqInt sourceReg, sqInt destReg, sqInt forEntry) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *entryLabel; - AbstractInstruction *immLabel; - AbstractInstruction *jumpCompare; - AbstractInstruction *jumpNotImm; - - if (forEntry) { - /* begin AlignmentNops: */ - genoperand(AlignmentNops, BytesPerWord); - /* begin Label */ - immLabel = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, 1, destReg); - /* begin Jump: */ - jumpCompare = genoperand(Jump, ((sqInt)0)); - /* begin AlignmentNops: */ - genoperand(AlignmentNops, BytesPerWord); - /* begin Label */ - entryLabel = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - gAndCqRR(tagMask(), sourceReg, destReg); - /* begin JumpNonZero: */ - genConditionalBranchoperand(JumpNonZero, ((sqInt)immLabel)); - flag("endianness"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, 0, sourceReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - classIndexMask(); - anInstruction2 = genoperandoperand(AndCqR, classIndexMask(), destReg); - jmpTarget(jumpCompare, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - else { - /* begin Label */ - entryLabel = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - gAndCqRR(tagMask(), sourceReg, destReg); - /* begin JumpZero: */ - jumpNotImm = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(AndCqR, 1, destReg); - /* begin Jump: */ - jumpCompare = genoperand(Jump, ((sqInt)0)); - flag("endianness"); - jmpTarget(jumpNotImm, checkQuickConstantforInstruction(0, genoperandoperandoperand(MoveMwrR, 0, sourceReg, destReg))); - jmpTarget(jumpCompare, checkQuickConstantforInstruction(classIndexMask(), genoperandoperand(AndCqR, classIndexMask(), destReg))); - } - return entryLabel; -} - - -/* Get the size in byte-sized slots of the object in srcReg into destReg. - srcReg may equal destReg. - destReg <- numSlots << self shiftForWord - (fmt bitAnd: 3). - Assumes the object in srcReg has a byte format, i.e. 16 to 23 or 24 to 31 */ - - /* CogObjectRepresentationFor32BitSpur>>#genGetNumBytesOf:into: */ -static sqInt NoDbgRegParms -genGetNumBytesOfinto(sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *jmp; - - genGetRawSlotSizeOfNonImminto(srcReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - numSlotsMask(); - anInstruction = genoperandoperand(CmpCqR, numSlotsMask(), destReg); - /* begin JumpLess: */ - jmp = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - genGetOverflowSlotsOfinto(srcReg, destReg); - jmpTarget(jmp, genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), destReg)); - genGetBitsofFormatByteOfinto(3, srcReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, destReg); - return 0; -} - - /* CogObjectRepresentationFor32BitSpur>>#genGetOverflowSlotsOf:into: */ -static sqInt NoDbgRegParms -genGetOverflowSlotsOfinto(sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - -BaseHeaderSize; - anInstruction = genoperandoperandoperand(MoveMwrR, -BaseHeaderSize, srcReg, destReg); - return 0; -} - - -/* Generate a test for aRegister containing an integer value in the - SmallInteger range, and a jump if so, answering the jump. - c.f. Spur32BitMemoryManager>>isIntegerValue: */ - - /* CogObjectRepresentationFor32BitSpur>>#genJumpIsSmallIntegerValue:scratch: */ -static AbstractInstruction * NoDbgRegParms -genJumpIsSmallIntegerValuescratch(sqInt aRegister, sqInt scratchReg) -{ - return (gLogicalShiftLeftCqRR(1, aRegister, scratchReg), - /* begin XorR:R: */ - genoperandoperand(XorRR, aRegister, scratchReg), - /* begin JumpGreaterOrEqual: */ - genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0))); -} - - /* CogObjectRepresentationFor32BitSpur>>#genJumpNotSmallIntegerInScratchReg: */ -static AbstractInstruction * NoDbgRegParms -genJumpNotSmallIntegerInScratchReg(sqInt aRegister) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, 1, aRegister); - /* begin JumpZero: */ - return genConditionalBranchoperand(JumpZero, ((sqInt)0)); -} - - -/* Generate a test for aRegister containing an integer value outside the - SmallInteger range, and a jump if so, answering the jump. - c.f. Spur32BitMemoryManager>>isIntegerValue: */ - - /* CogObjectRepresentationFor32BitSpur>>#genJumpNotSmallIntegerValue:scratch: */ -static AbstractInstruction * NoDbgRegParms -genJumpNotSmallIntegerValuescratch(sqInt aRegister, sqInt scratchReg) -{ - return (gArithmeticShiftRightCqRR(1, aRegister, scratchReg), - /* begin XorR:R: */ - genoperandoperand(XorRR, aRegister, scratchReg), - /* begin JumpLess: */ - genConditionalBranchoperand(JumpLess, ((sqInt)0))); -} - - /* CogObjectRepresentationFor32BitSpur>>#genJumpNotSmallInteger: */ -static AbstractInstruction * NoDbgRegParms -genJumpNotSmallInteger(sqInt aRegister) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(TstCqR, 1, aRegister); - /* begin JumpZero: */ - return genConditionalBranchoperand(JumpZero, ((sqInt)0)); -} - - /* CogObjectRepresentationFor32BitSpur>>#genJumpSmallInteger: */ -static AbstractInstruction * NoDbgRegParms -genJumpSmallInteger(sqInt aRegister) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(TstCqR, 1, aRegister); - /* begin JumpNonZero: */ - return genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -} - - /* CogObjectRepresentationFor32BitSpur>>#genLcInt32ToOop: */ -static void NoDbgRegParms -genLcInt32ToOop(sqInt value) -{ - AbstractInstruction *abstractInstruction; - - if (value != ReceiverResultReg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, value, ReceiverResultReg); - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceSigned32BitIntegerTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - ssPushRegister(ReceiverResultReg); -} - - /* CogObjectRepresentationFor32BitSpur>>#genLcOopToInt32: */ -static void NoDbgRegParms -genLcOopToInt32(sqInt value) -{ - AbstractInstruction *abstractInstruction; - - if (value != ReceiverResultReg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, value, ReceiverResultReg); - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceSigned32BitValueOfTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - ssPushNativeRegister(ReceiverResultReg); -} - - /* CogObjectRepresentationFor32BitSpur>>#genLcOopToUInt32: */ -static void NoDbgRegParms -genLcOopToUInt32(sqInt value) -{ - AbstractInstruction *abstractInstruction; - - if (value != ReceiverResultReg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, value, ReceiverResultReg); - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, cePositive32BitValueOfTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - ssPushNativeRegister(ReceiverResultReg); -} - - /* CogObjectRepresentationFor32BitSpur>>#genLcUInt32ToOop: */ -static void NoDbgRegParms -genLcUInt32ToOop(sqInt value) -{ - AbstractInstruction *abstractInstruction; - - if (value != ReceiverResultReg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, value, ReceiverResultReg); - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, cePositive32BitIntegerTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - ssPushRegister(ReceiverResultReg); -} - - -/* c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: - fixedFieldsOf:format:length: - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveAtPut */ -static sqInt -genPrimitiveAtPut(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt formatReg; - AbstractInstruction *jumpArrayOutOfBounds; - AbstractInstruction *jumpBadIndex; - AbstractInstruction *jumpBytesOutOfBounds; - AbstractInstruction *jumpBytesOutOfRange; - AbstractInstruction * jumpFixedFieldsOutOfBounds; - AbstractInstruction *jumpHasFixedFields; - AbstractInstruction *jumpImmediate; - AbstractInstruction * jumpImmutable; - AbstractInstruction *jumpIsBytes; - AbstractInstruction * jumpIsCompiledMethod; - AbstractInstruction *jumpIsContext; - AbstractInstruction *jumpIsShorts; - AbstractInstruction * jumpNonSmallIntegerValue; - AbstractInstruction *jumpNotIndexableBits; - AbstractInstruction *jumpNotIndexablePointers; - AbstractInstruction * jumpNotPointers; - AbstractInstruction *jumpShortsOutOfBounds; - AbstractInstruction *jumpShortsOutOfRange; - AbstractInstruction *jumpWordsOutOfBounds; - AbstractInstruction *jumpWordsOutOfRange; - AbstractInstruction *methodInBounds; - sqInt nSlotsOrBytesReg; - - jumpImmutable = ((AbstractInstruction *) 0); - nSlotsOrBytesReg = ClassReg; - /* begin genLoadArgAtDepth:into: */ - assert(1 < (numRegArgs())); - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - jumpImmediate = genJumpImmediate(ReceiverResultReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpBadIndex = genJumpNotSmallInteger(Arg0Reg); - genConvertSmallIntegerToIntegerInReg(Arg0Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(SubCqR, 1, Arg0Reg); -# if IMMUTABILITY - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), TempReg); - /* begin genJumpBaseHeaderImmutable: */ - immutableBitMask(); - anInstruction17 = genoperandoperand(TstCqR, immutableBitMask(), TempReg); - /* begin JumpNonZero: */ - jumpImmutable = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -# else // IMMUTABILITY - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), NoReg); -# endif // IMMUTABILITY - genGetNumSlotsOfinto(ReceiverResultReg, nSlotsOrBytesReg); - /* begin checkQuickConstant:forInstruction: */ - weakArrayFormat(); - anInstruction2 = genoperandoperand(CmpCqR, weakArrayFormat(), formatReg); - /* begin JumpAbove: */ - jumpNotPointers = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - genStoreCheckReceiverRegvalueRegscratchReginFrame(ReceiverResultReg, Arg1Reg, TempReg, 0); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction3 = genoperandoperand(CmpCqR, arrayFormat(), formatReg); - /* begin JumpBelow: */ - jumpNotIndexablePointers = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin JumpNonZero: */ - jumpHasFixedFields = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpArrayOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddCq:R: */ - anInstruction4 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg0Reg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, Arg1Reg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpHasFixedFields, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genGetClassIndexOfNonImminto(ReceiverResultReg, formatReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, formatReg); - /* begin JumpZero: */ - jumpIsContext = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin PushR: */ - genoperand(PushR, nSlotsOrBytesReg); - genGetClassObjectOfClassIndexintoscratchReg(formatReg, nSlotsOrBytesReg, TempReg); - genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, nSlotsOrBytesReg, formatReg); - /* begin PopR: */ - genoperand(PopR, nSlotsOrBytesReg); - genConvertSmallIntegerToIntegerInReg(formatReg); - /* begin checkQuickConstant:forInstruction: */ - fixedFieldsOfClassFormatMask(); - anInstruction6 = genoperandoperand(AndCqR, fixedFieldsOfClassFormatMask(), formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, nSlotsOrBytesReg); - /* begin AddCq:R: */ - anInstruction7 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), formatReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpFixedFieldsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddR:R: */ - genoperandoperand(AddRR, formatReg, Arg0Reg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, Arg1Reg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotPointers, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNonSmallIntegerValue = genJumpNotSmallInteger(Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction8 = genoperandoperand(CmpCqR, firstByteFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsBytes = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstShortFormat(); - anInstruction9 = genoperandoperand(CmpCqR, firstShortFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsShorts = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction10 = genoperandoperand(CmpCqR, firstLongFormat(), formatReg); - /* begin JumpBelow: */ - jumpNotIndexableBits = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpWordsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - if (!(setsConditionCodesFor(lastOpcode(), JumpLess))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, TempReg); - } - /* begin JumpLess: */ - jumpWordsOutOfRange = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin AddCq:R: */ - anInstruction11 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg0Reg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, TempReg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsBytes, checkQuickConstantforInstruction((((usqInt)0xFF << 1) | 1), genoperandoperand(CmpCqR, (((usqInt)0xFF << 1) | 1), Arg1Reg))); - /* begin JumpAbove: */ - jumpBytesOutOfRange = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), nSlotsOrBytesReg); - gAndCqRR(BytesPerWord - 1, formatReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, nSlotsOrBytesReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpBytesOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction12 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsCompiledMethod = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - methodInBounds = genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperand(AddCqR, BaseHeaderSize, Arg0Reg); - /* begin MoveR:Xbr:R: */ - genoperandoperandoperand(MoveRXbrR, TempReg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsShorts, checkQuickConstantforInstruction((((usqInt)0xFFFF << 1) | 1), genoperandoperand(CmpCqR, (((usqInt)0xFFFF << 1) | 1), Arg1Reg))); - /* begin JumpAbove: */ - jumpShortsOutOfRange = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (shiftForWord()) - 1, nSlotsOrBytesReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(AndCqR, (BytesPerWord / 2) - 1, formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, nSlotsOrBytesReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpShortsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperandoperand(MoveRM16r, TempReg, BaseHeaderSize, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsCompiledMethod, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - getLiteralCountOfplusOneinBytesintoscratch(ReceiverResultReg, 1, 1, nSlotsOrBytesReg, TempReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelow: */ - genConditionalBranchoperand(JumpBelow, ((sqInt)methodInBounds)); - jmpTarget(jumpIsContext, jmpTarget(jumpNotIndexableBits, jmpTarget(jumpBytesOutOfRange, jmpTarget(jumpWordsOutOfRange, jmpTarget(jumpShortsOutOfRange, jmpTarget(jumpIsCompiledMethod, jmpTarget(jumpArrayOutOfBounds, jmpTarget(jumpBytesOutOfBounds, jmpTarget(jumpShortsOutOfBounds, jmpTarget(jumpWordsOutOfBounds, jmpTarget(jumpNotIndexablePointers, jmpTarget(jumpNonSmallIntegerValue, jmpTarget(jumpFixedFieldsOutOfBounds, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))))))))))))); -# if IMMUTABILITY - jmpTarget(jumpImmutable, ((AbstractInstruction *) (((jumpIsContext->operands))[0]))); -# endif - /* begin checkQuickConstant:forInstruction: */ - anInstruction16 = genoperandoperand(AddCqR, 1, Arg0Reg); - genConvertIntegerToSmallIntegerInReg(Arg0Reg); - jmpTarget(jumpBadIndex, jmpTarget(jumpImmediate, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return 0; -} - - -/* Generate the code for primitives 61 & 165, at:put:/basicAt:put: & - integerAt:put:. If signedVersion is true - then generate signed accesses to the bits classes (a la 164 & 165). If - signedVersion is false, - generate unsigned accesses (a la 60, 61, 63 & 64). */ -/* c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: - fixedFieldsOf:format:length: - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveAtPutSigned: */ -static sqInt NoDbgRegParms -genPrimitiveAtPutSigned(sqInt signedVersion) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt formatReg; - AbstractInstruction * jumpArrayOutOfBounds; - AbstractInstruction * jumpBadIndex; - AbstractInstruction * jumpBytesOutOfBounds; - AbstractInstruction * jumpBytesOutOfRange; - AbstractInstruction * jumpFixedFieldsOutOfBounds; - AbstractInstruction * jumpHasFixedFields; - AbstractInstruction * jumpImmediate; - AbstractInstruction * jumpImmutable; - AbstractInstruction * jumpIsBytes; - AbstractInstruction * jumpIsCompiledMethod; - AbstractInstruction * jumpIsContext; - AbstractInstruction * jumpIsShorts; - AbstractInstruction * jumpNonSmallIntegerValue; - AbstractInstruction * jumpNotIndexableBits; - AbstractInstruction * jumpNotIndexablePointers; - AbstractInstruction * jumpNotPointers; - AbstractInstruction * jumpShortsOutOfBounds; - AbstractInstruction * jumpShortsOutOfRange; - AbstractInstruction * jumpWordsOutOfBounds; - AbstractInstruction * jumpWordsOutOfRange; - AbstractInstruction * methodInBounds; - sqInt nSlotsOrBytesReg; - - jumpImmutable = ((AbstractInstruction *) 0); - jumpWordsOutOfRange = ((AbstractInstruction *) 0); - nSlotsOrBytesReg = ClassReg; - /* begin genLoadArgAtDepth:into: */ - assert(1 < (numRegArgs())); - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - jumpImmediate = genJumpImmediate(ReceiverResultReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpBadIndex = genJumpNotSmallInteger(Arg0Reg); - genConvertSmallIntegerToIntegerInReg(Arg0Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(SubCqR, 1, Arg0Reg); -# if IMMUTABILITY - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), TempReg); - /* begin genJumpBaseHeaderImmutable: */ - immutableBitMask(); - anInstruction21 = genoperandoperand(TstCqR, immutableBitMask(), TempReg); - /* begin JumpNonZero: */ - jumpImmutable = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -# else // IMMUTABILITY - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), NoReg); -# endif // IMMUTABILITY - genGetNumSlotsOfinto(ReceiverResultReg, nSlotsOrBytesReg); - /* begin checkQuickConstant:forInstruction: */ - weakArrayFormat(); - anInstruction6 = genoperandoperand(CmpCqR, weakArrayFormat(), formatReg); - /* begin JumpAbove: */ - jumpNotPointers = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - genStoreCheckReceiverRegvalueRegscratchReginFrame(ReceiverResultReg, Arg1Reg, TempReg, 0); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction7 = genoperandoperand(CmpCqR, arrayFormat(), formatReg); - /* begin JumpBelow: */ - jumpNotIndexablePointers = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin JumpNonZero: */ - jumpHasFixedFields = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpArrayOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddCq:R: */ - anInstruction8 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg0Reg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, Arg1Reg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpHasFixedFields, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genGetClassIndexOfNonImminto(ReceiverResultReg, formatReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, formatReg); - /* begin JumpZero: */ - jumpIsContext = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin PushR: */ - genoperand(PushR, nSlotsOrBytesReg); - genGetClassObjectOfClassIndexintoscratchReg(formatReg, nSlotsOrBytesReg, TempReg); - genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, nSlotsOrBytesReg, formatReg); - /* begin PopR: */ - genoperand(PopR, nSlotsOrBytesReg); - genConvertSmallIntegerToIntegerInReg(formatReg); - /* begin checkQuickConstant:forInstruction: */ - fixedFieldsOfClassFormatMask(); - anInstruction10 = genoperandoperand(AndCqR, fixedFieldsOfClassFormatMask(), formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, nSlotsOrBytesReg); - /* begin AddCq:R: */ - anInstruction11 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), formatReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpFixedFieldsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddR:R: */ - genoperandoperand(AddRR, formatReg, Arg0Reg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, Arg1Reg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotPointers, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNonSmallIntegerValue = genJumpNotSmallInteger(Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction12 = genoperandoperand(CmpCqR, firstByteFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsBytes = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstShortFormat(); - anInstruction13 = genoperandoperand(CmpCqR, firstShortFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsShorts = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction14 = genoperandoperand(CmpCqR, firstLongFormat(), formatReg); - /* begin JumpBelow: */ - jumpNotIndexableBits = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpWordsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - if (!signedVersion) { - if (!(setsConditionCodesFor(lastOpcode(), JumpLess))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, TempReg); - } - /* begin JumpLess: */ - jumpWordsOutOfRange = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - } - /* begin AddCq:R: */ - anInstruction15 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg0Reg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, TempReg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - if (signedVersion) { - jmpTarget(jumpIsBytes, gArithmeticShiftRightCqRR(8, Arg1Reg, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AddCqR, 1, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(CmpCqR, 1, TempReg); - } - else { - jmpTarget(jumpIsBytes, checkQuickConstantforInstruction((((usqInt)0xFF << 1) | 1), genoperandoperand(CmpCqR, (((usqInt)0xFF << 1) | 1), Arg1Reg))); - } - /* begin JumpAbove: */ - jumpBytesOutOfRange = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), nSlotsOrBytesReg); - gAndCqRR(BytesPerWord - 1, formatReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, nSlotsOrBytesReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpBytesOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction16 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsCompiledMethod = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - methodInBounds = genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperand(AddCqR, BaseHeaderSize, Arg0Reg); - /* begin MoveR:Xbr:R: */ - genoperandoperandoperand(MoveRXbrR, TempReg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - if (signedVersion) { - jmpTarget(jumpIsShorts, gArithmeticShiftRightCqRR(16, Arg1Reg, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(AddCqR, 1, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, 1, TempReg); - } - else { - jmpTarget(jumpIsShorts, checkQuickConstantforInstruction((((usqInt)0xFFFF << 1) | 1), genoperandoperand(CmpCqR, (((usqInt)0xFFFF << 1) | 1), Arg1Reg))); - } - /* begin JumpAbove: */ - jumpShortsOutOfRange = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (shiftForWord()) - 1, nSlotsOrBytesReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction18 = genoperandoperand(AndCqR, (BytesPerWord / 2) - 1, formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, nSlotsOrBytesReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpShortsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperandoperand(MoveRM16r, TempReg, BaseHeaderSize, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsCompiledMethod, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - getLiteralCountOfplusOneinBytesintoscratch(ReceiverResultReg, 1, 1, nSlotsOrBytesReg, TempReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelow: */ - genConditionalBranchoperand(JumpBelow, ((sqInt)methodInBounds)); - jmpTarget(jumpIsContext, jmpTarget(jumpNotIndexableBits, jmpTarget(jumpBytesOutOfRange, jmpTarget(jumpShortsOutOfRange, jmpTarget(jumpIsCompiledMethod, jmpTarget(jumpArrayOutOfBounds, jmpTarget(jumpBytesOutOfBounds, jmpTarget(jumpShortsOutOfBounds, jmpTarget(jumpWordsOutOfBounds, jmpTarget(jumpNotIndexablePointers, jmpTarget(jumpNonSmallIntegerValue, jmpTarget(jumpFixedFieldsOutOfBounds, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))))))))))); - if (!signedVersion) { - jmpTarget(jumpWordsOutOfRange, ((AbstractInstruction *) (((jumpIsContext->operands))[0]))); - } -# if IMMUTABILITY - jmpTarget(jumpImmutable, ((AbstractInstruction *) (((jumpIsContext->operands))[0]))); -# endif - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperand(AddCqR, 1, Arg0Reg); - genConvertIntegerToSmallIntegerInReg(Arg0Reg); - jmpTarget(jumpBadIndex, jmpTarget(jumpImmediate, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return 0; -} - - -/* Generate the code for primitives 60 & 164, at:/basicAt: & integerAt:. If - signedVersion is true - then generate signed accesses to the bits classes (a la 164 & 165). If - signedVersion is false, - generate unsigned accesses (a la 60, 61, 63 & 64). */ -/* c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: - fixedFieldsOf:format:length: - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveAtSigned: */ -static sqInt NoDbgRegParms -genPrimitiveAtSigned(sqInt signedVersion) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - AbstractInstruction * convertToIntAndReturn; - AbstractInstruction * first; - AbstractInstruction * first1; - sqInt formatReg; - AbstractInstruction * jumpArrayOutOfBounds; - AbstractInstruction * jumpBadIndex; - AbstractInstruction * jumpBytesOutOfBounds; - AbstractInstruction * jumpFixedFieldsOutOfBounds; - AbstractInstruction * jumpHasFixedFields; - AbstractInstruction * jumpImmediate; - AbstractInstruction * jumpIsArray; - AbstractInstruction * jumpIsBytes; - AbstractInstruction * jumpIsContext; - AbstractInstruction * jumpIsMethod; - AbstractInstruction * jumpIsShorts; - AbstractInstruction * jumpIsWords; - AbstractInstruction * jumpNotIndexable; - AbstractInstruction * jumpShortsOutOfBounds; - AbstractInstruction * jumpWordsOutOfBounds; - AbstractInstruction * jumpWordTooBig; - AbstractInstruction * methodInBounds; - sqInt nSlotsOrBytesReg; - - nSlotsOrBytesReg = ClassReg; - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - jumpImmediate = genJumpImmediate(ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, Arg1Reg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpBadIndex = genJumpNotSmallInteger(Arg0Reg); - genConvertSmallIntegerToIntegerInReg(Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, 1, Arg1Reg); - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), TempReg); - genGetNumSlotsOfinto(ReceiverResultReg, nSlotsOrBytesReg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction1 = genoperandoperand(CmpCqR, firstByteFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsBytes = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction2 = genoperandoperand(CmpCqR, arrayFormat(), formatReg); - /* begin JumpZero: */ - jumpIsArray = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin JumpBelow: */ - jumpNotIndexable = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - weakArrayFormat(); - anInstruction3 = genoperandoperand(CmpCqR, weakArrayFormat(), formatReg); - /* begin JumpBelowOrEqual: */ - jumpHasFixedFields = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstShortFormat(); - anInstruction4 = genoperandoperand(CmpCqR, firstShortFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsShorts = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction5 = genoperandoperand(CmpCqR, firstLongFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsWords = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - jmpTarget(jumpNotIndexable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin Jump: */ - jumpNotIndexable = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpIsArray, (assert(!((Arg1Reg == SPReg))), - genoperandoperand(CmpRR, Arg1Reg, nSlotsOrBytesReg))); - /* begin JumpBelowOrEqual: */ - jumpArrayOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddCq:R: */ - anInstruction6 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg1Reg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, Arg1Reg, ReceiverResultReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsBytes, genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), nSlotsOrBytesReg)); - gAndCqRR(BytesPerWord - 1, formatReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, nSlotsOrBytesReg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpBytesOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction7 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsMethod = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(AddCqR, BaseHeaderSize, Arg1Reg); - methodInBounds = anInstruction8; - if (signedVersion) { - /* begin MoveXbr:R:R: */ - genoperandoperandoperand(MoveXbrRR, Arg1Reg, ReceiverResultReg, ReceiverResultReg); - } - else { - - /* formatReg already contains a value <= 16r1f, so no need to zero it */ - /* begin MoveXbr:R:R: */ - genoperandoperandoperand(MoveXbrRR, Arg1Reg, ReceiverResultReg, formatReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, formatReg, ReceiverResultReg); - } - if (signedVersion) { - /* begin SignExtend8R:R: */ - /* begin LogicalShiftLeftCq:R: */ - first = genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 8, ReceiverResultReg); - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, (BytesPerWord * 8) - 8, ReceiverResultReg); - goto l8; - l8: /* end SignExtend8R:R: */; - } - /* begin Label */ - convertToIntAndReturn = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - genConvertIntegerToSmallIntegerInReg(ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsShorts, gLogicalShiftLeftCqR((shiftForWord()) - 1, nSlotsOrBytesReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(AndCqR, 1, formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, nSlotsOrBytesReg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpShortsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg1Reg, ReceiverResultReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg1Reg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveM16rR, BaseHeaderSize, ReceiverResultReg, ReceiverResultReg); - if (signedVersion) { - /* begin SignExtend16R:R: */ - /* begin LogicalShiftLeftCq:R: */ - first1 = genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 16, ReceiverResultReg); - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, (BytesPerWord * 8) - 16, ReceiverResultReg); - goto l13; - l13: /* end SignExtend16R:R: */; - } - /* begin Jump: */ - genoperand(Jump, ((sqInt)convertToIntAndReturn)); - jmpTarget(jumpIsWords, (assert(!((Arg1Reg == SPReg))), - genoperandoperand(CmpRR, Arg1Reg, nSlotsOrBytesReg))); - /* begin JumpBelowOrEqual: */ - jumpWordsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddCq:R: */ - anInstruction11 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg1Reg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, Arg1Reg, ReceiverResultReg, TempReg); - jumpWordTooBig = jumpNotSmallIntegerUnsignedValueInRegister(TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)convertToIntAndReturn)); - jmpTarget(jumpHasFixedFields, checkQuickConstantforInstruction(classIndexMask(), genoperandoperand(AndCqR, classIndexMask(), TempReg))); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, formatReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, TempReg); - /* begin JumpZero: */ - jumpIsContext = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin PushR: */ - genoperand(PushR, nSlotsOrBytesReg); - genGetClassObjectOfClassIndexintoscratchReg(formatReg, nSlotsOrBytesReg, TempReg); - genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, nSlotsOrBytesReg, formatReg); - /* begin PopR: */ - genoperand(PopR, nSlotsOrBytesReg); - genConvertSmallIntegerToIntegerInReg(formatReg); - /* begin checkQuickConstant:forInstruction: */ - fixedFieldsOfClassFormatMask(); - anInstruction13 = genoperandoperand(AndCqR, fixedFieldsOfClassFormatMask(), formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, nSlotsOrBytesReg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpFixedFieldsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddR:R: */ - genoperandoperand(AddRR, formatReg, Arg1Reg); - /* begin AddCq:R: */ - anInstruction14 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg1Reg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, Arg1Reg, ReceiverResultReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsMethod, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - getLiteralCountOfplusOneinBytesintoscratch(ReceiverResultReg, 1, 1, nSlotsOrBytesReg, TempReg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, nSlotsOrBytesReg); - /* begin JumpBelow: */ - genConditionalBranchoperand(JumpBelow, ((sqInt)methodInBounds)); - jmpTarget(jumpWordTooBig, jmpTarget(jumpFixedFieldsOutOfBounds, jmpTarget(jumpArrayOutOfBounds, jmpTarget(jumpBytesOutOfBounds, jmpTarget(jumpShortsOutOfBounds, jmpTarget(jumpWordsOutOfBounds, jmpTarget(jumpNotIndexable, jmpTarget(jumpIsContext, jmpTarget(jumpBadIndex, jmpTarget(jumpImmediate, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))))))))); - return 0; -} - - -/* Arguably we should fail for immediates, but so far no one has complained, - so... - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveIdentityHash */ -static sqInt -genPrimitiveIdentityHash(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction * inst; - AbstractInstruction *jumpImm; - AbstractInstruction *jumpNotSet; - AbstractInstruction *jumpSI; - AbstractInstruction * ret; - - jumpImm = genJumpImmediate(ReceiverResultReg); - genGetHashFieldNonImmOfasSmallIntegerInto(ReceiverResultReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, ConstZero, TempReg); - /* begin JumpZero: */ - jumpNotSet = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - ret = genoperand(RetN, 0); - } - else { - /* begin RetN: */ - ret = genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpImm, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - jumpSI = genJumpSmallInteger(ReceiverResultReg); - jmpTarget(jumpSI, ret); - genConvertCharacterToSmallIntegerInReg(ReceiverResultReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)ret)); - jmpTarget(jumpNotSet, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (!(primitiveIndex == 75)) { - return 0; - } - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceNewHashTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin PopR: */ - genoperand(PopR, LinkReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - return UnfailingPrimitive; -} - - -/* :Assume the receiuver is never a SmallInteger. One would use ^self for - that. - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveImmediateAsInteger */ -static sqInt -genPrimitiveImmediateAsInteger(void) -{ - genConvertCharacterToSmallIntegerInReg(ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - return UnfailingPrimitive; -} - - -/* Implement primitiveNew for convenient cases: - - the receiver has a hash - - the receiver is fixed size (excluding ephemerons to save instructions & - miniscule time) - - single word header/num slots < numSlotsMask - - the result fits in eden (actually below scavengeThreshold) - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveNew */ -static sqInt -genPrimitiveNew(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt byteSizeReg; - AbstractInstruction *fillLoop; - sqInt fillReg; - sqInt halfHeaderReg; - sqInt instSpecReg; - AbstractInstruction *jumpHasSlots; - AbstractInstruction *jumpNoSpace; - AbstractInstruction *jumpTooBig; - AbstractInstruction *jumpUnhashed; - AbstractInstruction *jumpVariableOrEphemeron; - sqInt quickConstant; - sqInt quickConstant1; - AbstractInstruction *skip; - - if (methodOrBlockNumArgs != 0) { - return UnimplementedPrimitive; - } - - /* inst spec will hold class's instance specification, then byte size and finally end of new object. */ - halfHeaderReg = (fillReg = SendNumArgsReg); - - /* get freeStart as early as possible so as not to wait later... */ - instSpecReg = (byteSizeReg = ClassReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction = genoperandoperand(MoveAwR, freeStartAddress(), Arg1Reg); - genGetHashFieldNonImmOfinto(ReceiverResultReg, halfHeaderReg); - /* begin JumpZero: */ - jumpUnhashed = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, ReceiverResultReg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, instSpecReg); - /* begin LogicalShiftRightCq:R: */ - quickConstant = fixedFieldsFieldWidth(); - genoperandoperand(LogicalShiftRightCqR, quickConstant, TempReg); - /* begin checkQuickConstant:forInstruction: */ - formatMask(); - anInstruction1 = genoperandoperand(AndCqR, formatMask(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - fixedFieldsOfClassFormatMask(); - anInstruction2 = genoperandoperand(AndCqR, fixedFieldsOfClassFormatMask(), instSpecReg); - /* begin checkQuickConstant:forInstruction: */ - nonIndexablePointerFormat(); - anInstruction3 = genoperandoperand(CmpCqR, nonIndexablePointerFormat(), TempReg); - /* begin JumpAbove: */ - jumpVariableOrEphemeron = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - numSlotsMask(); - anInstruction4 = genoperandoperand(CmpCqR, numSlotsMask(), instSpecReg); - /* begin JumpAboveOrEqual: */ - jumpTooBig = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - quickConstant1 = formatShift(); - genoperandoperand(LogicalShiftLeftCqR, quickConstant1, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, halfHeaderReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(MoveRMwr, halfHeaderReg, 0, Arg1Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instSpecReg, halfHeaderReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(CmpCqR, 0, byteSizeReg); - /* begin JumpNonZero: */ - jumpHasSlots = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(MoveCqR, BaseHeaderSize * 2, byteSizeReg); - /* begin Jump: */ - skip = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpHasSlots, genoperandoperand(MoveRR, byteSizeReg, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(AndCqR, 1, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, byteSizeReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(AddCqR, BaseHeaderSize / BytesPerWord, byteSizeReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), byteSizeReg); - jmpTarget(skip, genoperandoperand(LogicalShiftLeftCqR, numSlotsHalfShift(), halfHeaderReg)); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg1Reg, byteSizeReg); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction10 = genoperandoperand(CmpCqR, getScavengeThreshold(), byteSizeReg); - /* begin JumpAboveOrEqual: */ - jumpNoSpace = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction11 = genoperandoperand(MoveRAw, byteSizeReg, freeStartAddress()); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveRMwr, halfHeaderReg, 4, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperandoperand(LoadEffectiveAddressMwrR, BaseHeaderSize, ReceiverResultReg, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - nilObject(); - anInstruction14 = genoperandoperand(MoveCqR, nilObject(), fillReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperandoperand(MoveRMwr, fillReg, 0, Arg1Reg); - fillLoop = anInstruction15; - /* begin checkQuickConstant:forInstruction: */ - anInstruction16 = genoperandoperandoperand(MoveRMwr, fillReg, 4, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperand(AddCqR, 8, Arg1Reg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, byteSizeReg); - /* begin JumpAbove: */ - genConditionalBranchoperand(JumpAbove, ((sqInt)fillLoop)); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpUnhashed, jmpTarget(jumpVariableOrEphemeron, jmpTarget(jumpTooBig, jmpTarget(jumpNoSpace, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))); - return 0; -} - - -/* Implement primitiveNewWithArg for convenient cases: - - the receiver has a hash - - the receiver is variable and not compiled method - - single word header/num slots < numSlotsMask - - the result fits in eden - See superclass method for dynamic frequencies of formats. - For the moment we implement only arrayFormat, firstByteFormat & - firstLongFormat - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveNewWithArg */ -static sqInt -genPrimitiveNewWithArg(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction22; - AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt byteSizeReg; - AbstractInstruction *fillLoop; - sqInt fillReg; - sqInt halfHeaderReg; - sqInt instSpecReg; - AbstractInstruction *jumpArrayFormat; - AbstractInstruction *jumpArrayTooBig; - AbstractInstruction *jumpByteFormat; - AbstractInstruction *jumpBytePrepDone; - AbstractInstruction *jumpByteTooBig; - AbstractInstruction *jumpFailCuzFixed; - AbstractInstruction *jumpHasSlots; - AbstractInstruction *jumpLongPrepDone; - AbstractInstruction *jumpLongTooBig; - AbstractInstruction *jumpNElementsNonInt; - AbstractInstruction *jumpNoSpace; - AbstractInstruction *jumpUnhashed; - sqInt maxSlots; - sqInt quickConstant; - sqInt quickConstant1; - sqInt quickConstant2; - AbstractInstruction *skip; - - if (methodOrBlockNumArgs != 1) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - - /* inst spec will hold class's instance specification and then byte size and finally numSlots half of header */ - halfHeaderReg = (fillReg = SendNumArgsReg); - - /* The max slots we'll allocate here are those for a single header */ - instSpecReg = (byteSizeReg = ClassReg); - - /* get freeStart as early as possible so as not to wait later... */ - maxSlots = (numSlotsMask()) - 1; - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction = genoperandoperand(MoveAwR, freeStartAddress(), Arg1Reg); - genGetHashFieldNonImmOfinto(ReceiverResultReg, halfHeaderReg); - /* begin JumpZero: */ - jumpUnhashed = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - - /* get class's format inst var for inst spec (format field) */ - jumpNElementsNonInt = genJumpNotSmallInteger(Arg0Reg); - genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, ReceiverResultReg, instSpecReg); - /* begin LogicalShiftRightCq:R: */ - quickConstant = (fixedFieldsFieldWidth()) + 1 /* numSmallIntegerTagBits */; - genoperandoperand(LogicalShiftRightCqR, quickConstant, instSpecReg); - /* begin checkQuickConstant:forInstruction: */ - formatMask(); - anInstruction1 = genoperandoperand(AndCqR, formatMask(), instSpecReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instSpecReg, TempReg); - /* begin LogicalShiftLeftCq:R: */ - quickConstant1 = formatShift(); - genoperandoperand(LogicalShiftLeftCqR, quickConstant1, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, halfHeaderReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction2 = genoperandoperand(CmpCqR, arrayFormat(), instSpecReg); - /* begin JumpZero: */ - jumpArrayFormat = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction3 = genoperandoperand(CmpCqR, firstByteFormat(), instSpecReg); - /* begin JumpZero: */ - jumpByteFormat = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction4 = genoperandoperand(CmpCqR, firstLongFormat(), instSpecReg); - /* begin JumpNonZero: */ - jumpFailCuzFixed = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)maxSlots << 1) | 1); - anInstruction5 = genoperandoperand(CmpCqR, (((usqInt)maxSlots << 1) | 1), Arg0Reg); - /* begin JumpAbove: */ - jumpLongTooBig = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, instSpecReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperand(PushCq, 0); - /* begin Jump: */ - jumpLongPrepDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpByteFormat, checkQuickConstantforInstruction((((usqInt)(maxSlots * BytesPerWord) << 1) | 1), genoperandoperand(CmpCqR, (((usqInt)(maxSlots * BytesPerWord) << 1) | 1), Arg0Reg))); - /* begin JumpAbove: */ - jumpByteTooBig = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, instSpecReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(MoveCqR, BytesPerWord, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, instSpecReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(AndCqR, BytesPerWord - 1, TempReg); - /* begin LogicalShiftLeftCq:R: */ - quickConstant2 = formatShift(); - genoperandoperand(LogicalShiftLeftCqR, quickConstant2, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, halfHeaderReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(AddCqR, BytesPerWord - 1, instSpecReg); - /* begin LogicalShiftRightCq:R: */ - genoperandoperand(LogicalShiftRightCqR, shiftForWord(), instSpecReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperand(PushCq, 0); - /* begin Jump: */ - jumpBytePrepDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpArrayFormat, checkQuickConstantforInstruction((((usqInt)maxSlots << 1) | 1), genoperandoperand(CmpCqR, (((usqInt)maxSlots << 1) | 1), Arg0Reg))); - /* begin JumpAbove: */ - jumpArrayTooBig = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, instSpecReg); - /* begin checkLiteral:forInstruction: */ - nilObject(); - anInstruction11 = genoperand(PushCw, nilObject()); - jmpTarget(jumpBytePrepDone, jmpTarget(jumpLongPrepDone, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveRMwr, halfHeaderReg, 0, Arg1Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instSpecReg, halfHeaderReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperand(CmpCqR, 0, byteSizeReg); - /* begin JumpNonZero: */ - jumpHasSlots = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(MoveCqR, BaseHeaderSize * 2, byteSizeReg); - /* begin Jump: */ - skip = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpHasSlots, genoperandoperand(MoveRR, byteSizeReg, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperand(AndCqR, 1, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, byteSizeReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction16 = genoperandoperand(AddCqR, BaseHeaderSize / BytesPerWord, byteSizeReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), byteSizeReg); - jmpTarget(skip, genoperandoperand(LogicalShiftLeftCqR, numSlotsHalfShift(), halfHeaderReg)); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg1Reg, byteSizeReg); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction17 = genoperandoperand(CmpCqR, getScavengeThreshold(), byteSizeReg); - /* begin JumpAboveOrEqual: */ - jumpNoSpace = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction18 = genoperandoperand(MoveRAw, byteSizeReg, freeStartAddress()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperandoperand(MoveRMwr, halfHeaderReg, 4, ReceiverResultReg); - /* begin PopR: */ - genoperand(PopR, fillReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperandoperand(LoadEffectiveAddressMwrR, BaseHeaderSize, ReceiverResultReg, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperandoperand(MoveRMwr, fillReg, 0, Arg1Reg); - fillLoop = anInstruction21; - /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperandoperand(MoveRMwr, fillReg, 4, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction23 = genoperandoperand(AddCqR, 8, Arg1Reg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, byteSizeReg); - /* begin JumpAbove: */ - genConditionalBranchoperand(JumpAbove, ((sqInt)fillLoop)); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNoSpace, genoperand(PopR, TempReg)); - jmpTarget(jumpUnhashed, jmpTarget(jumpFailCuzFixed, jmpTarget(jumpArrayTooBig, jmpTarget(jumpByteTooBig, jmpTarget(jumpLongTooBig, jmpTarget(jumpNElementsNonInt, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))))); - return 0; -} - - -/* Implement primitiveShallowCopy/primitiveClone for convenient cases: - - the receiver is not a context - - the receiver is not a compiled method - - the result fits in eden (actually below scavengeThreshold) */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveShallowCopy */ -static sqInt -genPrimitiveShallowCopy(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction22; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - AbstractInstruction *continuance; - AbstractInstruction *copyLoop; - sqInt formatReg; - AbstractInstruction * jumpEmpty; - AbstractInstruction *jumpImmediate; - AbstractInstruction *jumpIsMethod; - AbstractInstruction *jumpNoSpace; - AbstractInstruction *jumpTooBig; - AbstractInstruction *jumpVariable; - sqInt ptrReg; - sqInt quickConstant; - sqInt quickConstant1; - sqInt resultReg; - sqInt slotsReg; - - jumpImmediate = genJumpImmediate(ReceiverResultReg); - resultReg = Arg0Reg; - - /* get freeStart as early as possible so as not to wait later... */ - slotsReg = Arg1Reg; - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction = genoperandoperand(MoveAwR, freeStartAddress(), resultReg); - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (ptrReg = (formatReg = SendNumArgsReg)), NoReg); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction1 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsMethod = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - indexablePointersFormat(); - anInstruction2 = genoperandoperand(CmpCqR, indexablePointersFormat(), formatReg); - /* begin JumpZero: */ - jumpVariable = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin Label */ - continuance = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - genGetRawSlotSizeOfNonImminto(ReceiverResultReg, slotsReg); - /* begin checkQuickConstant:forInstruction: */ - numSlotsMask(); - anInstruction3 = genoperandoperand(CmpCqR, numSlotsMask(), slotsReg); - /* begin JumpZero: */ - jumpTooBig = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, 0, slotsReg); - /* begin JumpZero: */ - jumpEmpty = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, slotsReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(AndCqR, 1, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, slotsReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(AddCqR, BaseHeaderSize / BytesPerWord, slotsReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), slotsReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, resultReg, slotsReg); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction7 = genoperandoperand(CmpCqR, getScavengeThreshold(), slotsReg); - /* begin JumpAboveOrEqual: */ - jumpNoSpace = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, resultReg, ptrReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction8 = genoperandoperand(MoveRAw, slotsReg, freeStartAddress()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(SubCqR, BytesPerWord * 2, slotsReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveMwrR, 0, ReceiverResultReg, TempReg); - /* begin AndCq:R: */ - quickConstant = (((sqInt)((usqInt)((formatMask())) << (formatShift())))) + (classIndexMask()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperand(AndCqR, quickConstant, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveRMwr, TempReg, 0, resultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperandoperand(MoveMwrR, BytesPerWord, ReceiverResultReg, TempReg); - /* begin AndCq:R: */ - quickConstant1 = ((sqInt)((usqInt)((numSlotsMask())) << (numSlotsHalfShift()))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(AndCqR, quickConstant1, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperandoperand(MoveRMwr, TempReg, BytesPerWord, resultReg); - /* begin Label */ - copyLoop = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - /* begin checkQuickConstant:forInstruction: */ - anInstruction16 = genoperandoperand(AddCqR, BytesPerWord * 2, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperand(AddCqR, BytesPerWord * 2, ptrReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction18 = genoperandoperandoperand(MoveMwrR, 0, ReceiverResultReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperandoperand(MoveRMwr, TempReg, 0, ptrReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperandoperand(MoveMwrR, BytesPerWord, ReceiverResultReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperandoperand(MoveRMwr, TempReg, BytesPerWord, ptrReg); - /* begin CmpR:R: */ - assert(!((ptrReg == SPReg))); - genoperandoperand(CmpRR, ptrReg, slotsReg); - /* begin JumpAbove: */ - genConditionalBranchoperand(JumpAbove, ((sqInt)copyLoop)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, resultReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpVariable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genGetClassIndexOfNonImminto(ReceiverResultReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, ClassReg); - /* begin JumpNonZero: */ - genConditionalBranchoperand(JumpNonZero, ((sqInt)continuance)); - jmpTarget(jumpImmediate, jmpTarget(jumpNoSpace, jmpTarget(jumpIsMethod, jmpTarget(jumpTooBig, jmpTarget(jumpEmpty, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))))); - return 0; -} - - -/* c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: - fixedFieldsOf:format:length: - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveStringAt */ -static sqInt -genPrimitiveStringAt(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - AbstractInstruction *done; - sqInt formatReg; - AbstractInstruction *jumpBadIndex; - AbstractInstruction *jumpBytesOutOfBounds; - AbstractInstruction *jumpIsBytes; - AbstractInstruction *jumpIsShorts; - AbstractInstruction *jumpNotIndexable; - AbstractInstruction *jumpShortsOutOfBounds; - AbstractInstruction *jumpWordsDone; - AbstractInstruction *jumpWordsOutOfBounds; - AbstractInstruction *jumpWordTooBig; - - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, Arg1Reg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpBadIndex = genJumpNotSmallInteger(Arg0Reg); - genConvertSmallIntegerToIntegerInReg(Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(SubCqR, 1, Arg1Reg); - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), NoReg); - genGetNumSlotsOfinto(ReceiverResultReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction2 = genoperandoperand(CmpCqR, firstByteFormat(), formatReg); - /* begin JumpGreaterOrEqual: */ - jumpIsBytes = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstShortFormat(); - anInstruction3 = genoperandoperand(CmpCqR, firstShortFormat(), formatReg); - /* begin JumpGreaterOrEqual: */ - jumpIsShorts = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction4 = genoperandoperand(CmpCqR, firstLongFormat(), formatReg); - /* begin JumpLess: */ - jumpNotIndexable = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, ClassReg); - /* begin JumpBelowOrEqual: */ - jumpWordsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddCq:R: */ - anInstruction5 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg1Reg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, Arg1Reg, ReceiverResultReg, TempReg); - jumpWordTooBig = jumpNotCharacterUnsignedValueInRegister(TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - /* begin Jump: */ - jumpWordsDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpIsBytes, genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), ClassReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(AndCqR, BytesPerWord - 1, formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, ClassReg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, ClassReg); - /* begin JumpBelowOrEqual: */ - jumpBytesOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(AddCqR, BaseHeaderSize, Arg1Reg); - /* begin MoveXbr:R:R: */ - genoperandoperandoperand(MoveXbrRR, Arg1Reg, ReceiverResultReg, ReceiverResultReg); - /* begin AndCq:R: */ - anInstruction = genoperandoperand(AndCqR, 0xFF, ReceiverResultReg); - jmpTarget(jumpWordsDone, (done = genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - genConvertIntegerToCharacterInReg(ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsShorts, gLogicalShiftLeftCqR((shiftForWord()) - 1, ClassReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(AndCqR, (BytesPerWord / 1) - 1, formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, ClassReg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, ClassReg); - /* begin JumpBelowOrEqual: */ - jumpShortsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg1Reg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperandoperand(MoveM16rR, BaseHeaderSize, ReceiverResultReg, ReceiverResultReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)done)); - jmpTarget(jumpWordTooBig, jmpTarget(jumpBytesOutOfBounds, jmpTarget(jumpShortsOutOfBounds, jmpTarget(jumpWordsOutOfBounds, jmpTarget(jumpNotIndexable, jmpTarget(jumpBadIndex, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))))); - return CompletePrimitive; -} - - -/* c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: - fixedFieldsOf:format:length: - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveStringAtPut */ -static sqInt -genPrimitiveStringAtPut(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt formatReg; - AbstractInstruction *jumpBadArg; - AbstractInstruction *jumpBadIndex; - AbstractInstruction *jumpBytesOutOfBounds; - AbstractInstruction *jumpBytesOutOfRange; - AbstractInstruction * jumpImmutable; - AbstractInstruction *jumpIsBytes; - AbstractInstruction * jumpIsCompiledMethod; - AbstractInstruction *jumpIsShorts; - AbstractInstruction * jumpNotString; - AbstractInstruction *jumpShortsOutOfBounds; - AbstractInstruction *jumpShortsOutOfRange; - AbstractInstruction *jumpWordsOutOfBounds; - AbstractInstruction *jumpWordsOutOfRange; - - jumpImmutable = ((AbstractInstruction *) 0); - /* begin genLoadArgAtDepth:into: */ - assert(1 < (numRegArgs())); - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - jumpBadIndex = genJumpNotSmallInteger(Arg0Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - jumpBadArg = genJumpNotCharacterInScratchReg(TempReg); - genConvertSmallIntegerToIntegerInReg(Arg0Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, 1, Arg0Reg); -# if IMMUTABILITY - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), TempReg); - /* begin genJumpBaseHeaderImmutable: */ - immutableBitMask(); - anInstruction12 = genoperandoperand(TstCqR, immutableBitMask(), TempReg); - /* begin JumpNonZero: */ - jumpImmutable = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -# else // IMMUTABILITY - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), NoReg); -# endif // IMMUTABILITY - genGetNumSlotsOfinto(ReceiverResultReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction1 = genoperandoperand(CmpCqR, firstLongFormat(), formatReg); - /* begin JumpBelow: */ - jumpNotString = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction2 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsCompiledMethod = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction3 = genoperandoperand(CmpCqR, firstByteFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsBytes = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstShortFormat(); - anInstruction4 = genoperandoperand(CmpCqR, firstShortFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsShorts = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(CmpCqR, 0, Arg1Reg); - /* begin JumpLess: */ - jumpWordsOutOfRange = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, ClassReg); - /* begin JumpBelowOrEqual: */ - jumpWordsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertCharacterToCodeInReg(TempReg); - /* begin AddCq:R: */ - anInstruction6 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg0Reg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, TempReg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsShorts, gCmpCqR(characterObjectOf(0xFFFF), Arg1Reg)); - /* begin JumpAbove: */ - jumpShortsOutOfRange = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (shiftForWord()) - 1, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(AndCqR, (BytesPerWord / 2) - 1, formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, ClassReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, ClassReg); - /* begin JumpBelowOrEqual: */ - jumpShortsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertCharacterToCodeInReg(TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperandoperand(MoveRM16r, TempReg, BaseHeaderSize, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsBytes, gCmpCqR(characterObjectOf(0xFF), Arg1Reg)); - /* begin JumpAbove: */ - jumpBytesOutOfRange = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(AndCqR, BytesPerWord - 1, formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, ClassReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, ClassReg); - /* begin JumpBelowOrEqual: */ - jumpBytesOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertCharacterToCodeInReg(TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperand(AddCqR, BaseHeaderSize, Arg0Reg); - /* begin MoveR:Xbr:R: */ - genoperandoperandoperand(MoveRXbrR, TempReg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotString, jmpTarget(jumpBytesOutOfRange, jmpTarget(jumpShortsOutOfRange, jmpTarget(jumpWordsOutOfRange, jmpTarget(jumpIsCompiledMethod, jmpTarget(jumpBytesOutOfBounds, jmpTarget(jumpShortsOutOfBounds, jmpTarget(jumpWordsOutOfBounds, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))))))); -# if IMMUTABILITY - jmpTarget(jumpImmutable, ((AbstractInstruction *) (((jumpNotString->operands))[0]))); -# endif - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperand(AddCqR, 1, Arg0Reg); - genConvertIntegerToSmallIntegerInReg(Arg0Reg); - jmpTarget(jumpBadArg, jmpTarget(jumpBadIndex, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - /* CogObjectRepresentationFor32BitSpur>>#genRemoveSmallIntegerTagsInScratchReg: */ -static sqInt NoDbgRegParms -genRemoveSmallIntegerTagsInScratchReg(sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, 1, scratchReg); - return 0; -} - - /* CogObjectRepresentationFor32BitSpur>>#genShiftAwaySmallIntegerTagsInScratchReg: */ -static sqInt NoDbgRegParms -genShiftAwaySmallIntegerTagsInScratchReg(sqInt scratchReg) -{ - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, 1, scratchReg); - return 0; -} - - -/* Get the literal count of a CompiledMethod into headerReg, plus one if - requested. If inBytes is true, scale the count by the word size. Deal with - the possibility of - the method being cogged. */ - - /* CogObjectRepresentationFor32BitSpur>>#getLiteralCountOf:plusOne:inBytes:into:scratch: */ -static sqInt NoDbgRegParms -getLiteralCountOfplusOneinBytesintoscratch(sqInt methodReg, sqInt plusOne, sqInt inBytes, sqInt litCountReg, sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - sqInt quickConstant; - sqInt quickConstant1; - - genGetMethodHeaderOfintoscratch(methodReg, litCountReg, scratchReg); - if (inBytes) { - /* begin AndCq:R: */ - quickConstant = ((sqInt)((usqInt)((alternateHeaderNumLiteralsMask())) << 1)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, quickConstant, litCountReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, 1, litCountReg); - } - else { - /* begin LogicalShiftRightCq:R: */ - genoperandoperand(LogicalShiftRightCqR, 1, litCountReg); - /* begin checkQuickConstant:forInstruction: */ - alternateHeaderNumLiteralsMask(); - anInstruction1 = genoperandoperand(AndCqR, alternateHeaderNumLiteralsMask(), litCountReg); - } - if (plusOne) { - /* begin AddCq:R: */ - quickConstant1 = (inBytes - ? BytesPerWord - : 1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AddCqR, quickConstant1, litCountReg); - } - return 0; -} - - -/* Answer the relevant inline cache tag for an instance. - c.f. getInlineCacheClassTagFrom:into: & inlineCacheTagForClass: */ - - /* CogObjectRepresentationFor32BitSpur>>#inlineCacheTagForInstance: */ -static sqInt NoDbgRegParms -inlineCacheTagForInstance(sqInt oop) -{ - return (isImmediate(oop) - ? oop & 1 - : classIndexOf(oop)); -} - - /* CogObjectRepresentationFor32BitSpur>>#jumpNotSmallIntegerUnsignedValueInRegister: */ -static AbstractInstruction * NoDbgRegParms -jumpNotSmallIntegerUnsignedValueInRegister(sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0x3FFFFFFF, reg); - /* begin JumpAbove: */ - return genConditionalBranchoperand(JumpAbove, ((sqInt)0)); -} - - -/* Mark and trace a literal in an inline cache preceding address in - cogMethodOrNil. Answer if code was modified. */ - - /* CogObjectRepresentationFor32BitSpur>>#markAndTraceCacheTagLiteral:in:atpc: */ -static sqInt NoDbgRegParms -markAndTraceCacheTagLiteralinatpc(sqInt literal, CogMethod *cogMethodOrNil, usqInt address) -{ - sqInt objOop; - - if (!(couldBeObject(literal))) { - return 0; - } - assert(addressCouldBeObj(literal)); - if (!(isForwarded(literal))) { - markAndTrace(literal); - return 0; - } - objOop = followForwarded(literal); - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheTagat(backEnd(), objOop, address); - markAndTraceUpdatedLiteralin(objOop, cogMethodOrNil); - return 1; -} - - /* CogObjectRepresentationFor32BitSpur>>#numSmallIntegerBits */ -static sqInt -numSmallIntegerBits(void) -{ - return 0x1F; -} - - -/* The two valid tag patterns are 0 (Character) and 1 (SmallInteger) */ - - /* CogObjectRepresentationFor32BitSpur>>#validInlineCacheTag: */ -static sqInt NoDbgRegParms -validInlineCacheTag(usqInt classIndexOrTagPattern) -{ - return (classIndexOrTagPattern <= 1) - || ((classAtIndex(classIndexOrTagPattern)) != null); -} - - /* CogObjectRepresentationForSpur>>#callStoreCheckTrampoline */ -static void -callStoreCheckTrampoline(void) -{ - AbstractInstruction *abstractInstruction; - - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceStoreCheckTrampoline); - (abstractInstruction->annotation = IsRelativeCall); -} - - /* CogObjectRepresentationForSpur>>#checkValidDerivedObjectReference: */ -static sqInt NoDbgRegParms -checkValidDerivedObjectReference(sqInt bodyAddress) -{ - return (heapMapAtWord(pointerForOop(bodyAddress - BaseHeaderSize))) != 0; -} - - /* CogObjectRepresentationForSpur>>#checkValidOopReference: */ -static sqInt NoDbgRegParms -checkValidOopReference(sqInt anOop) -{ - return (isImmediate(anOop)) - || ((heapMapAtWord(pointerForOop(anOop))) != 0); -} - - /* CogObjectRepresentationForSpur>>#couldBeDerivedObject: */ -static sqInt NoDbgRegParms -couldBeDerivedObject(sqInt bodyAddress) -{ - return oopisGreaterThanOrEqualTo(bodyAddress - BaseHeaderSize, startOfMemory()); -} - - /* CogObjectRepresentationForSpur>>#couldBeObject: */ -static sqInt NoDbgRegParms -couldBeObject(sqInt literal) -{ - return (isNonImmediate(literal)) - && (oopisGreaterThanOrEqualTo(literal, startOfMemory())); -} - - -/* Create a trampoline to answer the active context that will - answer it if a frame is already married, and create it otherwise. - Assume numArgs is in SendNumArgsReg and ClassReg is free. */ - - /* CogObjectRepresentationForSpur>>#genActiveContextTrampolineLarge:inBlock:called: */ -static usqInt NoDbgRegParms -genActiveContextTrampolineLargeinBlockcalled(sqInt isLarge, sqInt isInBlock, char *aString) -{ - usqInt startAddress; - - startAddress = methodZoneBase(); - zeroOpcodeIndex(); - genGetActiveContextLargeinBlock(isLarge, isInBlock); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress(aString, startAddress); - recordRunTimeObjectReferences(); - return startAddress; -} - - -/* Check the remembered bit of the object in objReg; answer the jump taken if - the bit is already set. - Only need to fetch the byte containing it, which reduces the size of the - mask constant. - */ - - /* CogObjectRepresentationForSpur>>#genCheckRememberedBitOf:scratch: */ -static AbstractInstruction * NoDbgRegParms -genCheckRememberedBitOfscratch(sqInt objReg, sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt mask; - sqInt rememberedBitByteOffset; - - rememberedBitByteOffset = (rememberedBitShift()) / 8; - mask = 1U << ((rememberedBitShift()) % 8); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMbrR, rememberedBitByteOffset, objReg, scratchReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(TstCqR, mask, scratchReg); - /* begin JumpNonZero: */ - return genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -} - - /* CogObjectRepresentationForSpur>>#genConvertCharacterToCodeInReg: */ -static sqInt NoDbgRegParms -genConvertCharacterToCodeInReg(sqInt reg) -{ - sqInt quickConstant; - - /* begin LogicalShiftRightCq:R: */ - quickConstant = numTagBits(); - genoperandoperand(LogicalShiftRightCqR, quickConstant, reg); - return 0; -} - - /* CogObjectRepresentationForSpur>>#genConvertIntegerToCharacterInReg: */ -static sqInt NoDbgRegParms -genConvertIntegerToCharacterInReg(sqInt reg) -{ - AbstractInstruction *anInstruction; - sqInt quickConstant; - - /* begin LogicalShiftLeftCq:R: */ - quickConstant = numTagBits(); - genoperandoperand(LogicalShiftLeftCqR, quickConstant, reg); - /* begin checkQuickConstant:forInstruction: */ - characterTag(); - anInstruction = genoperandoperand(AddCqR, characterTag(), reg); - return 0; -} - - -/* Create a closure with the given startpc, numArgs and numCopied - within a context with ctxtNumArgs, large if isLargeCtxt that is in a - block if isInBlock. If numCopied > 0 pop those values off the stack. */ - - /* CogObjectRepresentationForSpur>>#genCreateClosureAt:numArgs:numCopied:contextNumArgs:large:inBlock: */ -static sqInt NoDbgRegParms -genCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(sqInt bcpc, sqInt numArgs, sqInt numCopied, sqInt ctxtNumArgs, sqInt isLargeCtxt, sqInt isInBlock) -{ - AbstractInstruction *anInstruction; - sqInt i; - - genNoPopCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(bcpc, numArgs, numCopied, ctxtNumArgs, isLargeCtxt, isInBlock); - for (i = 1; i <= numCopied; i += 1) { - /* begin PopR: */ - genoperand(PopR, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveRMwr, TempReg, (((numCopied - i) + ClosureFirstCopiedValueIndex) * BytesPerOop) + BaseHeaderSize, ReceiverResultReg); - } - return 0; -} - - -/* Create a full closure with the given values. */ - - /* CogObjectRepresentationForSpur>>#genCreateFullClosure:numArgs:numCopied:ignoreContext:contextNumArgs:large:inBlock: */ -static sqInt NoDbgRegParms -genCreateFullClosurenumArgsnumCopiedignoreContextcontextNumArgslargeinBlock(sqInt compiledBlock, sqInt numArgs, sqInt numCopied, sqInt ignoreContext, sqInt contextNumArgs, sqInt contextIsLarge, sqInt contextIsBlock) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - usqInt byteSize; - sqInt constant; - usqLong header; - sqInt numSlots; - AbstractInstruction *skip; - - - /* First get thisContext into ReceiverResultReg and thence in ClassReg. */ - if (ignoreContext) { - /* begin genMoveConstant:R: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ClassReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperand(MoveCqR, constant, ClassReg); - } - } - else { - genGetActiveContextNumArgslargeinBlock(contextNumArgs, contextIsLarge, contextIsBlock); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, ClassReg); - } - numSlots = FullClosureFirstCopiedValueIndex + numCopied; - byteSize = smallObjectBytesForSlots(numSlots); - assert(ClassFullBlockClosureCompactIndex != 0); - header = headerForSlotsformatclassIndex(numSlots, indexablePointersFormat(), ClassFullBlockClosureCompactIndex); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction1 = genoperandoperand(MoveAwR, freeStartAddress(), ReceiverResultReg); - /* begin genStoreHeader:intoNewInstance:using: */ - anInstruction4 = genoperandoperand(MoveCqR, ((usqInt) header), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperandoperand(MoveRMwr, TempReg, 0, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, (header) >> 32, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperandoperand(MoveRMwr, TempReg, 4, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(LoadEffectiveAddressMwrR, byteSize, ReceiverResultReg, TempReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction6 = genoperandoperand(MoveRAw, TempReg, freeStartAddress()); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction7 = genoperandoperand(CmpCqR, getScavengeThreshold(), TempReg); - /* begin JumpBelow: */ - skip = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceScheduleScavengeTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperandoperand(MoveRMwr, ClassReg, (ClosureOuterContextIndex * BytesPerOop) + BaseHeaderSize, ReceiverResultReg); - if (shouldAnnotateObjectReference(compiledBlock)) { - annotateobjRef(gMoveCwR(compiledBlock, TempReg), compiledBlock); - } - else { - /* begin MoveCq:R: */ - anInstruction = genoperandoperand(MoveCqR, compiledBlock, TempReg); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperandoperand(MoveRMwr, TempReg, (ClosureStartPCIndex * BytesPerOop) + BaseHeaderSize, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)numArgs << 1) | 1); - anInstruction10 = genoperandoperand(MoveCqR, (((usqInt)numArgs << 1) | 1), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveRMwr, TempReg, (ClosureNumArgsIndex * BytesPerOop) + BaseHeaderSize, ReceiverResultReg); - return 0; -} - - -/* Make sure that the object in reg is not forwarded. This routine assumes - the object will - never be forwarded to an immediate, as it is used to unforward literal - variables (associations). - Use the fact that isForwardedObjectClassIndexPun is a power of two to save - an instruction. */ - - /* CogObjectRepresentationForSpur>>#genEnsureObjInRegNotForwarded:scratchReg: */ -static sqInt NoDbgRegParms -genEnsureObjInRegNotForwardedscratchReg(sqInt reg, sqInt scratch) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *loop; - AbstractInstruction *ok; - sqInt quickConstant; - - assert(reg != scratch); - /* begin Label */ - loop = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, reg, scratch); - /* begin AndCq:R: */ - quickConstant = (classIndexMask()) - (isForwardedObjectClassIndexPun()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, quickConstant, scratch); - /* begin JumpNonZero: */ - ok = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(0, reg, reg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)loop)); - jmpTarget(ok, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - /* CogObjectRepresentationForSpur>>#genEnsureOopInRegNotForwarded:scratchReg: */ -static sqInt NoDbgRegParms -genEnsureOopInRegNotForwardedscratchReg(sqInt reg, sqInt scratch) -{ - AbstractInstruction *instruction; - - /* begin genEnsureOopInRegNotForwarded:scratchReg:jumpBackTo: */ - instruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - return genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(reg, scratch, instruction, 0); -} - - -/* Make sure that the oop in reg is not forwarded. - Use the fact that isForwardedObjectClassIndexPun is a power of two to save - an instruction. */ -/* maybe a fixup or an instruction */ -/* maybe a fixup or an instruction */ - - /* CogObjectRepresentationForSpur>>#genEnsureOopInRegNotForwarded:scratchReg:ifForwarder:ifNotForwarder: */ -static sqInt NoDbgRegParms -genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(sqInt reg, sqInt scratch, void *fwdJumpTarget, void *nonFwdJumpTargetOrZero) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction * finished; - AbstractInstruction * imm; - AbstractInstruction * ok; - sqInt quickConstant; - - assert(reg != scratch); - - /* notionally - self genGetClassIndexOfNonImm: reg into: scratch. - cogit CmpCq: objectMemory isForwardedObjectClassIndexPun R: TempReg. - but the following is an instruction shorter: */ - imm = genJumpImmediate(reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, reg, scratch); - /* begin AndCq:R: */ - quickConstant = (classIndexMask()) - (isForwardedObjectClassIndexPun()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, quickConstant, scratch); - /* begin JumpNonZero: */ - ok = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(0, reg, reg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)fwdJumpTarget)); - if ((((usqInt)nonFwdJumpTargetOrZero)) == 0) { - /* begin Label */ - finished = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - else { - finished = nonFwdJumpTargetOrZero; - } - jmpTarget(imm, jmpTarget(ok, finished)); - return 0; -} - - -/* Make sure that the oop in reg is not forwarded, updating the slot in - objReg with the value. - */ - - /* CogObjectRepresentationForSpur>>#genEnsureOopInRegNotForwarded:scratchReg:updatingSlot:in: */ -static sqInt NoDbgRegParms -genEnsureOopInRegNotForwardedscratchRegupdatingSlotin(sqInt reg, sqInt scratch, sqInt index, sqInt objReg) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *imm; - AbstractInstruction *loop; - AbstractInstruction *ok; - sqInt quickConstant; - - - /* Open-code - self genEnsureOopInRegNotForwarded: reg - scratchReg: scratch - updatingMw: index * objectMemory wordSize + objectMemory baseHeaderSize - r: objReg. - to avoid calling the store check unless the receiver is forwarded. */ - assert((reg != scratch) - && (objReg != scratch)); - /* begin Label */ - loop = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - - /* notionally - self genGetClassIndexOfNonImm: reg into: scratch. - cogit CmpCq: objectMemory isForwardedObjectClassIndexPun R: TempReg. - but the following is an instruction shorter: */ - imm = genJumpImmediate(reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, reg, scratch); - /* begin AndCq:R: */ - quickConstant = (classIndexMask()) - (isForwardedObjectClassIndexPun()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, quickConstant, scratch); - /* begin JumpNonZero: */ - ok = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(0, reg, reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveRMwr, reg, (index * BytesPerWord) + BaseHeaderSize, objReg); - assert((reg == Arg0Reg) - && ((scratch == TempReg) - && (objReg == ReceiverResultReg))); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceStoreCheckContextReceiverTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin Jump: */ - genoperand(Jump, ((sqInt)loop)); - jmpTarget(ok, jmpTarget(imm, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return 0; -} - - -/* Do the store check. Answer the argument for the benefit of the code - generator; ReceiverResultReg may be caller-saved and hence smashed by this - call. Answering - it allows the code generator to reload ReceiverResultReg cheaply. - In Spur the only thing we leave to the run-time is adding the receiver to - the remembered set and setting its isRemembered bit. */ - - /* CogObjectRepresentationForSpur>>#generateObjectRepresentationTrampolines */ -static void -generateObjectRepresentationTrampolines(void) -{ - sqInt instVarIndex; - AbstractInstruction *jumpSC; - - -# if IMMUTABILITY - for (instVarIndex = 0; instVarIndex < NumStoreTrampolines; instVarIndex += 1) { - ceStoreTrampolines[instVarIndex] = (genStoreTrampolineCalledinstVarIndex(trampolineNamenumArgslimit("ceStoreTrampoline", instVarIndex, NumStoreTrampolines - 2), instVarIndex)); - } -# endif // IMMUTABILITY - ceNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceNewHash", 1, ReceiverResultReg, null, null, null, /* begin emptyRegisterMask */ 0, 1, ReceiverResultReg, 0); - ceInlineNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceInlineNewHash", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, ReceiverResultReg, 0); - /* begin genStoreCheckTrampoline */ - if (CheckRememberedInTrampoline) { - zeroOpcodeIndex(); - jumpSC = genCheckRememberedBitOfscratch(ReceiverResultReg, ABIResultReg); - assert(((jumpSC->opcode)) == JumpNonZero); - (jumpSC->opcode = JumpZero); - /* begin RetN: */ - genoperand(RetN, 0); - jmpTarget(jumpSC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) - ? ReceiverResultReg - : ABIResultReg), CheckRememberedInTrampoline); - ceStoreCheckContextReceiverTrampoline = genStoreCheckContextReceiverTrampoline(); - /* begin genTrampolineFor:called:regsToSave: */ - ceScheduleScavengeTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceScheduleScavenge, "ceScheduleScavengeTrampoline", 0, null, null, null, null, CallerSavedRegisterMask, 1, NoReg, 0); - ceSmallActiveContextInMethodTrampoline = genActiveContextTrampolineLargeinBlockcalled(0, 0, "ceSmallMethodContext"); - ceSmallActiveContextInBlockTrampoline = genActiveContextTrampolineLargeinBlockcalled(0, InVanillaBlock, "ceSmallBlockContext"); - ceSmallActiveContextInFullBlockTrampoline = genActiveContextTrampolineLargeinBlockcalled(0, InFullBlock, "ceSmallFullBlockContext"); - ceLargeActiveContextInMethodTrampoline = genActiveContextTrampolineLargeinBlockcalled(1, 0, "ceLargeMethodContext"); - ceLargeActiveContextInBlockTrampoline = genActiveContextTrampolineLargeinBlockcalled(1, InVanillaBlock, "ceLargeBlockContext"); - ceLargeActiveContextInFullBlockTrampoline = genActiveContextTrampolineLargeinBlockcalled(1, InFullBlock, "ceLargeFullBlockContext"); - generateLowcodeObjectTrampolines(); -} - - -/* Create a trampoline to answer the active context that will - answer it if a frame is already married, and create it otherwise. - Assume numArgs is in SendNumArgsReg and ClassReg is free. */ - - /* CogObjectRepresentationForSpur>>#genGetActiveContextLarge:inBlock: */ -static sqInt NoDbgRegParms -genGetActiveContextLargeinBlock(sqInt isLarge, sqInt isInBlock) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction22; - AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction24; - AbstractInstruction *anInstruction25; - AbstractInstruction *anInstruction26; - AbstractInstruction *anInstruction27; - AbstractInstruction *anInstruction28; - AbstractInstruction *anInstruction29; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction30; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction32; - AbstractInstruction *anInstruction33; - AbstractInstruction *anInstruction34; - AbstractInstruction *anInstruction35; - AbstractInstruction *anInstruction36; - AbstractInstruction *anInstruction37; - AbstractInstruction *anInstruction38; - AbstractInstruction *anInstruction39; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction40; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt constant; - AbstractInstruction * continuation; - AbstractInstruction * exit; - usqLong header; - AbstractInstruction * inst; - AbstractInstruction * jumpNeedScavenge; - AbstractInstruction * jumpSingle; - AbstractInstruction * loopHead; - sqInt offset; - sqInt offset1; - sqInt quickConstant; - sqInt quickConstant1; - sqInt slotSize; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, FoxMethod, FPReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(TstCqR, MFMethodFlagHasContextFlag, ClassReg); - /* begin JumpZero: */ - jumpSingle = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperandoperand(MoveMwrR, FoxThisContext, FPReg, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, 0); - jmpTarget(jumpSingle, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperand(OrCqR, MFMethodFlagHasContextFlag, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperandoperand(MoveRMwr, ClassReg, FoxMethod, FPReg); - switch (isInBlock) { - case InFullBlock: - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, 3, ClassReg); - break; - case InVanillaBlock: - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(SubCqR, 3, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveM16rR, 0, ClassReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, ClassReg); - break; - case 0: - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(SubCqR, 1, ClassReg); - break; - default: - error("Case not found and no otherwise clause"); - } - slotSize = (isLarge - ? LargeContextSlots - : SmallContextSlots); - header = headerForSlotsformatclassIndex(slotSize, indexablePointersFormat(), ClassMethodContextCompactIndex); - flag("endianness"); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction12 = genoperandoperand(MoveAwR, freeStartAddress(), ReceiverResultReg); - /* begin genStoreHeader:intoNewInstance:using: */ - anInstruction13 = genoperandoperand(MoveCqR, ((usqInt) header), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperandoperand(MoveRMwr, TempReg, 0, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperand(MoveCqR, (header) >> 32, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction31 = genoperandoperandoperand(MoveRMwr, TempReg, 4, ReceiverResultReg); - /* begin LoadEffectiveAddressMw:r:R: */ - offset = smallObjectBytesForSlots(slotSize); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperandoperand(LoadEffectiveAddressMwrR, offset, ReceiverResultReg, TempReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction16 = genoperandoperand(MoveRAw, TempReg, freeStartAddress()); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction17 = genoperandoperand(CmpCqR, getScavengeThreshold(), TempReg); - /* begin JumpAboveOrEqual: */ - jumpNeedScavenge = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin LoadEffectiveAddressMw:r:R: */ - anInstruction18 = genoperandoperandoperand(LoadEffectiveAddressMwrR, 1, FPReg, TempReg); - continuation = anInstruction18; - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperandoperand(MoveRMwr, TempReg, BaseHeaderSize + (SenderIndex * BytesPerOop), ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperandoperand(MoveMwrR, FoxSavedFP, FPReg, TempReg); - genSetSmallIntegerTagsIn(TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperandoperand(MoveRMwr, TempReg, BaseHeaderSize + (InstructionPointerIndex * BytesPerOop), ReceiverResultReg); - /* begin MoveMw:r:R: */ - offset1 = offsetof(CogMethod, methodObject); - /* begin checkQuickConstant:forInstruction: */ - anInstruction23 = genoperandoperandoperand(MoveMwrR, offset1, ClassReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction24 = genoperandoperandoperand(MoveRMwr, TempReg, BaseHeaderSize + (MethodIndex * BytesPerWord), ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction25 = genoperandoperandoperand(MoveRMwr, ReceiverResultReg, FoxThisContext, FPReg); - gSubRRR(SPReg, FPReg, TempReg); - /* begin LogicalShiftRightCq:R: */ - quickConstant = 2 /* log2BytesPerWord */; - genoperandoperand(LogicalShiftRightCqR, quickConstant, TempReg); - /* begin SubCq:R: */ - quickConstant1 = 3; - /* begin checkQuickConstant:forInstruction: */ - anInstruction26 = genoperandoperand(SubCqR, quickConstant1, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, SendNumArgsReg, TempReg); - genConvertIntegerToSmallIntegerInReg(TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction27 = genoperandoperandoperand(MoveRMwr, TempReg, BaseHeaderSize + (StackPointerIndex * BytesPerOop), ReceiverResultReg); - if (isInBlock > 0) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperandoperand(LoadEffectiveAddressMwrR, 2, SendNumArgsReg, TempReg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, TempReg, FPReg, TempReg); - } - else { - /* begin genMoveConstant:R: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, TempReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction40 = genoperandoperand(MoveCqR, constant, TempReg); - } - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction28 = genoperandoperandoperand(MoveRMwr, TempReg, BaseHeaderSize + (ClosureIndex * BytesPerOop), ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction29 = genoperandoperandoperand(MoveMwrR, FoxMFReceiver, FPReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction30 = genoperandoperandoperand(MoveRMwr, TempReg, BaseHeaderSize + (ReceiverIndex * BytesPerOop), ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction32 = genoperandoperand(MoveCqR, 1, ClassReg); - /* begin CmpR:R: */ - assert(!((SendNumArgsReg == SPReg))); - loopHead = genoperandoperand(CmpRR, SendNumArgsReg, ClassReg); - /* begin JumpGreater: */ - exit = genConditionalBranchoperand(JumpGreater, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SendNumArgsReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, ClassReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction33 = genoperandoperand(AddCqR, 2, TempReg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, TempReg, FPReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction34 = genoperandoperand(AddCqR, ReceiverIndex + (BaseHeaderSize / BytesPerWord), ClassReg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, TempReg, ClassReg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction35 = genoperandoperand(SubCqR, (ReceiverIndex + (BaseHeaderSize / BytesPerWord)) - 1, ClassReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)loopHead)); - jmpTarget(exit, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - nilObject(); - anInstruction5 = genoperandoperand(MoveCqR, nilObject(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction36 = genoperandoperandoperand(LoadEffectiveAddressMwrR, FoxMFReceiver, FPReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction37 = genoperandoperand(AddCqR, (ReceiverIndex + 1) + (BaseHeaderSize / BytesPerWord), SendNumArgsReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction38 = genoperandoperand(SubCqR, BytesPerWord, ClassReg); - loopHead = anInstruction38; - /* begin CmpR:R: */ - assert(!((ClassReg == SPReg))); - genoperandoperand(CmpRR, ClassReg, SPReg); - /* begin JumpAbove: */ - exit = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, TempReg, SendNumArgsReg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction39 = genoperandoperand(AddCqR, 1, SendNumArgsReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)loopHead)); - jmpTarget(exit, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin RetN: */ - genoperand(RetN, 0); - jmpTarget(jumpNeedScavenge, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - CallRTregistersToBeSavedMask(ceScheduleScavengeTrampoline, ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)) | (1U << ClassReg)); - /* begin PopR: */ - genoperand(PopR, LinkReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuation)); - return 0; -} - - -/* Get the active context into ReceiverResultReg, creating it if necessary. */ - - /* CogObjectRepresentationForSpur>>#genGetActiveContextNumArgs:large:inBlock: */ -static sqInt NoDbgRegParms -genGetActiveContextNumArgslargeinBlock(sqInt numArgs, sqInt isLargeContext, sqInt isInBlock) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - sqInt routine; - - if (isLargeContext) { - switch (isInBlock) { - case 0: - routine = ceLargeActiveContextInMethodTrampoline; - break; - - case InVanillaBlock: - routine = ceLargeActiveContextInBlockTrampoline; - break; - - case InFullBlock: - routine = ceLargeActiveContextInFullBlockTrampoline; - break; - - default: - error("Case not found and no otherwise clause"); - routine = -1; - } - } - else { - switch (isInBlock) { - case 0: - routine = ceSmallActiveContextInMethodTrampoline; - break; - - case InVanillaBlock: - routine = ceSmallActiveContextInBlockTrampoline; - break; - - case InFullBlock: - routine = ceSmallActiveContextInFullBlockTrampoline; - break; - - default: - error("Case not found and no otherwise clause"); - routine = -1; - } - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, numArgs, SendNumArgsReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, routine); - (abstractInstruction->annotation = IsRelativeCall); - return 0; -} - - /* CogObjectRepresentationForSpur>>#genGetBits:ofFormatByteOf:into: */ -static sqInt NoDbgRegParms -genGetBitsofFormatByteOfinto(sqInt mask, sqInt sourceReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - flag("endianness"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMbrR, 3, sourceReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, mask, destReg); - return 0; -} - - -/* Fetch the instance's class index into destReg. */ - - /* CogObjectRepresentationForSpur>>#genGetClassIndexOfNonImm:into: */ -static sqInt NoDbgRegParms -genGetClassIndexOfNonImminto(sqInt sourceReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, sourceReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - classIndexMask(); - anInstruction1 = genoperandoperand(AndCqR, classIndexMask(), destReg); - return 0; -} - - -/* Fetch the class object whose index is in instReg into destReg. - It is non-obvious, but the Cogit assumes loading a class does not involve - a runtime call, so do not call classAtIndex: */ - - /* CogObjectRepresentationForSpur>>#genGetClassObjectOfClassIndex:into:scratchReg: */ -static sqInt NoDbgRegParms -genGetClassObjectOfClassIndexintoscratchReg(sqInt instReg, sqInt destReg, sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - sqInt offset; - sqInt quickConstant; - - assert(instReg != destReg); - assert(instReg != scratchReg); - assert(destReg != scratchReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instReg, scratchReg); - /* begin LogicalShiftRightCq:R: */ - quickConstant = classTableMajorIndexShift(); - genoperandoperand(LogicalShiftRightCqR, quickConstant, scratchReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), scratchReg); - assert(!(shouldAnnotateObjectReference(classTableRootObj()))); - /* begin MoveMw:r:R: */ - offset = (classTableRootObj()) + BaseHeaderSize; - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, scratchReg, destReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instReg, scratchReg); - /* begin checkQuickConstant:forInstruction: */ - classTableMinorIndexMask(); - anInstruction3 = genoperandoperand(AndCqR, classTableMinorIndexMask(), scratchReg); - /* begin AddCq:R: */ - anInstruction4 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), scratchReg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, scratchReg, destReg, destReg); - return 0; -} - - -/* Fetch the instance's class into destReg. If the instance is not the - receiver and is forwarded, follow forwarding. */ - - /* CogObjectRepresentationForSpur>>#genGetClassObjectOf:into:scratchReg:mayBeAForwarder: */ -static sqInt NoDbgRegParms -genGetClassObjectOfintoscratchRegmayBeAForwarder(sqInt instReg, sqInt destReg, sqInt scratchReg, sqInt mayBeForwarder) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *jumpIsImm; - AbstractInstruction *jumpNotForwarded; - AbstractInstruction *loop; - - if ((instReg == destReg) - || ((instReg == scratchReg) - || (destReg == scratchReg))) { - return BadRegisterSet; - } - /* begin MoveR:R: */ - loop = genoperandoperand(MoveRR, instReg, scratchReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AndCqR, tagMask(), scratchReg); - /* begin JumpNonZero: */ - jumpIsImm = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - flag("endianness"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperandoperand(MoveMwrR, 0, instReg, scratchReg); - /* begin checkQuickConstant:forInstruction: */ - classIndexMask(); - anInstruction4 = genoperandoperand(AndCqR, classIndexMask(), scratchReg); - if (mayBeForwarder) { - - /* if it is forwarded... */ - /* begin checkQuickConstant:forInstruction: */ - isForwardedObjectClassIndexPun(); - anInstruction = genoperandoperand(CmpCqR, isForwardedObjectClassIndexPun(), scratchReg); - /* begin JumpNonZero: */ - jumpNotForwarded = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, BaseHeaderSize, instReg, instReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)loop)); - jmpTarget(jumpNotForwarded, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - jmpTarget(jumpIsImm, genoperandoperand(MoveRR, scratchReg, destReg)); - if (scratchReg == TempReg) { - /* begin PushR: */ - genoperand(PushR, instReg); - genGetClassObjectOfClassIndexintoscratchReg(destReg, instReg, TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instReg, destReg); - /* begin PopR: */ - genoperand(PopR, instReg); - } - else { - genGetClassObjectOfClassIndexintoscratchReg(destReg, scratchReg, TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, scratchReg, destReg); - } - return 0; -} - - /* CogObjectRepresentationForSpur>>#genGetClassTagOf:into:scratchReg: */ -static AbstractInstruction * NoDbgRegParms -genGetClassTagOfintoscratchReg(sqInt instReg, sqInt destReg, sqInt scratchReg) -{ - return genGetInlineCacheClassTagFromintoforEntry(instReg, destReg, 1); -} - - -/* Fetch the instance's class index into destReg. */ - - /* CogObjectRepresentationForSpur>>#genGetCompactClassIndexNonImmOf:into: */ -static sqInt NoDbgRegParms -genGetCompactClassIndexNonImmOfinto(sqInt instReg, sqInt destReg) -{ - return genGetClassIndexOfNonImminto(instReg, destReg); -} - - /* CogObjectRepresentationForSpur>>#genGetDoubleValueOf:into: */ -static sqInt NoDbgRegParms -genGetDoubleValueOfinto(sqInt srcReg, sqInt destFPReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveM64rRd, BaseHeaderSize, srcReg, destFPReg); - return 0; -} - - -/* Get the format field of the object in srcReg into destReg. - srcReg may equal destReg. */ - - /* CogObjectRepresentationForSpur>>#genGetFormatOf:into: */ -static sqInt NoDbgRegParms -genGetFormatOfinto(sqInt srcReg, sqInt destReg) -{ - return genGetBitsofFormatByteOfinto(formatMask(), srcReg, destReg); -} - - -/* Get the format of the object in sourceReg into destReg. If - scratchRegOrNone is not NoReg, load at least the least significant 32-bits - (64-bits in 64-bits) of the - header word, which contains the format, into scratchRegOrNone. */ - - /* CogObjectRepresentationForSpur>>#genGetFormatOf:into:leastSignificantHalfOfBaseHeaderIntoScratch: */ -static sqInt NoDbgRegParms -genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(sqInt sourceReg, sqInt destReg, sqInt scratchRegOrNone) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - - if (scratchRegOrNone == NoReg) { - flag("endianness"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMbrR, 3, sourceReg, destReg); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, 0, sourceReg, scratchRegOrNone); - gLogicalShiftRightCqRR(formatShift(), scratchRegOrNone, destReg); - } - /* begin checkQuickConstant:forInstruction: */ - formatMask(); - anInstruction2 = genoperandoperand(AndCqR, formatMask(), destReg); - return 0; -} - - -/* Get the size in word-sized slots of the object in srcReg into destReg. - srcReg may equal destReg. */ - - /* CogObjectRepresentationForSpur>>#genGetNumSlotsOf:into: */ -static sqInt NoDbgRegParms -genGetNumSlotsOfinto(sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *jmp; - - assert(srcReg != destReg); - genGetRawSlotSizeOfNonImminto(srcReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - numSlotsMask(); - anInstruction = genoperandoperand(CmpCqR, numSlotsMask(), destReg); - /* begin JumpLess: */ - jmp = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - genGetOverflowSlotsOfinto(srcReg, destReg); - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - -/* The raw numSlots field is the most significant byte of the 64-bit header - word. MoveMbrR zero-extends. */ - - /* CogObjectRepresentationForSpur>>#genGetRawSlotSizeOfNonImm:into: */ -static sqInt NoDbgRegParms -genGetRawSlotSizeOfNonImminto(sqInt sourceReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin MoveCq:R: */ - anInstruction = genoperandoperand(MoveCqR, 0, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMbrR, 7, sourceReg, destReg); - return 0; -} - - /* CogObjectRepresentationForSpur>>#genJumpImmediate: */ -static AbstractInstruction * NoDbgRegParms -genJumpImmediate(sqInt aRegister) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(TstCqR, tagMask(), aRegister); - /* begin JumpNonZero: */ - return genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -} - - /* CogObjectRepresentationForSpur>>#genJumpImmutable:scratchReg: */ -#if IMMUTABILITY -static AbstractInstruction * NoDbgRegParms -genJumpImmutablescratchReg(sqInt sourceReg, sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, sourceReg, scratchReg); - /* begin genJumpBaseHeaderImmutable: */ - immutableBitMask(); - anInstruction1 = genoperandoperand(TstCqR, immutableBitMask(), scratchReg); - /* begin JumpNonZero: */ - return genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -} -#endif /* IMMUTABILITY */ - - /* CogObjectRepresentationForSpur>>#genJumpMutable:scratchReg: */ -#if IMMUTABILITY -static AbstractInstruction * NoDbgRegParms -genJumpMutablescratchReg(sqInt sourceReg, sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, sourceReg, scratchReg); - /* begin genJumpBaseHeaderMutable: */ - immutableBitMask(); - anInstruction1 = genoperandoperand(TstCqR, immutableBitMask(), scratchReg); - /* begin JumpZero: */ - return genConditionalBranchoperand(JumpZero, ((sqInt)0)); -} -#endif /* IMMUTABILITY */ - - /* CogObjectRepresentationForSpur>>#genJumpNotCharacterInScratchReg: */ -static AbstractInstruction * NoDbgRegParms -genJumpNotCharacterInScratchReg(sqInt reg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, tagMask(), reg); - /* begin checkQuickConstant:forInstruction: */ - characterTag(); - anInstruction1 = genoperandoperand(CmpCqR, characterTag(), reg); - /* begin JumpNonZero: */ - return genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -} - - /* CogObjectRepresentationForSpur>>#genLcFirstFieldPointer: */ -static void NoDbgRegParms -genLcFirstFieldPointer(sqInt objectReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, 8, objectReg); - ssPushNativeRegister(objectReg); -} - - -/* TODO: Retrieve the number of fixed fields. */ - - /* CogObjectRepresentationForSpur>>#genLcFirstIndexableFieldPointer: */ -static void NoDbgRegParms -genLcFirstIndexableFieldPointer(sqInt objectReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, 8, objectReg); - ssPushNativeRegister(objectReg); -} - - -/* Check for integer */ - - /* CogObjectRepresentationForSpur>>#genLcIsBytes:to: */ -static void NoDbgRegParms -genLcIsBytesto(sqInt objectReg, sqInt valueReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction * cont; - AbstractInstruction * falseTarget; - AbstractInstruction * isCompiledMethod; - AbstractInstruction * isImmediate; - AbstractInstruction * isNotBytes; - - /* begin MoveR:R: */ - genoperandoperand(MoveRR, objectReg, valueReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, tagMask(), valueReg); - /* begin JumpNonZero: */ - isImmediate = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genGetFormatOfinto(objectReg, valueReg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction1 = genoperandoperand(CmpCqR, firstByteFormat(), valueReg); - /* begin JumpLess: */ - isNotBytes = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction2 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), valueReg); - /* begin JumpGreaterOrEqual: */ - isCompiledMethod = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(MoveCqR, 1, valueReg); - /* begin Jump: */ - cont = genoperand(Jump, ((sqInt)0)); - /* begin Label */ - falseTarget = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - jmpTarget(isImmediate, falseTarget); - jmpTarget(isNotBytes, falseTarget); - jmpTarget(isCompiledMethod, falseTarget); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(MoveCqR, 0, valueReg); - jmpTarget(cont, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(valueReg); -} - - -/* TODO: Implement this one */ - - /* CogObjectRepresentationForSpur>>#genLcIsFloatObject:to: */ -static void NoDbgRegParms -genLcIsFloatObjectto(sqInt objectReg, sqInt valueReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 1, valueReg); - ssPushNativeRegister(valueReg); -} - - -/* TODO: Implement this one */ - - /* CogObjectRepresentationForSpur>>#genLcIsIndexable:to: */ -static void NoDbgRegParms -genLcIsIndexableto(sqInt objectReg, sqInt valueReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 1, valueReg); - ssPushNativeRegister(valueReg); -} - - -/* Check for the immediate case */ - - /* CogObjectRepresentationForSpur>>#genLcIsIntegerObject:to: */ -static void NoDbgRegParms -genLcIsIntegerObjectto(sqInt objectReg, sqInt valueReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction * cont; - AbstractInstruction * falseResult; - AbstractInstruction * isImmediate; - AbstractInstruction * isLargeNegativeInteger; - AbstractInstruction * isLargePositiveInteger; - AbstractInstruction * trueResult; - - /* begin MoveR:R: */ - genoperandoperand(MoveRR, objectReg, valueReg); - /* begin checkQuickConstant:forInstruction: */ - smallIntegerTag(); - anInstruction = genoperandoperand(AndCqR, smallIntegerTag(), valueReg); - /* begin JumpNonZero: */ - isImmediate = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genGetClassIndexOfNonImminto(objectReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, ClassLargePositiveInteger, TempReg); - /* begin JumpNonZero: */ - isLargePositiveInteger = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(CmpCqR, ClassLargeNegativeInteger, TempReg); - /* begin JumpNonZero: */ - isLargeNegativeInteger = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin XorR:R: */ - genoperandoperand(XorRR, valueReg, valueReg); - /* begin Jump: */ - falseResult = genoperand(Jump, ((sqInt)0)); - /* begin Label */ - trueResult = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - jmpTarget(isLargePositiveInteger, trueResult); - jmpTarget(isLargeNegativeInteger, trueResult); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(MoveCqR, 1, valueReg); - /* begin Label */ - cont = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - jmpTarget(falseResult, cont); - jmpTarget(isImmediate, cont); - ssPushNativeRegister(valueReg); -} - - -/* Check for immediate */ - - /* CogObjectRepresentationForSpur>>#genLcIsPointers:to: */ -static void NoDbgRegParms -genLcIsPointersto(sqInt objectReg, sqInt valueReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction * cont; - AbstractInstruction * falseTarget; - AbstractInstruction * isImmediate; - AbstractInstruction * isNotPointers; - - /* begin MoveR:R: */ - genoperandoperand(MoveRR, objectReg, valueReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, tagMask(), valueReg); - /* begin JumpNonZero: */ - isImmediate = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genGetFormatOfinto(objectReg, valueReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 9, valueReg); - /* begin JumpGreaterOrEqual: */ - isNotPointers = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, 1, valueReg); - /* begin Jump: */ - cont = genoperand(Jump, ((sqInt)0)); - /* begin Label */ - falseTarget = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - jmpTarget(isImmediate, falseTarget); - jmpTarget(isNotPointers, falseTarget); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(MoveCqR, 0, valueReg); - jmpTarget(cont, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(valueReg); -} - - -/* Check for immediate */ - - /* CogObjectRepresentationForSpur>>#genLcIsWordsOrBytes:to: */ -static void NoDbgRegParms -genLcIsWordsOrBytesto(sqInt objectReg, sqInt valueReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction * cont; - AbstractInstruction * falseTarget; - AbstractInstruction * isCompiledMethod; - AbstractInstruction * isImmediate; - AbstractInstruction * isNotBits; - - /* begin MoveR:R: */ - genoperandoperand(MoveRR, objectReg, valueReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, tagMask(), valueReg); - /* begin JumpNonZero: */ - isImmediate = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genGetFormatOfinto(objectReg, valueReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 9, valueReg); - /* begin JumpLess: */ - isNotBits = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(CmpCqR, 24, valueReg); - /* begin JumpGreaterOrEqual: */ - isCompiledMethod = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(MoveCqR, 1, valueReg); - /* begin Jump: */ - cont = genoperand(Jump, ((sqInt)0)); - /* begin Label */ - falseTarget = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - jmpTarget(isImmediate, falseTarget); - jmpTarget(isNotBits, falseTarget); - jmpTarget(isCompiledMethod, falseTarget); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(MoveCqR, 0, valueReg); - jmpTarget(cont, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(valueReg); -} - - -/* Check for immediate */ - - /* CogObjectRepresentationForSpur>>#genLcIsWords:to: */ -static void NoDbgRegParms -genLcIsWordsto(sqInt objectReg, sqInt valueReg) -{ - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction * cont; - AbstractInstruction * falseTarget; - AbstractInstruction * isImmediate; - AbstractInstruction * isNotWords; - - isNotWords = ((AbstractInstruction *) 0); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, objectReg, valueReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(AndCqR, tagMask(), valueReg); - /* begin JumpNonZero: */ - isImmediate = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genGetFormatOfinto(objectReg, valueReg); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction2 = genoperandoperand(CmpCqR, firstLongFormat(), valueReg); - /* begin JumpNonZero: */ - isNotWords = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(MoveCqR, 1, valueReg); - /* begin Jump: */ - cont = genoperand(Jump, ((sqInt)0)); - /* begin Label */ - falseTarget = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - jmpTarget(isImmediate, falseTarget); - jmpTarget(isNotWords, falseTarget); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(MoveCqR, 0, valueReg); - jmpTarget(cont, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(valueReg); -} - - /* CogObjectRepresentationForSpur>>#genLcLoadObject:at: */ -static void NoDbgRegParms -genLcLoadObjectat(sqInt object, sqInt fieldIndex) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, 8, object); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, fieldIndex, object, object); - ssPushRegister(object); -} - - /* CogObjectRepresentationForSpur>>#genLcLoadObject:field: */ -static void NoDbgRegParms -genLcLoadObjectfield(sqInt object, sqInt fieldIndex) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, BaseHeaderSize + (BytesPerOop * fieldIndex), object, object); - ssPushRegister(object); -} - - /* CogObjectRepresentationForSpur>>#genLcStore:object:at: */ -static void NoDbgRegParms -genLcStoreobjectat(sqInt value, sqInt object, sqInt fieldIndex) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, 8, object); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, value, fieldIndex, object); -} - - /* CogObjectRepresentationForSpur>>#genLcStore:object:field: */ -static void NoDbgRegParms -genLcStoreobjectfield(sqInt value, sqInt object, sqInt fieldIndex) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveRMwr, value, BaseHeaderSize + (fieldIndex * BytesPerOop), object); -} - - -/* Generate a call to code that allocates a new Array of size. - The Array should be initialized with nils iff initialize is true. - The size arg is passed in SendNumArgsReg, the result - must come back in ReceiverResultReg. */ - - /* CogObjectRepresentationForSpur>>#genNewArrayOfSize:initialized: */ -static sqInt NoDbgRegParms -genNewArrayOfSizeinitialized(sqInt size, sqInt initialize) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - usqLong header; - sqInt i; - sqInt offset; - sqInt quickConstant; - AbstractInstruction *skip; - - assert(size < (numSlotsMask())); - header = headerForSlotsformatclassIndex(size, arrayFormat(), ClassArrayCompactIndex); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction2 = genoperandoperand(MoveAwR, freeStartAddress(), ReceiverResultReg); - /* begin genStoreHeader:intoNewInstance:using: */ - anInstruction4 = genoperandoperand(MoveCqR, ((usqInt) header), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperandoperand(MoveRMwr, TempReg, 0, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperand(MoveCqR, (header) >> 32, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperandoperand(MoveRMwr, TempReg, 4, ReceiverResultReg); - if (initialize - && (size > 0)) { - if (shouldAnnotateObjectReference(nilObject())) { - annotateobjRef(gMoveCwR(nilObject(), TempReg), nilObject()); - } - else { - /* begin MoveCq:R: */ - quickConstant = nilObject(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, TempReg); - } - for (i = 0; i < size; i += 1) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveRMwr, TempReg, (i * BytesPerWord) + BaseHeaderSize, ReceiverResultReg); - } - } - /* begin LoadEffectiveAddressMw:r:R: */ - offset = smallObjectBytesForSlots(size); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(LoadEffectiveAddressMwrR, offset, ReceiverResultReg, TempReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction6 = genoperandoperand(MoveRAw, TempReg, freeStartAddress()); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction7 = genoperandoperand(CmpCqR, getScavengeThreshold(), TempReg); - /* begin JumpBelow: */ - skip = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceScheduleScavengeTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - -/* Create a closure with the given startpc, numArgs and numCopied - within a context with ctxtNumArgs, large if isLargeCtxt that is in a - block if isInBlock. Do /not/ initialize the copied values. */ - - /* CogObjectRepresentationForSpur>>#genNoPopCreateClosureAt:numArgs:numCopied:contextNumArgs:large:inBlock: */ -static sqInt NoDbgRegParms -genNoPopCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(sqInt bcpc, sqInt numArgs, sqInt numCopied, sqInt ctxtNumArgs, sqInt isLargeCtxt, sqInt isInBlock) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - usqInt byteSize; - usqLong header; - sqInt numSlots; - AbstractInstruction *skip; - - - /* First get thisContext into ReceiverResultRega and thence in ClassReg. */ - genGetActiveContextNumArgslargeinBlock(ctxtNumArgs, isLargeCtxt, isInBlock); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, ClassReg); - numSlots = ClosureFirstCopiedValueIndex + numCopied; - byteSize = smallObjectBytesForSlots(numSlots); - header = headerForSlotsformatclassIndex(numSlots, indexablePointersFormat(), ClassBlockClosureCompactIndex); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction = genoperandoperand(MoveAwR, freeStartAddress(), ReceiverResultReg); - /* begin genStoreHeader:intoNewInstance:using: */ - anInstruction4 = genoperandoperand(MoveCqR, ((usqInt) header), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveRMwr, TempReg, 0, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, (header) >> 32, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperandoperand(MoveRMwr, TempReg, 4, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(LoadEffectiveAddressMwrR, byteSize, ReceiverResultReg, TempReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction6 = genoperandoperand(MoveRAw, TempReg, freeStartAddress()); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction7 = genoperandoperand(CmpCqR, getScavengeThreshold(), TempReg); - /* begin JumpBelow: */ - skip = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceScheduleScavengeTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperandoperand(MoveRMwr, ClassReg, (ClosureOuterContextIndex * BytesPerOop) + BaseHeaderSize, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)bcpc << 1) | 1); - anInstruction9 = genoperandoperand(MoveCqR, (((usqInt)bcpc << 1) | 1), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveRMwr, TempReg, (ClosureStartPCIndex * BytesPerOop) + BaseHeaderSize, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)numArgs << 1) | 1); - anInstruction11 = genoperandoperand(MoveCqR, (((usqInt)numArgs << 1) | 1), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveRMwr, TempReg, (ClosureNumArgsIndex * BytesPerOop) + BaseHeaderSize, ReceiverResultReg); - return 0; -} - - /* CogObjectRepresentationForSpur>>#genPrimitiveAsCharacter */ -static sqInt -genPrimitiveAsCharacter(void) -{ - AbstractInstruction *jumpNotInt; - AbstractInstruction *jumpOutOfRange; - sqInt reg; - - jumpNotInt = ((AbstractInstruction *) 0); - if (methodOrBlockNumArgs == 0) { - reg = ReceiverResultReg; - } - else { - if (methodOrBlockNumArgs > 1) { - return UnimplementedPrimitive; - } - reg = Arg0Reg; - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotInt = genJumpNotSmallInteger(reg); - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - jumpOutOfRange = jumpNotCharacterUnsignedValueInRegister(TempReg); - genConvertSmallIntegerToCharacterInReg(reg); - if (reg != ReceiverResultReg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, reg, ReceiverResultReg); - } - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpOutOfRange, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (reg != ReceiverResultReg) { - jmpTarget(jumpNotInt, ((AbstractInstruction *) (((jumpOutOfRange->operands))[0]))); - } - return CompletePrimitive; -} - - -/* Generate primitive 60, at: with unsigned access for pure bits classes. */ - - /* CogObjectRepresentationForSpur>>#genPrimitiveAt */ -static sqInt -genPrimitiveAt(void) -{ - return genPrimitiveAtSigned(0); -} - - /* CogObjectRepresentationForSpur>>#genPrimitiveIdenticalOrNotIf: */ -static sqInt NoDbgRegParms -genPrimitiveIdenticalOrNotIf(sqInt orNot) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *comp; - sqInt constant; - sqInt constant1; - AbstractInstruction *jumpCmp; - - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - comp = genoperandoperand(CmpRR, Arg0Reg, ReceiverResultReg); - if (orNot) { - /* begin JumpZero: */ - jumpCmp = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin genEnsureOopInRegNotForwarded:scratchReg:jumpBackTo: */ - genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(Arg0Reg, TempReg, comp, 0); - } - else { - /* begin JumpNonZero: */ - jumpCmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - } - /* begin genMoveConstant:R: */ - constant = trueObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpCmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (!orNot) { - /* begin genEnsureOopInRegNotForwarded:scratchReg:jumpBackTo: */ - genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(Arg0Reg, TempReg, comp, 0); - } - /* begin genMoveConstant:R: */ - constant1 = falseObject(); - if (shouldAnnotateObjectReference(constant1)) { - annotateobjRef(checkLiteralforInstruction(constant1, genoperandoperand(MoveCwR, constant1, ReceiverResultReg)), constant1); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, constant1, ReceiverResultReg); - } - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - return UnfailingPrimitive; -} - - -/* Generate primitive 164, at: with signed access for pure bits classes. */ - - /* CogObjectRepresentationForSpur>>#genPrimitiveIntegerAt */ -static sqInt -genPrimitiveIntegerAt(void) -{ - return genPrimitiveAtSigned(1); -} - - -/* Generate primitive 165, at:put: with signed access for pure bits classes. */ - - /* CogObjectRepresentationForSpur>>#genPrimitiveIntegerAtPut */ -static sqInt -genPrimitiveIntegerAtPut(void) -{ - return genPrimitiveAtPutSigned(1); -} - - -/* */ - - /* CogObjectRepresentationForSpur>>#genPrimitiveMakePoint */ -static sqInt -genPrimitiveMakePoint(void) -{ - sqInt allocSize; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction * jumpFail; - usqLong newPointHeader; - sqInt resultReg; - sqInt scratchReg; - - resultReg = ClassReg; - - /* */ - scratchReg = SendNumArgsReg; - allocSize = BaseHeaderSize + (BytesPerWord * 2); - newPointHeader = headerForSlotsformatclassIndex(2, nonIndexablePointerFormat(), ClassPointCompactIndex); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction = genoperandoperand(MoveAwR, freeStartAddress(), resultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(LoadEffectiveAddressMwrR, allocSize, resultReg, scratchReg); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction2 = genoperandoperand(CmpCqR, getScavengeThreshold(), scratchReg); - /* begin JumpAboveOrEqual: */ - jumpFail = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction3 = genoperandoperand(MoveRAw, scratchReg, freeStartAddress()); - /* begin genStoreHeader:intoNewInstance:using: */ - anInstruction4 = genoperandoperand(MoveCqR, ((usqInt) newPointHeader), scratchReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperandoperand(MoveRMwr, scratchReg, 0, resultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperand(MoveCqR, (newPointHeader) >> 32, scratchReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction31 = genoperandoperandoperand(MoveRMwr, scratchReg, 4, resultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(MoveRMwr, ReceiverResultReg, BaseHeaderSize, resultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperandoperand(MoveRMwr, Arg0Reg, BaseHeaderSize + BytesPerWord, resultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, resultReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpFail, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - /* CogObjectRepresentationForSpur>>#genPrimitiveObjectAt */ -static sqInt -genPrimitiveObjectAt(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - sqInt headerReg; - AbstractInstruction *jumpBadIndex; - AbstractInstruction *jumpBounds; - AbstractInstruction *jumpNotHeaderIndex; - sqInt quickConstant; - - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpBadIndex = genJumpNotSmallInteger(Arg0Reg); - genGetMethodHeaderOfintoscratch(ReceiverResultReg, (headerReg = Arg1Reg), TempReg); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)1 << 1) | 1); - anInstruction = genoperandoperand(CmpCqR, (((usqInt)1 << 1) | 1), Arg0Reg); - /* begin JumpNonZero: */ - jumpNotHeaderIndex = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, headerReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotHeaderIndex, gAndCqR((((usqInt)(alternateHeaderNumLiteralsMask()) << 1) | 1), headerReg)); - /* begin SubCq:R: */ - quickConstant = ((((usqInt)1 << 1) | 1)) - (smallIntegerTag()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(SubCqR, quickConstant, Arg0Reg); - /* begin CmpR:R: */ - assert(!((headerReg == SPReg))); - genoperandoperand(CmpRR, headerReg, Arg0Reg); - /* begin JumpAbove: */ - jumpBounds = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - genConvertSmallIntegerToIntegerInReg(Arg0Reg); - /* begin AddCq:R: */ - anInstruction2 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg0Reg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, Arg0Reg, ReceiverResultReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpBounds, gAddCqR(((((usqInt)1 << 1) | 1)) - (smallIntegerTag()), Arg0Reg)); - jmpTarget(jumpBadIndex, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - -/* c.f. StackInterpreter>>stSizeOf: lengthOf:baseHeader:format: - fixedFieldsOf:format:length: - */ - - /* CogObjectRepresentationForSpur>>#genPrimitiveSize */ -static sqInt -genPrimitiveSize(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - AbstractInstruction * jump32BitLongsDone; - AbstractInstruction * jump64BitLongsDone; - AbstractInstruction * jumpArrayDone; - AbstractInstruction * jumpBytesDone; - AbstractInstruction * jumpHasFixedFields; - AbstractInstruction *jumpImm; - AbstractInstruction * jumpIs64BitLongs; - AbstractInstruction * jumpIsBytes; - AbstractInstruction *jumpIsContext; - AbstractInstruction * jumpIsContext1; - AbstractInstruction * jumpIsShorts; - AbstractInstruction *jumpNotIndexable; - AbstractInstruction * jumpNotIndexable1; - AbstractInstruction * jumpShortsDone; - - jumpImm = genJumpImmediate(ReceiverResultReg); - /* begin genGetSizeOf:into:formatReg:scratchReg:abortJumpsInto: */ - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, SendNumArgsReg, TempReg); - genGetNumSlotsOfinto(ReceiverResultReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction = genoperandoperand(CmpCqR, firstByteFormat(), SendNumArgsReg); - /* begin JumpGreaterOrEqual: */ - jumpIsBytes = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction1 = genoperandoperand(CmpCqR, arrayFormat(), SendNumArgsReg); - /* begin JumpZero: */ - jumpArrayDone = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin JumpLess: */ - jumpNotIndexable1 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - weakArrayFormat(); - anInstruction2 = genoperandoperand(CmpCqR, weakArrayFormat(), SendNumArgsReg); - /* begin JumpLessOrEqual: */ - jumpHasFixedFields = genConditionalBranchoperand(JumpLessOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstShortFormat(); - anInstruction3 = genoperandoperand(CmpCqR, firstShortFormat(), SendNumArgsReg); - /* begin JumpGreaterOrEqual: */ - jumpIsShorts = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction4 = genoperandoperand(CmpCqR, firstLongFormat(), SendNumArgsReg); - /* begin JumpGreaterOrEqual: */ - jump32BitLongsDone = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - sixtyFourBitIndexableFormat(); - anInstruction5 = genoperandoperand(CmpCqR, sixtyFourBitIndexableFormat(), SendNumArgsReg); - /* begin JumpZero: */ - jumpIs64BitLongs = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - jmpTarget(jumpNotIndexable1, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin Jump: */ - jumpNotIndexable1 = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpIsBytes, genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), ClassReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(AndCqR, BytesPerWord - 1, SendNumArgsReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, SendNumArgsReg, ClassReg); - /* begin Jump: */ - jumpBytesDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpIsShorts, gLogicalShiftLeftCqR((shiftForWord()) - 1, ClassReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(AndCqR, 1, SendNumArgsReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, SendNumArgsReg, ClassReg); - /* begin Jump: */ - jumpShortsDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpIs64BitLongs, genoperandoperand(LogicalShiftRightCqR, 1, ClassReg)); - /* begin Jump: */ - jump64BitLongsDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpHasFixedFields, checkQuickConstantforInstruction(classIndexMask(), genoperandoperand(AndCqR, classIndexMask(), TempReg))); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, SendNumArgsReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, TempReg); - /* begin JumpZero: */ - jumpIsContext1 = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin PushR: */ - genoperand(PushR, ClassReg); - genGetClassObjectOfClassIndexintoscratchReg(SendNumArgsReg, ClassReg, TempReg); - genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, ClassReg, SendNumArgsReg); - genConvertSmallIntegerToIntegerInReg(SendNumArgsReg); - /* begin PopR: */ - genoperand(PopR, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - fixedFieldsOfClassFormatMask(); - anInstruction9 = genoperandoperand(AndCqR, fixedFieldsOfClassFormatMask(), SendNumArgsReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, SendNumArgsReg, ClassReg); - jmpTarget(jumpArrayDone, jmpTarget(jump64BitLongsDone, jmpTarget(jump32BitLongsDone, jmpTarget(jumpShortsDone, jmpTarget(jumpBytesDone, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))))); - jumpNotIndexable = jumpNotIndexable1; - jumpIsContext = jumpIsContext1; - genConvertIntegerInRegtoSmallIntegerInReg(ClassReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpImm, jmpTarget(jumpNotIndexable, jmpTarget(jumpIsContext, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))); - return CompletePrimitive; -} - - -/* primitiveCompareWith: */ - - /* CogObjectRepresentationForSpur>>#genPrimitiveStringCompareWith */ -static sqInt -genPrimitiveStringCompareWith(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction * instr; - AbstractInstruction *jump; - AbstractInstruction *jumpAbove; - AbstractInstruction *jumpIncorrectFormat1; - AbstractInstruction *jumpIncorrectFormat2; - AbstractInstruction *jumpIncorrectFormat3; - AbstractInstruction *jumpIncorrectFormat4; - AbstractInstruction *jumpMidFailure; - AbstractInstruction *jumpSuccess; - sqInt minSizeReg; - sqInt string1CharOrByteSizeReg; - sqInt string1Reg; - sqInt string2CharOrByteSizeReg; - sqInt string2Reg; - - - /* I redefine those name to ease program comprehension */ - string1Reg = ReceiverResultReg; - string2Reg = Arg0Reg; - string1CharOrByteSizeReg = Arg1Reg; - string2CharOrByteSizeReg = ClassReg; - - /* Load arguments in reg */ - minSizeReg = SendNumArgsReg; - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - genGetFormatOfinto(string1Reg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction = genoperandoperand(CmpCqR, firstByteFormat(), TempReg); - /* begin JumpLess: */ - jumpIncorrectFormat1 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction1 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), TempReg); - /* begin JumpAboveOrEqual: */ - jumpIncorrectFormat2 = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - genGetNumSlotsOfinto(string1Reg, string1CharOrByteSizeReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), string1CharOrByteSizeReg); - gAndCqRR(BytesPerWord - 1, TempReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, string1CharOrByteSizeReg); - genGetFormatOfinto(string2Reg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction2 = genoperandoperand(CmpCqR, firstByteFormat(), TempReg); - /* begin JumpLess: */ - jumpIncorrectFormat3 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction3 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), TempReg); - /* begin JumpAboveOrEqual: */ - jumpIncorrectFormat4 = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - genGetNumSlotsOfinto(string2Reg, string2CharOrByteSizeReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), string2CharOrByteSizeReg); - gAndCqRR(BytesPerWord - 1, TempReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, string2CharOrByteSizeReg); - /* begin CmpR:R: */ - assert(!((string1CharOrByteSizeReg == SPReg))); - genoperandoperand(CmpRR, string1CharOrByteSizeReg, string2CharOrByteSizeReg); - /* begin JumpBelow: */ - jumpAbove = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, string1CharOrByteSizeReg, minSizeReg); - /* begin Jump: */ - jump = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpAbove, genoperandoperand(MoveRR, string2CharOrByteSizeReg, minSizeReg)); - jmpTarget(jump, checkQuickConstantforInstruction(0, genoperandoperand(CmpCqR, 0, minSizeReg))); - /* begin JumpZero: */ - jumpSuccess = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(MoveCqR, BaseHeaderSize, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(AddCqR, BaseHeaderSize, minSizeReg); - /* begin MoveXbr:R:R: */ - instr = genoperandoperandoperand(MoveXbrRR, TempReg, string1Reg, string1CharOrByteSizeReg); - /* begin MoveXbr:R:R: */ - genoperandoperandoperand(MoveXbrRR, TempReg, string2Reg, string2CharOrByteSizeReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, string2CharOrByteSizeReg, string1CharOrByteSizeReg); - /* begin JumpNonZero: */ - jumpMidFailure = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(AddCqR, 1, TempReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, minSizeReg); - /* begin JumpNonZero: */ - genConditionalBranchoperand(JumpNonZero, ((sqInt)instr)); - genGetNumBytesOfinto(string1Reg, string1CharOrByteSizeReg); - genGetNumBytesOfinto(string2Reg, string2CharOrByteSizeReg); - jmpTarget(jumpSuccess, genoperandoperand(SubRR, string2CharOrByteSizeReg, string1CharOrByteSizeReg)); - jmpTarget(jumpMidFailure, genoperandoperand(MoveRR, string1CharOrByteSizeReg, ReceiverResultReg)); - genConvertIntegerToSmallIntegerInReg(ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIncorrectFormat4, jmpTarget(jumpIncorrectFormat3, jmpTarget(jumpIncorrectFormat2, jmpTarget(jumpIncorrectFormat1, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))); - return CompletePrimitive; -} - - -/* replaceFrom: start to: stop with: replacement startingAt: repStart. - - The primitive in the JIT tries to deal with two pathological cases, copy - of arrays and byteStrings, - which often copies only a dozen of fields and where switching to the C - runtime cost a lot. - - Based on heuristics on the method class, I generate a quick array path - (typically for Array), - a quick byteString path (typically for ByteString, ByteArray and - LargeInteger) or no quick - path at all (Typically for Bitmap). - - The many tests to ensure that the primitive won't fail are not super - optimised (multiple reloading - or stack arguments in registers) but this is still good enough and worth - it since we're avoiding - the Smalltalk to C stack switch. The tight copying loops are optimised. - - It is possible to build a bigger version with the 2 different paths but I - (Clement) believe this - is too big machine code wise to be worth it. - */ - - /* CogObjectRepresentationForSpur>>#genPrimitiveStringReplace */ -static sqInt -genPrimitiveStringReplace(void) -{ - sqInt adjust; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction22; - AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction24; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt arrayReg; - AbstractInstruction * inst; - AbstractInstruction * instr; - AbstractInstruction *jmpAlreadyRemembered; - AbstractInstruction *jmpDestYoung; - AbstractInstruction *jumpEmpty; - AbstractInstruction *jumpImm; - AbstractInstruction *jumpImmutable; - AbstractInstruction *jumpIncorrectFormat1; - AbstractInstruction *jumpIncorrectFormat2; - AbstractInstruction *jumpIncorrectFormat3; - AbstractInstruction *jumpIncorrectFormat4; - AbstractInstruction *jumpNotSmi1; - AbstractInstruction *jumpNotSmi2; - AbstractInstruction *jumpNotSmi3; - AbstractInstruction *jumpOutOfBounds1; - AbstractInstruction *jumpOutOfBounds2; - AbstractInstruction *jumpOutOfBounds3; - AbstractInstruction *jumpOutOfBounds4; - sqInt offset; - sqInt offset1; - sqInt offset2; - sqInt offset3; - sqInt offset4; - sqInt offset5; - sqInt offset6; - sqInt offset7; - sqInt offset8; - sqInt offset9; - sqInt replReg; - sqInt repStartReg; - sqInt result; - sqInt startReg; - sqInt stopReg; - - - /* Can I generate a quick path for this method ? */ - jmpAlreadyRemembered = ((AbstractInstruction *) 0); - jumpImmutable = ((AbstractInstruction *) 0); - jumpOutOfBounds3 = ((AbstractInstruction *) 0); - jumpOutOfBounds4 = ((AbstractInstruction *) 0); - if (!((maybeMethodClassOfseemsToBeInstantiating(methodObj, arrayFormat())) - || (maybeMethodClassOfseemsToBeInstantiating(methodObj, firstByteFormat())))) { - return UnimplementedPrimitive; - } - arrayReg = ReceiverResultReg; - startReg = Arg0Reg; - stopReg = Arg1Reg; - replReg = ClassReg; - - /* Load arguments in reg */ - repStartReg = SendNumArgsReg; - /* begin genStackArgAt:into: */ - offset6 = (0) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperandoperand(MoveMwrR, offset6, SPReg, repStartReg); - /* begin genStackArgAt:into: */ - offset7 = (1) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperandoperand(MoveMwrR, offset7, SPReg, replReg); - /* begin genStackArgAt:into: */ - offset8 = (2) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction23 = genoperandoperandoperand(MoveMwrR, offset8, SPReg, stopReg); - /* begin genStackArgAt:into: */ - offset9 = (3) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction24 = genoperandoperandoperand(MoveMwrR, offset9, SPReg, startReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSmi1 = genJumpNotSmallInteger(repStartReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSmi2 = genJumpNotSmallInteger(stopReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSmi3 = genJumpNotSmallInteger(startReg); - - /* if start>stop primitive success */ - jumpImm = genJumpImmediate(replReg); - /* begin CmpR:R: */ - assert(!((startReg == SPReg))); - genoperandoperand(CmpRR, startReg, stopReg); - /* begin JumpLess: */ - jumpEmpty = genConditionalBranchoperand(JumpLess, ((sqInt)0)); -# if IMMUTABILITY - jumpImmutable = genJumpImmutablescratchReg(ReceiverResultReg, TempReg); -# endif - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)0 << 1) | 1); - anInstruction13 = genoperandoperand(CmpCqR, (((usqInt)0 << 1) | 1), startReg); - /* begin JumpLessOrEqual: */ - jumpOutOfBounds1 = genConditionalBranchoperand(JumpLessOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)0 << 1) | 1); - anInstruction14 = genoperandoperand(CmpCqR, (((usqInt)0 << 1) | 1), repStartReg); - /* begin JumpLessOrEqual: */ - jumpOutOfBounds2 = genConditionalBranchoperand(JumpLessOrEqual, ((sqInt)0)); - if (maybeMethodClassOfseemsToBeInstantiating(methodObj, arrayFormat())) { - - /* Are they both array format ? */ - genGetFormatOfinto(arrayReg, TempReg); - genGetFormatOfinto(replReg, startReg); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction2 = genoperandoperand(CmpCqR, arrayFormat(), startReg); - /* begin JumpNonZero: */ - jumpIncorrectFormat1 = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction3 = genoperandoperand(CmpCqR, arrayFormat(), TempReg); - /* begin JumpNonZero: */ - jumpIncorrectFormat2 = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genGetNumSlotsOfinto(arrayReg, TempReg); - genConvertSmallIntegerToIntegerInReg(stopReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, stopReg); - /* begin JumpGreater: */ - jumpOutOfBounds3 = genConditionalBranchoperand(JumpGreater, ((sqInt)0)); - genGetNumSlotsOfinto(replReg, TempReg); - /* begin genStackArgAt:into: */ - offset = (3) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperandoperand(MoveMwrR, offset, SPReg, startReg); - genConvertSmallIntegerToIntegerInReg(startReg); - genConvertSmallIntegerToIntegerInReg(repStartReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, startReg, stopReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, repStartReg, stopReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, stopReg); - /* begin JumpGreater: */ - jumpOutOfBounds4 = genConditionalBranchoperand(JumpGreater, ((sqInt)0)); - /* begin checkLiteral:forInstruction: */ - storeCheckBoundary(); - anInstruction4 = genoperandoperand(MoveCwR, storeCheckBoundary(), TempReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, arrayReg); - /* begin JumpBelow: */ - jmpDestYoung = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - if (!CheckRememberedInTrampoline) { - jmpAlreadyRemembered = genCheckRememberedBitOfscratch(arrayReg, TempReg); - } - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - callStoreCheckTrampoline(); - /* begin PopR: */ - genoperand(PopR, LinkReg); - jmpTarget(jmpDestYoung, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (!CheckRememberedInTrampoline) { - jmpTarget(jmpAlreadyRemembered, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - /* begin genStackArgAt:into: */ - offset1 = (2) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction16 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, stopReg); - genConvertSmallIntegerToIntegerInReg(stopReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, startReg, repStartReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), repStartReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, repStartReg, replReg); - adjust = (((usqInt)(BaseHeaderSize)) >> (shiftForWord())) - 1; - if (adjust != 0) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, adjust, startReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AddCqR, adjust, stopReg); - } - /* begin MoveXwr:R:R: */ - instr = genoperandoperandoperand(MoveXwrRR, startReg, replReg, TempReg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, TempReg, startReg, arrayReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(AddCqR, 1, startReg); - /* begin CmpR:R: */ - assert(!((startReg == SPReg))); - genoperandoperand(CmpRR, startReg, stopReg); - /* begin JumpAboveOrEqual: */ - genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)instr)); - jmpTarget(jumpEmpty, (methodOrBlockNumArgs <= 2 /* numRegArgs */ - ? (/* begin RetN: */ - genoperand(RetN, 0)) - : (/* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord)))); - jmpTarget(jumpIncorrectFormat1, jmpTarget(jumpIncorrectFormat2, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - } - if (maybeMethodClassOfseemsToBeInstantiating(methodObj, firstByteFormat())) { - - /* Are they both byte array format ? CompiledMethod excluded */ - genGetFormatOfinto(arrayReg, TempReg); - genGetFormatOfinto(replReg, repStartReg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction8 = genoperandoperand(CmpCqR, firstByteFormat(), repStartReg); - /* begin JumpLess: */ - jumpIncorrectFormat1 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction9 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), repStartReg); - /* begin JumpGreaterOrEqual: */ - jumpIncorrectFormat2 = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction10 = genoperandoperand(CmpCqR, firstByteFormat(), TempReg); - /* begin JumpLess: */ - jumpIncorrectFormat3 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction11 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), TempReg); - /* begin JumpGreaterOrEqual: */ - jumpIncorrectFormat4 = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - genGetNumSlotsOfinto(arrayReg, startReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), startReg); - gAndCqRR(BytesPerWord - 1, TempReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, startReg); - genConvertSmallIntegerToIntegerInReg(stopReg); - /* begin CmpR:R: */ - assert(!((startReg == SPReg))); - genoperandoperand(CmpRR, startReg, stopReg); - /* begin JumpGreater: */ - jumpOutOfBounds3 = genConditionalBranchoperand(JumpGreater, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, repStartReg, TempReg); - /* begin genStackArgAt:into: */ - offset2 = (0) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, repStartReg); - /* begin genStackArgAt:into: */ - offset3 = (3) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction18 = genoperandoperandoperand(MoveMwrR, offset3, SPReg, startReg); - genConvertSmallIntegerToIntegerInReg(startReg); - genConvertSmallIntegerToIntegerInReg(repStartReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, startReg, stopReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, repStartReg, stopReg); - genGetNumSlotsOfinto(replReg, startReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), startReg); - gAndCqRR(BytesPerWord - 1, TempReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, startReg); - /* begin CmpR:R: */ - assert(!((startReg == SPReg))); - genoperandoperand(CmpRR, startReg, stopReg); - /* begin JumpGreater: */ - jumpOutOfBounds4 = genConditionalBranchoperand(JumpGreater, ((sqInt)0)); - /* begin genStackArgAt:into: */ - offset4 = (3) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperandoperand(MoveMwrR, offset4, SPReg, startReg); - genConvertSmallIntegerToIntegerInReg(startReg); - /* begin genStackArgAt:into: */ - offset5 = (2) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperandoperand(MoveMwrR, offset5, SPReg, stopReg); - genConvertSmallIntegerToIntegerInReg(stopReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, startReg, repStartReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, repStartReg, replReg); - adjust = BaseHeaderSize - 1; - if (adjust != 0) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(AddCqR, adjust, startReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(AddCqR, adjust, stopReg); - } - /* begin MoveXbr:R:R: */ - instr = genoperandoperandoperand(MoveXbrRR, startReg, replReg, TempReg); - /* begin MoveR:Xbr:R: */ - genoperandoperandoperand(MoveRXbrR, TempReg, startReg, arrayReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperand(AddCqR, 1, startReg); - /* begin CmpR:R: */ - assert(!((startReg == SPReg))); - genoperandoperand(CmpRR, startReg, stopReg); - /* begin JumpAboveOrEqual: */ - genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)instr)); - jmpTarget(jumpEmpty, (methodOrBlockNumArgs <= 2 /* numRegArgs */ - ? (/* begin RetN: */ - genoperand(RetN, 0)) - : (/* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord)))); - jmpTarget(jumpIncorrectFormat4, jmpTarget(jumpIncorrectFormat3, jmpTarget(jumpIncorrectFormat2, jmpTarget(jumpIncorrectFormat1, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))); - } - if (((result = compileInterpreterPrimitive())) < 0) { - return result; - } - jmpTarget(jumpImm, jmpTarget(jumpNotSmi1, jmpTarget(jumpNotSmi2, jmpTarget(jumpNotSmi3, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))); - jmpTarget(jumpOutOfBounds1, jmpTarget(jumpOutOfBounds2, jmpTarget(jumpOutOfBounds3, jmpTarget(jumpOutOfBounds4, ((AbstractInstruction *) (((jumpImm->operands))[0])))))); -# if IMMUTABILITY - jmpTarget(jumpImmutable, ((AbstractInstruction *) (((jumpImm->operands))[0]))); -# endif - return CompletePrimitive; -} - - /* CogObjectRepresentationForSpur>>#genSetSmallIntegerTagsIn: */ -static sqInt NoDbgRegParms -genSetSmallIntegerTagsIn(sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(OrCqR, 1, scratchReg); - return 0; -} - - -/* Create a trampoline to store-check the update of the receiver in a - closure's outerContext in compileBlockFrameBuild:. */ - - /* CogObjectRepresentationForSpur>>#genStoreCheckContextReceiverTrampoline */ -static usqInt -genStoreCheckContextReceiverTrampoline(void) -{ - usqInt startAddress; - - startAddress = methodZoneBase(); - zeroOpcodeIndex(); - genStoreCheckReceiverRegvalueRegscratchReginFrame(ReceiverResultReg, Arg0Reg, TempReg, 0); - /* begin RetN: */ - genoperand(RetN, 0); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress("ceStoreCheckContextReceiver", startAddress); - recordRunTimeObjectReferences(); - return startAddress; -} - - -/* Generate the code for a store check of valueReg into destReg. */ - - /* CogObjectRepresentationForSpur>>#genStoreCheckReceiverReg:valueReg:scratchReg:inFrame: */ -static sqInt NoDbgRegParms -genStoreCheckReceiverRegvalueRegscratchReginFrame(sqInt destReg, sqInt valueReg, sqInt scratchReg, sqInt inFrame) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction * inst; - AbstractInstruction *jmpAlreadyRemembered; - AbstractInstruction *jmpDestYoung; - AbstractInstruction *jmpImmediate; - AbstractInstruction *jmpSourceOld; - - - /* Is value stored an immediate? If so we're done */ - jmpAlreadyRemembered = ((AbstractInstruction *) 0); - - /* Get the old/new boundary in scratchReg */ - jmpImmediate = genJumpImmediate(valueReg); - /* begin checkLiteral:forInstruction: */ - storeCheckBoundary(); - anInstruction = genoperandoperand(MoveCwR, storeCheckBoundary(), scratchReg); - /* begin CmpR:R: */ - assert(!((scratchReg == SPReg))); - genoperandoperand(CmpRR, scratchReg, destReg); - /* begin JumpBelow: */ - jmpDestYoung = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((scratchReg == SPReg))); - genoperandoperand(CmpRR, scratchReg, valueReg); - /* begin JumpAboveOrEqual: */ - jmpSourceOld = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - if (!CheckRememberedInTrampoline) { - jmpAlreadyRemembered = genCheckRememberedBitOfscratch(destReg, scratchReg); - } - assert(destReg == ReceiverResultReg); - /* begin evaluateTrampolineCallBlock:protectLinkRegIfNot: */ - if (inFrame) { - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceStoreCheckTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - } - else { - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceStoreCheckTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin PopR: */ - genoperand(PopR, LinkReg); - } - jmpTarget(jmpImmediate, jmpTarget(jmpDestYoung, jmpTarget(jmpSourceOld, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))); - if (!CheckRememberedInTrampoline) { - jmpTarget(jmpAlreadyRemembered, ((AbstractInstruction *) (((jmpSourceOld->operands))[0]))); - } - return 0; -} - - /* CogObjectRepresentationForSpur>>#genStoreSourceReg:slotIndex:destReg:scratchReg:inFrame:needsStoreCheck: */ -static sqInt NoDbgRegParms -genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt inFrame, sqInt needsStoreCheck) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - - /* begin genTraceStores */ - if (traceStores > 0) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, TempReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceTraceStoreTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveRMwr, sourceReg, (index * BytesPerWord) + BaseHeaderSize, destReg); - if (needsStoreCheck) { - return genStoreCheckReceiverRegvalueRegscratchReginFrame(destReg, sourceReg, scratchReg, inFrame); - } - return 0; -} - - -/* This method is used for unchecked stores in objects after their creation - (typically, inlined creation of Array, closures and some temp vectors). - Currently there is no need to do the immutability check here - */ - - /* CogObjectRepresentationForSpur>>#genStoreSourceReg:slotIndex:intoNewObjectInDestReg: */ -static sqInt NoDbgRegParms -genStoreSourceRegslotIndexintoNewObjectInDestReg(sqInt sourceReg, sqInt index, sqInt destReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveRMwr, sourceReg, (index * BytesPerWord) + BaseHeaderSize, destReg); - return 0; -} - - -/* Convention: - - RcvrResultReg holds the object mutated. - If immutability failure: - - TempReg holds the instance variable index mutated - if instVarIndex > numDedicatedStoreTrampoline - - ClassReg holds the value to store - Registers are not lived across this trampoline as the - immutability failure may need new stack frames. */ - - /* CogObjectRepresentationForSpur>>#genStoreTrampolineCalled:instVarIndex: */ -#if IMMUTABILITY -static usqInt NoDbgRegParms -genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) -{ - AbstractInstruction * jumpImmutable; - AbstractInstruction * jumpImmutable1; - AbstractInstruction * jumpRC; - sqInt pushLinkReg; - usqInt startAddress; - - startAddress = methodZoneBase(); - zeroOpcodeIndex(); - if (CheckRememberedInTrampoline) { - /* begin genStoreTrampolineCheckingRememberedCalled:instVarIndex: */ - - /* Store check */ - /* If on 64-bits and doing the remembered bit test here, we can combine the tests to fetch the header once. */ - jumpImmutable = genJumpImmutablescratchReg(ReceiverResultReg, SendNumArgsReg); - jumpRC = genCheckRememberedBitOfscratch(ReceiverResultReg, SendNumArgsReg); - assert(((jumpRC->opcode)) == JumpNonZero); - (jumpRC->opcode = JumpZero); - /* begin RetN: */ - genoperand(RetN, 0); - jmpTarget(jumpRC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) - ? ReceiverResultReg - : ABIResultReg)); - jmpTarget(jumpImmutable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(ceCannotAssignTowithIndexvalueToAssign, 3, ReceiverResultReg, (instVarIndex < (NumStoreTrampolines - 1) - ? (/* begin trampolineArgConstant: */ - assert(instVarIndex >= 0), - -2 - instVarIndex) - : TempReg), ClassReg, null, 0 /* emptyRegisterMask */, 1, NoReg); - } - else { - /* begin genStoreTrampolineNotCheckingRememberedCalled:instVarIndex: */ - genSmalltalkToCStackSwitch((pushLinkReg = 1)); - - /* Store check */ - jumpImmutable1 = genJumpImmutablescratchReg(ReceiverResultReg, SendNumArgsReg); - compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) - ? ReceiverResultReg - : ABIResultReg), 0 /* emptyRegisterMask */); - genLoadStackPointers(backEnd()); - genTrampolineReturn(pushLinkReg); - jmpTarget(jumpImmutable1, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileCallFornumArgsargargargargresultRegregsToSave(ceCannotAssignTowithIndexvalueToAssign, 3, ReceiverResultReg, (instVarIndex < (NumStoreTrampolines - 1) - ? (/* begin trampolineArgConstant: */ - assert(instVarIndex >= 0), - -2 - instVarIndex) - : TempReg), ClassReg, null, NoReg, 0 /* emptyRegisterMask */); - genLoadStackPointers(backEnd()); - genTrampolineReturn(pushLinkReg); - } - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress(trampolineName, startAddress); - recordRunTimeObjectReferences(); - return startAddress; -} -#endif /* IMMUTABILITY */ - - -/* Store check code is duplicated to use a single trampoline */ - - /* CogObjectRepresentationForSpur>>#genStoreWithImmutabilityAndStoreCheckSourceReg:slotIndex:destReg:scratchReg:needRestoreRcvr: */ -#if IMMUTABILITY -static sqInt NoDbgRegParms -genStoreWithImmutabilityAndStoreCheckSourceRegslotIndexdestRegscratchRegneedRestoreRcvr(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt needRestoreRcvr) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *abstractInstruction2; - AbstractInstruction *abstractInstruction3; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *immutableJump; - AbstractInstruction *jmpAlreadyRemembered; - AbstractInstruction *jmpDestYoung; - AbstractInstruction *jmpImmediate; - AbstractInstruction *jmpSourceOld; - - jmpAlreadyRemembered = ((AbstractInstruction *) 0); - immutableJump = genJumpImmutablescratchReg(destReg, scratchReg); - /* begin genTraceStores */ - if (traceStores > 0) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, TempReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceTraceStoreTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveRMwr, sourceReg, (index * BytesPerWord) + BaseHeaderSize, destReg); - - /* Get the old/new boundary in scratchReg */ - jmpImmediate = genJumpImmediate(sourceReg); - /* begin checkLiteral:forInstruction: */ - storeCheckBoundary(); - anInstruction1 = genoperandoperand(MoveCwR, storeCheckBoundary(), scratchReg); - /* begin CmpR:R: */ - assert(!((scratchReg == SPReg))); - genoperandoperand(CmpRR, scratchReg, destReg); - /* begin JumpBelow: */ - jmpDestYoung = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((scratchReg == SPReg))); - genoperandoperand(CmpRR, scratchReg, sourceReg); - /* begin JumpAboveOrEqual: */ - jmpSourceOld = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - if (!CheckRememberedInTrampoline) { - jmpAlreadyRemembered = genCheckRememberedBitOfscratch(destReg, scratchReg); - } - jmpTarget(immutableJump, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin genStoreTrampolineCall: */ - assert(IMMUTABILITY); - if (index >= (NumStoreTrampolines - 1)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, index, TempReg); - /* begin CallRT: */ - abstractInstruction3 = genoperand(Call, ceStoreTrampolines[NumStoreTrampolines - 1]); - (abstractInstruction3->annotation = IsRelativeCall); - } - else { - /* begin CallRT: */ - abstractInstruction1 = genoperand(Call, ceStoreTrampolines[index]); - (abstractInstruction1->annotation = IsRelativeCall); - } - /* begin annotateBytecode: */ - abstractInstruction2 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction2->annotation = HasBytecodePC); - /* begin voidReceiverOptStatus */ - ((simSelf())->liveRegister = NoReg); - if (needRestoreRcvr) { - /* begin putSelfInReceiverResultReg */ - storeToReg(simSelf(), ReceiverResultReg); - } - jmpTarget(jmpImmediate, jmpTarget(jmpDestYoung, jmpTarget(jmpSourceOld, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))); - if (!CheckRememberedInTrampoline) { - jmpTarget(jmpAlreadyRemembered, ((AbstractInstruction *) (((jmpSourceOld->operands))[0]))); - } - return 0; -} -#endif /* IMMUTABILITY */ - - -/* Gen an immutability check with no store check (e.g. assigning an immediate - literal) - */ -/* imm check has its own trampoline */ - - /* CogObjectRepresentationForSpur>>#genStoreWithImmutabilityButNoStoreCheckSourceReg:slotIndex:destReg:scratchReg:needRestoreRcvr: */ -#if IMMUTABILITY -static sqInt NoDbgRegParms -genStoreWithImmutabilityButNoStoreCheckSourceRegslotIndexdestRegscratchRegneedRestoreRcvr(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt needRestoreRcvr) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *abstractInstruction2; - AbstractInstruction *abstractInstruction3; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *immutabilityFailure; - AbstractInstruction *mutableJump; - - mutableJump = genJumpMutablescratchReg(destReg, scratchReg); - /* begin genStoreTrampolineCall: */ - assert(IMMUTABILITY); - if (index >= (NumStoreTrampolines - 1)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, index, TempReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceStoreTrampolines[NumStoreTrampolines - 1]); - (abstractInstruction->annotation = IsRelativeCall); - } - else { - /* begin CallRT: */ - abstractInstruction1 = genoperand(Call, ceStoreTrampolines[index]); - (abstractInstruction1->annotation = IsRelativeCall); - } - /* begin annotateBytecode: */ - abstractInstruction2 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction2->annotation = HasBytecodePC); - /* begin voidReceiverOptStatus */ - ((simSelf())->liveRegister = NoReg); - if (needRestoreRcvr) { - /* begin putSelfInReceiverResultReg */ - storeToReg(simSelf(), ReceiverResultReg); - } - /* begin Jump: */ - immutabilityFailure = genoperand(Jump, ((sqInt)0)); - jmpTarget(mutableJump, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin genTraceStores */ - if (traceStores > 0) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, TempReg); - /* begin CallRT: */ - abstractInstruction3 = genoperand(Call, ceTraceStoreTrampoline); - (abstractInstruction3->annotation = IsRelativeCall); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveRMwr, sourceReg, (index * BytesPerWord) + BaseHeaderSize, destReg); - jmpTarget(immutabilityFailure, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} -#endif /* IMMUTABILITY */ - - -/* We know there is a frame as immutability check requires a frame */ -/* needRestoreRcvr has to be true to keep RcvrResultReg live with the - receiver in it across the trampoline - */ -/* Trampoline convention... */ - - /* CogObjectRepresentationForSpur>>#genStoreWithImmutabilityCheckSourceReg:slotIndex:destReg:scratchReg:needsStoreCheck:needRestoreRcvr: */ -#if IMMUTABILITY -static sqInt NoDbgRegParms -genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt needsStoreCheck, sqInt needRestoreRcvr) -{ - assert(destReg == ReceiverResultReg); - assert(scratchReg == TempReg); - assert(sourceReg == ClassReg); - if (needsStoreCheck) { - genStoreWithImmutabilityAndStoreCheckSourceRegslotIndexdestRegscratchRegneedRestoreRcvr(sourceReg, index, destReg, scratchReg, needRestoreRcvr); - } - else { - genStoreWithImmutabilityButNoStoreCheckSourceRegslotIndexdestRegscratchRegneedRestoreRcvr(sourceReg, index, destReg, scratchReg, needRestoreRcvr); - } - return 0; -} -#endif /* IMMUTABILITY */ - - -/* Make sure SendNumArgsReg and ClassReg are available in addition to - ReceiverResultReg and TempReg in - genGetActiveContextNumArgs:large:inBlock:. - */ - - /* CogObjectRepresentationForSpur>>#getActiveContextAllocatesInMachineCode */ -static sqInt -getActiveContextAllocatesInMachineCode(void) -{ - return 1; -} - - -/* Since all cache tags in Spur are class indices none of - them are young or have to be updated in a scavenge. */ - - /* CogObjectRepresentationForSpur>>#inlineCacheTagIsYoung: */ -static sqInt NoDbgRegParms -inlineCacheTagIsYoung(sqInt cacheTag) -{ - return 0; -} - - /* CogObjectRepresentationForSpur>>#jumpNotCharacterUnsignedValueInRegister: */ -static AbstractInstruction * NoDbgRegParms -jumpNotCharacterUnsignedValueInRegister(sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin CmpCq:R: */ - anInstruction = genoperandoperand(CmpCqR, 0x3FFFFFFF, reg); - /* begin JumpAbove: */ - return genConditionalBranchoperand(JumpAbove, ((sqInt)0)); -} - - -/* Mark and trace a literal in a machine code instruction preceding address - in cogMethodOrNil. - Answer if code was modified. */ - - /* CogObjectRepresentationForSpur>>#markAndTraceLiteral:in:atpc: */ -static sqInt NoDbgRegParms -markAndTraceLiteralinatpc(sqInt literal, CogMethod *cogMethodOrNil, usqInt address) -{ - sqInt objOop; - - if (!(couldBeObject(literal))) { - return 0; - } - assert(addressCouldBeObj(literal)); - if (!(isForwarded(literal))) { - markAndTrace(literal); - return 0; - } - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - objOop = followForwarded(literal); - storeLiteralbeforeFollowingAddress(backEnd(), objOop, address); - markAndTraceUpdatedLiteralin(objOop, cogMethodOrNil); - return 1; -} - - -/* Mark and trace a literal in a sqInt variable of cogMethod. */ - - /* CogObjectRepresentationForSpur>>#markAndTraceLiteral:in:at: */ -static void NoDbgRegParms -markAndTraceLiteralinat(sqInt literal, CogMethod *cogMethod, sqInt *address) -{ - sqInt objOop; - - if (!(couldBeObject(literal))) { - return; - } - assert(addressCouldBeObj(literal)); - if (!(isForwarded(literal))) { - markAndTrace(literal); - return; - } - objOop = followForwarded(literal); - address[0] = objOop; - markAndTraceUpdatedLiteralin(objOop, cogMethod); -} - - -/* Common code to mark a literal in cogMethod and add - the cogMethod to youngReferrers if the literal is young. */ - - /* CogObjectRepresentationForSpur>>#markAndTraceUpdatedLiteral:in: */ -static void NoDbgRegParms -markAndTraceUpdatedLiteralin(sqInt objOop, CogMethod *cogMethodOrNil) -{ - if (isNonImmediate(objOop)) { - if ((cogMethodOrNil != null) - && (isYoungObject(objOop))) { - ensureInYoungReferrers(cogMethodOrNil); - } - markAndTrace(objOop); - } -} - - -/* If primIndex has an accessorDepth and fails, or it is external and fails - with PrimErrNoMemory, - call ceCheckAndMaybeRetryPrimitive if so If ceCheck.... answers true, - retry the primitive. */ - - /* CogObjectRepresentationForSpur>>#maybeCompileRetryOnPrimitiveFail: */ -static sqInt NoDbgRegParms -maybeCompileRetryOnPrimitiveFail(sqInt primIndex) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *jmp; - - if ((accessorDepthForPrimitiveIndex(primIndex)) >= 0) { - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpZero: */ - jmp = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - } - else { - if ((primNumberExternalCall()) != primIndex) { - return 0; - } - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction2 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(CmpCqR, PrimErrNoMemory, TempReg); - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - } - compileCallFornumArgsargargargargresultRegregsToSave(ceCheckAndMaybeRetryPrimitive, 1, trampolineArgConstant(primIndex), null, null, null, TempReg, 0 /* emptyRegisterMask */); - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - -/* Generate a shift of the register containing the class tag in a method - cache probe. - c.f. SpurMemoryManager>>methodCacheHashOf:with: */ - - /* CogObjectRepresentationForSpur>>#maybeShiftClassTagRegisterForMethodCacheProbe: */ -static sqInt NoDbgRegParms -maybeShiftClassTagRegisterForMethodCacheProbe(sqInt classTagReg) -{ - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, 2, classTagReg); - return 0; -} - - /* CogObjectRepresentationForSpur>>#numCharacterBits */ -static sqInt -numCharacterBits(void) -{ - return 30; -} - - -/* Define how many register arguments a StackToRegisterMappingCogit can - and should use with the receiver. The value must be 0, 1 or 2. Note that a - SimpleStackBasedCogit always has 0 register args (although the receiver is - passed in a register). The Spur object representation is simple enough - that implementing at:put: is straight-forward and hence 2 register args - are worth - while. The method must be inlined in CoInterpreter, and dead code - eliminated so that the register-popping enilopmarts such as - enterRegisterArgCogMethod:- at:receiver: do not have to be implemented in - SimpleStackBasedCogit. */ - - /* CogObjectRepresentationForSpur>>#numRegArgs */ -sqInt -numRegArgs(void) -{ - return 2; -} - - /* CogObjectRepresentationForSpur>>#remapObject: */ -static sqInt NoDbgRegParms -remapObject(sqInt objOop) -{ - assert(addressCouldBeObj(objOop)); - return (shouldRemapObj(objOop) - ? remapObj(objOop) - : objOop); -} - - /* CogObjectRepresentationForSpur>>#remapOop: */ -static sqInt NoDbgRegParms -remapOop(sqInt objOop) -{ - return (shouldRemapOop(objOop) - ? remapObj(objOop) - : objOop); -} - - -/* Objects in newSpace or oldSpace except nil, true, false & - classTableRootObj need to be annotated. - */ - - /* CogObjectRepresentationForSpur>>#shouldAnnotateObjectReference: */ -static sqInt NoDbgRegParms -shouldAnnotateObjectReference(sqInt anOop) -{ - return (isNonImmediate(anOop)) - && ((oopisGreaterThan(anOop, classTableRootObj())) - || (oopisLessThan(anOop, nilObject()))); -} - - /* CogObjectRepresentationForSpur>>#slotOffsetOfInstVarIndex: */ -static sqInt NoDbgRegParms -slotOffsetOfInstVarIndex(sqInt index) -{ - return (index * BytesPerWord) + BaseHeaderSize; -} - - /* CogSimStackEntry>>#ensureSpilledAt:from: */ -static SimStackEntry * NoDbgRegParms -ensureSpilledAtfrom(SimStackEntry * self_in_ensureSpilledAtfrom, sqInt baseOffset, sqInt baseRegister) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *inst; - sqInt reg; - sqInt wordConstant; - - if ((self_in_ensureSpilledAtfrom->spilled)) { - if (((self_in_ensureSpilledAtfrom->type)) == SSSpill) { - assert(((((self_in_ensureSpilledAtfrom->offset)) == baseOffset) - && (((self_in_ensureSpilledAtfrom->registerr)) == baseRegister)) - || (violatesEnsureSpilledSpillAssert())); - return self_in_ensureSpilledAtfrom; - } - } - assert(((self_in_ensureSpilledAtfrom->type)) != SSSpill); - traceSpill(self_in_ensureSpilledAtfrom); - if (((self_in_ensureSpilledAtfrom->type)) == SSConstant) { - if (shouldAnnotateObjectReference((self_in_ensureSpilledAtfrom->constant))) { - inst = annotateobjRef(gPushCw((self_in_ensureSpilledAtfrom->constant)), (self_in_ensureSpilledAtfrom->constant)); - } - else { - /* begin PushCq: */ - wordConstant = (self_in_ensureSpilledAtfrom->constant); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperand(PushCq, wordConstant); - inst = anInstruction; - } - } - else { - if (((self_in_ensureSpilledAtfrom->type)) == SSBaseOffset) { - /* begin checkQuickConstant:forInstruction: */ - (self_in_ensureSpilledAtfrom->offset); - anInstruction1 = genoperandoperandoperand(MoveMwrR, (self_in_ensureSpilledAtfrom->offset), (self_in_ensureSpilledAtfrom->registerr), TempReg); - /* begin PushR: */ - inst = genoperand(PushR, TempReg); - } - else { - assert(((self_in_ensureSpilledAtfrom->type)) == SSRegister); - /* begin PushR: */ - reg = (self_in_ensureSpilledAtfrom->registerr); - inst = genoperand(PushR, reg); - } - (self_in_ensureSpilledAtfrom->type) = SSSpill; - (self_in_ensureSpilledAtfrom->offset) = baseOffset; - (self_in_ensureSpilledAtfrom->registerr) = baseRegister; - } - (self_in_ensureSpilledAtfrom->spilled) = 1; - return 0; -} - - /* CogSimStackEntry>>#isSameEntryAs: */ -static sqInt NoDbgRegParms -isSameEntryAs(SimStackEntry * self_in_isSameEntryAs, CogSimStackEntry *ssEntry) -{ - return (((self_in_isSameEntryAs->type)) == ((ssEntry->type))) - && ((((((self_in_isSameEntryAs->type)) == SSBaseOffset) - || (((self_in_isSameEntryAs->type)) == SSSpill)) - && ((((self_in_isSameEntryAs->offset)) == ((ssEntry->offset))) - && (((self_in_isSameEntryAs->registerr)) == ((ssEntry->registerr))))) - || (((((self_in_isSameEntryAs->type)) == SSRegister) - && (((self_in_isSameEntryAs->registerr)) == ((ssEntry->registerr)))) - || ((((self_in_isSameEntryAs->type)) == SSConstant) - && (((self_in_isSameEntryAs->constant)) == ((ssEntry->constant)))))); -} - - -/* Receiver is not a forwarder, except in blocks with no inst var access. - For now we optimize only the case where receiver is accessed in a method. */ - - /* CogSimStackEntry>>#mayBeAForwarder */ -static sqInt NoDbgRegParms -mayBeAForwarder(SimStackEntry * self_in_mayBeAForwarder) -{ - if ((((self_in_mayBeAForwarder->type)) == SSRegister) - && (isNonForwarderReceiver((self_in_mayBeAForwarder->registerr)))) { - return 0; - } - return ((self_in_mayBeAForwarder->type)) != SSConstant; -} - - /* CogSimStackEntry>>#popToReg: */ -static void NoDbgRegParms -popToReg(SimStackEntry * self_in_popToReg, sqInt reg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt quickConstant; - sqInt reg1; - - if ((self_in_popToReg->spilled)) { - /* begin PopR: */ - genoperand(PopR, reg); - } - else { - switch ((self_in_popToReg->type)) { - case SSBaseOffset: - /* begin checkQuickConstant:forInstruction: */ - (self_in_popToReg->offset); - anInstruction = genoperandoperandoperand(MoveMwrR, (self_in_popToReg->offset), (self_in_popToReg->registerr), reg); - break; - case SSConstant: - if (shouldAnnotateObjectReference((self_in_popToReg->constant))) { - annotateobjRef(gMoveCwR((self_in_popToReg->constant), reg), (self_in_popToReg->constant)); - } - else { - /* begin MoveCq:R: */ - quickConstant = (self_in_popToReg->constant); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, quickConstant, reg); - } - break; - case SSRegister: - if (reg != ((self_in_popToReg->registerr))) { - /* begin MoveR:R: */ - reg1 = (self_in_popToReg->registerr); - genoperandoperand(MoveRR, reg1, reg); - } - else { - /* begin Label */ - genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - break; - default: - error("Case not found and no otherwise clause"); - } - } -} - - -/* Answer a bit mask for the receiver's register, if any. */ - - /* CogSimStackEntry>>#registerMask */ -static sqInt NoDbgRegParms -registerMask(SimStackEntry * self_in_registerMask) -{ - sqInt reg; - - return ((((self_in_registerMask->type)) == SSBaseOffset) - || (((self_in_registerMask->type)) == SSRegister) - ? (/* begin registerMaskFor: */ - (reg = (self_in_registerMask->registerr)), - 1U << reg) - : 0); -} - - /* CogSimStackEntry>>#registerMaskOrNone */ -static sqInt NoDbgRegParms -registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone) -{ - sqInt reg; - - return (((self_in_registerMaskOrNone->type)) == SSRegister - ? (/* begin registerMaskFor: */ - (reg = (self_in_registerMaskOrNone->registerr)), - 1U << reg) - : 0); -} - - /* CogSimStackEntry>>#registerOrNone */ -static sqInt NoDbgRegParms -registerOrNone(SimStackEntry * self_in_registerOrNone) -{ - return (((self_in_registerOrNone->type)) == SSRegister - ? (self_in_registerOrNone->registerr) - : NoReg); -} - - /* CogSimStackEntry>>#storeToReg: */ -static void NoDbgRegParms -storeToReg(SimStackEntry * self_in_storeToReg, sqInt reg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt quickConstant; - sqInt reg1; - - switch ((self_in_storeToReg->type)) { - case SSBaseOffset: - case SSSpill: - /* begin checkQuickConstant:forInstruction: */ - (self_in_storeToReg->offset); - anInstruction = genoperandoperandoperand(MoveMwrR, (self_in_storeToReg->offset), (self_in_storeToReg->registerr), reg); - break; - case SSConstant: - if (shouldAnnotateObjectReference((self_in_storeToReg->constant))) { - annotateobjRef(gMoveCwR((self_in_storeToReg->constant), reg), (self_in_storeToReg->constant)); - } - else { - /* begin MoveCq:R: */ - quickConstant = (self_in_storeToReg->constant); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, quickConstant, reg); - } - break; - case SSRegister: - if (reg != ((self_in_storeToReg->registerr))) { - /* begin MoveR:R: */ - reg1 = (self_in_storeToReg->registerr); - genoperandoperand(MoveRR, reg1, reg); - } - else { - /* begin Label */ - genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - break; - default: - error("Case not found and no otherwise clause"); - } -} - - /* CogSimStackNativeEntry>>#ensureIsMarkedAsSpilled */ -static void NoDbgRegParms -ensureIsMarkedAsSpilled(CogSimStackNativeEntry * self_in_ensureIsMarkedAsSpilled) -{ - if (!((self_in_ensureIsMarkedAsSpilled->spilled))) { - switch ((self_in_ensureIsMarkedAsSpilled->type)) { - case SSNativeRegister: - case SSConstantInt32: - case SSConstantNativePointer: - (self_in_ensureIsMarkedAsSpilled->type) = SSSpillNative; - break; - case SSRegisterSingleFloat: - case SSConstantFloat32: - (self_in_ensureIsMarkedAsSpilled->type) = SSSpillFloat32; - break; - case SSRegisterDoubleFloat: - case SSConstantFloat64: - (self_in_ensureIsMarkedAsSpilled->type) = SSSpillFloat64; - break; - default: - error("Case not found and no otherwise clause"); - } - } - (self_in_ensureIsMarkedAsSpilled->spilled) = 1; -} - - /* CogSimStackNativeEntry>>#ensureSpilledSP:scratchRegister: */ -static void NoDbgRegParms -ensureSpilledSPscratchRegister(CogSimStackNativeEntry * self_in_ensureSpilledSPscratchRegister, sqInt spRegister, sqInt scratchRegister) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt wordConstant; - sqInt wordConstant1; - - if (!((self_in_ensureSpilledSPscratchRegister->spilled))) { - switch ((self_in_ensureSpilledSPscratchRegister->type)) { - case SSNativeRegister: - /* begin checkQuickConstant:forInstruction: */ - (-((self_in_ensureSpilledSPscratchRegister->offset))) - 1; - anInstruction = genoperandoperandoperand(MoveRMwr, (self_in_ensureSpilledSPscratchRegister->registerr), (-((self_in_ensureSpilledSPscratchRegister->offset))) - 1, spRegister); - (self_in_ensureSpilledSPscratchRegister->type) = SSSpillNative; - break; - case SSRegisterSingleFloat: - /* begin checkQuickConstant:forInstruction: */ - (-((self_in_ensureSpilledSPscratchRegister->offset))) - 1; - anInstruction1 = genoperandoperandoperand(MoveRsM32r, (self_in_ensureSpilledSPscratchRegister->registerr), (-((self_in_ensureSpilledSPscratchRegister->offset))) - 1, spRegister); - (self_in_ensureSpilledSPscratchRegister->type) = SSSpillFloat32; - break; - case SSRegisterDoubleFloat: - /* begin checkQuickConstant:forInstruction: */ - (-((self_in_ensureSpilledSPscratchRegister->offset))) - 1; - anInstruction2 = genoperandoperandoperand(MoveRdM64r, (self_in_ensureSpilledSPscratchRegister->registerr), (-((self_in_ensureSpilledSPscratchRegister->offset))) - 1, spRegister); - (self_in_ensureSpilledSPscratchRegister->type) = SSSpillFloat64; - break; - case SSConstantFloat32: - /* begin checkLiteral:forInstruction: */ - asIEEE32BitWord((self_in_ensureSpilledSPscratchRegister->constantFloat32)); - anInstruction3 = genoperandoperand(MoveCwR, asIEEE32BitWord((self_in_ensureSpilledSPscratchRegister->constantFloat32)), scratchRegister); - /* begin checkQuickConstant:forInstruction: */ - (-((self_in_ensureSpilledSPscratchRegister->offset))) - 1; - anInstruction4 = genoperandoperandoperand(MoveRM32r, scratchRegister, (-((self_in_ensureSpilledSPscratchRegister->offset))) - 1, spRegister); - (self_in_ensureSpilledSPscratchRegister->type) = SSSpillFloat32; - break; - case SSConstantFloat64: - if (BytesPerWord == 4) { - /* begin MoveCw:R: */ - wordConstant = (asIEEE64BitWord((self_in_ensureSpilledSPscratchRegister->constantFloat64))) & 0xFFFFFFFFU; - /* begin checkLiteral:forInstruction: */ - anInstruction5 = genoperandoperand(MoveCwR, wordConstant, scratchRegister); - /* begin checkQuickConstant:forInstruction: */ - (-((self_in_ensureSpilledSPscratchRegister->offset))) - 1; - anInstruction6 = genoperandoperandoperand(MoveRM32r, scratchRegister, (-((self_in_ensureSpilledSPscratchRegister->offset))) - 1, spRegister); - /* begin MoveCw:R: */ - wordConstant1 = (((((sqLong) -32)) < 0) ? (((usqInt)((asIEEE64BitWord((self_in_ensureSpilledSPscratchRegister->constantFloat64))))) >> (-(((sqLong) -32)))) : (((sqInt)((usqInt)((asIEEE64BitWord((self_in_ensureSpilledSPscratchRegister->constantFloat64)))) << (((sqLong) -32)))))); - /* begin checkLiteral:forInstruction: */ - anInstruction7 = genoperandoperand(MoveCwR, wordConstant1, scratchRegister); - /* begin checkQuickConstant:forInstruction: */ - ((-((self_in_ensureSpilledSPscratchRegister->offset))) - 1) + 4; - anInstruction8 = genoperandoperandoperand(MoveRM32r, scratchRegister, ((-((self_in_ensureSpilledSPscratchRegister->offset))) - 1) + 4, spRegister); - } - else { - /* begin checkLiteral:forInstruction: */ - asIEEE64BitWord((self_in_ensureSpilledSPscratchRegister->constantFloat32)); - anInstruction9 = genoperandoperand(MoveCwR, asIEEE64BitWord((self_in_ensureSpilledSPscratchRegister->constantFloat32)), scratchRegister); - /* begin checkQuickConstant:forInstruction: */ - (-((self_in_ensureSpilledSPscratchRegister->offset))) - 1; - anInstruction10 = genoperandoperandoperand(MoveRMwr, scratchRegister, (-((self_in_ensureSpilledSPscratchRegister->offset))) - 1, spRegister); - } - (self_in_ensureSpilledSPscratchRegister->type) = SSSpillFloat64; - break; - case SSConstantInt32: - /* begin checkQuickConstant:forInstruction: */ - (self_in_ensureSpilledSPscratchRegister->constantInt32); - anInstruction11 = genoperandoperand(MoveCqR, (self_in_ensureSpilledSPscratchRegister->constantInt32), scratchRegister); - /* begin checkQuickConstant:forInstruction: */ - (-((self_in_ensureSpilledSPscratchRegister->offset))) - 1; - anInstruction12 = genoperandoperandoperand(MoveRMwr, scratchRegister, (-((self_in_ensureSpilledSPscratchRegister->offset))) - 1, spRegister); - (self_in_ensureSpilledSPscratchRegister->type) = SSSpillNative; - break; - case SSConstantNativePointer: - /* begin checkLiteral:forInstruction: */ - (self_in_ensureSpilledSPscratchRegister->constantNativePointer); - anInstruction13 = genoperandoperand(MoveCwR, (self_in_ensureSpilledSPscratchRegister->constantNativePointer), scratchRegister); - /* begin checkQuickConstant:forInstruction: */ - (-((self_in_ensureSpilledSPscratchRegister->offset))) - 1; - anInstruction14 = genoperandoperandoperand(MoveRMwr, scratchRegister, (-((self_in_ensureSpilledSPscratchRegister->offset))) - 1, spRegister); - (self_in_ensureSpilledSPscratchRegister->type) = SSSpillNative; - break; - default: - error("Case not found and no otherwise clause"); - } - } - (self_in_ensureSpilledSPscratchRegister->spilled) = 1; -} - - -/* Answer a bit mask for the receiver's register, if any. */ - - /* CogSimStackNativeEntry>>#nativeFloatRegisterMask */ -static sqInt NoDbgRegParms -nativeFloatRegisterMask(CogSimStackNativeEntry * self_in_nativeFloatRegisterMask) -{ - sqInt reg; - - return ((((self_in_nativeFloatRegisterMask->type)) == SSRegisterSingleFloat) - || (((self_in_nativeFloatRegisterMask->type)) == SSRegisterDoubleFloat) - ? (/* begin registerMaskFor: */ - (reg = (self_in_nativeFloatRegisterMask->registerr)), - 1U << reg) - : 0); -} - - /* CogSimStackNativeEntry>>#nativeFloatRegisterOrNone */ -static sqInt NoDbgRegParms -nativeFloatRegisterOrNone(CogSimStackNativeEntry * self_in_nativeFloatRegisterOrNone) -{ - return ((((self_in_nativeFloatRegisterOrNone->type)) == SSRegisterSingleFloat) - || (((self_in_nativeFloatRegisterOrNone->type)) == SSRegisterDoubleFloat) - ? (self_in_nativeFloatRegisterOrNone->registerr) - : NoReg); -} - - /* CogSimStackNativeEntry>>#nativePopToReg: */ -static void NoDbgRegParms -nativePopToReg(CogSimStackNativeEntry * self_in_nativePopToReg, sqInt reg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - float constantFloat32; - double constantFloat64; - sqInt dpreg1; - sqInt dpreg11; - sqInt reg1; - - if ((self_in_nativePopToReg->spilled)) { - loadNativeFramePointerInto(TempReg); - switch ((self_in_nativePopToReg->type)) { - case SSSpillNative: - /* begin checkQuickConstant:forInstruction: */ - (-((self_in_nativePopToReg->offset))) - 1; - anInstruction = genoperandoperandoperand(MoveMwrR, (-((self_in_nativePopToReg->offset))) - 1, TempReg, reg); - break; - case SSSpillInt64: - assert(BytesPerWord == 8); - /* begin checkQuickConstant:forInstruction: */ - (-((self_in_nativePopToReg->offset))) - 1; - anInstruction1 = genoperandoperandoperand(MoveMwrR, (-((self_in_nativePopToReg->offset))) - 1, TempReg, reg); - break; - case SSSpillFloat32: - /* begin checkQuickConstant:forInstruction: */ - (-((self_in_nativePopToReg->offset))) - 1; - anInstruction2 = genoperandoperandoperand(MoveM32rRs, (-((self_in_nativePopToReg->offset))) - 1, TempReg, reg); - break; - case SSSpillFloat64: - /* begin checkQuickConstant:forInstruction: */ - (-((self_in_nativePopToReg->offset))) - 1; - anInstruction3 = genoperandoperandoperand(MoveM64rRd, (-((self_in_nativePopToReg->offset))) - 1, TempReg, reg); - break; - default: - error("Case not found and no otherwise clause"); - } - } - else { - switch ((self_in_nativePopToReg->type)) { - case SSNativeRegister: - if (reg != ((self_in_nativePopToReg->registerr))) { - /* begin MoveR:R: */ - reg1 = (self_in_nativePopToReg->registerr); - genoperandoperand(MoveRR, reg1, reg); - } - break; - case SSRegisterSingleFloat: - if (reg != ((self_in_nativePopToReg->registerr))) { - /* begin MoveRs:Rs: */ - dpreg1 = (self_in_nativePopToReg->registerr); - genoperandoperand(MoveRsRs, dpreg1, reg); - } - break; - case SSRegisterDoubleFloat: - if (reg != ((self_in_nativePopToReg->registerr))) { - /* begin MoveRd:Rd: */ - dpreg11 = (self_in_nativePopToReg->registerr); - genoperandoperand(MoveRdRd, dpreg11, reg); - } - break; - case SSConstantInt32: - /* begin checkQuickConstant:forInstruction: */ - (self_in_nativePopToReg->constantInt32); - anInstruction4 = genoperandoperand(MoveCqR, (self_in_nativePopToReg->constantInt32), reg); - break; - case SSConstantNativePointer: - /* begin checkLiteral:forInstruction: */ - (self_in_nativePopToReg->constantNativePointer); - anInstruction5 = genoperandoperand(MoveCwR, (self_in_nativePopToReg->constantNativePointer), reg); - break; - case SSConstantFloat32: - /* begin MoveCf32:Rs: */ - constantFloat32 = (self_in_nativePopToReg->constantFloat32); - genMoveCf32Rs(backEnd, constantFloat32, reg); - break; - case SSConstantFloat64: - /* begin MoveCf64:Rd: */ - constantFloat64 = (self_in_nativePopToReg->constantFloat64); - genMoveCf64Rd(backEnd, constantFloat64, reg); - break; - default: - error("Case not found and no otherwise clause"); - } - } -} - - /* CogSimStackNativeEntry>>#nativePopToReg:secondReg: */ -static void NoDbgRegParms -nativePopToRegsecondReg(CogSimStackNativeEntry * self_in_nativePopToRegsecondReg, sqInt reg, sqInt secondReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt reg1; - sqInt reg11; - sqInt reg12; - - assert(BytesPerWord == 4); - if ((self_in_nativePopToRegsecondReg->spilled)) { - /* begin PopR: */ - genoperand(PopR, reg); - /* begin PopR: */ - genoperand(PopR, secondReg); - } - else { - switch ((self_in_nativePopToRegsecondReg->type)) { - case SSConstantInt64: - /* begin checkQuickConstant:forInstruction: */ - ((sqInt) (((self_in_nativePopToRegsecondReg->constantInt64)) & 0xFFFFFFFFU)); - anInstruction = genoperandoperand(MoveCqR, ((self_in_nativePopToRegsecondReg->constantInt64)) & 0xFFFFFFFFU, reg); - /* begin checkQuickConstant:forInstruction: */ - ((sqInt) ((((usqLong)(((self_in_nativePopToRegsecondReg->constantInt64)))) >> 32) & 0xFFFFFFFFU)); - anInstruction1 = genoperandoperand(MoveCqR, (((usqLong)(((self_in_nativePopToRegsecondReg->constantInt64)))) >> 32) & 0xFFFFFFFFU, secondReg); - break; - case SSRegisterPair: - /* begin Label */ - genoperandoperand(Label, (labelCounter += 1), bytecodePC); - if (reg != ((self_in_nativePopToRegsecondReg->registerr))) { - if (((self_in_nativePopToRegsecondReg->registerSecond)) == reg) { - /* begin MoveR:R: */ - reg1 = (self_in_nativePopToRegsecondReg->registerSecond); - genoperandoperand(MoveRR, reg1, TempReg); - } - /* begin MoveR:R: */ - reg11 = (self_in_nativePopToRegsecondReg->registerr); - genoperandoperand(MoveRR, reg11, reg); - } - if (((self_in_nativePopToRegsecondReg->registerSecond)) != secondReg) { - if (((self_in_nativePopToRegsecondReg->registerSecond)) == reg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, secondReg); - } - else { - /* begin MoveR:R: */ - reg12 = (self_in_nativePopToRegsecondReg->registerSecond); - genoperandoperand(MoveRR, reg12, secondReg); - } - } - break; - default: - error("Case not found and no otherwise clause"); - } - } -} - - -/* Answer a bit mask for the receiver's register, if any. */ - - /* CogSimStackNativeEntry>>#nativeRegisterMask */ -static sqInt NoDbgRegParms -nativeRegisterMask(CogSimStackNativeEntry * self_in_nativeRegisterMask) -{ - sqInt reg; - - return ((((((self_in_nativeRegisterMask->type)) == SSBaseOffset) - || (((self_in_nativeRegisterMask->type)) == SSNativeRegister)) - || (((self_in_nativeRegisterMask->type)) == SSRegisterSingleFloat)) - || (((self_in_nativeRegisterMask->type)) == SSRegisterDoubleFloat) - ? (/* begin registerMaskFor: */ - (reg = (self_in_nativeRegisterMask->registerr)), - 1U << reg) - : (((self_in_nativeRegisterMask->type)) == SSRegisterPair - ? (1U << ((self_in_nativeRegisterMask->registerr))) | (1U << ((self_in_nativeRegisterMask->registerSecond))) - : 0)); -} - - /* CogSimStackNativeEntry>>#nativeRegisterOrNone */ -static sqInt NoDbgRegParms -nativeRegisterOrNone(CogSimStackNativeEntry * self_in_nativeRegisterOrNone) -{ - return ((((self_in_nativeRegisterOrNone->type)) == SSNativeRegister) - || (((self_in_nativeRegisterOrNone->type)) == SSRegisterPair) - ? (self_in_nativeRegisterOrNone->registerr) - : NoReg); -} - - /* CogSimStackNativeEntry>>#nativeRegisterSecondOrNone */ -static sqInt NoDbgRegParms -nativeRegisterSecondOrNone(CogSimStackNativeEntry * self_in_nativeRegisterSecondOrNone) -{ - return (((self_in_nativeRegisterSecondOrNone->type)) == SSRegisterPair - ? (self_in_nativeRegisterSecondOrNone->registerSecond) - : NoReg); -} - - /* CogSimStackNativeEntry>>#nativeStackPopToReg: */ -static void NoDbgRegParms -nativeStackPopToReg(CogSimStackNativeEntry * self_in_nativeStackPopToReg, sqInt reg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - - assert((self_in_nativeStackPopToReg->spilled)); - switch ((self_in_nativeStackPopToReg->type)) { - case SSSpillNative: - /* begin checkQuickConstant:forInstruction: */ - -((self_in_nativeStackPopToReg->offset)); - anInstruction = genoperandoperandoperand(MoveMwrR, -((self_in_nativeStackPopToReg->offset)), FPReg, reg); - break; - case SSSpillInt64: - assert(BytesPerWord == 8); - /* begin checkQuickConstant:forInstruction: */ - -((self_in_nativeStackPopToReg->offset)); - anInstruction1 = genoperandoperandoperand(MoveMwrR, -((self_in_nativeStackPopToReg->offset)), FPReg, reg); - break; - case SSSpillFloat32: - /* begin checkQuickConstant:forInstruction: */ - -((self_in_nativeStackPopToReg->offset)); - anInstruction2 = genoperandoperandoperand(MoveM32rRs, -((self_in_nativeStackPopToReg->offset)), FPReg, reg); - break; - case SSSpillFloat64: - /* begin checkQuickConstant:forInstruction: */ - -((self_in_nativeStackPopToReg->offset)); - anInstruction3 = genoperandoperandoperand(MoveM64rRd, -((self_in_nativeStackPopToReg->offset)), FPReg, reg); - break; - default: - error("Case not found and no otherwise clause"); - } -} - - /* CogSimStackNativeEntry>>#nativeStackPopToReg:secondReg: */ -static void NoDbgRegParms -nativeStackPopToRegsecondReg(CogSimStackNativeEntry * self_in_nativeStackPopToRegsecondReg, sqInt reg, sqInt secondReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - assert((self_in_nativeStackPopToRegsecondReg->spilled)); - switch ((self_in_nativeStackPopToRegsecondReg->type)) { - case SSSpillInt64: - /* begin checkQuickConstant:forInstruction: */ - (-((self_in_nativeStackPopToRegsecondReg->offset))) + 4; - anInstruction = genoperandoperandoperand(MoveMwrR, (-((self_in_nativeStackPopToRegsecondReg->offset))) + 4, FPReg, reg); - /* begin checkQuickConstant:forInstruction: */ - -((self_in_nativeStackPopToRegsecondReg->offset)); - anInstruction1 = genoperandoperandoperand(MoveMwrR, -((self_in_nativeStackPopToRegsecondReg->offset)), FPReg, secondReg); - break; - default: - error("Case not found and no otherwise clause"); - } -} - - /* CogSimStackNativeEntry>>#spillingNeedsScratchRegister */ -static sqInt NoDbgRegParms -spillingNeedsScratchRegister(CogSimStackNativeEntry * self_in_spillingNeedsScratchRegister) -{ - if (!((self_in_spillingNeedsScratchRegister->spilled))) { - switch ((self_in_spillingNeedsScratchRegister->type)) { - case SSConstantInt32: - case SSConstantInt64: - case SSConstantFloat32: - case SSConstantFloat64: - case SSConstantNativePointer: - return 1; - - default: - return 0; - - } - } - return 0; -} - - /* CogSimStackNativeEntry>>#stackSpillSize */ -static sqInt NoDbgRegParms -stackSpillSize(CogSimStackNativeEntry * self_in_stackSpillSize) -{ - switch ((self_in_stackSpillSize->type)) { - case SSConstantInt64: - case SSConstantFloat64: - case SSRegisterDoubleFloat: - case SSRegisterPair: - case SSSpillFloat64: - case SSSpillInt64: - return 8; - - default: - return BytesPerOop; - - } - return 0; -} - - /* CogSSBytecodeFixup>>#isMergeFixup */ -static sqInt NoDbgRegParms -isMergeFixup(BytecodeFixup * self_in_isMergeFixup) -{ - return (((usqInt)((self_in_isMergeFixup->targetInstruction)))) == NeedsMergeFixupFlag; -} - - /* InLineLiteralsManager>>#checkLiteral:forInstruction: */ -static AbstractInstruction * NoDbgRegParms -checkLiteralforInstruction(sqInt literal, AbstractInstruction *anInstruction) -{ - return anInstruction; -} - - /* InLineLiteralsManager>>#checkQuickConstant:forInstruction: */ -static AbstractInstruction * NoDbgRegParms -checkQuickConstantforInstruction(sqInt literal, AbstractInstruction *anInstruction) -{ - return anInstruction; -} - - /* SimpleStackBasedCogit>>#cogMethodHasExternalPrim: */ -sqInt -cogMethodHasExternalPrim(CogMethod *aCogMethod) -{ - sqInt primIndex; - - primIndex = primitiveIndexOfMethodheader((aCogMethod->methodObject), (aCogMethod->methodHeader)); - return (primIndex == PrimNumberExternalCall) - || (primIndex == PrimNumberFFICall); -} - - /* SimpleStackBasedCogit>>#cogMethodHasMachineCodePrim: */ -sqInt -cogMethodHasMachineCodePrim(CogMethod *aCogMethod) -{ - sqInt primIndex; - - primIndex = primitiveIndexOfMethodheader((aCogMethod->methodObject), (aCogMethod->objectHeader)); - return (((primIndex >= 1) && (primIndex <= MaxCompiledPrimitiveIndex))) - && ((((primitiveGeneratorTable[primIndex]).primitiveGenerator)) != null); -} - - -/* Compile the jump instruction(s) at the end of the method that dispatch to - each block body. - */ - - /* SimpleStackBasedCogit>>#compileBlockDispatch */ -static sqInt -compileBlockDispatch(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *jumpSkip; - - assert(blockCount > 0); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 0, SendNumArgsReg); - blockEntryNoContextSwitch = anInstruction; - /* begin Jump: */ - jumpSkip = genoperand(Jump, ((sqInt)0)); - /* begin MoveR:R: */ - blockEntryLabel = genoperandoperand(MoveRR, ReceiverResultReg, SendNumArgsReg); - jmpTarget(jumpSkip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (blockCount > 1) { - genLoadSlotsourceRegdestReg(ClosureStartPCIndex, ReceiverResultReg, TempReg); - } - compileBlockDispatchFromto(0, blockCount - 1); - return 0; -} - - -/* After pushing the temporaries but before the stack limit check a primitive - method needs to fetch the error code, if any. If the primitive has failed, - call the trampoline - that will assign it to the last temp. */ - - /* SimpleStackBasedCogit>>#compileGetErrorCode */ -static void -compileGetErrorCode(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *jmpNoError; - - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpZero: */ - jmpNoError = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceReapAndResetErrorCodeTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - jmpTarget(jmpNoError, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); -} - - /* SimpleStackBasedCogit>>#compileInterpreterPrimitive */ -static sqInt -compileInterpreterPrimitive(void) -{ - sqInt flags; - void (*primitiveRoutine)(void); - - flags = 0; - primitiveRoutine = functionPointerForCompiledMethodprimitiveIndexprimitivePropertyFlagsInto(methodObj, primitiveIndex, (&flags)); - assert(!((((flags & PrimCallOnSmalltalkStack) != 0)))); - return compileInterpreterPrimitiveflags(primitiveRoutine, flags); -} - - -/* Compile a call to an interpreter primitive. Call the C routine with the - usual stack-switching dance, test the primFailCode and then either - return on success or continue to the method body. */ - - /* SimpleStackBasedCogit>>#compileInterpreterPrimitive:flags: */ -static sqInt NoDbgRegParms -compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) -{ - sqInt address; - sqInt address1; - sqInt address2; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction24; - AbstractInstruction *anInstruction25; - AbstractInstruction *anInstruction26; - AbstractInstruction *anInstruction28; - AbstractInstruction *anInstruction30; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction33; - AbstractInstruction *anInstruction34; - AbstractInstruction *anInstruction35; - AbstractInstruction *anInstruction36; - AbstractInstruction *anInstruction37; - AbstractInstruction *anInstruction38; - AbstractInstruction *anInstruction39; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction * continuePostSampleNonPrim; - AbstractInstruction * continuePostSamplePrim; - AbstractInstruction * jmp; - AbstractInstruction * jmpSampleNonPrim; - AbstractInstruction * jmpSamplePrim; - sqInt offset; - sqInt offset1; - sqInt offset2; - sqInt operand1; - sqInt operand3; - sqInt reg; - sqInt retpc; - - continuePostSampleNonPrim = ((AbstractInstruction *) 0); - continuePostSamplePrim = ((AbstractInstruction *) 0); - jmpSampleNonPrim = ((AbstractInstruction *) 0); - jmpSamplePrim = ((AbstractInstruction *) 0); - assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); - genExternalizePointersForPrimitiveCall(); - /* begin genLoadCStackPointersForPrimCall */ - if (cFramePointerInUse) { - genLoadCStackPointers(backEnd); - } - else { - genLoadCStackPointer(backEnd); - } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick if so */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin MoveAw:R: */ - address = (nextProfileTickAddress()) + BytesPerWord; - /* begin checkLiteral:forInstruction: */ - anInstruction1 = genoperandoperand(MoveAwR, address, ClassReg); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSampleNonPrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSampleNonPrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - if (recordPrimTraceForMethod(methodObj)) { - genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction36 = genoperandoperand(MoveCqR, 0, TempReg); - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction37 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); - if (methodOrBlockNumArgs != 0) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); - } - /* begin checkLiteral:forInstruction: */ - argumentCountAddress(); - anInstruction38 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); - if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { - /* begin checkLiteral:forInstruction: */ - ((sqInt)primitiveRoutine); - anInstruction5 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); - /* begin checkLiteral:forInstruction: */ - primitiveFunctionPointerAddress(); - anInstruction6 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); - } - if (((flags & (PrimCallNeedsNewMethod + PrimCallMayEndureCodeCompaction)) != 0)) { - - /* The ceActivateFailingPrimitiveMethod: machinery can't handle framelessness. */ - if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - needsFrame = 1; - } - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); - /* begin MoveMw:r:R: */ - offset = offsetof(CogMethod, methodObject); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - /* begin checkLiteral:forInstruction: */ - newMethodAddress(); - anInstruction8 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); - } - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction39 = genoperand(PrefetchAw, primFailCodeAddress()); - if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - - /* Sideways call the C primitive routine so that we return through cePrimReturnEnterCogCode. */ - /* On Spur ceActivateFailingPrimitiveMethod: would like to retry if forwarders - are found. So insist on PrimCallNeedsPrimitiveFunction being set too. */ - assert(((flags & PrimCallNeedsPrimitiveFunction) != 0)); - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l32; - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction11 = genoperandoperand(MoveCqR, -2 - null, A0); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A0); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction12 = genoperandoperand(MoveCqR, -2 - null, A1); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A1); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction21 = genoperandoperand(MoveCqR, -2 - null, A2); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A2); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction31 = genoperandoperand(MoveCqR, -2 - null, A3); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A3); - } - l32: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin genSubstituteReturnAddress: */ - retpc = (((flags & PrimCallCollectsProfileSamples) != 0) - ? cePrimReturnEnterCogCodeProfiling - : cePrimReturnEnterCogCode); - /* begin checkLiteral:forInstruction: */ - anInstruction13 = genoperandoperand(MoveCwR, retpc, RA); - /* begin gen:literal: */ - anInstruction10 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); - jmp = (jmpSamplePrim = (continuePostSamplePrim = null)); - } - else { - - /* Call the C primitive routine. */ - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l48; - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, A0); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, A1); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, A2); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, A3); - l48: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin gen:literal: */ - anInstruction15 = genoperand(CallFull, ((sqInt)primitiveRoutine)); - /* begin genRemoveNArgsFromStack: */ - assert(0 <= 4); - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction16 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin MoveAw:R: */ - address1 = (nextProfileTickAddress()) + BytesPerWord; - /* begin checkLiteral:forInstruction: */ - anInstruction17 = genoperandoperand(MoveAwR, address1, ClassReg); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSamplePrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSamplePrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - maybeCompileRetryOnPrimitiveFail(primitiveIndex); - /* begin MoveAw:R: */ - address2 = instructionPointerAddress(); - reg = LinkReg; - /* begin checkLiteral:forInstruction: */ - anInstruction23 = genoperandoperand(MoveAwR, address2, reg); - genLoadStackPointers(backEnd); - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction24 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction25 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset1 = 0; - /* begin checkQuickConstant:forInstruction: */ - anInstruction26 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, BytesPerWord); - } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* The sample is collected by cePrimReturnEnterCogCode for external calls */ - if (!(jmpSamplePrim == null)) { - - /* Call ceCheckProfileTick: to record sample and then continue. */ - jmpTarget(jmpSamplePrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin gen:literal: */ - operand1 = ((usqIntptr_t)ceCheckProfileTick); - /* begin checkLiteral:forInstruction: */ - anInstruction28 = genoperand(CallFull, operand1); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSamplePrim)); - } - jmpTarget(jmpSampleNonPrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction33 = genoperandoperand(MoveCqR, 0, TempReg); - /* begin checkLiteral:forInstruction: */ - newMethodAddress(); - anInstruction34 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); - /* begin gen:literal: */ - operand3 = ((usqIntptr_t)ceCheckProfileTick); - /* begin checkLiteral:forInstruction: */ - anInstruction30 = genoperand(CallFull, operand3); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSampleNonPrim)); - } - if (!(jmp == null)) { - - /* Jump to restore of receiver reg and proceed to frame build for failure. */ - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin MoveMw:r:R: */ - offset2 = BytesPerWord * (methodOrBlockNumArgs + (0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction35 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); - } - return 0; -} - - -/* Compile a call to a machine-code convention interpreter primitive. Call - the C routine - on the Smalltalk stack, assuming it consumes little or no stack space. */ -/* for now handle functions with less than 4 arguments; our C call - marshalling machinery - extends up to 4 arguments only, and the first argument of an mcprim is the - receiver. - */ - - /* SimpleStackBasedCogit>>#compileMachineCodeInterpreterPrimitive: */ -static sqInt NoDbgRegParms -compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)) -{ - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction5; - AbstractInstruction * jmpFail; - sqInt liveRegsMask; - sqInt n; - sqInt offset; - - assert(methodOrBlockNumArgs <= 3); - if ((methodOrBlockNumArgs > 2 /* numRegArgs */) - || (methodOrBlockNumArgs == 0)) { - /* begin registerMaskFor: */ - liveRegsMask = 1U << ReceiverResultReg; - } - else { - if (methodOrBlockNumArgs > 1) { - /* begin registerMaskFor:and:and: */ - liveRegsMask = ((1U << ReceiverResultReg) | (1U << Arg0Reg)) | (1U << Arg1Reg); - } - else { - /* begin registerMaskFor:and: */ - liveRegsMask = (1U << ReceiverResultReg) | (1U << Arg0Reg); - } - } - genSaveRegs(backEnd, liveRegsMask & CallerSavedRegisterMask); - if (methodOrBlockNumArgs > 2 /* numRegArgs */) { - - /* Wrangle args into Arg0Reg, Arg1Reg, SendNumArgsReg & ClassReg */ - /* offset := self bitCountOf: (liveRegsMask bitAnd: CallerSavedRegisterMask). */ - error("shouldBeImplemented"); - } - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - if ((methodOrBlockNumArgs + 1) == 0) { - goto l18; - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, A0); - if ((methodOrBlockNumArgs + 1) == 1) { - goto l18; - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, A1); - if ((methodOrBlockNumArgs + 1) == 2) { - goto l18; - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, A2); - if ((methodOrBlockNumArgs + 1) == 3) { - goto l18; - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SendNumArgsReg, A3); - l18: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin saveAndRestoreLinkRegUsingCalleeSavedRegNotLiveAtPointOfSendAround: */ - /* begin gen:literal: */ - anInstruction1 = genoperand(CallFull, ((sqInt)primitiveRoutine)); - /* begin genRemoveNArgsFromStack: */ - n = methodOrBlockNumArgs + 1; - assert(n <= 4); - genRestoreRegs(backEnd, liveRegsMask & CallerSavedRegisterMask); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(CmpCqR, 0, ABIResultReg); - /* begin JumpZero: */ - jmpFail = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - genWriteCResultIntoReg(backEnd, ReceiverResultReg); - /* begin RetN: */ - offset = (methodOrBlockNumArgs > 2 /* numRegArgs */ - ? (methodOrBlockNumArgs + 1) * BytesPerWord - : 0); - genoperand(RetN, offset); - jmpTarget(jmpFail, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - -/* Compile a fast call of a C primitive using the current stack page, - avoiding the stack switch except on failure. - This convention still uses stackPointer and argumentCount to access - operands. Push all operands to the stack, - assign stackPointer, argumentCount, and zero primFailCode. Make the call - (saving a LinkReg if required). - Test for failure and return. On failure on Spur, if there is an accessor - depth, assign framePointer and newMethod, - do the stack switch, call checkForAndFollowForwardedPrimitiveState, and - loop back if forwarders are found. - Fall through to frame build. */ - - /* SimpleStackBasedCogit>>#compileOnStackExternalPrimitive:flags: */ -static sqInt NoDbgRegParms -compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction22; - AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt calleeSavedRegisterMask; - AbstractInstruction * jmp; - sqInt linkRegSaveRegister; - sqInt offset; - sqInt offset1; - sqInt operand1; - AbstractInstruction * retry; - AbstractInstruction * skip; - sqInt spRegSaveRegister; - - linkRegSaveRegister = 0; - assert(((flags & PrimCallOnSmalltalkStack) != 0)); - assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); - if (recordFastCCallPrimTraceForMethod(methodObj)) { - genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction18 = genoperandoperand(MoveCqR, 0, TempReg); - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction19 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); - if (methodOrBlockNumArgs != 0) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); - } - /* begin checkLiteral:forInstruction: */ - argumentCountAddress(); - anInstruction20 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); - genExternalizeStackPointerForFastPrimitiveCall(); - calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | (1U << ClassReg)) - (1U << ClassReg)); - linkRegSaveRegister = availableRegisterOrNoneIn(calleeSavedRegisterMask); - assert(!((linkRegSaveRegister == NoReg))); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, LinkReg, linkRegSaveRegister); - calleeSavedRegisterMask = ((calleeSavedRegisterMask | (1U << linkRegSaveRegister)) - (1U << linkRegSaveRegister)); - spRegSaveRegister = NoReg; - /* begin Label */ - retry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - if (((flags & PrimCallOnSmalltalkStackAlign2x) != 0)) { - gAndCqRR((-1 - (((BytesPerWord * 2) - 1))), SPReg, NativeSPReg); - } - else { - } - /* begin gen:literal: */ - anInstruction2 = genoperand(CallFull, primitiveRoutine); - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction21 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - if (spRegSaveRegister != NoReg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, spRegSaveRegister, SPReg); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkLiteral:forInstruction: */ - stackPointerAddress(); - anInstruction23 = genoperandoperand(MoveAwR, stackPointerAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperandoperand(MoveMwrR, 0, TempReg, ReceiverResultReg); - gAddCqRR(BytesPerWord, TempReg, SPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, linkRegSaveRegister, LinkReg); - /* begin RetN: */ - genoperand(RetN, 0); - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if ((accessorDepthForExternalPrimitiveMethod(methodObj)) >= 0) { - - /* Given that following primitive state to the accessor depth is recursive, we're asking for - trouble if we run the fixup on the Smalltalk stack page. Run it on the full C stack instead. - This won't be a performance issue since primitive failure should be very rare. */ - /* begin checkLiteral:forInstruction: */ - framePointerAddress(); - anInstruction9 = genoperandoperand(MoveRAw, FPReg, framePointerAddress()); - /* begin checkLiteral:forInstruction: */ - ((sqInt)primitiveRoutine); - anInstruction10 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); - /* begin checkLiteral:forInstruction: */ - primitiveFunctionPointerAddress(); - anInstruction11 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); - /* begin MoveMw:r:R: */ - offset = offsetof(CogMethod, methodObject); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - /* begin checkLiteral:forInstruction: */ - newMethodAddress(); - anInstruction13 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); - /* begin genLoadCStackPointersForPrimCall */ - if (cFramePointerInUse) { - genLoadCStackPointers(backEnd); - } - else { - genLoadCStackPointer(backEnd); - } - /* begin gen:literal: */ - operand1 = ((usqIntptr_t)checkForAndFollowForwardedPrimitiveState); - /* begin checkLiteral:forInstruction: */ - anInstruction8 = genoperand(CallFull, operand1); - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(CmpCqR, 0, ABIResultReg); - /* begin JumpZero: */ - skip = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperand(MoveCqR, 0, TempReg); - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction16 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); - /* begin Jump: */ - genoperand(Jump, ((sqInt)retry)); - jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - else { - - /* must reload SPReg to undo any alignment change, */ - if (((flags & PrimCallOnSmalltalkStackAlign2x) != 0)) { - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); - } - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, linkRegSaveRegister, LinkReg); - if (((ABICallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { - /* begin MoveMw:r:R: */ - offset1 = (methodOrBlockNumArgs + (0)) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); - } - return 0; -} - - -/* Compile one method cache probe in an OpenPIC's lookup of selector. - Answer the jump taken if the selector probe fails. - The class tag of the receiver must be in SendNumArgsReg. ClassReg and - TempReg are used as scratch registers. - On a hit, the offset of the entry is in ClassReg. */ - - /* SimpleStackBasedCogit>>#compileOpenPICMethodCacheProbeFor:withShift:baseRegOrNone: */ -static AbstractInstruction * NoDbgRegParms -compileOpenPICMethodCacheProbeForwithShiftbaseRegOrNone(sqInt selector, sqInt shift, sqInt baseRegOrNone) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *jumpSelectorMiss; - sqInt offset; - sqInt offset1; - - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SendNumArgsReg, ClassReg); - maybeShiftClassTagRegisterForMethodCacheProbe(ClassReg); - annotateobjRef(checkLiteralforInstruction(selector, genoperandoperand(XorCwR, selector, ClassReg)), selector); - assert(shift <= (shiftForWord())); - if (shift < (shiftForWord())) { - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (shiftForWord()) - shift, ClassReg); - } - /* begin AndCq:R: */ - anInstruction4 = genoperandoperand(AndCqR, ((int)((usqInt)(MethodCacheMask) << (shiftForWord()))), ClassReg); - if (baseRegOrNone == NoReg) { - /* begin MoveMw:r:R: */ - offset = (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheSelector) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - } - else { - /* begin AddR:R: */ - genoperandoperand(AddRR, baseRegOrNone, ClassReg); - /* begin MoveMw:r:R: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, ((int)((usqInt)(MethodCacheSelector) << (shiftForWord()))), ClassReg, TempReg); - } - annotateobjRef(checkLiteralforInstruction(selector, genoperandoperand(CmpCwR, selector, TempReg)), selector); - /* begin JumpNonZero: */ - jumpSelectorMiss = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - if (baseRegOrNone == NoReg) { - /* begin MoveMw:r:R: */ - offset1 = (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheClass) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveMwrR, offset1, ClassReg, TempReg); - } - else { - /* begin MoveMw:r:R: */ - anInstruction3 = genoperandoperandoperand(MoveMwrR, ((int)((usqInt)(MethodCacheClass) << (shiftForWord()))), ClassReg, TempReg); - } - /* begin CmpR:R: */ - assert(!((SendNumArgsReg == SPReg))); - genoperandoperand(CmpRR, SendNumArgsReg, TempReg); - return jumpSelectorMiss; -} - - -/* Compile the code for an open PIC. Perform a probe of the first-level - method lookup cache followed by a call of ceSendFromInLineCacheMiss: if - the probe fails. */ - - /* SimpleStackBasedCogit>>#compileOpenPIC:numArgs: */ -static void NoDbgRegParms -compileOpenPICnumArgs(sqInt selector, sqInt numArgs) -{ - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - sqInt cacheBaseReg; - AbstractInstruction *itsAHit; - AbstractInstruction *jumpBCMethod; - AbstractInstruction *jumpClassMiss; - AbstractInstruction *jumpSelectorMiss; - sqInt offset; - - /* begin preenMethodLabel */ - (((((AbstractInstruction *) methodLabel))->operands))[1] = 0; - compilePICAbort(numArgs); - entry = genGetClassTagOfintoscratchReg(ReceiverResultReg, SendNumArgsReg, TempReg); - flag("lookupInMethodCacheSel:classTag:"); - cacheBaseReg = NoReg; - jumpSelectorMiss = compileOpenPICMethodCacheProbeForwithShiftbaseRegOrNone(selector, 0, cacheBaseReg); - /* begin JumpNonZero: */ - jumpClassMiss = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset = (cacheBaseReg == NoReg - ? (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheMethod) << (shiftForWord())))) - : ((int)((usqInt)(MethodCacheMethod) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, SendNumArgsReg); - itsAHit = anInstruction1; - genLoadSlotsourceRegdestReg(HeaderIndex, SendNumArgsReg, ClassReg); - jumpBCMethod = genJumpImmediate(ClassReg); - jmpTarget(jumpBCMethod, picInterpretAbort); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AddCqR, cmNoCheckEntryOffset, ClassReg); - /* begin JumpR: */ - genoperand(JumpR, ClassReg); - jmpTarget(jumpSelectorMiss, jmpTarget(jumpClassMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - jumpSelectorMiss = compileOpenPICMethodCacheProbeForwithShiftbaseRegOrNone(selector, 1, cacheBaseReg); - /* begin JumpZero: */ - genConditionalBranchoperand(JumpZero, ((sqInt)itsAHit)); - jmpTarget(jumpSelectorMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - jumpSelectorMiss = compileOpenPICMethodCacheProbeForwithShiftbaseRegOrNone(selector, 2, cacheBaseReg); - /* begin JumpZero: */ - genConditionalBranchoperand(JumpZero, ((sqInt)itsAHit)); - jmpTarget(jumpSelectorMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genPushRegisterArgsForNumArgsscratchReg(backEnd, numArgs, SendNumArgsReg); - genSmalltalkToCStackSwitch(1); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), SendNumArgsReg)))); - compileCallFornumArgsargargargargresultRegregsToSave(ceSendFromInLineCacheMiss, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); -} - - -/* Compile one method cache probe in a perform: primitive's lookup of - selector. Answer the jump taken if the selector probe fails. */ - - /* SimpleStackBasedCogit>>#compilePerformMethodCacheProbeFor:withShift:baseRegOrNone: */ -static AbstractInstruction * NoDbgRegParms -compilePerformMethodCacheProbeForwithShiftbaseRegOrNone(sqInt selectorReg, sqInt shift, sqInt baseRegOrNone) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *jumpSelectorMiss; - sqInt offset; - sqInt offset1; - - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SendNumArgsReg, ClassReg); - maybeShiftClassTagRegisterForMethodCacheProbe(ClassReg); - /* begin XorR:R: */ - genoperandoperand(XorRR, selectorReg, ClassReg); - assert(shift <= (shiftForWord())); - if (shift < (shiftForWord())) { - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (shiftForWord()) - shift, ClassReg); - } - /* begin AndCq:R: */ - anInstruction4 = genoperandoperand(AndCqR, ((int)((usqInt)(MethodCacheMask) << (shiftForWord()))), ClassReg); - if (baseRegOrNone == NoReg) { - /* begin MoveMw:r:R: */ - offset = (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheSelector) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - } - else { - /* begin AddR:R: */ - genoperandoperand(AddRR, baseRegOrNone, ClassReg); - /* begin MoveMw:r:R: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, ((int)((usqInt)(MethodCacheSelector) << (shiftForWord()))), ClassReg, TempReg); - } - /* begin CmpR:R: */ - assert(!((selectorReg == SPReg))); - genoperandoperand(CmpRR, selectorReg, TempReg); - /* begin JumpNonZero: */ - jumpSelectorMiss = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - if (baseRegOrNone == NoReg) { - /* begin MoveMw:r:R: */ - offset1 = (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheClass) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveMwrR, offset1, ClassReg, TempReg); - } - else { - /* begin MoveMw:r:R: */ - anInstruction3 = genoperandoperandoperand(MoveMwrR, ((int)((usqInt)(MethodCacheClass) << (shiftForWord()))), ClassReg, TempReg); - } - /* begin CmpR:R: */ - assert(!((SendNumArgsReg == SPReg))); - genoperandoperand(CmpRR, SendNumArgsReg, TempReg); - return jumpSelectorMiss; -} - - -/* Compile a primitive. If possible, performance-critical primitives will - be generated by their own routines (primitiveGenerator). Otherwise, - if there is a primitive at all, we call the C routine with the usual - stack-switching dance, test the primFailCode and then either return - on success or continue to the method body. */ - - /* SimpleStackBasedCogit>>#compilePrimitive */ -static sqInt -compilePrimitive(void) -{ - sqInt code; - sqInt flags; - sqInt opcodeIndexAtPrimitive; - PrimitiveDescriptor *primitiveDescriptor; - void (*primitiveRoutine)(void); - - flags = 0; - if (primitiveIndex == 0) { - return 0; - } - if ((((primitiveDescriptor = primitiveGeneratorOrNil())) != null) - && ((((primitiveDescriptor->primitiveGenerator)) != null) - && ((((primitiveDescriptor->primNumArgs)) < 0) - || (((primitiveDescriptor->primNumArgs)) == (argumentCountOf(methodObj)))))) { - - /* Note opcodeIndex so that any arg load instructions - for unimplemented primitives can be discarded. */ - opcodeIndexAtPrimitive = opcodeIndex; - code = ((primitiveDescriptor->primitiveGenerator))(); - if ((code < 0) - && (code != UnimplementedPrimitive)) { - - /* Generator failed, so no point continuing... */ - return code; - } - if (code == UnfailingPrimitive) { - return 0; - } - if ((code == CompletePrimitive) - && (!(((primitiveIndexOfMethodheader(methodObj, methodHeader)) > 0) - && ((longStoreBytecodeForHeader(methodHeader)) == (fetchByteofObject((startPCOfMethod(methodObj)) + (sizeOfCallPrimitiveBytecode(methodHeader)), methodObj)))))) { - return 0; - } - if (code == UnimplementedPrimitive) { - opcodeIndex = opcodeIndexAtPrimitive; - } - } - primitiveRoutine = functionPointerForCompiledMethodprimitiveIndexprimitivePropertyFlagsInto(methodObj, primitiveIndex, (&flags)); - if (((flags & PrimCallDoNotJIT) != 0)) { - return ShouldNotJIT; - } - if ((primitiveRoutine == 0) - || (primitiveRoutine == (((void (*)(void)) primitiveFail)))) { - return genFastPrimFail(); - } - if (((flags & PrimCallOnSmalltalkStack) != 0)) { - assert(!(((((flags & FastCPrimitiveUseCABIFlag) != 0)) - && (((flags & PrimCallOnSmalltalkStackAlign2x) != 0))))); - if (((flags & FastCPrimitiveUseCABIFlag) != 0)) { - return compileMachineCodeInterpreterPrimitive(((void (*)(void)) (mcprimFunctionForPrimitiveIndex(primitiveIndex)))); - } - return compileOnStackExternalPrimitiveflags(primitiveRoutine, flags); - } - minValidCallAddress = ((minValidCallAddress < (((usqInt)primitiveRoutine))) ? minValidCallAddress : (((usqInt)primitiveRoutine))); - return compileInterpreterPrimitiveflags(primitiveRoutine, flags); -} - - /* SimpleStackBasedCogit>>#extendedPushBytecode */ -static sqInt -extendedPushBytecode(void) -{ - sqInt variableIndex; - sqInt variableType; - - variableType = (((usqInt)(byte1)) >> 6) & 3; - variableIndex = byte1 & 0x3F; - if (variableType == 0) { - return genPushReceiverVariable(variableIndex); - } - if (variableType == 1) { - return genPushTemporaryVariable(variableIndex); - } - if (variableType == 2) { - return genPushLiteralIndex(variableIndex); - } - return genPushLiteralVariable(variableIndex); -} - - /* SimpleStackBasedCogit>>#extendedStoreAndPopBytecode */ -static sqInt -extendedStoreAndPopBytecode(void) -{ - AbstractInstruction *abstractInstruction; - sqInt variableIndex; - sqInt variableType; - - variableType = (((usqInt)(byte1)) >> 6) & 3; - variableIndex = byte1 & 0x3F; - if (variableType == 0) { - return genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(1, variableIndex, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } - if (variableType == 1) { - genStorePopTemporaryVariable(1, variableIndex); -# if IMMUTABILITY - /* begin annotateBytecode: */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction->annotation = HasBytecodePC); -# endif // IMMUTABILITY - return 0; - } - if (variableType == 3) { - return genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(1, variableIndex, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } - return EncounteredUnknownBytecode; -} - - /* SimpleStackBasedCogit>>#extendedStoreBytecode */ -static sqInt -extendedStoreBytecode(void) -{ - AbstractInstruction *abstractInstruction; - sqInt variableIndex; - sqInt variableType; - - variableType = (((usqInt)(byte1)) >> 6) & 3; - variableIndex = byte1 & 0x3F; - if (variableType == 0) { - return genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(0, variableIndex, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } - if (variableType == 1) { - genStorePopTemporaryVariable(0, variableIndex); -# if IMMUTABILITY - /* begin annotateBytecode: */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction->annotation = HasBytecodePC); -# endif // IMMUTABILITY - return 0; - } - if (variableType == 3) { - return genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(0, variableIndex, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } - return EncounteredUnknownBytecode; -} - - /* SimpleStackBasedCogit>>#frameOffsetOfNativeFrameMark */ -static sqInt -frameOffsetOfNativeFrameMark(void) -{ - return FoxMFReceiver - BytesPerWord; -} - - /* SimpleStackBasedCogit>>#frameOffsetOfNativeFramePointer */ -static sqInt -frameOffsetOfNativeFramePointer(void) -{ - return FoxMFReceiver - (BytesPerWord * 3); -} - - /* SimpleStackBasedCogit>>#frameOffsetOfNativeStackPointer */ -static sqInt -frameOffsetOfNativeStackPointer(void) -{ - return FoxMFReceiver - (BytesPerWord * 4); -} - - /* SimpleStackBasedCogit>>#frameOffsetOfPreviousNativeStackPointer */ -static sqInt -frameOffsetOfPreviousNativeStackPointer(void) -{ - return FoxMFReceiver - (BytesPerWord * 2); -} - - /* SimpleStackBasedCogit>>#frameOffsetOfTemporary: */ -static sqInt NoDbgRegParms -frameOffsetOfTemporary(sqInt index) -{ - return (index < methodOrBlockNumArgs - ? FoxCallerSavedIP + ((methodOrBlockNumArgs - index) * BytesPerWord) - : (FoxMFReceiver - BytesPerWord) + ((methodOrBlockNumArgs - index) * BytesPerWord)); -} - - -/* Implemented with SistaCogit only */ - - /* SimpleStackBasedCogit>>#genCallMappedInlinedPrimitive */ -static sqInt -genCallMappedInlinedPrimitive(void) -{ - return EncounteredUnknownBytecode; -} - - -/* Can use any of the first 32 literals for the selector and pass up to 7 - arguments. - */ - - /* SimpleStackBasedCogit>>#genExtendedSendBytecode */ -static sqInt -genExtendedSendBytecode(void) -{ - return genSendnumArgs(byte1 & 0x1F, ((usqInt)(byte1)) >> 5); -} - - /* SimpleStackBasedCogit>>#genExtendedSuperBytecode */ -static sqInt -genExtendedSuperBytecode(void) -{ - return genSendSupernumArgs(byte1 & 0x1F, ((usqInt)(byte1)) >> 5); -} - - -/* 244 11110100 i i i i i i i i Pop and Jump 0n False i i i i i i i i (+ - Extend B * 256, where Extend B >= 0) - */ - - /* SimpleStackBasedCogit>>#genExtJumpIfFalse */ -static sqInt -genExtJumpIfFalse(void) -{ - sqInt distance; - sqInt target; - - distance = byte1 + (((sqInt)((usqInt)(extB) << 8))); - assert(distance == (v4LongForwardBranchDistance(generatorAt(byte0), bytecodePC, ((extA != 0 - ? 1 - : 0)) + ((extB != 0 - ? 1 - : 0)), methodObj))); - extB = 0; - numExtB = 0; - target = (distance + 2) + bytecodePC; - return genJumpIfto(falseObject(), target); -} - - -/* 243 11110011 i i i i i i i i Pop and Jump 0n True i i i i i i i i (+ - Extend B * 256, where Extend B >= 0) - */ - - /* SimpleStackBasedCogit>>#genExtJumpIfTrue */ -static sqInt -genExtJumpIfTrue(void) -{ - sqInt distance; - sqInt target; - - distance = byte1 + (((sqInt)((usqInt)(extB) << 8))); - assert(distance == (v4LongForwardBranchDistance(generatorAt(byte0), bytecodePC, ((extA != 0 - ? 1 - : 0)) + ((extB != 0 - ? 1 - : 0)), methodObj))); - extB = 0; - numExtB = 0; - target = (distance + 2) + bytecodePC; - return genJumpIfto(trueObject(), target); -} - - -/* NewspeakV4: 221 11011101 Nop */ -/* SistaV1: 91 01011011' Nop */ - - /* SimpleStackBasedCogit>>#genExtNopBytecode */ -static sqInt -genExtNopBytecode(void) -{ - extA = (numExtB = (extB = 0)); - return 0; -} - - -/* SistaV1: 233 11101001 iiiiiiii Push Character #iiiiiiii (+ Extend B * - 256) - */ - - /* SimpleStackBasedCogit>>#genExtPushCharacterBytecode */ -static sqInt -genExtPushCharacterBytecode(void) -{ - sqInt value; - - value = byte1 + (((sqInt)((usqInt)(extB) << 8))); - extB = 0; - numExtB = 0; - return genPushLiteral(characterObjectOf(value)); -} - - -/* NewsqueakV4: 229 11100101 iiiiiiii Push Integer #iiiiiiii (+ Extend B * - 256, where bbbbbbbb = sddddddd, e.g. -32768 = i=0, a=0, s=1) - SistaV1: 232 11101000 iiiiiiii Push Integer #iiiiiiii (+ Extend B * 256, - where bbbbbbbb = sddddddd, e.g. -32768 = i=0, a=0, s=1) - */ - - /* SimpleStackBasedCogit>>#genExtPushIntegerBytecode */ -static sqInt -genExtPushIntegerBytecode(void) -{ - sqInt value; - - value = byte1 + (((sqInt)((usqInt)(extB) << 8))); - extB = 0; - numExtB = 0; - return genPushLiteral((((usqInt)value << 1) | 1)); -} - - -/* 228 11100100 i i i i i i i i Push Literal #iiiiiiii (+ Extend A * 256) */ - - /* SimpleStackBasedCogit>>#genExtPushLiteralBytecode */ -static sqInt -genExtPushLiteralBytecode(void) -{ - sqInt index; - - index = byte1 + (((sqInt)((usqInt)(extA) << 8))); - extA = 0; - return genPushLiteralIndex(index); -} - - -/* 227 11100011 i i i i i i i i Push Literal Variable #iiiiiiii (+ Extend A - * 256) - */ - - /* SimpleStackBasedCogit>>#genExtPushLiteralVariableBytecode */ -static sqInt -genExtPushLiteralVariableBytecode(void) -{ - sqInt index; - - index = byte1 + (((sqInt)((usqInt)(extA) << 8))); - extA = 0; - return genPushLiteralVariable(index); -} - - -/* SistaV1: * 82 01010010 Push thisContext, (then Extend B = 1 => push - thisProcess) - */ - - /* SimpleStackBasedCogit>>#genExtPushPseudoVariable */ -static sqInt -genExtPushPseudoVariable(void) -{ - sqInt ext; - - ext = extB; - extB = 0; - numExtB = 0; - switch (ext) { - case 0: - return genPushActiveContextBytecode(); - - default: - /* begin unknownBytecode */ - return EncounteredUnknownBytecode; - - } - return 0; -} - - -/* 226 11100010 i i i i i i i i Push Receiver Variable #iiiiiiii (+ Extend A - * 256) - */ - - /* SimpleStackBasedCogit>>#genExtPushReceiverVariableBytecode */ -static sqInt -genExtPushReceiverVariableBytecode(void) -{ - sqInt index; - - index = byte1 + (((sqInt)((usqInt)(extA) << 8))); - extA = 0; - return (isReadMediatedContextInstVarIndex(index) - ? genPushMaybeContextReceiverVariable(index) - : genPushReceiverVariable(index)); -} - - -/* 238 11101110 i i i i i j j j Send Literal Selector #iiiii (+ Extend A * - 32) with jjj (+ Extend B * 8) Arguments - */ - - /* SimpleStackBasedCogit>>#genExtSendBytecode */ -static sqInt -genExtSendBytecode(void) -{ - sqInt litIndex; - sqInt nArgs; - - litIndex = (((usqInt)(byte1)) >> 3) + (((sqInt)((usqInt)(extA) << 5))); - extA = 0; - nArgs = (byte1 & 7) + (((sqInt)((usqInt)(extB) << 3))); - extB = 0; - numExtB = 0; - return genSendnumArgs(litIndex, nArgs); -} - - -/* 239 11101111 i i i i i j j j Send To Superclass Literal Selector #iiiii - (+ Extend A * 32) with jjj (+ Extend B * 8) Arguments - */ - - /* SimpleStackBasedCogit>>#genExtSendSuperBytecode */ -static sqInt -genExtSendSuperBytecode(void) -{ - int isDirected; - sqInt litIndex; - sqInt nArgs; - - if ((isDirected = extB >= 64)) { - extB = extB & 0x3F; - } - litIndex = (((usqInt)(byte1)) >> 3) + (((sqInt)((usqInt)(extA) << 5))); - extA = 0; - nArgs = (byte1 & 7) + (((sqInt)((usqInt)(extB) << 3))); - extB = 0; - numExtB = 0; - return (isDirected - ? genSendDirectedSupernumArgs(litIndex, nArgs) - : genSendSupernumArgs(litIndex, nArgs)); -} - - -/* 236 11101100 i i i i i i i i Pop and Store Literal Variable #iiiiiiii (+ - Extend A * 256) - */ - - /* SimpleStackBasedCogit>>#genExtStoreAndPopLiteralVariableBytecode */ -static sqInt -genExtStoreAndPopLiteralVariableBytecode(void) -{ - sqInt index; - - index = byte1 + (((sqInt)((usqInt)(extA) << 8))); - extA = 0; - return genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(1, index, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); -} - - -/* 235 11101011 i i i i i i i i Pop and Store Receiver Variable #iiiiiii (+ - Extend A * 256) - */ - - /* SimpleStackBasedCogit>>#genExtStoreAndPopReceiverVariableBytecode */ -static sqInt -genExtStoreAndPopReceiverVariableBytecode(void) -{ - sqInt index; - - index = byte1 + (((sqInt)((usqInt)(extA) << 8))); - extA = 0; - return (isWriteMediatedContextInstVarIndex(index) - ? genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(1, index, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1) - : genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(1, index, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1)); -} - - -/* 233 11101001 i i i i i i i i Store Literal Variable #iiiiiiii (+ Extend A - * 256) - */ - - /* SimpleStackBasedCogit>>#genExtStoreLiteralVariableBytecode */ -static sqInt -genExtStoreLiteralVariableBytecode(void) -{ - sqInt index; - - index = byte1 + (((sqInt)((usqInt)(extA) << 8))); - extA = 0; - return genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(0, index, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); -} - - -/* 232 11101000 i i i i i i i i Store Receiver Variable #iiiiiii (+ Extend A - * 256) - */ - - /* SimpleStackBasedCogit>>#genExtStoreReceiverVariableBytecode */ -static sqInt -genExtStoreReceiverVariableBytecode(void) -{ - sqInt index; - - index = byte1 + (((sqInt)((usqInt)(extA) << 8))); - extA = 0; - return (isWriteMediatedContextInstVarIndex(index) - ? genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(0, index, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1) - : genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(0, index, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1)); -} - - -/* 242 11110010 i i i i i i i i Jump i i i i i i i i (+ Extend B * 256, - where bbbbbbbb = sddddddd, e.g. -32768 = i=0, a=0, s=1) - */ - - /* SimpleStackBasedCogit>>#genExtUnconditionalJump */ -static sqInt -genExtUnconditionalJump(void) -{ - AbstractInstruction *abstractInstruction; - sqInt distance; - sqInt target; - - distance = byte1 + (((sqInt)((usqInt)(extB) << 8))); - assert(distance == (v4LongBranchDistance(generatorAt(byte0), bytecodePC, ((extA != 0 - ? 1 - : 0)) + ((extB != 0 - ? 1 - : 0)), methodObj))); - extB = 0; - numExtB = 0; - target = (distance + 2) + bytecodePC; - if (distance < 0) { - return genJumpBackTo(target); - } - genJumpTo(target); - /* begin annotateBytecode: */ - abstractInstruction = lastOpcode(); - (abstractInstruction->annotation = HasBytecodePC); - return 0; -} - - /* SimpleStackBasedCogit>>#genFastPrimFail */ -static sqInt -genFastPrimFail(void) -{ - primitiveIndex = 0; - return UnfailingPrimitive; -} - - -/* Suport for compileInterpreterPrimitive. Generate inline code so as to - record the primitive - trace as fast as possible. */ - - /* SimpleStackBasedCogit>>#genFastPrimTraceUsing:and: */ -static void NoDbgRegParms -genFastPrimTraceUsingand(sqInt r1, sqInt r2) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - sqInt offset; - - /* begin MoveCq:R: */ - anInstruction = genoperandoperand(MoveCqR, 0, r2); - /* begin checkLiteral:forInstruction: */ - primTraceLogIndexAddress(); - anInstruction1 = genoperandoperand(MoveAbR, primTraceLogIndexAddress(), r2); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(LoadEffectiveAddressMwrR, 1, r2, r1); - /* begin checkLiteral:forInstruction: */ - primTraceLogIndexAddress(); - anInstruction3 = genoperandoperand(MoveRAb, r1, primTraceLogIndexAddress()); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), r1)))); - /* begin MoveMw:r:R: */ - offset = offsetof(CogMethod, selector); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperandoperand(MoveMwrR, offset, r1, TempReg); - /* begin checkLiteral:forInstruction: */ - ((sqInt)(primTraceLogAddress())); - anInstruction5 = genoperandoperand(MoveCwR, ((sqInt)(primTraceLogAddress())), r1); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, TempReg, r2, r1); -} - - /* SimpleStackBasedCogit>>#genLongJumpIfFalse */ -static sqInt -genLongJumpIfFalse(void) -{ - sqInt distance; - sqInt target; - - distance = v3LongForwardBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - target = (distance + 2) + bytecodePC; - return genJumpIfto(falseObject(), target); -} - - /* SimpleStackBasedCogit>>#genLongJumpIfTrue */ -static sqInt -genLongJumpIfTrue(void) -{ - sqInt distance; - sqInt target; - - distance = v3LongForwardBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - target = (distance + 2) + bytecodePC; - return genJumpIfto(trueObject(), target); -} - - -/* 230 11100110 i i i i i i i i Push Temporary Variable #iiiiiiii */ - - /* SimpleStackBasedCogit>>#genLongPushTemporaryVariableBytecode */ -static sqInt -genLongPushTemporaryVariableBytecode(void) -{ - return genPushTemporaryVariable(byte1); -} - - -/* 237 11101101 i i i i i i i i Pop and Store Temporary Variable #iiiiiiii */ - - /* SimpleStackBasedCogit>>#genLongStoreAndPopTemporaryVariableBytecode */ -static sqInt -genLongStoreAndPopTemporaryVariableBytecode(void) -{ - return genStorePopTemporaryVariable(1, byte1); -} - - -/* 234 11101010 i i i i i i i i Store Temporary Variable #iiiiiiii */ - - /* SimpleStackBasedCogit>>#genLongStoreTemporaryVariableBytecode */ -static sqInt -genLongStoreTemporaryVariableBytecode(void) -{ - return genStorePopTemporaryVariable(0, byte1); -} - - /* SimpleStackBasedCogit>>#genLongUnconditionalBackwardJump */ -static sqInt -genLongUnconditionalBackwardJump(void) -{ - sqInt distance; - - distance = v3LongBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - assert(distance < 0); - return genJumpBackTo((distance + 2) + bytecodePC); -} - - /* SimpleStackBasedCogit>>#genLongUnconditionalForwardJump */ -static sqInt -genLongUnconditionalForwardJump(void) -{ - sqInt distance; - sqInt targetpc; - - distance = v3LongBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - assert(distance >= 0); - targetpc = (distance + 2) + bytecodePC; - return genJumpTo(targetpc); -} - - -/* Compile the code for a probe of the first-level method cache for a perform - primitive. The selector is assumed to be in Arg0Reg. Defer to - adjustArgumentsForPerform: to - adjust the arguments before the jump to the method. */ - - /* SimpleStackBasedCogit>>#genLookupForPerformNumArgs: */ -static sqInt NoDbgRegParms -genLookupForPerformNumArgs(sqInt numArgs) -{ - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - sqInt cacheBaseReg; - AbstractInstruction *itsAHit; - AbstractInstruction *jumpClassMiss; - AbstractInstruction *jumpInterpret; - AbstractInstruction *jumpSelectorMiss; - sqInt offset; - - - /* N.B. Can't assume TempReg already contains the tag because a method can - of course be invoked via the unchecked entry-point, e.g. as does perform:. */ - genGetInlineCacheClassTagFromintoforEntry(ReceiverResultReg, SendNumArgsReg, 0); - flag("lookupInMethodCacheSel:classTag:"); - cacheBaseReg = NoReg; - jumpSelectorMiss = compilePerformMethodCacheProbeForwithShiftbaseRegOrNone(Arg0Reg, 0, cacheBaseReg); - /* begin JumpNonZero: */ - jumpClassMiss = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset = (cacheBaseReg == NoReg - ? (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheMethod) << (shiftForWord())))) - : ((int)((usqInt)(MethodCacheMethod) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, SendNumArgsReg); - itsAHit = anInstruction1; - genLoadSlotsourceRegdestReg(HeaderIndex, SendNumArgsReg, ClassReg); - - /* Adjust arguments and jump to the method's unchecked entry-point. */ - jumpInterpret = genJumpImmediate(ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AddCqR, cmNoCheckEntryOffset, ClassReg); - adjustArgumentsForPerform(numArgs); - /* begin JumpR: */ - genoperand(JumpR, ClassReg); - jmpTarget(jumpSelectorMiss, jmpTarget(jumpClassMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - jumpSelectorMiss = compilePerformMethodCacheProbeForwithShiftbaseRegOrNone(Arg0Reg, 1, cacheBaseReg); - /* begin JumpZero: */ - genConditionalBranchoperand(JumpZero, ((sqInt)itsAHit)); - jmpTarget(jumpSelectorMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - jumpSelectorMiss = compilePerformMethodCacheProbeForwithShiftbaseRegOrNone(Arg0Reg, 2, cacheBaseReg); - /* begin JumpZero: */ - genConditionalBranchoperand(JumpZero, ((sqInt)itsAHit)); - jmpTarget(jumpSelectorMiss, jmpTarget(jumpInterpret, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return 0; -} - - /* SimpleStackBasedCogit>>#genMustBeBooleanTrampolineFor:called: */ -static usqInt NoDbgRegParms -genMustBeBooleanTrampolineForcalled(sqInt boolean, char *trampolineName) -{ - AbstractInstruction *anInstruction; - - zeroOpcodeIndex(); - assert(!(shouldAnnotateObjectReference(boolean))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, boolean, TempReg); - return genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceSendMustBeBoolean, trampolineName, 1, TempReg, null, null, null, 0 /* emptyRegisterMask */, 1, NoReg, 1); -} - - -/* Implement 28-bit hashMultiply for SmallInteger and LargePositiveInteger - receivers. - */ - - /* SimpleStackBasedCogit>>#genPrimitiveHashMultiply */ -static sqInt -genPrimitiveHashMultiply(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction * jmpFailImm; - AbstractInstruction * jmpFailNotPositiveLargeInt; - - return UnimplementedPrimitive; - if (mclassIsSmallInteger()) { - genConvertSmallIntegerToIntegerInReg(ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, HashMultiplyConstant, TempReg); - /* begin MulR:R: */ - genMulRR(backEnd, TempReg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, HashMultiplyMask, ReceiverResultReg); - genConvertIntegerToSmallIntegerInReg(ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, 0); - return CompletePrimitive; - } - jmpFailImm = genJumpImmediate(ReceiverResultReg); - genGetCompactClassIndexNonImmOfinto(ReceiverResultReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(CmpCqR, ClassLargePositiveIntegerCompactIndex, ClassReg); - /* begin JumpNonZero: */ - jmpFailNotPositiveLargeInt = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(0, ReceiverResultReg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(MoveCqR, HashMultiplyConstant, TempReg); - /* begin MulR:R: */ - genMulRR(backEnd, TempReg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(AndCqR, HashMultiplyMask, ReceiverResultReg); - genConvertIntegerToSmallIntegerInReg(ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, 0); - jmpTarget(jmpFailImm, jmpTarget(jmpFailNotPositiveLargeInt, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - -/* Generate the substitute return code for an external or FFI primitive call. - On success simply return, extracting numArgs from newMethod. - On primitive failure call ceActivateFailingPrimitiveMethod: newMethod. */ - - /* SimpleStackBasedCogit>>#genPrimReturnEnterCogCodeEnilopmart: */ -static void NoDbgRegParms -genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) -{ - sqInt address; - sqInt address1; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - sqInt callTarget; - AbstractInstruction *continuePostSample; - AbstractInstruction * inst; - AbstractInstruction *jmpFail; - AbstractInstruction *jmpSample; - sqInt quickConstant; - sqInt reg; - - continuePostSample = ((AbstractInstruction *) 0); - jmpSample = ((AbstractInstruction *) 0); - zeroOpcodeIndex(); - /* begin MoveCq:R: */ - quickConstant = varBaseAddress(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - if (profiling) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick: if so. - N.B. nextProfileTick is 64-bits so 32-bit systems need to test both halves. */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction1 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin MoveAw:R: */ - address = (nextProfileTickAddress()) + BytesPerWord; - /* begin checkLiteral:forInstruction: */ - anInstruction2 = genoperandoperand(MoveAwR, address, ClassReg); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSample = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction13 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadStackPointers(backEnd); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); - /* begin checkLiteral:forInstruction: */ - instructionPointerAddress(); - anInstruction7 = genoperandoperand(MoveAwR, instructionPointerAddress(), LinkReg); - /* begin RetN: */ - genoperand(RetN, BytesPerWord); - jmpTarget(jmpFail, checkLiteralforInstruction(newMethodAddress(), genoperandoperand(MoveAwR, newMethodAddress(), SendNumArgsReg))); - /* begin checkLiteral:forInstruction: */ - cStackPointerAddress(); - anInstruction15 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); - compileCallFornumArgsargargargargresultRegregsToSave(ceActivateFailingPrimitiveMethod, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); - /* begin MoveAw:R: */ - address1 = instructionPointerAddress(); - reg = LinkReg; - /* begin checkLiteral:forInstruction: */ - anInstruction16 = genoperandoperand(MoveAwR, address1, reg); - genLoadStackPointers(backEnd); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, BytesPerWord); - if (profiling) { - - /* Call ceCheckProfileTick: to record sample and then continue. newMethod - should be up-to-date. Need to save and restore the link reg around this call. */ - jmpTarget(jmpSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - /* begin CallFullRT: */ - callTarget = (usqIntptr_t)ceCheckProfileTick; - /* begin checkLiteral:forInstruction: */ - anInstruction18 = genoperand(CallFull, callTarget); - /* begin PopR: */ - genoperand(PopR, LinkReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSample)); - } -} - - /* SimpleStackBasedCogit>>#genPushConstantFalseBytecode */ -static sqInt -genPushConstantFalseBytecode(void) -{ - return genPushLiteral(falseObject()); -} - - /* SimpleStackBasedCogit>>#genPushConstantNilBytecode */ -static sqInt -genPushConstantNilBytecode(void) -{ - return genPushLiteral(nilObject()); -} - - -/* 79 01001111 Push 1 */ - - /* SimpleStackBasedCogit>>#genPushConstantOneBytecode */ -static sqInt -genPushConstantOneBytecode(void) -{ - return genPushLiteral((((usqInt)1 << 1) | 1)); -} - - /* SimpleStackBasedCogit>>#genPushConstantTrueBytecode */ -static sqInt -genPushConstantTrueBytecode(void) -{ - return genPushLiteral(trueObject()); -} - - -/* 78 01001110 Push 0 */ - - /* SimpleStackBasedCogit>>#genPushConstantZeroBytecode */ -static sqInt -genPushConstantZeroBytecode(void) -{ - return genPushLiteral((((usqInt)0 << 1) | 1)); -} - - /* SimpleStackBasedCogit>>#genPushLiteralConstantBytecode */ -static sqInt -genPushLiteralConstantBytecode(void) -{ - return genPushLiteralIndex(byte0 & 0x1F); -} - - -/* 16-31 0001 i i i i Push Literal Variable #iiii */ - - /* SimpleStackBasedCogit>>#genPushLiteralVariable16CasesBytecode */ -static sqInt -genPushLiteralVariable16CasesBytecode(void) -{ - return genPushLiteralVariable(byte0 & 15); -} - - /* SimpleStackBasedCogit>>#genPushLiteralVariableBytecode */ -static sqInt -genPushLiteralVariableBytecode(void) -{ - return genPushLiteralVariable(byte0 & 0x1F); -} - - /* SimpleStackBasedCogit>>#genPushQuickIntegerConstantBytecode */ -static sqInt -genPushQuickIntegerConstantBytecode(void) -{ - return genPushLiteral((((usqInt)(byte0 - 117) << 1) | 1)); -} - - /* SimpleStackBasedCogit>>#genPushReceiverVariableBytecode */ -static sqInt -genPushReceiverVariableBytecode(void) -{ - return genPushReceiverVariable(byte0 & 15); -} - - /* SimpleStackBasedCogit>>#genPushTemporaryVariableBytecode */ -static sqInt -genPushTemporaryVariableBytecode(void) -{ - return genPushTemporaryVariable(byte0 & 15); -} - - -/* because selected by CoInterpreter>>quickPrimitiveGeneratorFor: */ - - /* SimpleStackBasedCogit>>#genQuickReturnConst */ -sqInt -genQuickReturnConst(void) -{ - AbstractInstruction *anInstruction; - sqInt constant; - - constant = quickPrimitiveConstantFor(primitiveIndex); - /* begin genMoveConstant:R: */ - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - genUpArrowReturn(); - return UnfailingPrimitive; -} - - -/* because selected by CoInterpreter>>quickPrimitiveGeneratorFor: */ - - /* SimpleStackBasedCogit>>#genQuickReturnInstVar */ -sqInt -genQuickReturnInstVar(void) -{ - sqInt index; - - index = quickPrimitiveInstVarIndexFor(primitiveIndex); - genLoadSlotsourceRegdestReg(index, ReceiverResultReg, ReceiverResultReg); - genUpArrowReturn(); - return UnfailingPrimitive; -} - - -/* because selected by CoInterpreter>>quickPrimitiveGeneratorFor: */ - - /* SimpleStackBasedCogit>>#genQuickReturnSelf */ -sqInt -genQuickReturnSelf(void) -{ - genUpArrowReturn(); - return UnfailingPrimitive; -} - - /* SimpleStackBasedCogit>>#genReturnFalse */ -static sqInt -genReturnFalse(void) -{ - AbstractInstruction *anInstruction; - sqInt constant; - - /* begin genMoveFalseR: */ - constant = falseObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - return genUpArrowReturn(); -} - - /* SimpleStackBasedCogit>>#genReturnNil */ -static sqInt -genReturnNil(void) -{ - AbstractInstruction *anInstruction; - sqInt constant; - - /* begin genMoveNilR: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - return genUpArrowReturn(); -} - - /* SimpleStackBasedCogit>>#genReturnNilFromBlock */ -static sqInt -genReturnNilFromBlock(void) -{ - AbstractInstruction *anInstruction; - sqInt constant; - - assert(inBlock > 0); - /* begin genMoveNilR: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - return genBlockReturn(); -} - - /* SimpleStackBasedCogit>>#genReturnTrue */ -static sqInt -genReturnTrue(void) -{ - AbstractInstruction *anInstruction; - sqInt constant; - - /* begin genMoveTrueR: */ - constant = trueObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - return genUpArrowReturn(); -} - - -/* Can use any of the first 64 literals for the selector and pass up to 3 - arguments. - */ - - /* SimpleStackBasedCogit>>#genSecondExtendedSendBytecode */ -static sqInt -genSecondExtendedSendBytecode(void) -{ - return genSendnumArgs(byte1 & 0x3F, ((usqInt)(byte1)) >> 6); -} - - /* SimpleStackBasedCogit>>#genSendLiteralSelector0ArgsBytecode */ -static sqInt -genSendLiteralSelector0ArgsBytecode(void) -{ - return genSendnumArgs(byte0 & 15, 0); -} - - /* SimpleStackBasedCogit>>#genSendLiteralSelector1ArgBytecode */ -static sqInt -genSendLiteralSelector1ArgBytecode(void) -{ - return genSendnumArgs(byte0 & 15, 1); -} - - /* SimpleStackBasedCogit>>#genSendLiteralSelector2ArgsBytecode */ -static sqInt -genSendLiteralSelector2ArgsBytecode(void) -{ - return genSendnumArgs(byte0 & 15, 2); -} - - /* SimpleStackBasedCogit>>#genShortJumpIfFalse */ -static sqInt -genShortJumpIfFalse(void) -{ - sqInt distance; - sqInt target; - - distance = v3ShortForwardBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - target = (distance + 1) + bytecodePC; - return genJumpIfto(falseObject(), target); -} - - /* SimpleStackBasedCogit>>#genShortJumpIfTrue */ -static sqInt -genShortJumpIfTrue(void) -{ - sqInt distance; - sqInt target; - - distance = v3ShortForwardBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - target = (distance + 1) + bytecodePC; - return genJumpIfto(trueObject(), target); -} - - /* SimpleStackBasedCogit>>#genShortUnconditionalJump */ -static sqInt -genShortUnconditionalJump(void) -{ - sqInt distance; - sqInt target; - - distance = v3ShortForwardBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - target = (distance + 1) + bytecodePC; - return genJumpTo(target); -} - - /* SimpleStackBasedCogit>>#genSpecialSelectorEqualsEquals */ -static sqInt -genSpecialSelectorEqualsEquals(void) -{ - return genInlinedIdenticalOrNotIf(0); -} - - /* SimpleStackBasedCogit>>#genSpecialSelectorNotEqualsEquals */ -static sqInt -genSpecialSelectorNotEqualsEquals(void) -{ - return genInlinedIdenticalOrNotIf(1); -} - - /* SimpleStackBasedCogit>>#genSpecialSelectorSend */ -static sqInt -genSpecialSelectorSend(void) -{ - sqInt index; - sqInt numArgs; - - index = byte0 - ( -#if MULTIPLEBYTECODESETS - (bytecodeSetOffset == 0x100 - ? AltFirstSpecialSelector + 0x100 - : FirstSpecialSelector) -#else - FirstSpecialSelector -#endif - ); - numArgs = specialSelectorNumArgs(index); - return genSendnumArgs((-index) - 1, numArgs); -} - - /* SimpleStackBasedCogit>>#genStoreAndPopReceiverVariableBytecode */ -static sqInt -genStoreAndPopReceiverVariableBytecode(void) -{ - return genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(1, byte0 & 7, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); -} - - /* SimpleStackBasedCogit>>#genStoreAndPopRemoteTempLongBytecode */ -static sqInt -genStoreAndPopRemoteTempLongBytecode(void) -{ - return genStorePopRemoteTempAtneedsStoreCheck(1, byte1, byte2, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant))))); -} - - /* SimpleStackBasedCogit>>#genStoreAndPopTemporaryVariableBytecode */ -static sqInt -genStoreAndPopTemporaryVariableBytecode(void) -{ - return genStorePopTemporaryVariable(1, byte0 & 7); -} - - /* SimpleStackBasedCogit>>#genStoreRemoteTempLongBytecode */ -static sqInt -genStoreRemoteTempLongBytecode(void) -{ - return genStorePopRemoteTempAtneedsStoreCheck(0, byte1, byte2, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant))))); -} - - -/* SistaV1: * 217 Trap */ - - /* SimpleStackBasedCogit>>#genUnconditionalTrapBytecode */ -static sqInt -genUnconditionalTrapBytecode(void) -{ - return EncounteredUnknownBytecode; -} - - /* SimpleStackBasedCogit>>#loadNativeArgumentAddress:to: */ -static void NoDbgRegParms -loadNativeArgumentAddressto(sqInt baseOffset, sqInt reg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt offset; - - /* begin MoveMw:r:R: */ - offset = frameOffsetOfPreviousNativeStackPointer(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, FPReg, reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AddCqR, baseOffset - 1, reg); -} - - /* SimpleStackBasedCogit>>#loadNativeFramePointerInto: */ -static void NoDbgRegParms -loadNativeFramePointerInto(sqInt reg) -{ - AbstractInstruction *anInstruction; - sqInt offset; - - /* begin MoveMw:r:R: */ - offset = frameOffsetOfNativeFramePointer(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, FPReg, reg); -} - - /* SimpleStackBasedCogit>>#loadNativeLocalAddress:to: */ -static void NoDbgRegParms -loadNativeLocalAddressto(sqInt baseOffset, sqInt reg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt offset; - - /* begin MoveMw:r:R: */ - offset = frameOffsetOfNativeFramePointer(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, FPReg, reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AddCqR, baseOffset - 1, reg); -} - - -/* Collect the branch and send data for cogMethod, storing it into arrayObj. */ - - /* SimpleStackBasedCogit>>#mapPCDataFor:into: */ -sqInt -mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj) -{ - sqInt aMethodHeader; - sqInt aMethodHeader1; - sqInt aMethodObj; - sqInt annotation; - sqInt bcpc; - sqInt bsOffset; - sqInt byte; - BytecodeDescriptor *descriptor; - sqInt distance; - sqInt endbcpc; - sqInt errCode; - CogMethod *homeMethod; - sqInt isBackwardBranch; - sqInt isInBlock; - sqInt latestContinuation; - usqInt map; - sqInt mapByte; - usqInt mcpc; - sqInt nExts; - sqInt nextBcpc; - sqInt result; - sqInt startbcpc; - sqInt targetPC; - - latestContinuation = 0; - introspectionDataIndex = 0; - introspectionData = arrayObj; - if (((cogMethod->stackCheckOffset)) == 0) { - assert(introspectionDataIndex == 0); - if ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock)) { - storePointerUncheckedofObjectwithValue(0, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(1, introspectionData, (((usqInt)cbNoSwitchEntryOffset << 1) | 1)); - storePointerUncheckedofObjectwithValue(2, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(3, introspectionData, (((usqInt)cbEntryOffset << 1) | 1)); - } - else { - storePointerUncheckedofObjectwithValue(0, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(1, introspectionData, (((usqInt)cmEntryOffset << 1) | 1)); - storePointerUncheckedofObjectwithValue(2, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(3, introspectionData, (((usqInt)cmNoCheckEntryOffset << 1) | 1)); - } - return 4; - } - /* begin mapFor:bcpc:performUntil:arg: */ - startbcpc = startPCOfMethod((cogMethod->methodObject)); - assert((((((CogBlockMethod *) cogMethod))->stackCheckOffset)) > 0); - - /* The stack check maps to the start of the first bytecode, - the first bytecode being effectively after frame build. */ - mcpc = (((usqInt)(((CogBlockMethod *) cogMethod)))) + (((((CogBlockMethod *) cogMethod))->stackCheckOffset)); - result = pcDataForAnnotationMcpcBcpcMethod(null, (0 + (((int)((usqInt)(HasBytecodePC) << 1)))), (((char *) mcpc)), startbcpc, (((void *)cogMethod))); - if (result != 0) { - errCode = result; - goto l7; - } - - /* In both CMMethod and CMBlock cases find the start of the map and - skip forward to the bytecode pc map entry for the stack check. */ - bcpc = startbcpc; - if ((((((CogBlockMethod *) cogMethod))->cmType)) == CMMethod) { - /* begin cmIsFullBlock */ - isInBlock = ((((CogBlockMethod *) cogMethod))->cpicHasMNUCaseOrCMIsFullBlock); - homeMethod = ((CogMethod *) (((CogBlockMethod *) cogMethod))); - assert(startbcpc == (startPCOfMethodHeader((homeMethod->methodHeader)))); - map = ((((usqInt)homeMethod)) + ((homeMethod->blockSize))) - 1; - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert((annotation == IsAbsPCReference) - || ((annotation == IsObjectReference) - || ((annotation == IsRelativeCall) - || (annotation == IsDisplacementX2N)))); - latestContinuation = startbcpc; - aMethodObj = (homeMethod->methodObject); - endbcpc = (numBytesOf(aMethodObj)) - 1; - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader) - ? 0x100 - : 0) -# else - 0 -# endif - ; - bcpc += deltaToSkipPrimAndErrorStoreInheader(aMethodObj, (homeMethod->methodHeader)); - } - else { - isInBlock = 1; - assert(bcpc == (((((CogBlockMethod *) cogMethod))->startpc))); - homeMethod = cmHomeMethod(((CogBlockMethod *) cogMethod)); - map = findMapLocationForMcpcinMethod((((usqInt)(((CogBlockMethod *) cogMethod)))) + (sizeof(CogBlockMethod)), homeMethod); - assert(map != 0); - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert(((((usqInt)(annotation)) >> AnnotationShift) == HasBytecodePC) - || ((((usqInt)(annotation)) >> AnnotationShift) == IsDisplacementX2N)); - while (((annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift)) != HasBytecodePC) { - map -= 1; - } - - /* skip fiducial; i.e. the map entry for the pc immediately following the method header. */ - map -= 1; - aMethodObj = (homeMethod->methodObject); - bcpc = startbcpc - ( -#if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet((homeMethod->methodHeader)) - ? AltBlockCreationBytecodeSize - : BlockCreationBytecodeSize) -#else // MULTIPLEBYTECODESETS - BlockCreationBytecodeSize -#endif - ); - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader1 = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader1) - ? 0x100 - : 0) -# else - 0 -# endif - ; - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - endbcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, -1, aMethodObj)) - : 0)); - bcpc = startbcpc; - } - nExts = 0; - while ((((usqInt)((byteAt(map)))) >> AnnotationShift) != HasBytecodePC) { - map -= 1; - } - map -= 1; - while (((mapByte = byteAt(map))) != MapEnd) { - - /* defensive; we exit on bcpc */ - if (mapByte >= FirstAnnotation) { - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if (annotation >= HasBytecodePC) { - if ((annotation == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - while (1) { - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - if (isInBlock) { - if (bcpc >= endbcpc) { - errCode = 0; - goto l7; - } - } - else { - if (((descriptor->isReturn)) - && (bcpc >= latestContinuation)) { - errCode = 0; - goto l7; - } - if ((isBranch(descriptor)) - || ((descriptor->isBlockCreation))) { - /* begin latestContinuationPCFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj); - targetPC = (bcpc + ((descriptor->numBytes))) + (((distance < 0) ? 0 : distance)); - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - /* latestContinuation = */ latestContinuation; - } - nextBcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) - : 0)); - if (((descriptor->isMapped)) - || (isInBlock - && ((descriptor->isMappedInBlock)))) break; - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - isBackwardBranch = (isBranch(descriptor)) - && ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) < 0)); - result = pcDataForAnnotationMcpcBcpcMethod(descriptor, ((isBackwardBranch - ? (((sqInt)((usqInt)(annotation) << 1))) + 1 - : ((sqInt)((usqInt)(annotation) << 1)))), (((char *) mcpc)), ((isBackwardBranch - ? bcpc - (2 * nExts) - : bcpc)), (((void *)cogMethod))); - if (result != 0) { - errCode = result; - goto l7; - } - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - } - else { - assert(((((usqInt)(mapByte)) >> AnnotationShift) == IsDisplacementX2N) - || ((((usqInt)(mapByte)) >> AnnotationShift) == IsAnnotationExtension)); - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - errCode = 0; - l7: /* end mapFor:bcpc:performUntil:arg: */; - if (errCode != 0) { - assert(errCode == PrimErrNoMemory); - return -1; - } - if (((cogMethod->blockEntryOffset)) != 0) { - errCode = blockDispatchTargetsForperformarg(cogMethod, pcDataForBlockEntryMethod, ((sqInt)cogMethod)); - if (errCode != 0) { - assert(errCode == PrimErrNoMemory); - return -1; - } - } - return introspectionDataIndex; -} - - /* SimpleStackBasedCogit>>#numSpecialSelectors */ -static sqInt -numSpecialSelectors(void) -{ - return -# if MULTIPLEBYTECODESETS - (bytecodeSetOffset == 0x100 - ? AltNumSpecialSelectors - : NumSpecialSelectors) -# else - NumSpecialSelectors -# endif - ; -} - - -/* Collect the branch and send data for the block method starting at - blockEntryMcpc, storing it into picData. - */ - - /* SimpleStackBasedCogit>>#pcDataForBlockEntry:Method: */ -static usqInt NoDbgRegParms -pcDataForBlockEntryMethod(sqInt blockEntryMcpc, sqInt cogMethod) -{ - storePointerUncheckedofObjectwithValue(introspectionDataIndex, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 1, introspectionData, (((usqInt)(blockEntryMcpc - blockNoContextSwitchOffset) << 1) | 1)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 2, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 3, introspectionData, (((usqInt)blockEntryMcpc << 1) | 1)); - introspectionDataIndex += 4; - return 0; -} - - /* SimpleStackBasedCogit>>#pcDataFor:Annotation:Mcpc:Bcpc:Method: */ -static sqInt NoDbgRegParms -pcDataForAnnotationMcpcBcpcMethod(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *cogMethodArg) -{ - sqInt actualBcpc; - sqInt actualMcpc; - - if (!descriptor) { - - /* this is the stackCheck offset */ - assert(introspectionDataIndex == 0); - if (((((CogMethod *) cogMethodArg))->cpicHasMNUCaseOrCMIsFullBlock)) { - storePointerUncheckedofObjectwithValue(introspectionDataIndex, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 1, introspectionData, (((usqInt)cbNoSwitchEntryOffset << 1) | 1)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 2, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 3, introspectionData, (((usqInt)cbEntryOffset << 1) | 1)); - } - else { - storePointerUncheckedofObjectwithValue(introspectionDataIndex, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 1, introspectionData, (((usqInt)cmEntryOffset << 1) | 1)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 2, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 3, introspectionData, (((usqInt)cmNoCheckEntryOffset << 1) | 1)); - } - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 4, introspectionData, (((usqInt)(bcpc + 1) << 1) | 1)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 5, introspectionData, (((((((CogMethod *) cogMethodArg))->stackCheckOffset)) << 1) | 1)); - introspectionDataIndex += 6; - return 0; - } - if ((((usqInt)(isBackwardBranchAndAnnotation)) >> 1) >= HasBytecodePC) { - actualBcpc = (((isBackwardBranchAndAnnotation & 1) != 0) - ? bcpc + 1 - : (bcpc + ((descriptor->numBytes))) + 1); - actualMcpc = (((usqInt)mcpc)) - (((usqInt)cogMethodArg)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex, introspectionData, (((usqInt)actualBcpc << 1) | 1)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 1, introspectionData, (((usqInt)actualMcpc << 1) | 1)); - introspectionDataIndex += 2; - } - return 0; -} - - -/* If there is a generator for the current primitive then answer it; - otherwise answer nil. */ - - /* SimpleStackBasedCogit>>#primitiveGeneratorOrNil */ -static PrimitiveDescriptor * -primitiveGeneratorOrNil(void) -{ - PrimitiveDescriptor *primitiveDescriptor; - - if (isQuickPrimitiveIndex(primitiveIndex)) { - - /* an unused one */ - primitiveDescriptor = (&(primitiveGeneratorTable[0])); - (primitiveDescriptor->primitiveGenerator = quickPrimitiveGeneratorFor(primitiveIndex)); - return primitiveDescriptor; - } - if (((primitiveIndex >= 1) && (primitiveIndex <= MaxCompiledPrimitiveIndex))) { - return (&(primitiveGeneratorTable[primitiveIndex])); - } - return null; -} - - /* SimpleStackBasedCogit>>#register:isInMask: */ -static sqInt NoDbgRegParms -registerisInMask(sqInt reg, sqInt mask) -{ - return ((mask & (1U << reg)) != 0); -} - - /* SimpleStackBasedCogit>>#v3:Block:Code:Size: */ -static sqInt NoDbgRegParms -v3BlockCodeSize(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - assert(nExts <= 0); - return (((sqInt)((usqInt)((fetchByteofObject(pc + 2, aMethodObj))) << 8))) + (fetchByteofObject(pc + 3, aMethodObj)); -} - - -/* Answer the distance of a two byte forward long jump. */ - - /* SimpleStackBasedCogit>>#v3:LongForward:Branch:Distance: */ -static sqInt NoDbgRegParms -v3LongForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - assert(nExts == 0); - return (((sqInt)((usqInt)(((fetchByteofObject(pc, aMethodObj)) & 3)) << 8))) + (fetchByteofObject(pc + 1, aMethodObj)); -} - - -/* Answer the distance of a two byte forward long jump. */ - - /* SimpleStackBasedCogit>>#v3:Long:Branch:Distance: */ -static sqInt NoDbgRegParms -v3LongBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - assert(nExts == 0); - return (((sqInt)((usqInt)((((fetchByteofObject(pc, aMethodObj)) & 7) - 4)) << 8))) + (fetchByteofObject(pc + 1, aMethodObj)); -} - - -/* N.B. This serves for both BlueBook/V3 and V4 short jumps. */ - - /* SimpleStackBasedCogit>>#v3:ShortForward:Branch:Distance: */ -static sqInt NoDbgRegParms -v3ShortForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - assert(nExts == 0); - return ((fetchByteofObject(pc, aMethodObj)) & 7) + 1; -} - - -/* 253 11111101 eei i i kkk jjjjjjjj Push Closure Num Copied iii (+ Ext A - // 16 * 8) Num Args kkk (+ Ext A \\ 16 * 8) BlockSize jjjjjjjj (+ Ext B * - 256). ee = num extensions - */ - - /* SimpleStackBasedCogit>>#v4:Block:Code:Size: */ -static sqInt NoDbgRegParms -v4BlockCodeSize(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - sqInt byte; - sqInt byteOne; - sqInt extAValue; - sqInt extBValue; - sqInt extBValue1; - sqInt extByte; - sqInt pc1; - - - /* If nExts < 0 it isn't known and we rely on the number of extensions encoded in the eeiiikkk byte. */ - byteOne = fetchByteofObject(pc + 1, aMethodObj); - assert((nExts < 0) - || (nExts == (((usqInt)(byteOne)) >> 6))); - /* begin parseV4Exts:priorTo:in:into: */ - extAValue = (extBValue1 = 0); - pc1 = (pc - (((usqInt)(byteOne)) >> 6)) - (((usqInt)(byteOne)) >> 6); - while (pc1 < pc) { - byte = fetchByteofObject(pc1, aMethodObj); - pc1 += 1; - extByte = fetchByteofObject(pc1, aMethodObj); - pc1 += 1; - assert((byte == 224) - || (byte == 225)); - if (byte == 224) { - extAValue = ((((sqInt)((usqInt)(extAValue) << 8)))) + extByte; - } - else { - extBValue1 = ((extBValue1 == 0) - && (extByte > 0x7F) - ? extByte - 0x100 - : ((((sqInt)((usqInt)(extBValue1) << 8)))) + extByte); - } - } - extBValue = extBValue1; - return (fetchByteofObject(pc + 2, aMethodObj)) + (((sqInt)((usqInt)(extBValue) << 8))); -} - - -/* 242 11110010 i i i i i i i i Jump i i i i i i i i (+ Extend B * 256, - where bbbbbbbb = sddddddd, e.g. -32768 = i=0, a=0, s=1) - */ -/* 243 11110011 i i i i i i i i Pop and Jump 0n True i i i i i i i i (+ - Extend A * 256) - */ -/* 244 11110100 i i i i i i i i Pop and Jump 0n False i i i i i i i i (+ - Extend A * 256) - */ - - /* SimpleStackBasedCogit>>#v4:LongForward:Branch:Distance: */ -static sqInt NoDbgRegParms -v4LongForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - sqInt byte; - sqInt extAValue; - sqInt extBValue; - sqInt extBValue1; - sqInt extByte; - sqInt pc1; - - assert(nExts >= 0); - /* begin parseV4Exts:priorTo:in:into: */ - extAValue = (extBValue1 = 0); - pc1 = (pc - nExts) - nExts; - while (pc1 < pc) { - byte = fetchByteofObject(pc1, aMethodObj); - pc1 += 1; - extByte = fetchByteofObject(pc1, aMethodObj); - pc1 += 1; - assert((byte == 224) - || (byte == 225)); - if (byte == 224) { - extAValue = ((((sqInt)((usqInt)(extAValue) << 8)))) + extByte; - } - else { - extBValue1 = ((extBValue1 == 0) - && (extByte > 0x7F) - ? extByte - 0x100 - : ((((sqInt)((usqInt)(extBValue1) << 8)))) + extByte); - } - } - extBValue = extBValue1; - return (fetchByteofObject(pc + 1, aMethodObj)) + (((sqInt)((usqInt)(extBValue) << 8))); -} - - -/* 242 11110010 i i i i i i i i Jump i i i i i i i i (+ Extend B * 256, - where bbbbbbbb = sddddddd, e.g. -32768 = i=0, a=0, s=1) - */ - - /* SimpleStackBasedCogit>>#v4:Long:Branch:Distance: */ -static sqInt NoDbgRegParms -v4LongBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - sqInt byte; - sqInt extAValue; - sqInt extBValue; - sqInt extBValue1; - sqInt extByte; - sqInt pc1; - - assert(nExts >= 0); - /* begin parseV4Exts:priorTo:in:into: */ - extAValue = (extBValue1 = 0); - pc1 = (pc - nExts) - nExts; - while (pc1 < pc) { - byte = fetchByteofObject(pc1, aMethodObj); - pc1 += 1; - extByte = fetchByteofObject(pc1, aMethodObj); - pc1 += 1; - assert((byte == 224) - || (byte == 225)); - if (byte == 224) { - extAValue = ((((sqInt)((usqInt)(extAValue) << 8)))) + extByte; - } - else { - extBValue1 = ((extBValue1 == 0) - && (extByte > 0x7F) - ? extByte - 0x100 - : ((((sqInt)((usqInt)(extBValue1) << 8)))) + extByte); - } - } - extBValue = extBValue1; - return (fetchByteofObject(pc + 1, aMethodObj)) + (((sqInt)((usqInt)(extBValue) << 8))); -} - - /* SistaMethodZone>>#getCogCodeZoneThreshold */ -double -getCogCodeZoneThreshold(void) -{ - return thresholdRatio; -} - - /* SistaMethodZone>>#setCogCodeZoneThreshold: */ -sqInt -setCogCodeZoneThreshold(double ratio) -{ - if (!((ratio >= 0.1) - && (ratio <= 1.0))) { - return PrimErrBadArgument; - } - thresholdRatio = ratio; - /* begin computeAllocationThreshold */ - allocationThreshold = ((((((usqInt)((limitAddress - baseAddress) * thresholdRatio))) + (7)) & ~7)) + baseAddress; - return 0; -} - - -/* Add a blockStart for an embedded block. For a binary tree walk block - dispatch blocks must be compiled in pc/depth-first order but are scanned - in breadth-first - order, so do an insertion sort (which of course is really a bubble sort - because we - have to move everything higher to make room). */ - - /* StackToRegisterMappingCogit>>#addBlockStartAt:numArgs:numCopied:span: */ -static BlockStart * NoDbgRegParms -addBlockStartAtnumArgsnumCopiedspan(sqInt bytecodepc, sqInt numArgs, sqInt numCopied, sqInt span) -{ - BlockStart *blockStart; - sqInt i; - sqInt j; - - - /* Transcript ensureCr; nextPutAll: 'addBlockStartAt: '; print: bytecodepc; cr; flush. */ - if (blockCount > 0) { - i = blockCount - 1; - while (1) { - - /* check for repeat addition during recompilation due to initialNil miscount. */ - blockStart = (&(blockStarts[i])); - if (((blockStart->startpc)) == bytecodepc) { - return blockStart; - } - if (!((((blockStart->startpc)) > bytecodepc) - && (i > 0))) break; - i -= 1; - } - for (j = blockCount; j >= (i + 1); j += -1) { - blockStarts[j] = (blockStarts[j - 1]); - } - blockStart = (&(blockStarts[i + 1])); - } - else { - blockStart = (&(blockStarts[blockCount])); - } - blockCount += 1; - (blockStart->startpc = bytecodepc); - (blockStart->numArgs = numArgs); - (blockStart->numCopied = numCopied); - (blockStart->numInitialNils = 0); - (blockStart->stackCheckLabel = null); - (blockStart->hasInstVarRef = 0); - (blockStart->span = span); - return blockStart; -} - - -/* e.g. Receiver Receiver or Receiver Receiver (RISC) - Selector/Arg0 => Arg1 Selector/Arg0 => Arg1 - Arg1 Arg2 Arg1 Arg2 - Arg2 Arg3 Arg2 sp-> Arg3 - Arg3 sp-> retpc sp-> Arg3 - sp-> retpc */ -/* Generate code to adjust the possibly stacked arguments immediately - before jumping to a method looked up by a perform primitive. */ - - /* StackToRegisterMappingCogit>>#adjustArgumentsForPerform: */ -static void NoDbgRegParms -adjustArgumentsForPerform(sqInt numArgs) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction3; - sqInt index; - - assert((numRegArgs()) <= 2); - assert(numArgs >= 1); - if (numArgs <= 2 /* numRegArgs */) { - if (numArgs == 2) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, Arg0Reg); - } - return; - } - if ((3) == numArgs) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, SPReg, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, BytesPerWord, SPReg, Arg0Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(AddCqR, (numArgs + 1) * BytesPerWord, SPReg); - return; - } - for (index = (numArgs - 2); index >= 0; index += -1) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveMwrR, index * BytesPerWord, SPReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperandoperand(MoveRMwr, TempReg, (index + 1) * BytesPerWord, SPReg); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperand(AddCqR, BytesPerWord, SPReg); -} - - -/* if there's a free register, use it */ - - /* StackToRegisterMappingCogit>>#allocateFloatRegNotConflictingWith: */ -static sqInt NoDbgRegParms -allocateFloatRegNotConflictingWith(sqInt regMask) -{ - sqInt reg; - - reg = availableFloatRegisterOrNoneFor(backEnd, (liveFloatRegisters()) | regMask); - if (reg == NoReg) { - - /* No free register, choose one that does not conflict with regMask */ - reg = freeAnyFloatRegNotConflictingWith(regMask); - } - return reg; -} - - -/* If the stack entry is already in a register not conflicting with regMask, - answers it, - else allocate a new register not conflicting with reg mask - */ - - /* StackToRegisterMappingCogit>>#allocateRegForStackEntryAt:notConflictingWith: */ -static sqInt NoDbgRegParms -allocateRegForStackEntryAtnotConflictingWith(sqInt index, sqInt regMask) -{ - sqInt mask; - CogSimStackEntry *stackEntry; - - stackEntry = ssValue(index); - mask = registerMaskOrNone(stackEntry); - if ((mask != 0) - && ((!(mask & regMask)))) { - flag("TODO"); - return registerOrNone(stackEntry); - } - return allocateRegNotConflictingWith(regMask); -} - - -/* if there's a free register, use it */ - - /* StackToRegisterMappingCogit>>#allocateRegNotConflictingWith: */ -static sqInt NoDbgRegParms -allocateRegNotConflictingWith(sqInt regMask) -{ - sqInt reg; - - reg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); - if (reg == NoReg) { - - /* No free register, choose one that does not conflict with regMask */ - reg = freeAnyRegNotConflictingWith(regMask); - } - if (reg == ReceiverResultReg) { - - /* If we've allocated RcvrResultReg, it's not live anymore */ - voidReceiverResultRegContainsSelf(); - } - return reg; -} - - /* StackToRegisterMappingCogit>>#anyReferencesToRegister:inTopNItems: */ -static sqInt NoDbgRegParms -anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n) -{ - sqInt i; - sqInt regMask; - - /* begin registerMaskFor: */ - regMask = 1U << reg; - for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { - if ((((registerMask(simStackAt(i))) & regMask) != 0)) { - return 1; - } - } - return 0; -} - - -/* Store the smalltalk pointers */ - - /* StackToRegisterMappingCogit>>#beginHighLevelCall: */ -static void NoDbgRegParms -beginHighLevelCall(sqInt alignment) -{ - sqInt actualAlignment; - sqInt address; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - sqInt i; - sqInt mask; - sqInt offset; - - /* begin ssFlushAll */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - voidReceiverResultRegContainsSelf(); - genSaveStackPointers(backEnd); - /* begin MoveAw:R: */ - address = instructionPointerAddress(); - /* begin checkLiteral:forInstruction: */ - anInstruction = genoperandoperand(MoveAwR, address, LinkReg); - genLoadCStackPointer(backEnd); - /* begin MoveMw:r:R: */ - offset = frameOffsetOfNativeFramePointer(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveMwrR, offset, FPReg, FPReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(SubCqR, 1, FPReg); - actualAlignment = ((alignment < BytesPerWord) ? BytesPerWord : alignment); - if (actualAlignment > BytesPerWord) { - mask = -actualAlignment; - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, mask, SPReg); - } - currentCallCleanUpSize = 0; -} - - -/* This is a static version of ceCallCogCodePopReceiverArg0Regs - for break-pointing when debugging in C. */ -/* This exists only for break-pointing. */ - - /* StackToRegisterMappingCogit>>#callCogCodePopReceiverArg0Regs */ -void -callCogCodePopReceiverArg0Regs(void) -{ - realCECallCogCodePopReceiverArg0Regs(); -} - - -/* This is a static version of ceCallCogCodePopReceiverArg1Arg0Regs - for break-pointing when debugging in C. */ -/* This exists only for break-pointing. */ - - /* StackToRegisterMappingCogit>>#callCogCodePopReceiverArg1Arg0Regs */ -void -callCogCodePopReceiverArg1Arg0Regs(void) -{ - realCECallCogCodePopReceiverArg1Arg0Regs(); -} - - /* StackToRegisterMappingCogit>>#callSwitchToCStack */ -static sqInt -callSwitchToCStack(void) -{ - AbstractInstruction *anInstruction; - - /* begin checkLiteral:forInstruction: */ - cFramePointerAddress(); - anInstruction = genoperandoperand(MoveAwR, cFramePointerAddress(), FPReg); - return 0; -} - - -/* Restore the link register */ - - /* StackToRegisterMappingCogit>>#callSwitchToSmalltalkStack */ -static void -callSwitchToSmalltalkStack(void) -{ - sqInt address; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt quickConstant; - - /* begin MoveCq:R: */ - quickConstant = varBaseAddress(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - /* begin MoveAw:R: */ - address = instructionPointerAddress(); - /* begin checkLiteral:forInstruction: */ - anInstruction1 = genoperandoperand(MoveAwR, address, LinkReg); - genLoadStackPointers(backEnd); -} - - -/* Loop over bytecodes, dispatching to the generator for each bytecode, - handling fixups in due course. - */ - - /* StackToRegisterMappingCogit>>#compileAbstractInstructionsFrom:through: */ -static sqInt NoDbgRegParms -compileAbstractInstructionsFromthrough(sqInt start, sqInt end) -{ - BytecodeDescriptor *descriptor; - BytecodeFixup *fixup; - sqInt nExts; - sqInt nextOpcodeIndex; - sqInt result; - - traceSimStack(); - bytecodePC = start; - nExts = (result = 0); - descriptor = null; - deadCode = 0; - while (1) { - maybeHaltIfDebugPC(); - mergeWithFixupIfRequired((fixup = fixupAt(bytecodePC))); - descriptor = loadBytesAndGetDescriptor(); - nextOpcodeIndex = opcodeIndex; - result = (deadCode - ? mapDeadDescriptorIfNeeded(descriptor) - : ((descriptor->generator))()); - if (result == 0) { - /* begin assertExtsAreConsumed: */ - if (!((descriptor->isExtension))) { - assert((extA == 0) - && ((extB == 0) - && (numExtB == 0))); - } - } - traceDescriptor(descriptor); - traceSimStack(); - /* begin patchFixupTargetIfNeeded:nextOpcodeIndex: */ - if ((((((usqInt)((fixup->targetInstruction)))) >= NeedsNonMergeFixupFlag) && ((((usqInt)((fixup->targetInstruction)))) <= NeedsMergeFixupFlag))) { - - /* There is a fixup for this bytecode. It must point to the first generated - instruction for this bytecode. If there isn't one we need to add a label. */ - if (opcodeIndex == nextOpcodeIndex) { - /* begin Label */ - genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (fixup->targetInstruction = abstractInstructionAt(nextOpcodeIndex)); - } - /* begin maybeDumpLiterals: */ - if (((isBranch(descriptor)) - && (!(((descriptor->isBranchTrue)) - || ((descriptor->isBranchFalse))))) - || ((descriptor->isReturn))) { - /* begin dumpLiterals: */ - !(((isBranch(descriptor)) - && (!(((descriptor->isBranchTrue)) - || ((descriptor->isBranchFalse))))) - || ((descriptor->isReturn))); - } - /* begin nextBytecodePCFor:exts: */ - bytecodePC = (bytecodePC + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? ((descriptor->spanFunction))(descriptor, bytecodePC, nExts, methodObj) - : 0)); - if (!((result == 0) - && (bytecodePC <= end))) break; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - /* begin checkEnoughOpcodes */ - if (opcodeIndex > numAbstractOpcodes) { - error("Cog JIT internal error. Too many abstract opcodes. Num opcodes heuristic is too optimistic."); - } - return result; -} - - /* StackToRegisterMappingCogit>>#compileBlockBodies */ -static sqInt -compileBlockBodies(void) -{ - BlockStart *blockStart; - sqInt compiledBlocksCount; - sqInt initialCounterIndex; - sqInt initialOpcodeIndex; - sqInt initialStackPtr; - sqInt (* const pushNilSizeFunction)(sqInt,sqInt) = squeakV3orSistaV1PushNilSizenumInitialNils; - sqInt result; - sqInt savedNeedsFrame; - sqInt savedNumArgs; - sqInt savedNumTemps; - - assert(blockCount > 0); - savedNeedsFrame = needsFrame; - savedNumArgs = methodOrBlockNumArgs; - savedNumTemps = methodOrBlockNumTemps; - inBlock = InVanillaBlock; - compiledBlocksCount = 0; - while (compiledBlocksCount < blockCount) { - compilationPass = 1; - blockStart = blockStartAt(compiledBlocksCount); - if (((result = scanBlock(blockStart))) < 0) { - return result; - } - initialOpcodeIndex = opcodeIndex; - - /* for SistaCogit */ - initialCounterIndex = 0 /* maybeCounterIndex */; - while (1) { - compileBlockEntry(blockStart); - initialStackPtr = simStackPtr; - if (((result = compileAbstractInstructionsFromthrough(((blockStart->startpc)) + (pushNilSizeFunction(methodObj, ((blockStart->numInitialNils)))), (((blockStart->startpc)) + ((blockStart->span))) - 1))) < 0) { - return result; - } - if (initialStackPtr == simStackPtr) break; - assert((initialStackPtr > simStackPtr) - || (deadCode)); - - /* for asserts */ - compilationPass += 1; - (blockStart->numInitialNils = (((blockStart->numInitialNils)) + simStackPtr) - initialStackPtr); - (((blockStart->fakeHeader))->dependent = null); - reinitializeFixupsFromthrough(((blockStart->startpc)) + ((blockStart->numInitialNils)), (((blockStart->startpc)) + ((blockStart->span))) - 1); - bzero(abstractOpcodes + initialOpcodeIndex, - (opcodeIndex - initialOpcodeIndex) * sizeof(AbstractInstruction)); - opcodeIndex = initialOpcodeIndex; - } - compiledBlocksCount += 1; - } - needsFrame = savedNeedsFrame; - methodOrBlockNumArgs = savedNumArgs; - methodOrBlockNumTemps = savedNumTemps; - return 0; -} - - -/* Build a frame for a block activation. See CoInterpreter - class>>initializeFrameIndices. closure (in ReceiverResultReg) - arg0 - ... - argN - caller's saved ip/this stackPage (for a base frame) - fp-> saved fp - method - context (uninitialized?) - receiver - first temp - ... - sp-> Nth temp - Avoid use of SendNumArgsReg which is the flag determining whether - context switch is allowed on stack-overflow. */ -/* Build a frame for a block activation. See CoInterpreter - class>>initializeFrameIndices. Override to push the register receiver and - register arguments, if any, and to correctly - initialize the explicitly nilled/pushed temp entries (they are /not/ of - type constant nil). */ - - /* StackToRegisterMappingCogit>>#compileBlockFrameBuild: */ -static void NoDbgRegParms -compileBlockFrameBuild(BlockStart *blockStart) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction * cascade0; - sqInt constant; - sqInt constant1; - sqInt i; - sqInt ign; - - /* begin annotateBytecode: */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction->annotation = HasBytecodePC); - /* begin PushR: */ - genoperand(PushR, LinkReg); - /* begin PushR: */ - genoperand(PushR, FPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SPReg, FPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, ClassReg); - cascade0 = (blockStart->fakeHeader); - addDependent(cascade0, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)((blockStart->fakeHeader))), genoperand(PushCw, ((sqInt)((blockStart->fakeHeader))))))); - /* begin setLabelOffset: */ - ((cascade0->operands))[1] = MFMethodFlagIsBlockFlag; - annotateobjRef(checkLiteralforInstruction(nilObject(), genoperand(PushCw, nilObject())), nilObject()); - if ((blockStart->hasInstVarRef)) { - - /* Use ReceiverResultReg for Context to agree with store check trampoline */ - genLoadSlotsourceRegdestReg(ClosureOuterContextIndex, ClassReg, ReceiverResultReg); - genLoadSlotsourceRegdestReg(ReceiverIndex, ReceiverResultReg, Arg0Reg); - genEnsureOopInRegNotForwardedscratchRegupdatingSlotin(Arg0Reg, TempReg, ReceiverIndex, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ReceiverResultReg); - } - else { - genLoadSlotsourceRegdestReg(ClosureOuterContextIndex, ClassReg, Arg0Reg); - genLoadSlotsourceRegdestReg(ReceiverIndex, Arg0Reg, ReceiverResultReg); - } - /* begin PushR: */ - genoperand(PushR, ReceiverResultReg); - for (i = 0; i < ((blockStart->numCopied)); i += 1) { - genLoadSlotsourceRegdestReg(i + ClosureFirstCopiedValueIndex, ClassReg, TempReg); - /* begin PushR: */ - genoperand(PushR, TempReg); - } - (blockStart->stackCheckLabel = compileStackOverflowCheck(1)); - methodOrBlockNumTemps = (((blockStart->numArgs)) + ((blockStart->numCopied))) + ((blockStart->numInitialNils)); - initSimStackForFramefulMethod((blockStart->startpc)); - if (((blockStart->numInitialNils)) > 0) { - if (((blockStart->numInitialNils)) > 1) { - /* begin genMoveNilR: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, TempReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, TempReg); - } - for (ign = 1; ign <= ((blockStart->numInitialNils)); ign += 1) { - /* begin PushR: */ - genoperand(PushR, TempReg); - } - } - else { - /* begin genPushConstant: */ - constant1 = nilObject(); - if (shouldAnnotateObjectReference(constant1)) { - annotateobjRef(checkLiteralforInstruction(constant1, genoperand(PushCw, constant1)), constant1); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperand(PushCq, constant1); - } - } - } -} - - -/* Make sure ReceiverResultReg holds the receiver, loaded from the closure, - which is what is initially in ReceiverResultReg. We must annotate the - first instruction in vanilla blocks so that - findMethodForStartBcpc:inHomeMethod: can function. We need two annotations - because the first is a fiducial. */ -/* Make sure ReceiverResultReg holds the receiver, loaded from - the closure, which is what is initially in ReceiverResultReg */ - - /* StackToRegisterMappingCogit>>#compileBlockFramelessEntry: */ -static void NoDbgRegParms -compileBlockFramelessEntry(BlockStart *blockStart) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - - methodOrBlockNumTemps = (((blockStart->numArgs)) + ((blockStart->numCopied))) + ((blockStart->numInitialNils)); - initSimStackForFramelessBlock((blockStart->startpc)); - if (!(((blockStart->entryLabel)) == null)) { - /* begin annotateBytecode: */ - abstractInstruction = (blockStart->entryLabel); - (abstractInstruction->annotation = HasBytecodePC); - /* begin annotateBytecode: */ - abstractInstruction1 = (blockStart->entryLabel); - (abstractInstruction1->annotation = HasBytecodePC); - } - if ((blockStart->hasInstVarRef)) { - - /* Use ReceiverResultReg for Context to agree with store check trampoline */ - genLoadSlotsourceRegdestReg(ClosureOuterContextIndex, ReceiverResultReg, ReceiverResultReg); - genLoadSlotsourceRegdestReg(ReceiverIndex, ReceiverResultReg, Arg0Reg); - genEnsureOopInRegNotForwardedscratchRegupdatingSlotin(Arg0Reg, TempReg, ReceiverIndex, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ReceiverResultReg); - } - else { - genLoadSlotsourceRegdestReg(ClosureOuterContextIndex, ReceiverResultReg, TempReg); - genLoadSlotsourceRegdestReg(ReceiverIndex, TempReg, ReceiverResultReg); - } -} - - /* StackToRegisterMappingCogit>>#compileCogFullBlockMethod: */ -static CogMethod * NoDbgRegParms -compileCogFullBlockMethod(sqInt numCopied) -{ - sqInt allocBytes; - sqInt fixupBytes; - sqInt numBlocks; - sqInt numBytecodes; - sqInt numberOfAbstractOpcodes; - sqInt numCleanBlocks; - sqInt opcodeBytes; - sqInt result; - - methodOrBlockNumTemps = tempCountOf(methodObj); - setHasMovableLiteral(0); - setHasYoungReferent(isYoungObject(methodObj)); - methodOrBlockNumArgs = argumentCountOf(methodObj); - inBlock = InFullBlock; - maxLitIndex = -1; - assert((primitiveIndexOf(methodObj)) == 0); - - /* initial estimate. Actual endPC is determined in scanMethod. */ - initialPC = startPCOfMethod(methodObj); - endPC = numBytesOf(methodObj); - numBytecodes = (endPC - initialPC) + 1; - primitiveIndex = 0; - /* begin allocateOpcodes:bytecodes:ifFail: */ - numberOfAbstractOpcodes = (numBytecodes + 10) * 10 /* estimateOfAbstractOpcodesPerBytecodes */; - numAbstractOpcodes = numberOfAbstractOpcodes; - opcodeBytes = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupBytes = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - - /* Document the fact that the MaxStackAllocSize ensures that the number of abstract - opcodes fits in a 16 bit integer (e.g. CogBytecodeFixup's instructionIndex). */ - allocBytes = opcodeBytes + fixupBytes; - assert((((sizeof(CogAbstractInstruction)) + (sizeof(CogBytecodeFixup))) * 0xC000) > MaxStackAllocSize); - if (allocBytes > MaxStackAllocSize) { - return ((CogMethod *) MethodTooBig); - goto l1; - } - abstractOpcodes = alloca(allocBytes); - bzero(abstractOpcodes, allocBytes); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeBytes)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - l1: /* end allocateOpcodes:bytecodes:ifFail: */; - flag("TODO"); - if (((numBlocks = scanMethod())) < 0) { - return ((CogMethod *) numBlocks); - } - assert(numBlocks == 0); - numCleanBlocks = scanForCleanBlocks(); - assert(numCleanBlocks == 0); - allocateBlockStarts(numBlocks + numCleanBlocks); - blockCount = 0; - if (numCleanBlocks > 0) { - addCleanBlockStarts(); - } - if (!(maybeAllocAndInitIRCs())) { - - /* Inaccurate error code, but it'll do. This will likely never fail. */ - return ((CogMethod *) InsufficientCodeSpace); - } - blockEntryLabel = null; - (methodLabel->dependent = null); - if (((result = compileEntireFullBlockMethod(numCopied))) < 0) { - return ((CogMethod *) result); - } - return generateCogFullBlock(); -} - - /* StackToRegisterMappingCogit>>#compileCogMethod: */ -static CogMethod * NoDbgRegParms -compileCogMethod(sqInt selector) -{ - sqInt allocBytes; - int extra; - sqInt fixupBytes; - sqInt numBlocks; - sqInt numBytecodes; - sqInt numberOfAbstractOpcodes; - sqInt numCleanBlocks; - sqInt opcodeBytes; - sqInt result; - - methodOrBlockNumTemps = tempCountOf(methodObj); - setHasMovableLiteral(0); - setHasYoungReferent((isYoungObject(methodObj)) - || (isYoung(selector))); - methodOrBlockNumArgs = argumentCountOf(methodObj); - inBlock = 0; - maxLitIndex = -1; - extra = ((((primitiveIndex = primitiveIndexOf(methodObj))) > 0) - && (!(isQuickPrimitiveIndex(primitiveIndex))) - ? 30 - : 10); - - /* initial estimate. Actual endPC is determined in scanMethod. */ - initialPC = startPCOfMethod(methodObj); - endPC = (isQuickPrimitiveIndex(primitiveIndex) - ? initialPC - 1 - : numBytesOf(methodObj)); - numBytecodes = (endPC - initialPC) + 1; - /* begin allocateOpcodes:bytecodes:ifFail: */ - numberOfAbstractOpcodes = (numBytecodes + extra) * 10 /* estimateOfAbstractOpcodesPerBytecodes */; - numAbstractOpcodes = numberOfAbstractOpcodes; - opcodeBytes = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupBytes = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - - /* Document the fact that the MaxStackAllocSize ensures that the number of abstract - opcodes fits in a 16 bit integer (e.g. CogBytecodeFixup's instructionIndex). */ - allocBytes = opcodeBytes + fixupBytes; - assert((((sizeof(CogAbstractInstruction)) + (sizeof(CogBytecodeFixup))) * 0xC000) > MaxStackAllocSize); - if (allocBytes > MaxStackAllocSize) { - return ((CogMethod *) MethodTooBig); - goto l1; - } - abstractOpcodes = alloca(allocBytes); - bzero(abstractOpcodes, allocBytes); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeBytes)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - l1: /* end allocateOpcodes:bytecodes:ifFail: */; - if (((numBlocks = scanMethod())) < 0) { - return ((CogMethod *) numBlocks); - } - numCleanBlocks = scanForCleanBlocks(); - if (methodFoundInvalidPostScan()) { - return ((CogMethod *) ShouldNotJIT); - } - allocateBlockStarts(numBlocks + numCleanBlocks); - blockCount = 0; - if (numCleanBlocks > 0) { - addCleanBlockStarts(); - } - if (!(maybeAllocAndInitIRCs())) { - - /* Inaccurate error code, but it'll do. This will likely never fail. */ - return ((CogMethod *) InsufficientCodeSpace); - } - blockEntryLabel = null; - (methodLabel->dependent = null); - if (((result = compileEntireMethod())) < 0) { - return ((CogMethod *) result); - } - return generateCogMethod(selector); -} - - -/* Compile the abstract instructions for the entire method, including blocks. */ -/* Compile the abstract instructions for the entire method, including blocks. */ - - /* StackToRegisterMappingCogit>>#compileEntireMethod */ -static sqInt -compileEntireMethod(void) -{ - sqInt result; - - regArgsHaveBeenPushed = 0; - /* begin preenMethodLabel */ - (((((AbstractInstruction *) methodLabel))->operands))[1] = 0; - compileAbort(); - compileEntry(); - if (((result = compilePrimitive())) < 0) { - return result; - } - compileFrameBuild(); - if (((result = compileMethodBody())) < 0) { - return result; - } - if (blockCount == 0) { - return 0; - } - if (((result = compileBlockBodies())) < 0) { - return result; - } - return compileBlockDispatch(); -} - - -/* Build a frame for a CogMethod activation. See CoInterpreter - class>>initializeFrameIndices. receiver (in ReceiverResultReg) - arg0 - ... - argN - caller's saved ip/this stackPage (for a base frame) - fp-> saved fp - method - context (uninitialized?) - receiver - first temp - ... - sp-> Nth temp - If there is a primitive and an error code the Nth temp is the error code. - Ensure SendNumArgsReg is set early on (incidentally to nilObj) because - it is the flag determining whether context switch is allowed on - stack-overflow. */ -/* Build a frame for a CogMethod activation. See CoInterpreter - class>>initializeFrameIndices. Override to push the register receiver and - register arguments, if any. */ - - /* StackToRegisterMappingCogit>>#compileFrameBuild */ -static void -compileFrameBuild(void) -{ - AbstractInstruction *anInstruction; - sqInt constant; - sqInt i; - sqInt iLimiT; - - -# if IMMUTABILITY - if (useTwoPaths) { - compileTwoPathFrameBuild(); - return; - } -# endif - if (!needsFrame) { - if (useTwoPaths) { - compileTwoPathFramelessInit(); - } - initSimStackForFramelessMethod(initialPC); - return; - } - assert(!(useTwoPaths)); - genPushRegisterArgs(); - if (!needsFrame) { - return; - } - /* begin PushR: */ - genoperand(PushR, LinkReg); - /* begin PushR: */ - genoperand(PushR, FPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SPReg, FPReg); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperand(PushCw, ((sqInt)methodLabel))))); - /* begin genMoveNilR: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, SendNumArgsReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, SendNumArgsReg); - } - /* begin PushR: */ - genoperand(PushR, SendNumArgsReg); - /* begin PushR: */ - genoperand(PushR, ReceiverResultReg); - for (i = (methodOrBlockNumArgs + 1), iLimiT = (temporaryCountOfMethodHeader(methodHeader)); i <= iLimiT; i += 1) { - /* begin PushR: */ - genoperand(PushR, SendNumArgsReg); - } - if (((primitiveIndexOfMethodheader(methodObj, methodHeader)) > 0) - && ((longStoreBytecodeForHeader(methodHeader)) == (fetchByteofObject((startPCOfMethod(methodObj)) + (sizeOfCallPrimitiveBytecode(methodHeader)), methodObj)))) { - compileGetErrorCode(); - } - stackCheckLabel = compileStackOverflowCheck(canContextSwitchIfActivatingheader(methodObj, methodHeader)); - initSimStackForFramefulMethod(initialPC); -} - - -/* Make sure ReceiverResultReg holds the receiver, loaded from the closure, - which is what is initially in ReceiverResultReg. */ -/* Make sure ReceiverResultReg holds the receiver, loaded from - the closure, which is what is initially in ReceiverResultReg */ - - /* StackToRegisterMappingCogit>>#compileFullBlockFramelessEntry: */ -static void NoDbgRegParms -compileFullBlockFramelessEntry(sqInt numCopied) -{ - initSimStackForFramelessBlock(initialPC); - flag("TODO"); - genLoadSlotsourceRegdestReg(FullClosureReceiverIndex, ReceiverResultReg, Arg0Reg); - genEnsureOopInRegNotForwardedscratchRegupdatingSlotin(Arg0Reg, TempReg, FullClosureReceiverIndex, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ReceiverResultReg); -} - - -/* Build a frame for a block activation. See CoInterpreter - class>>initializeFrameIndices. closure (in ReceiverResultReg) - arg0 - ... - argN - caller's saved ip/this stackPage (for a base frame) - fp-> saved fp - method - context (uninitialized?) - receiver - first temp - ... - sp-> Nth temp - Avoid use of SendNumArgsReg which is the flag determining whether - context switch is allowed on stack-overflow. */ - - /* StackToRegisterMappingCogit>>#compileFullBlockMethodFrameBuild: */ -static void NoDbgRegParms -compileFullBlockMethodFrameBuild(sqInt numCopied) -{ - AbstractInstruction *anInstruction; - sqInt constant; - sqInt i; - sqInt iLimiT; - - if (useTwoPaths) { - - /* method with only inst var store, we compile only slow path for now */ - useTwoPaths = 0; -# if IMMUTABILITY - needsFrame = 1; -# endif - } - if (!needsFrame) { - - /* it is OK for numCopied to be non-zero provided that the block does not actually use the copied values. - There are some blocks like this, e.g. that simply reference copied values to mark them as used for Slang. - See e.g. CroquetPlugin>>#primitiveGatherEntropy which contains the block [bufPtr. bufSize. false], - which the bytecode compiler optimizes to [false]. */ - compileFullBlockFramelessEntry(numCopied); - initSimStackForFramelessBlock(initialPC); - return; - } - if (!needsFrame) { - return; - } - /* begin PushR: */ - genoperand(PushR, LinkReg); - /* begin PushR: */ - genoperand(PushR, FPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SPReg, FPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, ClassReg); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperand(PushCw, ((sqInt)methodLabel))))); - /* begin setLabelOffset: */ - (((((AbstractInstruction *) methodLabel))->operands))[1] = MFMethodFlagIsBlockFlag; - /* begin genMoveNilR: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, SendNumArgsReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, SendNumArgsReg); - } - /* begin PushR: */ - genoperand(PushR, SendNumArgsReg); - flag("TODO"); - genLoadSlotsourceRegdestReg(FullClosureReceiverIndex, ClassReg, Arg0Reg); - genEnsureOopInRegNotForwardedscratchRegupdatingSlotin(Arg0Reg, TempReg, FullClosureReceiverIndex, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ReceiverResultReg); - /* begin PushR: */ - genoperand(PushR, ReceiverResultReg); - for (i = 0; i < numCopied; i += 1) { - genLoadSlotsourceRegdestReg(i + FullClosureFirstCopiedValueIndex, ClassReg, TempReg); - /* begin PushR: */ - genoperand(PushR, TempReg); - } - for (i = ((methodOrBlockNumArgs + numCopied) + 1), iLimiT = (temporaryCountOfMethodHeader(methodHeader)); i <= iLimiT; i += 1) { - /* begin PushR: */ - genoperand(PushR, SendNumArgsReg); - } - stackCheckLabel = compileStackOverflowCheck(1); - initSimStackForFramefulMethod(initialPC); -} - - -/* Build a frame for a CogMethod activation. See CoInterpreter - class>>initializeFrameIndices. receiver (in ReceiverResultReg) - arg0 - ... - argN - caller's saved ip/this stackPage (for a base frame) - fp-> saved fp - method - context (uninitialized?) - receiver - first temp - ... - sp-> Nth temp - If there is a primitive and an error code the Nth temp is the error code. - Ensure SendNumArgsReg is set early on (incidentally to nilObj) because - it is the flag determining whether context switch is allowed on - stack-overflow. */ -/* We are in a method where the frame is needed *only* for instance variable - store, typically a setter method. - This case has 20% overhead with Immutability compared to setter without - immutability because of the stack - frame creation. We compile two path, one where the object is immutable, - one where it isn't. At the beginning - of the frame build, we take one path or the other depending on the - receiver mutability. - - Note: this specific case happens only where there are only instance - variabel stores. We could do something - similar for literal variable stores, but we don't as it's too uncommon. - */ - - /* StackToRegisterMappingCogit>>#compileTwoPathFrameBuild */ -#if IMMUTABILITY -static void -compileTwoPathFrameBuild(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt constant; - sqInt i; - sqInt iLimiT; - AbstractInstruction * jumpImmutable; - AbstractInstruction * jumpOld; - - assert(useTwoPaths); - assert(blockCount == 0); - jumpImmutable = genJumpImmutablescratchReg(ReceiverResultReg, TempReg); - - /* first path. The receiver is mutable */ - - /* N.B. FLAGS := destReg - scratchReg */ - /* begin checkQuickConstant:forInstruction: */ - storeCheckBoundary(); - anInstruction = genoperandoperand(CmpCqR, storeCheckBoundary(), ReceiverResultReg); - /* begin JumpAboveOrEqual: */ - jumpOld = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - assert(!needsFrame); - initSimStackForFramelessMethod(initialPC); - /* begin compileMethodBody */ - if (endPC < initialPC) { - goto l3; - } - compileAbstractInstructionsFromthrough(initialPC + (deltaToSkipPrimAndErrorStoreInheader(methodObj, methodHeader)), endPC); - l3: /* end compileMethodBody */; - - /* reset because it impacts inst var store compilation */ - useTwoPaths = 0; - needsFrame = 1; - jmpTarget(jumpOld, jmpTarget(jumpImmutable, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - genPushRegisterArgs(); - if (!needsFrame) { - return; - } - /* begin PushR: */ - genoperand(PushR, LinkReg); - /* begin PushR: */ - genoperand(PushR, FPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SPReg, FPReg); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperand(PushCw, ((sqInt)methodLabel))))); - /* begin genMoveNilR: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, SendNumArgsReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, constant, SendNumArgsReg); - } - /* begin PushR: */ - genoperand(PushR, SendNumArgsReg); - /* begin PushR: */ - genoperand(PushR, ReceiverResultReg); - for (i = (methodOrBlockNumArgs + 1), iLimiT = (temporaryCountOfMethodHeader(methodHeader)); i <= iLimiT; i += 1) { - /* begin PushR: */ - genoperand(PushR, SendNumArgsReg); - } - if (((primitiveIndexOfMethodheader(methodObj, methodHeader)) > 0) - && ((longStoreBytecodeForHeader(methodHeader)) == (fetchByteofObject((startPCOfMethod(methodObj)) + (sizeOfCallPrimitiveBytecode(methodHeader)), methodObj)))) { - compileGetErrorCode(); - } - stackCheckLabel = compileStackOverflowCheck(canContextSwitchIfActivatingheader(methodObj, methodHeader)); - initSimStackForFramefulMethod(initialPC); -} -#endif /* IMMUTABILITY */ - - -/* We are in a frameless method with at least two inst var stores. We compile - two paths, - one where the object is in new space, and one where it isn't. At the - beginning - of the method, we take one path or the other depending on the receiver - being in newSpace. - */ - - /* StackToRegisterMappingCogit>>#compileTwoPathFramelessInit */ -static void -compileTwoPathFramelessInit(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction * jumpOld; - - assert(!(IMMUTABILITY)); - assert(!(needsFrame)); - assert(useTwoPaths); - - /* first path. The receiver is young */ - - /* N.B. FLAGS := destReg - scratchReg */ - /* begin checkQuickConstant:forInstruction: */ - storeCheckBoundary(); - anInstruction = genoperandoperand(CmpCqR, storeCheckBoundary(), ReceiverResultReg); - /* begin JumpAboveOrEqual: */ - jumpOld = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - initSimStackForFramelessMethod(initialPC); - /* begin compileMethodBody */ - if (endPC < initialPC) { - goto l1; - } - compileAbstractInstructionsFromthrough(initialPC + (deltaToSkipPrimAndErrorStoreInheader(methodObj, methodHeader)), endPC); - l1: /* end compileMethodBody */; - - /* reset because it impacts inst var store compilation */ - useTwoPaths = 0; - jmpTarget(jumpOld, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); -} - - /* StackToRegisterMappingCogit>>#cPICMissTrampolineFor: */ -static sqInt NoDbgRegParms -cPICMissTrampolineFor(sqInt numArgs) -{ - return picMissTrampolines[((numArgs < (3)) ? numArgs : (3))]; -} - - -/* Replaces the Blue Book double-extended send [132], in which the first byte - was wasted on 8 bits of argument count. - Here we use 3 bits for the operation sub-type (opType), and the remaining - 5 bits for argument count where needed. - The last byte give access to 256 instVars or literals. - See also secondExtendedSendBytecode - */ - - /* StackToRegisterMappingCogit>>#doubleExtendedDoAnythingBytecode */ -static sqInt -doubleExtendedDoAnythingBytecode(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *abstractInstruction2; - sqInt opType; - - opType = ((usqInt)(byte1)) >> 5; - if (opType == 0) { - return genSendnumArgs(byte2, byte1 & 0x1F); - } - if (opType == 1) { - return genSendSupernumArgs(byte2, byte1 & 0x1F); - } - switch (opType) { - case 2: - if (isReadMediatedContextInstVarIndex(byte2)) { - genPushMaybeContextReceiverVariable(byte2); - } - else { - genPushReceiverVariable(byte2); - /* begin annotateInstructionForBytecode */ - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (abstractInstruction->annotation = HasBytecodePC); - return 0; - } - break; - case 3: - genPushLiteralIndex(byte2); - /* begin annotateInstructionForBytecode */ - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction1 = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction1 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (abstractInstruction1->annotation = HasBytecodePC); - return 0; - - case 4: - genPushLiteralVariable(byte2); - break; - case 7: - genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(0, byte2, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); -# if IMMUTABILITY - - /* genStorePop:LiteralVariable: annotates; don't annotate twice */ - return 0; -# endif - break; - default: - - /* 5 & 6 */ - if (isWriteMediatedContextInstVarIndex(byte2)) { - genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(opType == 6, byte2, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } - else { - genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(opType == 6, byte2, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } -# if IMMUTABILITY - - /* genStorePop:...ReceiverVariable: annotate; don't annotate twice */ - return 0; -# endif -; - } - assert(needsFrame); - assert(!(prevInstIsPCAnnotated())); - /* begin annotateBytecode: */ - abstractInstruction2 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction2->annotation = HasBytecodePC); - return 0; -} - - /* StackToRegisterMappingCogit>>#duplicateTopBytecode */ -static sqInt -duplicateTopBytecode(void) -{ - SimStackEntry desc; - - /* begin ssTopDescriptor */ - desc = simStack[simStackPtr]; - return ssPushDesc(desc); -} - - /* StackToRegisterMappingCogit>>#endHighLevelCallWithCleanup */ -static void -endHighLevelCallWithCleanup(void) -{ - AbstractInstruction *anInstruction; - - if (currentCallCleanUpSize > 0) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, currentCallCleanUpSize, SPReg); - } - callSwitchToSmalltalkStack(); -} - - /* StackToRegisterMappingCogit>>#endHighLevelCallWithoutCleanup */ -static void -endHighLevelCallWithoutCleanup(void) -{ - callSwitchToSmalltalkStack(); -} - - -/* Make sure there's a flagged fixup at the target pc in fixups. - Initially a fixup's target is just a flag. Later on it is replaced with a - proper instruction. */ - - /* StackToRegisterMappingCogit>>#ensureFixupAt: */ -static BytecodeFixup * NoDbgRegParms -ensureFixupAt(sqInt targetPC) -{ - BytecodeFixup *fixup; - - /* begin fixupAt: */ - fixup = fixupAtIndex(targetPC - initialPC); - traceFixupmerge(fixup, 1); - if ((((usqInt)((fixup->targetInstruction)))) <= NeedsNonMergeFixupFlag) { - - /* convert a non-merge into a merge */ - /* begin becomeMergeFixup */ - (fixup->targetInstruction) = ((AbstractInstruction *) NeedsMergeFixupFlag); - (fixup->simStackPtr = simStackPtr); - (fixup->simNativeStackPtr = simNativeStackPtr); - (fixup->simNativeStackSize = simNativeStackSize); - } - else { - if ((fixup->isTargetOfBackwardBranch)) { - - /* this is the target of a backward branch and - so doesn't have a simStackPtr assigned yet. */ - (fixup->simStackPtr = simStackPtr); - (fixup->simNativeStackPtr = simNativeStackPtr); - (fixup->simNativeStackSize = simNativeStackSize); - } - else { - assert(((fixup->simStackPtr)) == simStackPtr); - assert(((fixup->simNativeStackPtr)) == simNativeStackPtr); - assert(((fixup->simNativeStackSize)) == simNativeStackSize); - } - } - /* begin recordBcpc: */ - return fixup; -} - - -/* Make sure there's a flagged fixup at the target pc in fixups. - Initially a fixup's target is just a flag. Later on it is replaced with a - proper instruction. */ - - /* StackToRegisterMappingCogit>>#ensureNonMergeFixupAt: */ -static BytecodeFixup * NoDbgRegParms -ensureNonMergeFixupAt(sqInt targetPC) -{ - BytecodeFixup *fixup; - - /* begin fixupAt: */ - fixup = fixupAtIndex(targetPC - initialPC); - traceFixupmerge(fixup, 1); - if (((fixup->targetInstruction)) == 0) { - /* begin becomeNonMergeFixup */ - (fixup->targetInstruction) = ((AbstractInstruction *) NeedsNonMergeFixupFlag); - } - /* begin recordBcpc: */ - return fixup; -} - - /* StackToRegisterMappingCogit>>#ensureReceiverResultRegContainsSelf */ -static void -ensureReceiverResultRegContainsSelf(void) -{ - if (needsFrame) { - if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); - /* begin putSelfInReceiverResultReg */ - storeToReg(simSelf(), ReceiverResultReg); - ((simSelf())->liveRegister = ReceiverResultReg); - } - } - else { - assert(((((simSelf())->type)) == SSRegister) - && (((((simSelf())->registerr)) == ReceiverResultReg) - && (receiverIsInReceiverResultReg()))); - } -} - - /* StackToRegisterMappingCogit>>#evaluate:at: */ -static void NoDbgRegParms -evaluateat(BytecodeDescriptor *descriptor, sqInt pc) -{ - byte0 = fetchByteofObject(pc, methodObj); - assert(descriptor == (generatorAt(bytecodeSetOffset + byte0))); - loadSubsequentBytesForDescriptorat(descriptor, pc); - ((descriptor->generator))(); -} - - -/* Attempt to follow a branch to a pc. Handle branches to unconditional jumps - and branches to push: aBoolean; conditional branch pairs. If the branch - cannot be - followed answer targetBytecodePC. It is not possible to follow jumps to - conditional branches because the stack changes depth. That following is - left to the genJumpIf:to: - clients. */ - - /* StackToRegisterMappingCogit>>#eventualTargetOf: */ -static sqInt NoDbgRegParms -eventualTargetOf(sqInt targetBytecodePC) -{ - sqInt cond; - sqInt currentTarget; - BytecodeDescriptor *descriptor; - sqInt nExts; - sqInt nextPC; - sqInt span; - - cond = 0; - nextPC = (currentTarget = targetBytecodePC); - while (1) { - nExts = 0; - while (1) { - /* begin generatorForPC: */ - descriptor = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC, methodObj))); - if ((descriptor->isReturn)) { - return currentTarget; - } - if (!((descriptor->isExtension))) break; - nExts += 1; - nextPC += (descriptor->numBytes); - } - if ((isBranch(descriptor)) - && (!(((descriptor->isBranchTrue)) - || ((descriptor->isBranchFalse))))) { - /* begin spanFor:at:exts:in: */ - span = ((descriptor->spanFunction))(descriptor, nextPC, nExts, methodObj); - if (span < 0) { - - /* Do *not* follow backward branches; these are interrupt points and should not be elided. */ - return currentTarget; - } - nextPC = (nextPC + ((descriptor->numBytes))) + span; - } - else { - if (((descriptor->generator)) == genPushConstantTrueBytecode) { - cond = 1; - } - else { - if (((descriptor->generator)) == genPushConstantFalseBytecode) { - cond = 0; - } - else { - return currentTarget; - } - } - if (((fixupAt(nextPC))->isTargetOfBackwardBranch)) { - return currentTarget; - } - nextPC = eventualTargetOf(nextPC + ((descriptor->numBytes))); - nExts = 0; - while (1) { - /* begin generatorForPC: */ - descriptor = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC, methodObj))); - if ((descriptor->isReturn)) { - return currentTarget; - } - if (!((descriptor->isExtension))) break; - nExts += 1; - nextPC += (descriptor->numBytes); - } - if (!(isBranch(descriptor))) { - return currentTarget; - } - if ((isBranch(descriptor)) - && (!(((descriptor->isBranchTrue)) - || ((descriptor->isBranchFalse))))) { - return currentTarget; - } - nextPC = (cond == ((descriptor->isBranchTrue)) - ? (nextPC + ((descriptor->numBytes))) + (((descriptor->spanFunction))(descriptor, nextPC, nExts, methodObj)) - : nextPC + ((descriptor->numBytes))); - } - currentTarget = nextPC; - } - return 0; -} - - -/* Spill the closest register on stack not conflicting with regMask. - Assertion Failure if regMask has already all the registers */ - - /* StackToRegisterMappingCogit>>#freeAnyFloatRegNotConflictingWith: */ -static sqInt NoDbgRegParms -freeAnyFloatRegNotConflictingWith(sqInt regMask) -{ - CogSimStackEntry *desc; - sqInt index; - sqInt reg; - - assert(needsFrame); - reg = NoReg; - index = ((simSpillBase < 0) ? 0 : simSpillBase); - index = ((simNativeSpillBase < 0) ? 0 : simNativeSpillBase); - while ((reg == NoReg) - && (index < simNativeStackPtr)) { - desc = simNativeStackAt(index); - if ((((desc->type)) == SSRegisterSingleFloat) - || (((desc->type)) == SSRegisterDoubleFloat)) { - if (!(((regMask & (1U << ((desc->registerr)))) != 0))) { - reg = (desc->registerr); - } - } - index += 1; - } - assert(!((reg == NoReg))); - ssAllocateRequiredFloatReg(reg); - return reg; -} - - -/* Spill the closest register on stack not conflicting with regMask. - Assertion Failure if regMask has already all the registers */ - - /* StackToRegisterMappingCogit>>#freeAnyRegNotConflictingWith: */ -static sqInt NoDbgRegParms -freeAnyRegNotConflictingWith(sqInt regMask) -{ - CogSimStackEntry *desc; - sqInt index; - sqInt reg; - - assert(needsFrame); - reg = NoReg; - index = ((simSpillBase < 0) ? 0 : simSpillBase); - while ((reg == NoReg) - && (index < simStackPtr)) { - desc = simStackAt(index); - if (((desc->type)) == SSRegister) { - if (!(((regMask & (1U << ((desc->registerr)))) != 0))) { - reg = (desc->registerr); - } - } - index += 1; - } - assert(!((reg == NoReg))); - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << reg, simStackPtr, simNativeStackPtr); - return reg; -} - - -/* Return from block, assuming result already loaded into ReceiverResultReg. */ -/* Return from block, assuming result already loaded into ReceiverResultReg. */ - - /* StackToRegisterMappingCogit>>#genBlockReturn */ -static sqInt -genBlockReturn(void) -{ - if (needsFrame) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, FPReg, SPReg); - /* begin PopR: */ - genoperand(PopR, FPReg); - /* begin PopR: */ - genoperand(PopR, LinkReg); - } - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - - /* can't fall through */ - deadCode = 1; - return 0; -} - - -/* Generate special versions of the ceCallCogCodePopReceiverAndClassRegs - enilopmart that also pop register args from the stack to undo the pushing - of register args in the abort/miss trampolines. */ - - /* StackToRegisterMappingCogit>>#genCallPICEnilopmartNumArgs: */ -static void (*genCallPICEnilopmartNumArgs(sqInt numArgs))(void) - -{ - AbstractInstruction *anInstruction; - sqInt endAddress; - usqInt enilopmart; - sqInt quickConstant; - sqInt reg; - sqInt size; - - zeroOpcodeIndex(); - /* begin MoveCq:R: */ - quickConstant = varBaseAddress(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - genLoadStackPointers(backEnd); - /* begin PopR: */ - genoperand(PopR, ClassReg); - /* begin PopR: */ - genoperand(PopR, TempReg); - /* begin PopR: */ - reg = LinkReg; - genoperand(PopR, reg); - if (numArgs > 0) { - if (numArgs > 1) { - /* begin PopR: */ - genoperand(PopR, Arg1Reg); - assert((numRegArgs()) == 2); - } - /* begin PopR: */ - genoperand(PopR, Arg0Reg); - } - /* begin PopR: */ - genoperand(PopR, ReceiverResultReg); - /* begin JumpR: */ - genoperand(JumpR, TempReg); - computeMaximumSizes(); - size = generateInstructionsAt(methodZoneBase); - endAddress = outputInstructionsAt(methodZoneBase); - assert((methodZoneBase + size) == endAddress); - enilopmart = methodZoneBase; - methodZoneBase = alignUptoRoutineBoundary(endAddress); - stopsFromto(backEnd, endAddress, methodZoneBase - 1); - recordGeneratedRunTimeaddress(trampolineNamenumRegArgs("ceCallPIC", numArgs), enilopmart); - return ((void (*)(void)) enilopmart); -} - - -/* SistaV1: ** 248 (2) 11111000 iiiiiiii mssjjjjj Call Primitive #iiiiiiii - + (jjjjj * 256) - m=1 means inlined primitive, no hard return after execution. - ss defines the unsafe operation set used to encode the operations. - (ss = 0 means sista unsafe operations, ss = 01 means lowcode operations, - other numbers are as yet used). - See SistaCogit genCallPrimitiveBytecode, EncoderForSistaV1's class comment - and StackInterpreter>>#callPrimitiveBytecode for more information. */ - - /* StackToRegisterMappingCogit>>#genCallPrimitiveBytecode */ -static sqInt -genCallPrimitiveBytecode(void) -{ - sqInt prim; - sqInt primSet; - - if (byte2 < 128) { - return (bytecodePC == initialPC - ? 0 - : EncounteredUnknownBytecode); - } - prim = (((sqInt)((usqInt)((byte2 - 128)) << 8))) + byte1; - primSet = (((usqInt)(prim)) >> 13) & 3; - prim = prim & 0x1FFF; - if (primSet == 1) { - if (prim < 1000) { - return genLowcodeNullaryInlinePrimitive(prim); - } - if (prim < 2000) { - return genLowcodeUnaryInlinePrimitive(prim - 1000); - } - if (prim < 3000) { - return genLowcodeBinaryInlinePrimitive(prim - 2000); - } - if (prim < 4000) { - return genLowcodeTrinaryInlinePrimitive(prim - 3000); - } - } - return EncounteredUnknownBytecode; -} - - -/* Override to push the register receiver and register arguments, if any. */ - - /* StackToRegisterMappingCogit>>#genExternalizePointersForPrimitiveCall */ -static sqInt -genExternalizePointersForPrimitiveCall(void) -{ - AbstractInstruction *anInstruction; - - genPushRegisterArgs(); - /* begin checkLiteral:forInstruction: */ - instructionPointerAddress(); - anInstruction = genoperandoperand(MoveRAw, LinkReg, instructionPointerAddress()); - return genSaveStackPointers(backEnd); -} - - -/* Override to push the register receiver and register arguments, if any. */ - - /* StackToRegisterMappingCogit>>#genExternalizeStackPointerForFastPrimitiveCall */ -static AbstractInstruction * -genExternalizeStackPointerForFastPrimitiveCall(void) -{ - AbstractInstruction *anInstruction; - - genPushRegisterArgs(); - return (/* begin checkLiteral:forInstruction: */ - stackPointerAddress(), - (anInstruction = genoperandoperand(MoveRAw, SPReg, stackPointerAddress())), - anInstruction); -} - - -/* Block compilation. At this point in the method create the block. Note its - start and defer generating code for it until after the method and any - other preceding - blocks. The block's actual code will be compiled later. */ -/* 253 11111101 eei i i kkk jjjjjjjj Push Closure Num Copied iii (+ Ext A - // 16 * 8) Num Args kkk (+ Ext A \\ 16 * 8) BlockSize jjjjjjjj (+ Ext B * - 256). ee = num extensions - */ - - /* StackToRegisterMappingCogit>>#genExtPushClosureBytecode */ -static sqInt -genExtPushClosureBytecode(void) -{ - sqInt i; - sqInt numArgs; - sqInt numCopied; - sqInt reg; - sqInt startpc; - - assert(needsFrame); - startpc = bytecodePC + (((generatorAt(byte0))->numBytes)); - addBlockStartAtnumArgsnumCopiedspan(startpc, (numArgs = (byte1 & 7) + ((extA % 16) * 8)), (numCopied = ((((usqInt)(byte1)) >> 3) & 7) + ((extA / 16) * 8)), byte2 + (((sqInt)((usqInt)(extB) << 8)))); - extA = (numExtB = (extB = 0)); - /* begin genInlineClosure:numArgs:numCopied: */ - assert(getActiveContextAllocatesInMachineCode()); - voidReceiverResultRegContainsSelf(); - /* begin ssAllocateCallReg:and:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg) | (1U << SendNumArgsReg)) | (1U << ClassReg)), simStackPtr, simNativeStackPtr); - genNoPopCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(startpc + 1, numArgs, numCopied, methodOrBlockNumArgs, methodNeedsLargeContext(methodObj), inBlock); - for (i = 1; i <= numCopied; i += 1) { - reg = ssStorePoptoPreferredReg(1, TempReg); - genStoreSourceRegslotIndexintoNewObjectInDestReg(reg, (ClosureFirstCopiedValueIndex + numCopied) - i, ReceiverResultReg); - } - ssPushRegister(ReceiverResultReg); - return 0; -} - - -/* Full Block creation compilation. The block's actual code will be compiled - separatedly. - */ -/* * 255 11111111 xxxxxxxx siyyyyyy push Closure Compiled block literal - index xxxxxxxx (+ Extend A * 256) numCopied yyyyyy receiverOnStack: s = 1 - ignoreOuterContext: i = 1 - */ - - /* StackToRegisterMappingCogit>>#genExtPushFullClosureBytecode */ -static sqInt -genExtPushFullClosureBytecode(void) -{ - sqInt compiledBlock; - sqInt i; - int ignoreContext; - sqInt numCopied; - int receiverIsOnStack; - sqInt reg; - - assert(needsFrame); - compiledBlock = getLiteral(byte1 + (((sqInt)((usqInt)(extA) << 8)))); - extA = 0; - numCopied = byte2 & (0x3F); - receiverIsOnStack = ((byte2 & (128)) != 0); - ignoreContext = ((byte2 & (64)) != 0); - voidReceiverResultRegContainsSelf(); - /* begin ssAllocateCallReg:and:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg) | (1U << SendNumArgsReg)) | (1U << ClassReg)), simStackPtr, simNativeStackPtr); - genCreateFullClosurenumArgsnumCopiedignoreContextcontextNumArgslargeinBlock(compiledBlock, argumentCountOf(compiledBlock), numCopied, ignoreContext, methodOrBlockNumArgs, methodNeedsLargeContext(methodObj), inBlock); - for (i = 1; i <= numCopied; i += 1) { - reg = ssStorePoptoPreferredReg(1, TempReg); - genStoreSourceRegslotIndexintoNewObjectInDestReg(reg, (FullClosureFirstCopiedValueIndex + numCopied) - i, ReceiverResultReg); - } - if (receiverIsOnStack) { - reg = ssStorePoptoPreferredReg(1, TempReg); - } - else { - storeToReg(simSelf(), (reg = TempReg)); - } - genStoreSourceRegslotIndexintoNewObjectInDestReg(reg, FullClosureReceiverIndex, ReceiverResultReg); - ssPushRegister(ReceiverResultReg); - return 0; -} - - -/* Enilopmarts transfer control from C into machine code (backwards - trampolines). - */ -/* Enilopmarts transfer control from C into machine code (backwards - trampolines). Override to add version for generic and PIC-specific entry - with reg args. */ - - /* StackToRegisterMappingCogit>>#generateEnilopmarts */ -static void -generateEnilopmarts(void) -{ - -# if Debug - /* begin genEnilopmartFor:forCall:called: */ - realCEEnterCogCodePopReceiverReg = genEnilopmartForandandforCallcalled(ReceiverResultReg, NoReg, NoReg, 0, "realCEEnterCogCodePopReceiverReg"); - ceEnterCogCodePopReceiverReg = enterCogCodePopReceiver; - /* begin genEnilopmartFor:forCall:called: */ - realCECallCogCodePopReceiverReg = genEnilopmartForandandforCallcalled(ReceiverResultReg, NoReg, NoReg, 1, "realCECallCogCodePopReceiverReg"); - ceCallCogCodePopReceiverReg = callCogCodePopReceiver; - /* begin genEnilopmartFor:and:forCall:called: */ - realCECallCogCodePopReceiverAndClassRegs = genEnilopmartForandandforCallcalled(ReceiverResultReg, ClassReg, NoReg, 1, "realCECallCogCodePopReceiverAndClassRegs"); - ceCallCogCodePopReceiverAndClassRegs = callCogCodePopReceiverAndClassRegs; -# else // Debug - /* begin genEnilopmartFor:forCall:called: */ - ceEnterCogCodePopReceiverReg = genEnilopmartForandandforCallcalled(ReceiverResultReg, NoReg, NoReg, 0, "ceEnterCogCodePopReceiverReg"); - /* begin genEnilopmartFor:forCall:called: */ - ceCallCogCodePopReceiverReg = genEnilopmartForandandforCallcalled(ReceiverResultReg, NoReg, NoReg, 1, "ceCallCogCodePopReceiverReg"); - /* begin genEnilopmartFor:and:forCall:called: */ - ceCallCogCodePopReceiverAndClassRegs = genEnilopmartForandandforCallcalled(ReceiverResultReg, ClassReg, NoReg, 1, "ceCallCogCodePopReceiverAndClassRegs"); -# endif // Debug - genPrimReturnEnterCogCodeEnilopmart(0); - cePrimReturnEnterCogCode = methodZoneBase; - outputInstructionsForGeneratedRuntimeAt(cePrimReturnEnterCogCode); - recordGeneratedRunTimeaddress("cePrimReturnEnterCogCode", cePrimReturnEnterCogCode); - genPrimReturnEnterCogCodeEnilopmart(1); - cePrimReturnEnterCogCodeProfiling = methodZoneBase; - outputInstructionsForGeneratedRuntimeAt(cePrimReturnEnterCogCodeProfiling); - recordGeneratedRunTimeaddress("cePrimReturnEnterCogCodeProfiling", cePrimReturnEnterCogCodeProfiling); -# if Debug - /* begin genEnilopmartFor:and:forCall:called: */ - realCECallCogCodePopReceiverArg0Regs = genEnilopmartForandandforCallcalled(ReceiverResultReg, Arg0Reg, NoReg, 1, "realCECallCogCodePopReceiverArg0Regs"); - ceCallCogCodePopReceiverArg0Regs = callCogCodePopReceiverArg0Regs; - realCECallCogCodePopReceiverArg1Arg0Regs = genEnilopmartForandandforCallcalled(ReceiverResultReg, Arg0Reg, Arg1Reg, 1, "realCECallCogCodePopReceiverArg1Arg0Regs"); - ceCallCogCodePopReceiverArg1Arg0Regs = callCogCodePopReceiverArg1Arg0Regs; -# else // Debug - /* begin genEnilopmartFor:and:forCall:called: */ - ceCallCogCodePopReceiverArg0Regs = genEnilopmartForandandforCallcalled(ReceiverResultReg, Arg0Reg, NoReg, 1, "ceCallCogCodePopReceiverArg0Regs"); - ceCallCogCodePopReceiverArg1Arg0Regs = genEnilopmartForandandforCallcalled(ReceiverResultReg, Arg0Reg, Arg1Reg, 1, "ceCallCogCodePopReceiverArg1Arg0Regs"); -# endif // Debug - ceCall0ArgsPIC = genCallPICEnilopmartNumArgs(0); - ceCall1ArgsPIC = genCallPICEnilopmartNumArgs(1); - ceCall2ArgsPIC = genCallPICEnilopmartNumArgs(2); - assert((numRegArgs()) == 2); -} - - -/* Size pc-dependent instructions and assign eventual addresses to all - instructions. Answer the size of the code. - Compute forward branches based on virtual address (abstract code starts at - 0), assuming that any branches branched over are long. - Compute backward branches based on actual address. - Reuse the fixups array to record the pc-dependent instructions that need - to have - their code generation postponed until after the others. - - Override to add handling for null branches (branches to the immediately - following instruction) occasioned by StackToRegisterMapping's following of - jumps. */ - - /* StackToRegisterMappingCogit>>#generateInstructionsAt: */ -static sqInt NoDbgRegParms -generateInstructionsAt(sqInt eventualAbsoluteAddress) -{ - sqInt absoluteAddress; - AbstractInstruction *abstractInstruction; - BytecodeFixup *fixup; - sqInt i; - sqInt j; - sqInt pcDependentIndex; - - absoluteAddress = eventualAbsoluteAddress; - pcDependentIndex = 0; - for (i = 0; i < opcodeIndex; i += 1) { - - /* N.B. if you want to break in resizing, break here, note the instruction index, back up to the - sender, restart, and step into computeMaximumSizes, breaking at this instruction's index. */ - abstractInstruction = abstractInstructionAt(i); - maybeBreakGeneratingFromto(absoluteAddress, absoluteAddress + ((abstractInstruction->maxSize))); - if (isPCDependent(abstractInstruction)) { - sizePCDependentInstructionAt(abstractInstruction, absoluteAddress); - if ((isJump(abstractInstruction)) - && ((((i + 1) < opcodeIndex) - && ((((AbstractInstruction *) (((abstractInstruction->operands))[0]))) == (abstractInstructionAt(i + 1)))) - || (((i + 2) < opcodeIndex) - && (((((AbstractInstruction *) (((abstractInstruction->operands))[0]))) == (abstractInstructionAt(i + 2))) - && ((((abstractInstructionAt(i + 1))->opcode)) == Nop))))) { - (abstractInstruction->opcode = Nop); - concretizeAt(abstractInstruction, absoluteAddress); - } - else { - fixup = fixupAtIndex(pcDependentIndex); - pcDependentIndex += 1; - (fixup->instructionIndex = i); - } - absoluteAddress += (abstractInstruction->machineCodeSize); - } - else { - - /* N.B. if you want to break in resizing, break here, note the instruction index, back up to the - sender, restart, and step into computeMaximumSizes, breaking at this instruction's index. */ - absoluteAddress = concretizeAt(abstractInstruction, absoluteAddress); - assert(((abstractInstruction->machineCodeSize)) == ((abstractInstruction->maxSize))); - } - } - for (j = 0; j < pcDependentIndex; j += 1) { - fixup = fixupAtIndex(j); - abstractInstruction = abstractInstructionAt((fixup->instructionIndex)); - maybeBreakGeneratingFromto((abstractInstruction->address), (((abstractInstruction->address)) + ((abstractInstruction->maxSize))) - 1); - concretizeAt(abstractInstruction, (abstractInstruction->address)); - } - return absoluteAddress - eventualAbsoluteAddress; -} - - -/* Generate the run-time entries for the various method and PIC entry misses - and aborts. - Read the class-side method trampolines for documentation on the various - trampolines - */ - - /* StackToRegisterMappingCogit>>#generateMissAbortTrampolines */ -static void -generateMissAbortTrampolines(void) -{ - sqInt numArgs; - sqInt numArgsLimiT; - - for (numArgs = 0, numArgsLimiT = (3); numArgs <= numArgsLimiT; numArgs += 1) { - methodAbortTrampolines[numArgs] = (genMethodAbortTrampolineFor(numArgs)); - } - for (numArgs = 0, numArgsLimiT = (3); numArgs <= numArgsLimiT; numArgs += 1) { - picAbortTrampolines[numArgs] = (genPICAbortTrampolineFor(numArgs)); - } - for (numArgs = 0, numArgsLimiT = (3); numArgs <= numArgsLimiT; numArgs += 1) { - picMissTrampolines[numArgs] = (genPICMissTrampolineFor(numArgs)); - } - /* begin genTrampolineFor:called:arg: */ - ceReapAndResetErrorCodeTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceReapAndResetErrorCodeFor, "ceReapAndResetErrorCodeTrampoline", 1, ClassReg, null, null, null, 0 /* emptyRegisterMask */, 1, NoReg, 0); -} - - -/* Override to generate code to push the register arg(s) for <= numRegArg - arity sends. - */ - - /* StackToRegisterMappingCogit>>#generateSendTrampolines */ -static void -generateSendTrampolines(void) -{ - sqInt numArgs; - - for (numArgs = 0; numArgs < NumSendTrampolines; numArgs += 1) { - ordinarySendTrampolines[numArgs] = (genSendTrampolineFornumArgscalledargargargarg(ceSendsupertonumArgs, numArgs, trampolineNamenumArgs("ceSend", numArgs), ClassReg, trampolineArgConstant(0), ReceiverResultReg, (numArgs <= (NumSendTrampolines - 2) - ? (/* begin trampolineArgConstant: */ - assert(numArgs >= 0), - -2 - numArgs) - : SendNumArgsReg))); - } - for (numArgs = 0; numArgs < NumSendTrampolines; numArgs += 1) { - directedSuperSendTrampolines[numArgs] = (genSendTrampolineFornumArgscalledargargargarg(ceSendabovetonumArgs, numArgs, trampolineNamenumArgs("ceDirectedSuperSend", numArgs), ClassReg, TempReg, ReceiverResultReg, (numArgs <= (NumSendTrampolines - 2) - ? (/* begin trampolineArgConstant: */ - assert(numArgs >= 0), - -2 - numArgs) - : SendNumArgsReg))); - directedSuperBindingSendTrampolines[numArgs] = (genSendTrampolineFornumArgscalledargargargarg(ceSendaboveClassBindingtonumArgs, numArgs, trampolineNamenumArgs("ceDirectedSuperBindingSend", numArgs), ClassReg, TempReg, ReceiverResultReg, (numArgs <= (NumSendTrampolines - 2) - ? (/* begin trampolineArgConstant: */ - assert(numArgs >= 0), - -2 - numArgs) - : SendNumArgsReg))); - } - for (numArgs = 0; numArgs < NumSendTrampolines; numArgs += 1) { - superSendTrampolines[numArgs] = (genSendTrampolineFornumArgscalledargargargarg(ceSendsupertonumArgs, numArgs, trampolineNamenumArgs("ceSuperSend", numArgs), ClassReg, trampolineArgConstant(1), ReceiverResultReg, (numArgs <= (NumSendTrampolines - 2) - ? (/* begin trampolineArgConstant: */ - assert(numArgs >= 0), - -2 - numArgs) - : SendNumArgsReg))); - } - firstSend = ordinarySendTrampolines[0]; - lastSend = superSendTrampolines[NumSendTrampolines - 1]; -} - - -/* Generate trampolines for tracing. In the simulator we can save a lot of - time and avoid noise instructions in the lastNInstructions log by - short-cutting these - trampolines, but we need them in the real vm. */ - - /* StackToRegisterMappingCogit>>#generateTracingTrampolines */ -static void -generateTracingTrampolines(void) -{ - /* begin genTrampolineFor:called:arg:regsToSave: */ - ceTraceLinkedSendTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceTraceLinkedSend, "ceTraceLinkedSendTrampoline", 1, ReceiverResultReg, null, null, null, CallerSavedRegisterMask, 1, NoReg, 0); - /* begin genTrampolineFor:called:regsToSave: */ - ceTraceBlockActivationTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceTraceBlockActivation, "ceTraceBlockActivationTrampoline", 0, null, null, null, null, CallerSavedRegisterMask, 1, NoReg, 0); - /* begin genTrampolineFor:called:arg:arg:regsToSave: */ - ceTraceStoreTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceTraceStoreOfinto, "ceTraceStoreTrampoline", 2, TempReg, ReceiverResultReg, null, null, CallerSavedRegisterMask, 1, NoReg, 0); -} - - /* StackToRegisterMappingCogit>>#genForwardersInlinedIdenticalOrNotIf: */ -static sqInt NoDbgRegParms -genForwardersInlinedIdenticalOrNotIf(sqInt orNot) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - sqInt argConstant; - sqInt argNeedsReg; - sqInt argReg; - sqInt argReg1; - BytecodeDescriptor *branchDescriptor; - BytecodeDescriptor *branchDescriptor1; - sqInt constant; - sqInt constant1; - BytecodeFixup * fixup; - sqInt i; - void *jumpTarget; - void *jumpTarget1; - AbstractInstruction *label; - sqInt nExts; - sqInt nextPC; - sqInt nextPC1; - sqInt postBranchPC; - sqInt postBranchPC1; - BytecodeDescriptor *primDescriptor; - sqInt rcvrConstant; - sqInt rcvrNeedsReg; - sqInt rcvrReg; - sqInt rcvrReg1; - sqInt reg; - sqInt rNext1; - sqInt rTop1; - CogSimStackEntry *simStackEntry; - CogSimStackEntry *simStackEntry1; - sqInt targetBytecodePC; - sqInt targetBytecodePC1; - sqInt topRegistersMask; - sqInt unforwardArg; - sqInt unforwardRcvr; - - unforwardRcvr = mayBeAForwarder(ssValue(1)); - unforwardArg = mayBeAForwarder(ssTop()); - if ((!unforwardRcvr) - && (!unforwardArg)) { - return genVanillaInlinedIdenticalOrNotIf(orNot); - } - assert(unforwardArg - || (unforwardRcvr)); - /* begin isUnannotatableConstant: */ - simStackEntry = ssValue(1); - rcvrConstant = (((simStackEntry->type)) == SSConstant) - && ((isImmediate((simStackEntry->constant))) - || (!(shouldAnnotateObjectReference((simStackEntry->constant))))); - /* begin isUnannotatableConstant: */ - simStackEntry1 = ssTop(); - argConstant = (((simStackEntry1->type)) == SSConstant) - && ((isImmediate((simStackEntry1->constant))) - || (!(shouldAnnotateObjectReference((simStackEntry1->constant))))); - /* begin extractMaybeBranchDescriptorInto: */ - primDescriptor = generatorAt(byte0); - nextPC1 = bytecodePC + ((primDescriptor->numBytes)); - nExts = 0; - while (1) { - while (1) { - /* begin generatorForPC: */ - branchDescriptor1 = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC1, methodObj))); - if (!((branchDescriptor1->isExtension))) break; - nExts += 1; - nextPC1 += (branchDescriptor1->numBytes); - } - /* begin isUnconditionalBranch */ - if (!((isBranch(branchDescriptor1)) - && (!(((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse)))))) break; - nextPC1 = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - } - targetBytecodePC1 = (postBranchPC1 = 0); - if (((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse))) { - targetBytecodePC1 = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - postBranchPC1 = eventualTargetOf(nextPC1 + ((branchDescriptor1->numBytes))); - } - else { - nextPC1 = bytecodePC + ((primDescriptor->numBytes)); - } - branchDescriptor = branchDescriptor1; - nextPC = nextPC1; - postBranchPC = postBranchPC1; - targetBytecodePC = targetBytecodePC1; - /* begin allocateEqualsEqualsRegistersArgNeedsReg:rcvrNeedsReg:into: */ - argNeedsReg = !argConstant; - rcvrNeedsReg = !rcvrConstant; - assert(argNeedsReg - || (rcvrNeedsReg)); - argReg1 = (rcvrReg1 = NoReg); - if (argNeedsReg) { - if (rcvrNeedsReg) { - /* begin allocateRegForStackTopTwoEntriesInto: */ - topRegistersMask = 0; - rTop1 = (rNext1 = NoReg); - if ((registerOrNone(ssTop())) != NoReg) { - rTop1 = registerOrNone(ssTop()); - } - if ((registerOrNone(ssValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; - } - if (rTop1 == NoReg) { - rTop1 = allocateRegNotConflictingWith(topRegistersMask); - } - if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); - } - assert(!(((rTop1 == NoReg) - || (rNext1 == NoReg)))); - argReg1 = rTop1; - rcvrReg1 = rNext1; - popToReg(ssTop(), argReg1); - popToReg(ssValue(1), rcvrReg1); - } - else { - argReg1 = allocateRegForStackEntryAtnotConflictingWith(0, 0); - popToReg(ssTop(), argReg1); - if (((ssValue(1))->spilled)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AddCqR, BytesPerWord, SPReg); - } - } - } - else { - assert(rcvrNeedsReg); - assert(!((((ssTop())->spilled)))); - rcvrReg1 = allocateRegForStackEntryAtnotConflictingWith(1, 0); - popToReg(ssValue(1), rcvrReg1); - } - assert(!((argNeedsReg - && (argReg1 == NoReg)))); - assert(!((rcvrNeedsReg - && (rcvrReg1 == NoReg)))); - rcvrReg = rcvrReg1; - argReg = argReg1; - if (!(((branchDescriptor->isBranchTrue)) - || ((branchDescriptor->isBranchFalse)))) { - return genIdenticalNoBranchArgIsConstantrcvrIsConstantargRegrcvrRegorNotIf(argConstant, rcvrConstant, argReg, rcvrReg, orNot); - } - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= (simStackPtr - 2)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 2)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 2))); i <= (simStackPtr - 2); i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 2) + 1; - } - /* begin Label */ - label = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - /* begin genCmpArgIsConstant:rcvrIsConstant:argReg:rcvrReg: */ - assert((argReg != NoReg) - || (rcvrReg != NoReg)); - if (argConstant) { - /* begin genCmpConstant:R: */ - constant = ((ssTop())->constant); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(CmpCwR, constant, rcvrReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, constant, rcvrReg); - } - } - else { - if (rcvrConstant) { - /* begin genCmpConstant:R: */ - constant1 = ((ssValue(1))->constant); - if (shouldAnnotateObjectReference(constant1)) { - annotateobjRef(checkLiteralforInstruction(constant1, genoperandoperand(CmpCwR, constant1, argReg)), constant1); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, constant1, argReg); - } - } - else { - /* begin CmpR:R: */ - assert(!((argReg == SPReg))); - genoperandoperand(CmpRR, argReg, rcvrReg); - } - } - ssPop(2); - if ((((fixupAt(nextPC))->targetInstruction)) == 0) { - - /* The next instruction is dead. we can skip it. */ - deadCode = 1; - ensureFixupAt(targetBytecodePC); - ensureFixupAt(postBranchPC); - } - else { - assert(!(deadCode)); - } - if (orNot == ((branchDescriptor->isBranchTrue))) { - - /* a == b ifFalse: ... or a ~~ b ifTrue: ... jump on equal to post-branch pc */ - fixup = ensureNonMergeFixupAt(targetBytecodePC); - /* begin JumpZero: */ - jumpTarget = ensureNonMergeFixupAt(postBranchPC); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget)); - } - else { - - /* orNot is true for ~~ */ - /* a == b ifTrue: ... or a ~~ b ifFalse: ... jump on equal to target pc */ - fixup = ensureNonMergeFixupAt(postBranchPC); - /* begin JumpZero: */ - jumpTarget1 = ensureNonMergeFixupAt(targetBytecodePC); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget1)); - } - if (unforwardArg - && (unforwardRcvr)) { - /* begin genEnsureOopInRegNotForwarded:scratchReg:jumpBackTo: */ - genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(argReg, TempReg, label, 0); - } - genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder((unforwardRcvr - ? rcvrReg - : argReg), TempReg, label, fixup); - if (!deadCode) { - ssPushConstant(trueObject()); - } - return 0; -} - - -/* Generates the machine code for #== in the case where the instruction is - not followed by a branch - */ - - /* StackToRegisterMappingCogit>>#genIdenticalNoBranchArgIsConstant:rcvrIsConstant:argReg:rcvrReg:orNotIf: */ -static sqInt NoDbgRegParms -genIdenticalNoBranchArgIsConstantrcvrIsConstantargRegrcvrRegorNotIf(sqInt argIsConstant, sqInt rcvrIsConstant, sqInt argReg, sqInt rcvrRegOrNone, sqInt orNot) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - sqInt constant; - sqInt constant1; - sqInt constant11; - sqInt constant2; - sqInt constant3; - sqInt constant4; - AbstractInstruction *jumpEqual; - AbstractInstruction *jumpNotEqual; - AbstractInstruction *label; - sqInt resultReg; - - /* begin Label */ - label = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - /* begin genCmpArgIsConstant:rcvrIsConstant:argReg:rcvrReg: */ - assert((argReg != NoReg) - || (rcvrRegOrNone != NoReg)); - if (argIsConstant) { - /* begin genCmpConstant:R: */ - constant4 = ((ssTop())->constant); - if (shouldAnnotateObjectReference(constant4)) { - annotateobjRef(checkLiteralforInstruction(constant4, genoperandoperand(CmpCwR, constant4, rcvrRegOrNone)), constant4); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, constant4, rcvrRegOrNone); - } - } - else { - if (rcvrIsConstant) { - /* begin genCmpConstant:R: */ - constant11 = ((ssValue(1))->constant); - if (shouldAnnotateObjectReference(constant11)) { - annotateobjRef(checkLiteralforInstruction(constant11, genoperandoperand(CmpCwR, constant11, argReg)), constant11); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, constant11, argReg); - } - } - else { - /* begin CmpR:R: */ - assert(!((argReg == SPReg))); - genoperandoperand(CmpRR, argReg, rcvrRegOrNone); - } - } - ssPop(2); - resultReg = (rcvrRegOrNone == NoReg - ? argReg - : rcvrRegOrNone); - /* begin JumpZero: */ - jumpEqual = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - if (!argIsConstant) { - /* begin genEnsureOopInRegNotForwarded:scratchReg:jumpBackTo: */ - genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(argReg, TempReg, label, 0); - } - if (!rcvrIsConstant) { - /* begin genEnsureOopInRegNotForwarded:scratchReg:jumpBackTo: */ - genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(rcvrRegOrNone, TempReg, label, 0); - } - if (orNot) { - /* begin genMoveTrueR: */ - constant = trueObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, resultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, constant, resultReg); - } - } - else { - /* begin genMoveFalseR: */ - constant1 = falseObject(); - if (shouldAnnotateObjectReference(constant1)) { - annotateobjRef(checkLiteralforInstruction(constant1, genoperandoperand(MoveCwR, constant1, resultReg)), constant1); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(MoveCqR, constant1, resultReg); - } - } - /* begin Jump: */ - jumpNotEqual = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpEqual, (orNot - ? (/* begin genMoveFalseR: */ - (constant2 = falseObject()), - (shouldAnnotateObjectReference(constant2) - ? annotateobjRef(checkLiteralforInstruction(constant2, genoperandoperand(MoveCwR, constant2, resultReg)), constant2) - : (/* begin checkQuickConstant:forInstruction: */ - (anInstruction4 = genoperandoperand(MoveCqR, constant2, resultReg)), - anInstruction4))) - : (/* begin genMoveTrueR: */ - (constant3 = trueObject()), - (shouldAnnotateObjectReference(constant3) - ? annotateobjRef(checkLiteralforInstruction(constant3, genoperandoperand(MoveCwR, constant3, resultReg)), constant3) - : (/* begin checkQuickConstant:forInstruction: */ - (anInstruction5 = genoperandoperand(MoveCqR, constant3, resultReg)), - anInstruction5))))); - jmpTarget(jumpNotEqual, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushRegister(resultReg); - return 0; -} - - -/* Decompose code generation for #== into a common constant-folding version, - followed by a double dispatch through the objectRepresentation to a - version that doesn't deal with forwarders and a version that does. */ - - /* StackToRegisterMappingCogit>>#genInlinedIdenticalOrNotIf: */ -static sqInt NoDbgRegParms -genInlinedIdenticalOrNotIf(sqInt orNot) -{ - BytecodeDescriptor *primDescriptor; - sqInt result; - - primDescriptor = generatorAt(byte0); - if ((isUnannotatableConstant(ssTop())) - && (isUnannotatableConstant(ssValue(1)))) { - assert(!((primDescriptor->isMapped))); - result = ((orNot - ? (((ssTop())->constant)) != (((ssValue(1))->constant)) - : (((ssTop())->constant)) == (((ssValue(1))->constant))) - ? trueObject() - : falseObject()); - ssPop(2); - return ssPushConstant(result); - } - /* begin genInlinedIdenticalOrNotIfGuts: */ - return genForwardersInlinedIdenticalOrNotIf(orNot); -} - - /* StackToRegisterMappingCogit>>#genJumpBackTo: */ -static sqInt NoDbgRegParms -genJumpBackTo(sqInt targetBytecodePC) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *anInstruction; - sqInt i; - void *jumpTarget; - void *jumpTarget1; - - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - - /* can't fall through */ - deadCode = 1; - /* begin checkLiteral:forInstruction: */ - stackLimitAddress(); - anInstruction = genoperandoperand(MoveAwR, stackLimitAddress(), TempReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, SPReg); - /* begin JumpAboveOrEqual: */ - jumpTarget = fixupAtIndex(targetBytecodePC - initialPC); - genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)jumpTarget)); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceCheckForInterruptTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin annotateBytecode: */ - abstractInstruction1 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction1->annotation = HasBytecodePC); - /* begin Jump: */ - jumpTarget1 = fixupAtIndex(targetBytecodePC - initialPC); - genoperand(Jump, ((sqInt)jumpTarget1)); - return 0; -} - - /* StackToRegisterMappingCogit>>#genJumpIf:to: */ -static sqInt NoDbgRegParms -genJumpIfto(sqInt boolean, sqInt targetBytecodePC) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - CogSimStackEntry *desc; - sqInt eventualTarget; - BytecodeFixup *fixup; - sqInt i; - void *jumpTarget; - AbstractInstruction *ok; - sqInt quickConstant; - - eventualTarget = eventualTargetOf(targetBytecodePC); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= (simStackPtr - 1)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 1)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 1))); i < simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 1) + 1; - } - desc = ssTop(); - ssPop(1); - if ((((desc->type)) == SSConstant) - && ((((desc->constant)) == (trueObject())) - || (((desc->constant)) == (falseObject())))) { - - /* Must arrange there's a fixup at the target whether it is jumped to or - not so that the simStackPtr can be kept correct. */ - - /* Must annotate the bytecode for correct pc mapping. */ - fixup = ensureFixupAt(eventualTarget); - /* begin annotateBytecode: */ - if (((desc->constant)) == boolean) { - /* begin Jump: */ - abstractInstruction = genoperand(Jump, ((sqInt)fixup)); - } - else { - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - } - (abstractInstruction->annotation = HasBytecodePC); - extA = 0; - return 0; - } - popToReg(desc, TempReg); - assert((objectAfter(falseObject())) == (trueObject())); - /* begin genSubConstant:R: */ - if (shouldAnnotateObjectReference(boolean)) { - annotateobjRef(checkLiteralforInstruction(boolean, genoperandoperand(SubCwR, boolean, TempReg)), TempReg); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, boolean, TempReg); - } - /* begin JumpZero: */ - jumpTarget = ensureFixupAt(eventualTarget); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget)); - if (((extA & 1) != 0)) { - extA = 0; - /* begin annotateBytecode: */ - abstractInstruction1 = lastOpcode(); - (abstractInstruction1->annotation = HasBytecodePC); - return 0; - } - extA = 0; - /* begin CmpCq:R: */ - quickConstant = (boolean == (falseObject()) - ? (trueObject()) - (falseObject()) - : (falseObject()) - (trueObject())); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, quickConstant, TempReg); - /* begin JumpZero: */ - ok = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - genCallMustBeBooleanFor(boolean); - jmpTarget(ok, annotateBytecode(genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return 0; -} - - /* StackToRegisterMappingCogit>>#genJumpTo: */ -static sqInt NoDbgRegParms -genJumpTo(sqInt targetBytecodePC) -{ - sqInt eventualTarget; - BytecodeFixup * fixup; - BytecodeDescriptor * generator; - sqInt i; - sqInt i1; - - eventualTarget = eventualTargetOf(targetBytecodePC); - if ((eventualTarget > bytecodePC) - && (((simStackPtr >= methodOrBlockNumArgs) - && (stackEntryIsBoolean(ssTop()))) - && ((((generator = generatorForPC(eventualTarget))->isBranchTrue)) - || (((generator = generatorForPC(eventualTarget))->isBranchFalse))))) { - eventualTarget = (eventualTarget + ((generator->numBytes))) + ((((generator->isBranchTrue)) == ((((ssTop())->constant)) == (trueObject())) - ? (/* begin spanFor:at:exts:in: */ - ((generator->spanFunction))(generator, eventualTarget, 0, methodObj)) - : 0)); - ssPop(1); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - fixup = ensureFixupAt(eventualTarget); - ssPop(-1); - } - else { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i1 <= simStackPtr; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - fixup = ensureFixupAt(eventualTarget); - } - - /* can't fall through */ - deadCode = 1; - /* begin Jump: */ - genoperand(Jump, ((sqInt)fixup)); - return 0; -} - - -/* Lowcode instruction generator dispatch */ - - /* StackToRegisterMappingCogit>>#genLowcodeBinaryInlinePrimitive: */ -static sqInt NoDbgRegParms -genLowcodeBinaryInlinePrimitive(sqInt prim) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt frResult; - sqInt frResult1; - sqInt i1; - sqInt i11; - sqInt i110; - sqInt i112; - sqInt i114; - sqInt i115; - sqInt i116; - sqInt i117; - sqInt i118; - sqInt i119; - sqInt i12; - sqInt i120; - sqInt i121; - sqInt i122; - sqInt i123; - sqInt i124; - sqInt i125; - sqInt i13; - sqInt i14; - sqInt i15; - sqInt i16; - sqInt i17; - sqInt i18; - sqInt i19; - sqInt i210; - sqInt i211; - sqInt i212; - sqInt i213; - sqInt i215; - sqInt i33; - sqInt i36; - sqInt index1; - sqInt index11; - sqInt index110; - sqInt index112; - sqInt index113; - sqInt index115; - sqInt index116; - sqInt index117; - sqInt index118; - sqInt index119; - sqInt index12; - sqInt index120; - sqInt index121; - sqInt index122; - sqInt index123; - sqInt index124; - sqInt index125; - sqInt index13; - sqInt index14; - sqInt index15; - sqInt index16; - sqInt index17; - sqInt index18; - sqInt index19; - sqInt object; - sqInt object1; - sqInt object10; - sqInt object11; - sqInt object12; - sqInt object13; - sqInt object14; - sqInt object15; - sqInt object16; - sqInt object17; - sqInt object18; - sqInt object19; - sqInt object2; - sqInt object20; - sqInt object21; - sqInt object22; - sqInt object23; - sqInt object3; - sqInt object4; - sqInt object5; - sqInt object6; - sqInt object7; - sqInt object8; - sqInt object9; - sqInt pointer; - sqInt rOopTop; - sqInt rOopTop1; - sqInt rOopTop10; - sqInt rOopTop12; - sqInt rOopTop13; - sqInt rOopTop15; - sqInt rOopTop16; - sqInt rOopTop17; - sqInt rOopTop18; - sqInt rOopTop19; - sqInt rOopTop2; - sqInt rOopTop20; - sqInt rOopTop21; - sqInt rOopTop22; - sqInt rOopTop23; - sqInt rOopTop24; - sqInt rOopTop25; - sqInt rOopTop3; - sqInt rOopTop4; - sqInt rOopTop5; - sqInt rOopTop6; - sqInt rOopTop7; - sqInt rOopTop8; - sqInt rOopTop9; - sqInt rResult; - sqInt rResult1; - sqInt rResult10; - sqInt rResult14; - sqInt rResult15; - sqInt rResult17; - sqInt rResult2; - sqInt rResult21; - sqInt rResult22; - sqInt rResult23; - sqInt rResult24; - sqInt rResult3; - sqInt rResult4; - sqInt rResult5; - sqInt rResult6; - sqInt rResult7; - sqInt rResult8; - sqInt rResult9; - sqInt value; - sqInt value1; - sqInt value10; - sqInt value11; - sqInt value13; - sqInt value2; - sqInt value3; - sqInt value4; - sqInt value5; - sqInt value6; - sqInt valueHigh; - sqInt valueHigh1; - sqInt valueHigh2; - sqInt valueHigh3; - sqInt valueLow; - sqInt valueLow1; - sqInt valueLow2; - sqInt valueLow3; - sqInt value9; - - switch (prim) { - case 0: - /* begin genLowcodeByteSizeOf */ - rOopTop19 = NoReg; - rResult10 = NoReg; - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop19 = registerOrNone(ssTop()); - index119 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i119 = index119; i119 <= (simStackPtr); i119 += 1) { - if ((registerOrNone(simStackAt(index119))) == rOopTop19) { - goto l62; - } - } - l62: ; - rOopTop19 = NoReg; - l61: ; - } - if (rOopTop19 == NoReg) { - rOopTop19 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult10 = allocateRegNotConflictingWith(1U << rOopTop19); - assert(!(((rOopTop19 == NoReg) - || (rResult10 == NoReg)))); - object17 = rOopTop19; - value9 = rResult10; - popToReg(ssTop(), object17); - ssPop(1); - /* begin ssFlushAll */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i210 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i210 <= simStackPtr; i210 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i210), frameOffsetOfTemporary(i210 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - voidReceiverResultRegContainsSelf(); - genLcByteSizeOfto(object17, value9); - return 0; - - case 1: - /* begin genLowcodeFirstFieldPointer */ - rOopTop = NoReg; - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop = registerOrNone(ssTop()); - index1 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i1 = index1; i1 <= (simStackPtr); i1 += 1) { - if ((registerOrNone(simStackAt(index1))) == rOopTop) { - goto l2; - } - } - l2: ; - rOopTop = NoReg; - l1: ; - } - if (rOopTop == NoReg) { - rOopTop = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rOopTop == NoReg))); - object = rOopTop; - popToReg(ssTop(), object); - ssPop(1); - genLcFirstFieldPointer(object); - return 0; - - case 2: - /* begin genLowcodeFirstIndexableFieldPointer */ - rOopTop1 = NoReg; - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop1 = registerOrNone(ssTop()); - index11 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i11 = index11; i11 <= (simStackPtr); i11 += 1) { - if ((registerOrNone(simStackAt(index11))) == rOopTop1) { - goto l6; - } - } - l6: ; - rOopTop1 = NoReg; - l5: ; - } - if (rOopTop1 == NoReg) { - rOopTop1 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rOopTop1 == NoReg))); - object1 = rOopTop1; - popToReg(ssTop(), object1); - ssPop(1); - genLcFirstIndexableFieldPointer(object1); - return 0; - - case 3: - /* begin genLowcodeIsBytes */ - rOopTop2 = NoReg; - rResult = NoReg; - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop2 = registerOrNone(ssTop()); - index12 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i12 = index12; i12 <= (simStackPtr); i12 += 1) { - if ((registerOrNone(simStackAt(index12))) == rOopTop2) { - goto l9; - } - } - l9: ; - rOopTop2 = NoReg; - l8: ; - } - if (rOopTop2 == NoReg) { - rOopTop2 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult = allocateRegNotConflictingWith(1U << rOopTop2); - assert(!(((rOopTop2 == NoReg) - || (rResult == NoReg)))); - object2 = rOopTop2; - value = rResult; - popToReg(ssTop(), object2); - ssPop(1); - genLcIsBytesto(object2, value); - return 0; - - case 4: - /* begin genLowcodeIsFloatObject */ - rOopTop3 = NoReg; - rResult1 = NoReg; - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop3 = registerOrNone(ssTop()); - index13 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i13 = index13; i13 <= (simStackPtr); i13 += 1) { - if ((registerOrNone(simStackAt(index13))) == rOopTop3) { - goto l12; - } - } - l12: ; - rOopTop3 = NoReg; - l11: ; - } - if (rOopTop3 == NoReg) { - rOopTop3 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult1 = allocateRegNotConflictingWith(1U << rOopTop3); - assert(!(((rOopTop3 == NoReg) - || (rResult1 == NoReg)))); - object3 = rOopTop3; - value1 = rResult1; - popToReg(ssTop(), object3); - ssPop(1); - genLcIsFloatObjectto(object3, value1); - return 0; - - case 5: - /* begin genLowcodeIsIndexable */ - rOopTop4 = NoReg; - rResult2 = NoReg; - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop4 = registerOrNone(ssTop()); - index14 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i14 = index14; i14 <= (simStackPtr); i14 += 1) { - if ((registerOrNone(simStackAt(index14))) == rOopTop4) { - goto l15; - } - } - l15: ; - rOopTop4 = NoReg; - l14: ; - } - if (rOopTop4 == NoReg) { - rOopTop4 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult2 = allocateRegNotConflictingWith(1U << rOopTop4); - assert(!(((rOopTop4 == NoReg) - || (rResult2 == NoReg)))); - object4 = rOopTop4; - value2 = rResult2; - popToReg(ssTop(), object4); - ssPop(1); - genLcIsIndexableto(object4, value2); - return 0; - - case 6: - /* begin genLowcodeIsIntegerObject */ - rOopTop5 = NoReg; - rResult3 = NoReg; - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop5 = registerOrNone(ssTop()); - index15 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i15 = index15; i15 <= (simStackPtr); i15 += 1) { - if ((registerOrNone(simStackAt(index15))) == rOopTop5) { - goto l18; - } - } - l18: ; - rOopTop5 = NoReg; - l17: ; - } - if (rOopTop5 == NoReg) { - rOopTop5 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult3 = allocateRegNotConflictingWith(1U << rOopTop5); - assert(!(((rOopTop5 == NoReg) - || (rResult3 == NoReg)))); - object5 = rOopTop5; - value3 = rResult3; - popToReg(ssTop(), object5); - ssPop(1); - genLcIsIntegerObjectto(object5, value3); - return 0; - - case 7: - /* begin genLowcodeIsPointers */ - rOopTop6 = NoReg; - rResult4 = NoReg; - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop6 = registerOrNone(ssTop()); - index16 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i16 = index16; i16 <= (simStackPtr); i16 += 1) { - if ((registerOrNone(simStackAt(index16))) == rOopTop6) { - goto l21; - } - } - l21: ; - rOopTop6 = NoReg; - l20: ; - } - if (rOopTop6 == NoReg) { - rOopTop6 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult4 = allocateRegNotConflictingWith(1U << rOopTop6); - assert(!(((rOopTop6 == NoReg) - || (rResult4 == NoReg)))); - object6 = rOopTop6; - value4 = rResult4; - popToReg(ssTop(), object6); - ssPop(1); - genLcIsPointersto(object6, value4); - return 0; - - case 8: - /* begin genLowcodeIsWords */ - rOopTop7 = NoReg; - rResult5 = NoReg; - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop7 = registerOrNone(ssTop()); - index17 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i17 = index17; i17 <= (simStackPtr); i17 += 1) { - if ((registerOrNone(simStackAt(index17))) == rOopTop7) { - goto l24; - } - } - l24: ; - rOopTop7 = NoReg; - l23: ; - } - if (rOopTop7 == NoReg) { - rOopTop7 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult5 = allocateRegNotConflictingWith(1U << rOopTop7); - assert(!(((rOopTop7 == NoReg) - || (rResult5 == NoReg)))); - object7 = rOopTop7; - value5 = rResult5; - popToReg(ssTop(), object7); - ssPop(1); - genLcIsWordsto(object7, value5); - return 0; - - case 9: - /* begin genLowcodeIsWordsOrBytes */ - rOopTop8 = NoReg; - rResult6 = NoReg; - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop8 = registerOrNone(ssTop()); - index18 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i18 = index18; i18 <= (simStackPtr); i18 += 1) { - if ((registerOrNone(simStackAt(index18))) == rOopTop8) { - goto l27; - } - } - l27: ; - rOopTop8 = NoReg; - l26: ; - } - if (rOopTop8 == NoReg) { - rOopTop8 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult6 = allocateRegNotConflictingWith(1U << rOopTop8); - assert(!(((rOopTop8 == NoReg) - || (rResult6 == NoReg)))); - object8 = rOopTop8; - value6 = rResult6; - popToReg(ssTop(), object8); - ssPop(1); - genLcIsWordsOrBytesto(object8, value6); - return 0; - - case 10: - /* begin genLowcodeOopSmallIntegerToInt32 */ - rOopTop9 = NoReg; - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop9 = registerOrNone(ssTop()); - index19 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i19 = index19; i19 <= (simStackPtr); i19 += 1) { - if ((registerOrNone(simStackAt(index19))) == rOopTop9) { - goto l30; - } - } - l30: ; - rOopTop9 = NoReg; - l29: ; - } - if (rOopTop9 == NoReg) { - rOopTop9 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rOopTop9 == NoReg))); - object9 = rOopTop9; - popToReg(ssTop(), object9); - ssPop(1); - genConvertSmallIntegerToIntegerInReg(object9); - ssPushNativeRegister(object9); - return 0; - - case 11: - /* begin genLowcodeOopSmallIntegerToInt64 */ - /* begin allocateRegistersForLowcodeOopResultInteger2: */ - rOopTop10 = NoReg; - rResult7 = (rResult21 = NoReg); - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop10 = registerOrNone(ssTop()); - index110 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i110 = index110; i110 <= (simStackPtr); i110 += 1) { - if ((registerOrNone(simStackAt(index110))) == rOopTop10) { - goto l36; - } - } - l36: ; - rOopTop10 = NoReg; - l33: ; - } - if (rOopTop10 == NoReg) { - rOopTop10 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult7 = allocateRegNotConflictingWith(1U << rOopTop10); - rResult21 = allocateRegNotConflictingWith((1U << rOopTop10) | (1U << rResult7)); - assert(!(((rOopTop10 == NoReg) - || (rResult7 == NoReg)))); - object10 = rOopTop10; - valueLow = rResult7; - valueHigh = rResult21; - popToReg(ssTop(), object10); - ssPop(1); - genConvertSmallIntegerToIntegerInReg(object10); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 0, valueHigh); - ssPushNativeRegistersecondRegister(object10, valueHigh); - return 0; - - case 12: - /* begin genLowcodeOopToBoolean32 */ - rOopTop12 = NoReg; - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop12 = registerOrNone(ssTop()); - index112 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i112 = index112; i112 <= (simStackPtr); i112 += 1) { - if ((registerOrNone(simStackAt(index112))) == rOopTop12) { - goto l39; - } - } - l39: ; - rOopTop12 = NoReg; - l38: ; - } - if (rOopTop12 == NoReg) { - rOopTop12 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rOopTop12 == NoReg))); - object11 = rOopTop12; - popToReg(ssTop(), object11); - ssPop(1); - annotateobjRef(checkLiteralforInstruction(falseObject(), genoperandoperand(SubCwR, falseObject(), object11)), falseObject()); - ssPushNativeRegister(object11); - return 0; - - case 13: - /* begin genLowcodeOopToBoolean64 */ - /* begin allocateRegistersForLowcodeOopResultInteger2: */ - rOopTop13 = NoReg; - rResult8 = (rResult22 = NoReg); - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop13 = registerOrNone(ssTop()); - index113 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i114 = index113; i114 <= (simStackPtr); i114 += 1) { - if ((registerOrNone(simStackAt(index113))) == rOopTop13) { - goto l45; - } - } - l45: ; - rOopTop13 = NoReg; - l42: ; - } - if (rOopTop13 == NoReg) { - rOopTop13 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult8 = allocateRegNotConflictingWith(1U << rOopTop13); - rResult22 = allocateRegNotConflictingWith((1U << rOopTop13) | (1U << rResult8)); - assert(!(((rOopTop13 == NoReg) - || (rResult8 == NoReg)))); - object12 = rOopTop13; - valueLow1 = rResult8; - valueHigh1 = rResult22; - popToReg(ssTop(), object12); - ssPop(1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, 0, valueHigh1); - annotateobjRef(checkLiteralforInstruction(falseObject(), genoperandoperand(SubCwR, falseObject(), object12)), falseObject()); - ssPushNativeRegistersecondRegister(object12, valueHigh1); - return 0; - - case 14: - /* begin genLowcodeOopToFloat32 */ - rOopTop20 = NoReg; - frResult = NoReg; - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop20 = registerOrNone(ssTop()); - index120 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i120 = index120; i120 <= (simStackPtr); i120 += 1) { - if ((registerOrNone(simStackAt(index120))) == rOopTop20) { - goto l65; - } - } - l65: ; - rOopTop20 = NoReg; - l64: ; - } - if (rOopTop20 == NoReg) { - rOopTop20 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - frResult = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!(((rOopTop20 == NoReg) - || (frResult == NoReg)))); - object18 = rOopTop20; - value10 = frResult; - popToReg(ssTop(), object18); - ssPop(1); - /* begin ssFlushAll */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i211 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i211 <= simStackPtr; i211 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i211), frameOffsetOfTemporary(i211 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - voidReceiverResultRegContainsSelf(); - genLcOoptoFloat32(object18, value10); - return 0; - - case 15: - /* begin genLowcodeOopToFloat64 */ - rOopTop21 = NoReg; - frResult1 = NoReg; - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop21 = registerOrNone(ssTop()); - index121 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i121 = index121; i121 <= (simStackPtr); i121 += 1) { - if ((registerOrNone(simStackAt(index121))) == rOopTop21) { - goto l68; - } - } - l68: ; - rOopTop21 = NoReg; - l67: ; - } - if (rOopTop21 == NoReg) { - rOopTop21 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - frResult1 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!(((rOopTop21 == NoReg) - || (frResult1 == NoReg)))); - object19 = rOopTop21; - value11 = frResult1; - popToReg(ssTop(), object19); - ssPop(1); - /* begin ssFlushAll */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i212 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i212 <= simStackPtr; i212 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i212), frameOffsetOfTemporary(i212 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - voidReceiverResultRegContainsSelf(); - genLcOoptoFloat64(object19, value11); - return 0; - - case 16: - /* begin genLowcodeOopToInt32 */ - rOopTop22 = NoReg; - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop22 = registerOrNone(ssTop()); - index122 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i122 = index122; i122 <= (simStackPtr); i122 += 1) { - if ((registerOrNone(simStackAt(index122))) == rOopTop22) { - goto l71; - } - } - l71: ; - rOopTop22 = NoReg; - l70: ; - } - if (rOopTop22 == NoReg) { - rOopTop22 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rOopTop22 == NoReg))); - object20 = rOopTop22; - popToReg(ssTop(), object20); - ssPop(1); - /* begin ssFlushAll */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i213 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i213 <= simStackPtr; i213 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i213), frameOffsetOfTemporary(i213 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - voidReceiverResultRegContainsSelf(); - genLcOopToInt32(object20); - return 0; - - case 17: - /* begin genLowcodeOopToInt64 */ - /* begin allocateRegistersForLowcodeOopResultInteger2: */ - rOopTop23 = NoReg; - rResult14 = (rResult23 = NoReg); - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop23 = registerOrNone(ssTop()); - index123 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i123 = index123; i123 <= (simStackPtr); i123 += 1) { - if ((registerOrNone(simStackAt(index123))) == rOopTop23) { - goto l77; - } - } - l77: ; - rOopTop23 = NoReg; - l74: ; - } - if (rOopTop23 == NoReg) { - rOopTop23 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult14 = allocateRegNotConflictingWith(1U << rOopTop23); - rResult23 = allocateRegNotConflictingWith((1U << rOopTop23) | (1U << rResult14)); - assert(!(((rOopTop23 == NoReg) - || (rResult14 == NoReg)))); - object21 = rOopTop23; - valueLow2 = rResult14; - valueHigh2 = rResult23; - popToReg(ssTop(), object21); - ssPop(1); - /* begin ssFlushAll */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i33 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i33 <= simStackPtr; i33 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i33), frameOffsetOfTemporary(i33 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - voidReceiverResultRegContainsSelf(); - genLcOoptoInt64highPart(object21, valueLow2, valueHigh2); - return 0; - - case 18: - /* begin genLowcodeOopToPointer */ - rOopTop15 = NoReg; - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop15 = registerOrNone(ssTop()); - index115 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i115 = index115; i115 <= (simStackPtr); i115 += 1) { - if ((registerOrNone(simStackAt(index115))) == rOopTop15) { - goto l48; - } - } - l48: ; - rOopTop15 = NoReg; - l47: ; - } - if (rOopTop15 == NoReg) { - rOopTop15 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rOopTop15 == NoReg))); - object13 = rOopTop15; - popToReg(ssTop(), object13); - ssPop(1); - genLcOopToPointer(object13); - return 0; - - case 19: - /* begin genLowcodeOopToPointerReinterpret */ - rOopTop16 = NoReg; - rResult9 = NoReg; - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop16 = registerOrNone(ssTop()); - index116 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i116 = index116; i116 <= (simStackPtr); i116 += 1) { - if ((registerOrNone(simStackAt(index116))) == rOopTop16) { - goto l51; - } - } - l51: ; - rOopTop16 = NoReg; - l50: ; - } - if (rOopTop16 == NoReg) { - rOopTop16 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult9 = allocateRegNotConflictingWith(1U << rOopTop16); - assert(!(((rOopTop16 == NoReg) - || (rResult9 == NoReg)))); - object14 = rOopTop16; - pointer = rResult9; - popToReg(ssTop(), object14); - ssPop(1); - ssPushNativeRegister(object14); - return 0; - - case 20: - /* begin genLowcodeOopToUInt32 */ - rOopTop24 = NoReg; - rResult15 = NoReg; - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop24 = registerOrNone(ssTop()); - index124 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i124 = index124; i124 <= (simStackPtr); i124 += 1) { - if ((registerOrNone(simStackAt(index124))) == rOopTop24) { - goto l80; - } - } - l80: ; - rOopTop24 = NoReg; - l79: ; - } - if (rOopTop24 == NoReg) { - rOopTop24 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult15 = allocateRegNotConflictingWith(1U << rOopTop24); - assert(!(((rOopTop24 == NoReg) - || (rResult15 == NoReg)))); - object22 = rOopTop24; - value13 = rResult15; - popToReg(ssTop(), object22); - ssPop(1); - /* begin ssFlushAll */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i215 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i215 <= simStackPtr; i215 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i215), frameOffsetOfTemporary(i215 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - voidReceiverResultRegContainsSelf(); - genLcOopToUInt32(object22); - return 0; - - case 21: - /* begin genLowcodeOopToUInt64 */ - /* begin allocateRegistersForLowcodeOopResultInteger2: */ - rOopTop25 = NoReg; - rResult17 = (rResult24 = NoReg); - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop25 = registerOrNone(ssTop()); - index125 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i125 = index125; i125 <= (simStackPtr); i125 += 1) { - if ((registerOrNone(simStackAt(index125))) == rOopTop25) { - goto l86; - } - } - l86: ; - rOopTop25 = NoReg; - l83: ; - } - if (rOopTop25 == NoReg) { - rOopTop25 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult17 = allocateRegNotConflictingWith(1U << rOopTop25); - rResult24 = allocateRegNotConflictingWith((1U << rOopTop25) | (1U << rResult17)); - assert(!(((rOopTop25 == NoReg) - || (rResult17 == NoReg)))); - object23 = rOopTop25; - valueLow3 = rResult17; - valueHigh3 = rResult24; - popToReg(ssTop(), object23); - ssPop(1); - /* begin ssFlushAll */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i36 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i36 <= simStackPtr; i36 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i36), frameOffsetOfTemporary(i36 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - voidReceiverResultRegContainsSelf(); - genLcOoptoUInt64highPart(object23, valueLow3, valueHigh3); - return 0; - - case 22: - /* begin genLowcodePin */ - rOopTop17 = NoReg; - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop17 = registerOrNone(ssTop()); - index117 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i117 = index117; i117 <= (simStackPtr); i117 += 1) { - if ((registerOrNone(simStackAt(index117))) == rOopTop17) { - goto l54; - } - } - l54: ; - rOopTop17 = NoReg; - l53: ; - } - if (rOopTop17 == NoReg) { - rOopTop17 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rOopTop17 == NoReg))); - object15 = rOopTop17; - popToReg(ssTop(), object15); - ssPop(1); - abort(); - return 0; - - case 23: - /* begin genLowcodeUnpin */ - rOopTop18 = NoReg; - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop18 = registerOrNone(ssTop()); - index118 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i118 = index118; i118 <= (simStackPtr); i118 += 1) { - if ((registerOrNone(simStackAt(index118))) == rOopTop18) { - goto l57; - } - } - l57: ; - rOopTop18 = NoReg; - l56: ; - } - if (rOopTop18 == NoReg) { - rOopTop18 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rOopTop18 == NoReg))); - object16 = rOopTop18; - popToReg(ssTop(), object16); - ssPop(1); - abort(); - return 0; - - default: - return EncounteredUnknownBytecode; - - } - return 0; -} - - -/* Lowcode instruction generator dispatch */ - - /* StackToRegisterMappingCogit>>#genLowcodeNullaryInlinePrimitive: */ -static sqInt NoDbgRegParms -genLowcodeNullaryInlinePrimitive(sqInt prim) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction3; - AbstractInstruction * cont; - AbstractInstruction * cont1; - sqInt floatValue; - sqInt frTop; - sqInt frTop1; - sqInt i; - sqInt i1; - sqInt i2; - sqInt i3; - sqInt i4; - sqInt i5; - sqInt i6; - AbstractInstruction * inst; - AbstractInstruction * inst1; - sqInt object; - sqInt object1; - sqInt object2; - sqInt object3; - sqInt object4; - sqInt pointer; - sqInt pointer1; - sqInt pointerClassLiteral; - sqInt reg; - sqInt reg1; - sqInt reg2; - sqInt rNext; - sqInt rNext1; - sqInt rNext2; - sqInt rResult; - sqInt rResult2; - sqInt rResult3; - sqInt rResult4; - sqInt rResult5; - sqInt rTop; - sqInt rTop2; - sqInt rTop3; - sqInt rTop4; - sqInt rTop5; - sqInt rTop6; - sqInt rTop7; - sqInt rTop8; - sqInt rTop9; - sqInt singleFloatValue; - sqInt topRegistersMask; - sqInt topRegistersMask1; - sqInt topRegistersMask2; - AbstractInstruction * trueJump; - AbstractInstruction * trueJump1; - sqInt value; - sqInt value2; - sqInt value4; - sqInt value5; - sqInt valueHigh; - sqInt valueHigh1; - sqInt valueHigh2; - sqInt valueLow; - sqInt valueLow1; - sqInt valueLow2; - - switch (prim) { - case 0: - /* begin genLowcodeBoolean32ToOop */ - rTop = NoReg; - rResult = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop == NoReg) { - rTop = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult = allocateRegNotConflictingWith(1U << rTop); - assert(!(((rTop == NoReg) - || (rResult == NoReg)))); - value = rTop; - object = rResult; - nativePopToReg(ssNativeTop(), value); - ssNativePop(1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, value); - /* begin JumpNonZero: */ - trueJump = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - annotateobjRef(checkLiteralforInstruction(falseObject(), genoperandoperand(MoveCwR, falseObject(), value)), falseObject()); - /* begin Jump: */ - cont = genoperand(Jump, ((sqInt)0)); - /* begin checkLiteral:forInstruction: */ - trueObject(); - anInstruction1 = genoperandoperand(MoveCwR, trueObject(), value); - inst = anInstruction1; - jmpTarget(trueJump, inst); - annotateobjRef(inst, trueObject()); - jmpTarget(cont, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushRegister(value); - return 0; - - case 1: - /* begin genLowcodeBoolean64ToOop */ - /* begin allocateRegistersForLowcodeInteger2ResultOop: */ - topRegistersMask = 0; - rTop2 = (rNext = NoReg); - rResult2 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop2 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask = 1U << reg; - } - } - if (rTop2 == NoReg) { - rTop2 = allocateRegNotConflictingWith(topRegistersMask); - } - if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1U << rTop2); - } - assert(!(((rTop2 == NoReg) - || (rNext == NoReg)))); - rResult2 = allocateFloatRegNotConflictingWith((1U << rTop2) | (1U << rNext)); - assert(!((rResult2 == NoReg))); - valueLow = rTop2; - valueHigh = rNext; - object1 = rResult2; - nativePopToRegsecondReg(ssNativeTop(), valueLow, valueHigh); - ssNativePop(1); - /* begin OrR:R: */ - genoperandoperand(OrRR, valueLow, valueHigh); - /* begin JumpNonZero: */ - trueJump1 = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - annotateobjRef(checkLiteralforInstruction(falseObject(), genoperandoperand(MoveCwR, falseObject(), valueLow)), falseObject()); - /* begin Jump: */ - cont1 = genoperand(Jump, ((sqInt)0)); - /* begin checkLiteral:forInstruction: */ - trueObject(); - anInstruction3 = genoperandoperand(MoveCwR, trueObject(), valueLow); - inst1 = anInstruction3; - jmpTarget(trueJump1, inst1); - annotateobjRef(inst1, trueObject()); - jmpTarget(cont1, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushRegister(valueLow); - return 0; - - case 2: - /* begin genLowcodeFloat32ToOop */ - frTop = NoReg; - - /* Float argument */ - rResult3 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop = nativeFloatRegisterOrNone(ssNativeTop()); - } - if (frTop == NoReg) { - frTop = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult3 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!(((frTop == NoReg) - || (rResult3 == NoReg)))); - singleFloatValue = frTop; - object2 = rResult3; - nativePopToReg(ssNativeTop(), singleFloatValue); - ssNativePop(1); - /* begin ssFlushAll */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - voidReceiverResultRegContainsSelf(); - genLcFloat32toOop(singleFloatValue, object2); - return 0; - - case 3: - /* begin genLowcodeFloat64ToOop */ - frTop1 = NoReg; - - /* Float argument */ - rResult4 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop1 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if (frTop1 == NoReg) { - frTop1 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult4 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!(((frTop1 == NoReg) - || (rResult4 == NoReg)))); - floatValue = frTop1; - object3 = rResult4; - nativePopToReg(ssNativeTop(), floatValue); - ssNativePop(1); - /* begin ssFlushAll */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i1 <= simStackPtr; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - voidReceiverResultRegContainsSelf(); - genLcFloat64toOop(floatValue, object3); - return 0; - - case 4: - /* begin genLowcodeInt32ToOop */ - rTop3 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop3 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop3 == NoReg) { - rTop3 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rTop3 == NoReg))); - value2 = rTop3; - nativePopToReg(ssNativeTop(), value2); - ssNativePop(1); - /* begin ssFlushAll */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i2 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i2 <= simStackPtr; i2 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i2), frameOffsetOfTemporary(i2 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - voidReceiverResultRegContainsSelf(); - genLcInt32ToOop(value2); - return 0; - - case 5: - /* begin genLowcodeInt64ToOop */ - /* begin allocateRegistersForLowcodeInteger2: */ - topRegistersMask1 = 0; - rTop4 = (rNext1 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop4 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext1 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext1 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg1 = (rNext1 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask1 = 1U << reg1; - } - } - if (rTop4 == NoReg) { - rTop4 = allocateRegNotConflictingWith(topRegistersMask1); - } - if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop4); - } - assert(!(((rTop4 == NoReg) - || (rNext1 == NoReg)))); - valueLow1 = rTop4; - valueHigh1 = rNext1; - nativePopToRegsecondReg(ssNativeTop(), valueLow1, valueHigh1); - ssNativePop(1); - /* begin ssFlushAll */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i3 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i3 <= simStackPtr; i3 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i3), frameOffsetOfTemporary(i3 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - voidReceiverResultRegContainsSelf(); - genLcInt64ToOophighPart(valueLow1, valueHigh1); - return 0; - - case 6: - /* begin genLowcodePointerToOop */ - pointerClassLiteral = getLiteral(extA); - /* begin allocateRegistersForLowcodeInteger: */ - rTop7 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop7 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop7 == NoReg) { - rTop7 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rTop7 == NoReg))); - pointer1 = rTop7; - nativePopToReg(ssNativeTop(), pointer1); - ssNativePop(1); - /* begin ssFlushAll */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i4 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i4 <= simStackPtr; i4 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i4), frameOffsetOfTemporary(i4 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - voidReceiverResultRegContainsSelf(); - genLcPointerToOopclass(pointer1, pointerClassLiteral); - extA = 0; - return 0; - - case 7: - /* begin genLowcodePointerToOopReinterprer */ - rTop5 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop5 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop5 == NoReg) { - rTop5 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rTop5 == NoReg))); - pointer = rTop5; - nativePopToReg(ssNativeTop(), pointer); - ssNativePop(1); - ssPushRegister(pointer); - return 0; - - case 8: - /* begin genLowcodeSmallInt32ToOop */ - rTop6 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop6 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop6 == NoReg) { - rTop6 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rTop6 == NoReg))); - value4 = rTop6; - nativePopToReg(ssNativeTop(), value4); - ssNativePop(1); - genConvertIntegerToSmallIntegerInReg(value4); - ssPushRegister(value4); - return 0; - - case 9: - /* begin genLowcodeUint32ToOop */ - rTop8 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop8 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop8 == NoReg) { - rTop8 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rTop8 == NoReg))); - value5 = rTop8; - nativePopToReg(ssNativeTop(), value5); - ssNativePop(1); - /* begin ssFlushAll */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i5 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i5 <= simStackPtr; i5 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i5), frameOffsetOfTemporary(i5 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - voidReceiverResultRegContainsSelf(); - genLcUInt32ToOop(value5); - return 0; - - case 10: - /* begin genLowcodeUint64ToOop */ - /* begin allocateRegistersForLowcodeInteger2ResultOop: */ - topRegistersMask2 = 0; - rTop9 = (rNext2 = NoReg); - rResult5 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop9 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext2 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext2 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg2 = (rNext2 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask2 = 1U << reg2; - } - } - if (rTop9 == NoReg) { - rTop9 = allocateRegNotConflictingWith(topRegistersMask2); - } - if (rNext2 == NoReg) { - rNext2 = allocateRegNotConflictingWith(1U << rTop9); - } - assert(!(((rTop9 == NoReg) - || (rNext2 == NoReg)))); - rResult5 = allocateFloatRegNotConflictingWith((1U << rTop9) | (1U << rNext2)); - assert(!((rResult5 == NoReg))); - valueLow2 = rTop9; - valueHigh2 = rNext2; - object4 = rResult5; - nativePopToRegsecondReg(ssNativeTop(), valueLow2, valueHigh2); - ssNativePop(1); - /* begin ssFlushAll */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i6 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i6 <= simStackPtr; i6 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i6), frameOffsetOfTemporary(i6 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - voidReceiverResultRegContainsSelf(); - genLcUInt64ToOophighPart(valueLow2, valueHigh2); - return 0; - - default: - return EncounteredUnknownBytecode; - - } - return 0; -} - - -/* Lowcode instruction generator dispatch */ - - /* StackToRegisterMappingCogit>>#genLowcodeTrinaryInlinePrimitive: */ -static sqInt NoDbgRegParms -genLowcodeTrinaryInlinePrimitive(sqInt prim) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction * contJump; - AbstractInstruction * contJump1; - AbstractInstruction * falseJump; - AbstractInstruction * falseJump1; - sqInt fieldIndex; - sqInt fieldIndex1; - sqInt first; - sqInt first1; - sqInt i1; - sqInt i11; - sqInt i12; - sqInt index1; - sqInt index11; - sqInt index12; - sqInt object; - sqInt object1; - sqInt oopTopRegisterMask; - sqInt oopTopRegisterMask1; - sqInt oopTopRegisterMask2; - sqInt oopTopRegisterMask3; - sqInt rOopNext; - sqInt rOopNext1; - sqInt rOopNext2; - sqInt rOopNext3; - sqInt rOopTop; - sqInt rOopTop1; - sqInt rOopTop2; - sqInt rOopTop3; - sqInt rResult; - sqInt rTop; - sqInt second; - sqInt second1; - sqInt topRegisterMask; - sqInt value; - sqInt value1; - sqInt value2; - - switch (prim) { - case 0: - /* begin genLowcodeOopEqual */ - rOopTop = (rOopNext = NoReg); - rResult = NoReg; - oopTopRegisterMask = 0; - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop = registerOrNone(ssTop()); - index1 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i1 = index1; i1 <= (simStackPtr); i1 += 1) { - if ((registerOrNone(simStackAt(index1))) == rOopTop) { - goto l3; - } - } - l3: ; - rOopTop = NoReg; - l2: ; - } - if ((registerOrNone(ssValue(1))) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopNext = registerOrNone(ssValue(1)); - index1 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i1 = index1; i1 < simStackPtr; i1 += 1) { - if ((registerOrNone(simStackAt(index1))) == rOopNext) { - goto l5; - } - } - l5: ; - rOopNext = NoReg; - l4: ; - if (rOopNext != NoReg) { - /* begin registerMaskFor: */ - oopTopRegisterMask = 1U << rOopNext; - } - } - if (rOopTop == NoReg) { - rOopTop = allocateRegNotConflictingWith(oopTopRegisterMask); - } - if (rOopNext == NoReg) { - rOopNext = allocateRegNotConflictingWith(1U << rOopTop); - } - rResult = allocateRegNotConflictingWith((1U << rOopTop) | (1U << rOopNext)); - assert(!(((rOopTop == NoReg) - || ((rOopNext == NoReg) - || (rResult == NoReg))))); - second = rOopTop; - first = rOopNext; - value = rResult; - popToReg(ssTop(), second); - ssPop(1); - popToReg(ssTop(), first); - ssPop(1); - /* begin CmpR:R: */ - assert(!((second == SPReg))); - genoperandoperand(CmpRR, second, first); - /* begin JumpNonZero: */ - falseJump = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 1, first); - /* begin Jump: */ - contJump = genoperand(Jump, ((sqInt)0)); - jmpTarget(falseJump, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, 0, first); - jmpTarget(contJump, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(first); - return 0; - - case 1: - /* begin genLowcodeOopNotEqual */ - rOopTop1 = (rOopNext1 = NoReg); - oopTopRegisterMask1 = 0; - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop1 = registerOrNone(ssTop()); - index11 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i11 = index11; i11 <= (simStackPtr); i11 += 1) { - if ((registerOrNone(simStackAt(index11))) == rOopTop1) { - goto l14; - } - } - l14: ; - rOopTop1 = NoReg; - l11: ; - } - if ((registerOrNone(ssValue(1))) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopNext1 = registerOrNone(ssValue(1)); - index11 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i11 = index11; i11 < simStackPtr; i11 += 1) { - if ((registerOrNone(simStackAt(index11))) == rOopNext1) { - goto l12; - } - } - l12: ; - rOopNext1 = NoReg; - l18: ; - if (rOopNext1 != NoReg) { - /* begin registerMaskFor: */ - oopTopRegisterMask1 = 1U << rOopNext1; - } - } - if (rOopTop1 == NoReg) { - rOopTop1 = allocateRegNotConflictingWith(oopTopRegisterMask1); - } - if (rOopNext1 == NoReg) { - rOopNext1 = allocateRegNotConflictingWith(1U << rOopTop1); - } - assert(!(((rOopTop1 == NoReg) - || (rOopNext1 == NoReg)))); - second1 = rOopTop1; - first1 = rOopNext1; - popToReg(ssTop(), second1); - ssPop(1); - popToReg(ssTop(), first1); - ssPop(1); - /* begin CmpR:R: */ - assert(!((second1 == SPReg))); - genoperandoperand(CmpRR, second1, first1); - /* begin JumpZero: */ - falseJump1 = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, 1, first1); - /* begin Jump: */ - contJump1 = genoperand(Jump, ((sqInt)0)); - jmpTarget(falseJump1, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(MoveCqR, 0, first1); - jmpTarget(contJump1, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(first1); - return 0; - - case 2: - /* begin genLowcodeStoreObjectField */ - fieldIndex = extA; - /* begin allocateRegistersForLowcodeOop2: */ - rOopTop2 = (rOopNext2 = NoReg); - oopTopRegisterMask2 = 0; - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop2 = registerOrNone(ssTop()); - index12 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i12 = index12; i12 <= (simStackPtr); i12 += 1) { - if ((registerOrNone(simStackAt(index12))) == rOopTop2) { - goto l20; - } - } - l20: ; - rOopTop2 = NoReg; - l24: ; - } - if ((registerOrNone(ssValue(1))) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopNext2 = registerOrNone(ssValue(1)); - index12 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i12 = index12; i12 < simStackPtr; i12 += 1) { - if ((registerOrNone(simStackAt(index12))) == rOopNext2) { - goto l19; - } - } - l19: ; - rOopNext2 = NoReg; - l23: ; - if (rOopNext2 != NoReg) { - /* begin registerMaskFor: */ - oopTopRegisterMask2 = 1U << rOopNext2; - } - } - if (rOopTop2 == NoReg) { - rOopTop2 = allocateRegNotConflictingWith(oopTopRegisterMask2); - } - if (rOopNext2 == NoReg) { - rOopNext2 = allocateRegNotConflictingWith(1U << rOopTop2); - } - assert(!(((rOopTop2 == NoReg) - || (rOopNext2 == NoReg)))); - value1 = rOopTop2; - object = rOopNext2; - popToReg(ssTop(), value1); - ssPop(1); - popToReg(ssTop(), object); - ssPop(1); - genLcStoreobjectfield(value1, object, fieldIndex); - extA = 0; - return 0; - - case 3: - /* begin genLowcodeStoreObjectFieldAt */ - rTop = (rOopTop3 = (rOopNext3 = NoReg)); - oopTopRegisterMask3 = (topRegisterMask = 0); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop = nativeRegisterOrNone(ssNativeTop()); - /* begin registerMaskFor: */ - oopTopRegisterMask3 = 1U << rTop; - } - if ((registerOrNone(ssTop())) != NoReg) { - rOopTop3 = registerOrNone(ssTop()); - /* begin registerMaskFor: */ - topRegisterMask = 1U << rOopTop3; - } - if ((registerOrNone(ssValue(1))) != NoReg) { - rOopNext3 = registerOrNone(ssValue(1)); - topRegisterMask = topRegisterMask | (1U << rOopNext3); - oopTopRegisterMask3 = oopTopRegisterMask3 | (1U << rOopNext3); - } - if (rTop == NoReg) { - rTop = allocateRegNotConflictingWith(topRegisterMask); - } - if (rOopTop3 == NoReg) { - rOopTop3 = allocateRegNotConflictingWith(oopTopRegisterMask3); - } - if (rOopNext3 == NoReg) { - rOopNext3 = allocateRegNotConflictingWith((1U << rTop) | (1U << rOopTop3)); - } - assert(!(((rTop == NoReg) - || ((rOopTop3 == NoReg) - || (rOopNext3 == NoReg))))); - fieldIndex1 = rTop; - value2 = rOopTop3; - object1 = rOopNext3; - popToReg(ssTop(), value2); - ssPop(1); - nativePopToReg(ssNativeTop(), fieldIndex1); - ssNativePop(1); - popToReg(ssTop(), object1); - ssPop(1); - genLcStoreobjectat(value2, object1, fieldIndex1); - return 0; - - default: - return EncounteredUnknownBytecode; - - } - return 0; -} - - -/* Lowcode instruction generator dispatch */ - - /* StackToRegisterMappingCogit>>#genLowcodeUnaryInlinePrimitive2: */ -static sqInt NoDbgRegParms -genLowcodeUnaryInlinePrimitive2(sqInt prim) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction110; - AbstractInstruction *anInstruction111; - AbstractInstruction *anInstruction112; - AbstractInstruction *anInstruction113; - AbstractInstruction *anInstruction114; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction24; - AbstractInstruction *anInstruction25; - AbstractInstruction *anInstruction26; - AbstractInstruction *anInstruction27; - AbstractInstruction *anInstruction28; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction30; - AbstractInstruction *anInstruction33; - AbstractInstruction *anInstruction34; - AbstractInstruction *anInstruction35; - AbstractInstruction *anInstruction36; - AbstractInstruction *anInstruction37; - AbstractInstruction *anInstruction38; - AbstractInstruction *anInstruction39; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction40; - AbstractInstruction *anInstruction41; - AbstractInstruction *anInstruction42; - AbstractInstruction *anInstruction43; - AbstractInstruction *anInstruction44; - AbstractInstruction *anInstruction45; - AbstractInstruction *anInstruction46; - AbstractInstruction *anInstruction47; - AbstractInstruction *anInstruction48; - AbstractInstruction *anInstruction49; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt baseOffset; - sqInt baseOffset1; - sqInt baseOffset10; - sqInt baseOffset11; - sqInt baseOffset12; - sqInt baseOffset13; - sqInt baseOffset14; - sqInt baseOffset15; - sqInt baseOffset16; - sqInt baseOffset17; - sqInt baseOffset18; - sqInt baseOffset19; - sqInt baseOffset2; - sqInt baseOffset20; - sqInt baseOffset21; - sqInt baseOffset22; - sqInt baseOffset23; - sqInt baseOffset3; - sqInt baseOffset4; - sqInt baseOffset5; - sqInt baseOffset6; - sqInt baseOffset7; - sqInt baseOffset8; - sqInt baseOffset9; - sqInt classOop; - sqInt classOop1; - sqInt classOop2; - AbstractInstruction * contJump; - AbstractInstruction * contJump1; - AbstractInstruction * contJump2; - AbstractInstruction * contJump3; - AbstractInstruction * contJump4; - AbstractInstruction * contJump5; - AbstractInstruction * contJump6; - AbstractInstruction * contJump7; - sqInt doubleValue; - sqInt doubleValue1; - AbstractInstruction * falseJump; - AbstractInstruction * falseJump1; - AbstractInstruction * falseJump2; - AbstractInstruction * falseJump21; - AbstractInstruction * falseJump22; - AbstractInstruction * falseJump3; - AbstractInstruction * falseJump4; - AbstractInstruction * falseJump5; - AbstractInstruction * falseJump6; - AbstractInstruction * falseJump7; - AbstractInstruction * falseLabel; - AbstractInstruction * falseLabel1; - sqInt fieldIndex; - AbstractInstruction * first; - AbstractInstruction * first1; - sqInt first11; - sqInt first12; - sqInt first13; - sqInt first14; - AbstractInstruction * first16; - AbstractInstruction * first17; - AbstractInstruction * first2; - AbstractInstruction * first3; - sqInt first4; - sqInt first5; - sqInt first6; - sqInt first7; - sqInt first8; - sqInt firstHigh; - sqInt firstHigh5; - sqInt firstLow; - sqInt firstLow5; - sqInt first9; - sqInt floatValue; - sqInt floatValue1; - sqInt floatValue2; - sqInt floatValue3; - sqInt floatValue4; - sqInt floatValue5; - sqInt floatValue6; - sqInt frResult; - sqInt frResult1; - sqInt frResult2; - sqInt frResult3; - sqInt frResult4; - sqInt frResult5; - sqInt frResult6; - sqInt frResult7; - sqInt frResult8; - sqInt frResult9; - sqInt frTop; - sqInt frTop1; - sqInt frTop2; - sqInt frTop3; - sqInt frTop4; - sqInt i; - sqInt i1; - sqInt i11; - sqInt i12; - sqInt i2; - sqInt i21; - sqInt index1; - sqInt index11; - sqInt indexableSize; - sqInt indexableSize1; - sqInt int32Result; - sqInt int64Result; - sqInt int64Result1; - sqInt int64Result2; - sqInt nativeValueIndex; - sqInt nativeValueIndex1; - sqInt nextRegisterMask; - sqInt nextRegisterMask1; - sqInt object; - sqInt object1; - sqInt object2; - sqInt pointer; - sqInt pointer1; - sqInt pointer2; - sqInt pointer3; - sqInt pointer4; - sqInt pointer5; - sqInt pointer6; - sqInt pointer7; - sqInt pointer8; - sqInt pointerResult; - sqInt pointerResult1; - sqInt reg; - sqInt reg1; - sqInt reg10; - sqInt reg12; - sqInt reg13; - sqInt reg14; - sqInt reg2; - sqInt reg3; - sqInt reg4; - sqInt reg5; - sqInt reg7; - sqInt reg8; - sqInt reg9; - sqInt result; - sqInt result1; - sqInt result2; - sqInt result3; - sqInt result4; - sqInt rNext; - sqInt rNext1; - sqInt rNext10; - sqInt rNext12; - sqInt rNext14; - sqInt rNext15; - sqInt rNext16; - sqInt rNext2; - sqInt rNext3; - sqInt rNext4; - sqInt rNext5; - sqInt rNext6; - sqInt rNext7; - sqInt rNext8; - sqInt rNextNext; - sqInt rNextNext1; - sqInt rNextNextNext; - sqInt rNextNextNext1; - sqInt rNext9; - sqInt rOopResult; - sqInt rOopTop; - sqInt rOopTop1; - sqInt rOopTop2; - sqInt rOopTop3; - sqInt rResult; - sqInt rResult1; - sqInt rResult10; - sqInt rResult11; - sqInt rResult12; - sqInt rResult13; - sqInt rResult14; - sqInt rResult15; - sqInt rResult16; - sqInt rResult17; - sqInt rResult18; - sqInt rResult19; - sqInt rResult2; - sqInt rResult20; - sqInt rResult21; - sqInt rResult210; - sqInt rResult211; - sqInt rResult212; - sqInt rResult22; - sqInt rResult23; - sqInt rResult24; - sqInt rResult25; - sqInt rResult26; - sqInt rResult27; - sqInt rResult28; - sqInt rResult29; - sqInt rResult3; - sqInt rResult30; - sqInt rResult31; - sqInt rResult32; - sqInt rResult33; - sqInt rResult34; - sqInt rResult35; - sqInt rResult4; - sqInt rResult5; - sqInt rResult6; - sqInt rResult7; - sqInt rResult8; - sqInt rResult9; - sqInt rTop; - sqInt rTop1; - sqInt rTop10; - sqInt rTop12; - sqInt rTop13; - sqInt rTop14; - sqInt rTop15; - sqInt rTop17; - sqInt rTop18; - sqInt rTop2; - sqInt rTop20; - sqInt rTop21; - sqInt rTop22; - sqInt rTop23; - sqInt rTop24; - sqInt rTop25; - sqInt rTop26; - sqInt rTop27; - sqInt rTop28; - sqInt rTop29; - sqInt rTop3; - sqInt rTop30; - sqInt rTop31; - sqInt rTop4; - sqInt rTop5; - sqInt rTop6; - sqInt rTop7; - sqInt rTop8; - sqInt rTop9; - sqInt second; - sqInt second1; - sqInt second10; - sqInt second2; - sqInt second3; - sqInt second4; - sqInt second5; - sqInt second7; - sqInt second8; - sqInt secondHigh; - sqInt secondHigh5; - sqInt secondLow; - sqInt secondLow5; - sqInt second9; - sqInt shiftAmount; - sqInt shiftAmount1; - sqInt topRegisterMask; - sqInt topRegisterMask1; - sqInt topRegistersMask; - sqInt topRegistersMask1; - sqInt topRegistersMask10; - sqInt topRegistersMask11; - sqInt topRegistersMask13; - sqInt topRegistersMask14; - sqInt topRegistersMask15; - sqInt topRegistersMask2; - sqInt topRegistersMask3; - sqInt topRegistersMask4; - sqInt topRegistersMask5; - sqInt topRegistersMask6; - sqInt topRegistersMask8; - sqInt topRegistersMask9; - sqInt value; - sqInt value1; - sqInt value10; - sqInt value11; - sqInt value12; - sqInt value13; - sqInt value14; - sqInt value15; - sqInt value16; - sqInt value17; - sqInt value18; - sqInt value19; - sqInt value2; - sqInt value20; - sqInt value22; - sqInt value23; - sqInt value26; - sqInt value27; - sqInt value28; - sqInt value29; - sqInt value3; - sqInt value31; - sqInt value4; - sqInt value5; - sqInt value6; - sqInt value7; - sqInt value8; - sqInt valueHigh2; - sqInt valueHigh4; - sqInt valueHigh5; - sqInt valueHigh6; - sqInt valueHigh7; - sqInt valueHigh8; - sqInt valueLow2; - sqInt valueLow4; - sqInt valueLow5; - sqInt valueLow6; - sqInt valueLow7; - sqInt valueLow8; - sqInt value9; - - switch (prim) { - case 60: - /* begin genLowcodeFloat64ToFloat32 */ - topRegistersMask = 0; - frTop = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop = nativeFloatRegisterOrNone(ssNativeTop()); - } - if (frTop == NoReg) { - frTop = allocateFloatRegNotConflictingWith(topRegistersMask); - } - assert(!((frTop == NoReg))); - floatValue2 = frTop; - nativePopToReg(ssNativeTop(), floatValue2); - ssNativePop(1); - /* begin ConvertRd:Rs: */ - genoperandoperand(ConvertRdRs, floatValue2, floatValue2); - ssPushNativeRegisterSingleFloat(floatValue2); - return 0; - - case 61: - /* begin genLowcodeFloat64ToInt32 */ - frTop1 = NoReg; - - /* Float argument */ - rResult16 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop1 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if (frTop1 == NoReg) { - frTop1 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult16 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!(((frTop1 == NoReg) - || (rResult16 == NoReg)))); - floatValue3 = frTop1; - int32Result = rResult16; - nativePopToReg(ssNativeTop(), floatValue3); - ssNativePop(1); - /* begin ConvertRd:R: */ - genoperandoperand(ConvertRdR, floatValue3, int32Result); - ssPushNativeRegister(int32Result); - return 0; - - case 0x3E: - /* begin genLowcodeFloat64ToInt64 */ - frTop2 = NoReg; - - /* Float argument */ - rResult17 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop2 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if (frTop2 == NoReg) { - frTop2 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult17 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!(((frTop2 == NoReg) - || (rResult17 == NoReg)))); - floatValue4 = frTop2; - int64Result = rResult17; - nativePopToReg(ssNativeTop(), floatValue4); - ssNativePop(1); - abort(); - return 0; - - case 0x3F: - /* begin genLowcodeFloat64ToUInt32 */ - frTop3 = NoReg; - - /* Float argument */ - rResult18 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop3 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if (frTop3 == NoReg) { - frTop3 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult18 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!(((frTop3 == NoReg) - || (rResult18 == NoReg)))); - floatValue5 = frTop3; - int64Result1 = rResult18; - nativePopToReg(ssNativeTop(), floatValue5); - ssNativePop(1); - /* begin ConvertRd:R: */ - genoperandoperand(ConvertRdR, floatValue5, int64Result1); - ssPushNativeRegister(int64Result1); - return 0; - - case 64: - /* begin genLowcodeFloat64ToUInt64 */ - frTop4 = NoReg; - - /* Float argument */ - rResult19 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop4 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if (frTop4 == NoReg) { - frTop4 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult19 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!(((frTop4 == NoReg) - || (rResult19 == NoReg)))); - floatValue6 = frTop4; - int64Result2 = rResult19; - nativePopToReg(ssNativeTop(), floatValue6); - ssNativePop(1); - abort(); - return 0; - - case 65: - /* begin genLowcodeFree */ - rTop30 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop30 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop30 == NoReg) { - rTop30 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rTop30 == NoReg))); - pointer8 = rTop30; - nativePopToReg(ssNativeTop(), pointer8); - ssNativePop(1); - /* begin ssFlushAll */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - voidReceiverResultRegContainsSelf(); - if (pointer8 != ReceiverResultReg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, pointer8, ReceiverResultReg); - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceFreeTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - return 0; - - case 66: - /* begin genLowcodeInstantiateIndexable32Oop */ - rTop31 = (rOopTop1 = NoReg); - rOopResult = NoReg; - topRegisterMask1 = 0; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop31 = nativeRegisterOrNone(ssNativeTop()); - } - if ((registerOrNone(ssTop())) != NoReg) { - rOopTop1 = registerOrNone(ssTop()); - /* begin registerMaskFor: */ - topRegisterMask1 = 1U << rOopTop1; - } - if (rTop31 == NoReg) { - rTop31 = allocateRegNotConflictingWith(topRegisterMask1); - } - if (rOopTop1 == NoReg) { - rOopTop1 = allocateRegNotConflictingWith(1U << rTop31); - } - rOopResult = allocateRegNotConflictingWith((1U << rTop31) | (1U << rOopTop1)); - assert(!(((rTop31 == NoReg) - || ((rOopTop1 == NoReg) - || (rOopResult == NoReg))))); - indexableSize = rTop31; - classOop = rOopTop1; - object1 = rOopResult; - nativePopToReg(ssNativeTop(), indexableSize); - ssNativePop(1); - popToReg(ssTop(), classOop); - ssPop(1); - /* begin ssFlushAll */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i1 <= simStackPtr; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - voidReceiverResultRegContainsSelf(); - genLcInstantiateOopindexableSize(classOop, indexableSize); - return 0; - - case 67: - /* begin genLowcodeInstantiateIndexableOop */ - indexableSize1 = extA; - /* begin allocateRegistersForLowcodeOopResultOop: */ - rOopTop2 = NoReg; - rResult35 = NoReg; - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop2 = registerOrNone(ssTop()); - index1 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i11 = index1; i11 <= (simStackPtr); i11 += 1) { - if ((registerOrNone(simStackAt(index1))) == rOopTop2) { - goto l224; - } - } - l224: ; - rOopTop2 = NoReg; - l223: ; - } - if (rOopTop2 == NoReg) { - rOopTop2 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult35 = allocateRegNotConflictingWith(1U << rOopTop2); - assert(!(((rOopTop2 == NoReg) - || (rResult35 == NoReg)))); - classOop1 = rOopTop2; - object2 = rResult35; - popToReg(ssTop(), classOop1); - ssPop(1); - /* begin ssFlushAll */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i2 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i2 <= simStackPtr; i2 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i2), frameOffsetOfTemporary(i2 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - voidReceiverResultRegContainsSelf(); - genLcInstantiateOopconstantIndexableSize(classOop1, indexableSize1); - extA = 0; - return 0; - - case 68: - /* begin genLowcodeInstantiateOop */ - rOopTop3 = NoReg; - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop3 = registerOrNone(ssTop()); - index11 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i12 = index11; i12 <= (simStackPtr); i12 += 1) { - if ((registerOrNone(simStackAt(index11))) == rOopTop3) { - goto l227; - } - } - l227: ; - rOopTop3 = NoReg; - l226: ; - } - if (rOopTop3 == NoReg) { - rOopTop3 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rOopTop3 == NoReg))); - classOop2 = rOopTop3; - popToReg(ssTop(), classOop2); - ssPop(1); - /* begin ssFlushAll */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i21 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i21 <= simStackPtr; i21 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i21), frameOffsetOfTemporary(i21 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - voidReceiverResultRegContainsSelf(); - genLcInstantiateOop(classOop2); - return 0; - - case 69: - /* begin genLowcodeInt32Equal */ - topRegistersMask1 = 0; - rTop = (rNext = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask1 = 1U << reg; - } - } - if (rTop == NoReg) { - rTop = allocateRegNotConflictingWith(topRegistersMask1); - } - if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1U << rTop); - } - assert(!(((rTop == NoReg) - || (rNext == NoReg)))); - second = rTop; - first4 = rNext; - nativePopToReg(ssNativeTop(), second); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first4); - ssNativePop(1); - /* begin CmpR:R: */ - assert(!((second == SPReg))); - genoperandoperand(CmpRR, second, first4); - /* begin JumpNonZero: */ - falseJump = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 1, first4); - /* begin Jump: */ - contJump = genoperand(Jump, ((sqInt)0)); - jmpTarget(falseJump, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, 0, first4); - jmpTarget(contJump, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(first4); - return 0; - - case 70: - /* begin genLowcodeInt32Great */ - topRegistersMask2 = 0; - rTop1 = (rNext1 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop1 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext1 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext1 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg1 = (rNext1 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask2 = 1U << reg1; - } - } - if (rTop1 == NoReg) { - rTop1 = allocateRegNotConflictingWith(topRegistersMask2); - } - if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); - } - assert(!(((rTop1 == NoReg) - || (rNext1 == NoReg)))); - second1 = rTop1; - first5 = rNext1; - nativePopToReg(ssNativeTop(), second1); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first5); - ssNativePop(1); - /* begin CmpR:R: */ - assert(!((second1 == SPReg))); - genoperandoperand(CmpRR, second1, first5); - /* begin JumpLessOrEqual: */ - falseJump1 = genConditionalBranchoperand(JumpLessOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, 1, first5); - /* begin Jump: */ - contJump1 = genoperand(Jump, ((sqInt)0)); - jmpTarget(falseJump1, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperand(MoveCqR, 0, first5); - jmpTarget(contJump1, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(first5); - return 0; - - case 71: - /* begin genLowcodeInt32GreatEqual */ - topRegistersMask3 = 0; - rTop2 = (rNext2 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop2 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext2 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext2 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg2 = (rNext2 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask3 = 1U << reg2; - } - } - if (rTop2 == NoReg) { - rTop2 = allocateRegNotConflictingWith(topRegistersMask3); - } - if (rNext2 == NoReg) { - rNext2 = allocateRegNotConflictingWith(1U << rTop2); - } - assert(!(((rTop2 == NoReg) - || (rNext2 == NoReg)))); - second2 = rTop2; - first6 = rNext2; - nativePopToReg(ssNativeTop(), second2); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first6); - ssNativePop(1); - /* begin CmpR:R: */ - assert(!((second2 == SPReg))); - genoperandoperand(CmpRR, second2, first6); - /* begin JumpLess: */ - falseJump2 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(MoveCqR, 1, first6); - /* begin Jump: */ - contJump2 = genoperand(Jump, ((sqInt)0)); - jmpTarget(falseJump2, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperand(MoveCqR, 0, first6); - jmpTarget(contJump2, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(first6); - return 0; - - case 72: - /* begin genLowcodeInt32Less */ - topRegistersMask4 = 0; - rTop3 = (rNext3 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop3 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext3 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext3 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg3 = (rNext3 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask4 = 1U << reg3; - } - } - if (rTop3 == NoReg) { - rTop3 = allocateRegNotConflictingWith(topRegistersMask4); - } - if (rNext3 == NoReg) { - rNext3 = allocateRegNotConflictingWith(1U << rTop3); - } - assert(!(((rTop3 == NoReg) - || (rNext3 == NoReg)))); - second3 = rTop3; - first7 = rNext3; - nativePopToReg(ssNativeTop(), second3); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first7); - ssNativePop(1); - /* begin CmpR:R: */ - assert(!((second3 == SPReg))); - genoperandoperand(CmpRR, second3, first7); - /* begin JumpGreaterOrEqual: */ - falseJump3 = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(MoveCqR, 1, first7); - /* begin Jump: */ - contJump3 = genoperand(Jump, ((sqInt)0)); - jmpTarget(falseJump3, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperand(MoveCqR, 0, first7); - jmpTarget(contJump3, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(first7); - return 0; - - case 73: - /* begin genLowcodeInt32LessEqual */ - topRegistersMask5 = 0; - rTop4 = (rNext4 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop4 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext4 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext4 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg4 = (rNext4 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask5 = 1U << reg4; - } - } - if (rTop4 == NoReg) { - rTop4 = allocateRegNotConflictingWith(topRegistersMask5); - } - if (rNext4 == NoReg) { - rNext4 = allocateRegNotConflictingWith(1U << rTop4); - } - assert(!(((rTop4 == NoReg) - || (rNext4 == NoReg)))); - second4 = rTop4; - first8 = rNext4; - nativePopToReg(ssNativeTop(), second4); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first8); - ssNativePop(1); - /* begin CmpR:R: */ - assert(!((second4 == SPReg))); - genoperandoperand(CmpRR, second4, first8); - /* begin JumpGreater: */ - falseJump4 = genConditionalBranchoperand(JumpGreater, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(MoveCqR, 1, first8); - /* begin Jump: */ - contJump4 = genoperand(Jump, ((sqInt)0)); - jmpTarget(falseJump4, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(MoveCqR, 0, first8); - jmpTarget(contJump4, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(first8); - return 0; - - case 74: - /* begin genLowcodeInt32NotEqual */ - topRegistersMask6 = 0; - rTop5 = (rNext5 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop5 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext5 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext5 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg5 = (rNext5 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask6 = 1U << reg5; - } - } - if (rTop5 == NoReg) { - rTop5 = allocateRegNotConflictingWith(topRegistersMask6); - } - if (rNext5 == NoReg) { - rNext5 = allocateRegNotConflictingWith(1U << rTop5); - } - assert(!(((rTop5 == NoReg) - || (rNext5 == NoReg)))); - second5 = rTop5; - first9 = rNext5; - nativePopToReg(ssNativeTop(), second5); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first9); - ssNativePop(1); - /* begin CmpR:R: */ - assert(!((second5 == SPReg))); - genoperandoperand(CmpRR, second5, first9); - /* begin JumpZero: */ - falseJump5 = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(MoveCqR, 1, first9); - /* begin Jump: */ - contJump5 = genoperand(Jump, ((sqInt)0)); - jmpTarget(falseJump5, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperand(MoveCqR, 0, first9); - jmpTarget(contJump5, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(first9); - return 0; - - case 75: - /* begin genLowcodeInt32ToFloat32 */ - rTop6 = NoReg; - frResult4 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop6 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop6 == NoReg) { - rTop6 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - frResult4 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!(((rTop6 == NoReg) - || (frResult4 == NoReg)))); - value12 = rTop6; - result = frResult4; - nativePopToReg(ssNativeTop(), value12); - ssNativePop(1); - /* begin ConvertR:Rs: */ - genoperandoperand(ConvertRRs, value12, result); - ssPushNativeRegisterSingleFloat(result); - return 0; - - case 76: - /* begin genLowcodeInt32ToFloat64 */ - rTop7 = NoReg; - frResult5 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop7 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop7 == NoReg) { - rTop7 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - frResult5 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!(((rTop7 == NoReg) - || (frResult5 == NoReg)))); - value13 = rTop7; - result1 = frResult5; - nativePopToReg(ssNativeTop(), value13); - ssNativePop(1); - /* begin ConvertR:Rd: */ - genoperandoperand(ConvertRRd, value13, result1); - ssPushNativeRegisterDoubleFloat(result1); - return 0; - - case 77: - /* begin genLowcodeInt32ToPointer */ - rTop8 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop8 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop8 == NoReg) { - rTop8 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rTop8 == NoReg))); - value14 = rTop8; - nativePopToReg(ssNativeTop(), value14); - ssNativePop(1); - ssPushNativeRegister(value14); - return 0; - - case 78: - /* begin genLowcodeInt64Equal */ - /* begin allocateRegistersForLowcodeInteger4: */ - rTop9 = (rNext6 = (rNextNext = (rNextNextNext = NoReg))); - nativeValueIndex = 1; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop9 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext6 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext6 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex))) != NoReg) { - rNext6 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex)); - if ((nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex))) != NoReg) { - rNextNext = nativeRegisterOrNone(ssNativeValue(nativeValueIndex)); - } - nativeValueIndex += 1; - } - } - if (rNextNext == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex))) != NoReg) { - rNextNext = nativeRegisterOrNone(ssNativeValue(nativeValueIndex)); - if ((nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex))) != NoReg) { - rNextNextNext = nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex)); - } - nativeValueIndex += 1; - } - } - if (rNextNextNext == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex))) != NoReg) { - rNextNextNext = nativeRegisterOrNone(ssNativeValue(nativeValueIndex)); - nativeValueIndex += 1; - } - } - if (rTop9 == NoReg) { - nextRegisterMask = 0; - if (rNext6 != NoReg) { - /* begin registerMaskFor: */ - nextRegisterMask = 1U << rNext6; - } - if (rNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNext); - } - if (rNextNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNextNext); - } - rTop9 = allocateRegNotConflictingWith(nextRegisterMask); - } - if (rNext6 == NoReg) { - /* begin registerMaskFor: */ - nextRegisterMask = 1U << rTop9; - if (rNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNext); - } - if (rNextNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNextNext); - } - rNext6 = allocateRegNotConflictingWith(nextRegisterMask); - } - if (rNextNext == NoReg) { - /* begin registerMaskFor:and: */ - nextRegisterMask = (1U << rTop9) | (1U << rNext6); - if (rNextNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNextNext); - } - rNextNext = allocateRegNotConflictingWith(nextRegisterMask); - } - if (rNextNextNext == NoReg) { - /* begin registerMaskFor:and:and: */ - nextRegisterMask = ((1U << rTop9) | (1U << rNext6)) | (1U << rNextNext); - rNextNextNext = allocateRegNotConflictingWith(nextRegisterMask); - } - assert(!(((rTop9 == NoReg) - || ((rNext6 == NoReg) - || ((rNextNext == NoReg) - || (rNextNextNext == NoReg)))))); - secondLow = rTop9; - secondHigh = rNext6; - firstLow = rNextNext; - firstHigh = rNextNextNext; - nativePopToRegsecondReg(ssNativeTop(), secondLow, secondHigh); - ssNativePop(1); - nativePopToRegsecondReg(ssNativeTop(), firstLow, firstHigh); - ssNativePop(1); - /* begin CmpR:R: */ - assert(!((secondHigh == SPReg))); - genoperandoperand(CmpRR, secondHigh, firstHigh); - /* begin JumpNonZero: */ - falseJump6 = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((secondLow == SPReg))); - genoperandoperand(CmpRR, secondLow, firstLow); - /* begin JumpNonZero: */ - falseJump21 = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(MoveCqR, 1, firstLow); - /* begin Jump: */ - contJump6 = genoperand(Jump, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction16 = genoperandoperand(MoveCqR, 0, firstLow); - falseLabel = anInstruction16; - jmpTarget(falseJump6, falseLabel); - jmpTarget(falseJump21, falseLabel); - jmpTarget(contJump6, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(firstLow); - return 0; - - case 79: - /* begin genLowcodeInt64Great */ - topRegistersMask8 = 0; - rTop10 = (rNext7 = NoReg); - rResult20 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop10 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext7 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext7 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg7 = (rNext7 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask8 = 1U << reg7; - } - } - if (rTop10 == NoReg) { - rTop10 = allocateRegNotConflictingWith(topRegistersMask8); - } - if (rNext7 == NoReg) { - rNext7 = allocateRegNotConflictingWith(1U << rTop10); - } - assert(!(((rTop10 == NoReg) - || (rNext7 == NoReg)))); - rResult20 = allocateFloatRegNotConflictingWith((1U << rTop10) | (1U << rNext7)); - assert(!((rResult20 == NoReg))); - second7 = rTop10; - first11 = rNext7; - value15 = rResult20; - nativePopToReg(ssNativeTop(), second7); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first11); - ssNativePop(1); - abort(); - return 0; - - case 80: - /* begin genLowcodeInt64GreatEqual */ - topRegistersMask9 = 0; - rTop12 = (rNext8 = NoReg); - rResult21 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop12 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext8 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext8 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg8 = (rNext8 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask9 = 1U << reg8; - } - } - if (rTop12 == NoReg) { - rTop12 = allocateRegNotConflictingWith(topRegistersMask9); - } - if (rNext8 == NoReg) { - rNext8 = allocateRegNotConflictingWith(1U << rTop12); - } - assert(!(((rTop12 == NoReg) - || (rNext8 == NoReg)))); - rResult21 = allocateFloatRegNotConflictingWith((1U << rTop12) | (1U << rNext8)); - assert(!((rResult21 == NoReg))); - second8 = rTop12; - first12 = rNext8; - value16 = rResult21; - nativePopToReg(ssNativeTop(), second8); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first12); - ssNativePop(1); - abort(); - return 0; - - case 81: - /* begin genLowcodeInt64Less */ - topRegistersMask10 = 0; - rTop13 = (rNext9 = NoReg); - rResult22 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop13 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext9 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext9 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg9 = (rNext9 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask10 = 1U << reg9; - } - } - if (rTop13 == NoReg) { - rTop13 = allocateRegNotConflictingWith(topRegistersMask10); - } - if (rNext9 == NoReg) { - rNext9 = allocateRegNotConflictingWith(1U << rTop13); - } - assert(!(((rTop13 == NoReg) - || (rNext9 == NoReg)))); - rResult22 = allocateFloatRegNotConflictingWith((1U << rTop13) | (1U << rNext9)); - assert(!((rResult22 == NoReg))); - second9 = rTop13; - first13 = rNext9; - value17 = rResult22; - nativePopToReg(ssNativeTop(), second9); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first13); - ssNativePop(1); - abort(); - return 0; - - case 82: - /* begin genLowcodeInt64LessEqual */ - topRegistersMask11 = 0; - rTop14 = (rNext10 = NoReg); - rResult23 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop14 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext10 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext10 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg10 = (rNext10 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask11 = 1U << reg10; - } - } - if (rTop14 == NoReg) { - rTop14 = allocateRegNotConflictingWith(topRegistersMask11); - } - if (rNext10 == NoReg) { - rNext10 = allocateRegNotConflictingWith(1U << rTop14); - } - assert(!(((rTop14 == NoReg) - || (rNext10 == NoReg)))); - rResult23 = allocateFloatRegNotConflictingWith((1U << rTop14) | (1U << rNext10)); - assert(!((rResult23 == NoReg))); - second10 = rTop14; - first14 = rNext10; - value18 = rResult23; - nativePopToReg(ssNativeTop(), second10); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first14); - ssNativePop(1); - abort(); - return 0; - - case 83: - /* begin genLowcodeInt64NotEqual */ - /* begin allocateRegistersForLowcodeInteger4: */ - rTop15 = (rNext12 = (rNextNext1 = (rNextNextNext1 = NoReg))); - nativeValueIndex1 = 1; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop15 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext12 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext12 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex1))) != NoReg) { - rNext12 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex1)); - if ((nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex1))) != NoReg) { - rNextNext1 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex1)); - } - nativeValueIndex1 += 1; - } - } - if (rNextNext1 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex1))) != NoReg) { - rNextNext1 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex1)); - if ((nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex1))) != NoReg) { - rNextNextNext1 = nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex1)); - } - nativeValueIndex1 += 1; - } - } - if (rNextNextNext1 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex1))) != NoReg) { - rNextNextNext1 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex1)); - nativeValueIndex1 += 1; - } - } - if (rTop15 == NoReg) { - nextRegisterMask1 = 0; - if (rNext12 != NoReg) { - /* begin registerMaskFor: */ - nextRegisterMask1 = 1U << rNext12; - } - if (rNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNext1); - } - if (rNextNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNextNext1); - } - rTop15 = allocateRegNotConflictingWith(nextRegisterMask1); - } - if (rNext12 == NoReg) { - /* begin registerMaskFor: */ - nextRegisterMask1 = 1U << rTop15; - if (rNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNext1); - } - if (rNextNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNextNext1); - } - rNext12 = allocateRegNotConflictingWith(nextRegisterMask1); - } - if (rNextNext1 == NoReg) { - /* begin registerMaskFor:and: */ - nextRegisterMask1 = (1U << rTop15) | (1U << rNext12); - if (rNextNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNextNext1); - } - rNextNext1 = allocateRegNotConflictingWith(nextRegisterMask1); - } - if (rNextNextNext1 == NoReg) { - /* begin registerMaskFor:and:and: */ - nextRegisterMask1 = ((1U << rTop15) | (1U << rNext12)) | (1U << rNextNext1); - rNextNextNext1 = allocateRegNotConflictingWith(nextRegisterMask1); - } - assert(!(((rTop15 == NoReg) - || ((rNext12 == NoReg) - || ((rNextNext1 == NoReg) - || (rNextNextNext1 == NoReg)))))); - secondLow5 = rTop15; - secondHigh5 = rNext12; - firstLow5 = rNextNext1; - firstHigh5 = rNextNextNext1; - nativePopToRegsecondReg(ssNativeTop(), secondLow5, secondHigh5); - ssNativePop(1); - nativePopToRegsecondReg(ssNativeTop(), firstLow5, firstHigh5); - ssNativePop(1); - /* begin CmpR:R: */ - assert(!((secondHigh5 == SPReg))); - genoperandoperand(CmpRR, secondHigh5, firstHigh5); - /* begin JumpNonZero: */ - falseJump7 = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((secondLow5 == SPReg))); - genoperandoperand(CmpRR, secondLow5, firstLow5); - /* begin JumpNonZero: */ - falseJump22 = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(MoveCqR, 0, firstLow5); - /* begin Jump: */ - contJump7 = genoperand(Jump, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperand(MoveCqR, 1, firstLow5); - falseLabel1 = anInstruction17; - jmpTarget(falseJump7, falseLabel1); - jmpTarget(falseJump22, falseLabel1); - jmpTarget(contJump7, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(firstLow5); - return 0; - - case 84: - /* begin genLowcodeInt64ToFloat32 */ - rTop17 = NoReg; - frResult6 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop17 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop17 == NoReg) { - rTop17 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - frResult6 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!(((rTop17 == NoReg) - || (frResult6 == NoReg)))); - value19 = rTop17; - result2 = frResult6; - nativePopToReg(ssNativeTop(), value19); - ssNativePop(1); - abort(); - return 0; - - case 85: - /* begin genLowcodeInt64ToFloat64 */ - rTop18 = NoReg; - frResult7 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop18 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop18 == NoReg) { - rTop18 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - frResult7 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!(((rTop18 == NoReg) - || (frResult7 == NoReg)))); - value20 = rTop18; - result3 = frResult7; - nativePopToReg(ssNativeTop(), value20); - ssNativePop(1); - abort(); - return 0; - - case 86: - /* begin genLowcodeInt64ToPointer */ - /* begin allocateRegistersForLowcodeInteger2: */ - topRegistersMask13 = 0; - rTop20 = (rNext14 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop20 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext14 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext14 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg12 = (rNext14 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask13 = 1U << reg12; - } - } - if (rTop20 == NoReg) { - rTop20 = allocateRegNotConflictingWith(topRegistersMask13); - } - if (rNext14 == NoReg) { - rNext14 = allocateRegNotConflictingWith(1U << rTop20); - } - assert(!(((rTop20 == NoReg) - || (rNext14 == NoReg)))); - valueLow2 = rTop20; - valueHigh2 = rNext14; - nativePopToRegsecondReg(ssNativeTop(), valueLow2, valueHigh2); - ssNativePop(1); - ssPushNativeRegister(valueLow2); - return 0; - - case 87: - /* begin genLowcodeLeftShift32 */ - topRegistersMask14 = 0; - rTop21 = (rNext15 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop21 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext15 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext15 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg13 = (rNext15 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask14 = 1U << reg13; - } - } - if (rTop21 == NoReg) { - rTop21 = allocateRegNotConflictingWith(topRegistersMask14); - } - if (rNext15 == NoReg) { - rNext15 = allocateRegNotConflictingWith(1U << rTop21); - } - assert(!(((rTop21 == NoReg) - || (rNext15 == NoReg)))); - shiftAmount = rTop21; - value22 = rNext15; - nativePopToReg(ssNativeTop(), shiftAmount); - ssNativePop(1); - nativePopToReg(ssNativeTop(), value22); - ssNativePop(1); - /* begin LogicalShiftLeftR:R: */ - genoperandoperand(LogicalShiftLeftRR, shiftAmount, value22); - ssPushNativeRegister(value22); - return 0; - - case 88: - /* begin genLowcodeLeftShift64 */ - topRegistersMask15 = 0; - rTop22 = (rNext16 = NoReg); - rResult24 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop22 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext16 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext16 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg14 = (rNext16 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask15 = 1U << reg14; - } - } - if (rTop22 == NoReg) { - rTop22 = allocateRegNotConflictingWith(topRegistersMask15); - } - if (rNext16 == NoReg) { - rNext16 = allocateRegNotConflictingWith(1U << rTop22); - } - assert(!(((rTop22 == NoReg) - || (rNext16 == NoReg)))); - rResult24 = allocateFloatRegNotConflictingWith((1U << rTop22) | (1U << rNext16)); - assert(!((rResult24 == NoReg))); - shiftAmount1 = rTop22; - value23 = rNext16; - result4 = rResult24; - nativePopToReg(ssNativeTop(), shiftAmount1); - ssNativePop(1); - nativePopToReg(ssNativeTop(), value23); - ssNativePop(1); - abort(); - return 0; - - case 89: - /* begin genLowcodeLoadArgumentAddress */ - baseOffset = extA; - /* begin allocateRegistersForLowcodeResultInteger: */ - rResult = NoReg; - rResult = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!((rResult == NoReg))); - pointer = rResult; - loadNativeArgumentAddressto(baseOffset, pointer); - ssPushNativeRegister(pointer); - extA = 0; - return 0; - - case 90: - /* begin genLowcodeLoadArgumentFloat32 */ - baseOffset1 = extA; - /* begin allocateRegistersForLowcodeResultFloat: */ - frResult = NoReg; - frResult = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!((frResult == NoReg))); - floatValue = frResult; - loadNativeArgumentAddressto(baseOffset1, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperandoperand(MoveM32rRs, 0, TempReg, floatValue); - ssPushNativeRegisterSingleFloat(floatValue); - extA = 0; - return 0; - - case 91: - /* begin genLowcodeLoadArgumentFloat64 */ - baseOffset2 = extA; - /* begin allocateRegistersForLowcodeResultFloat: */ - frResult1 = NoReg; - frResult1 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!((frResult1 == NoReg))); - doubleValue = frResult1; - loadNativeArgumentAddressto(baseOffset2, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveM64rRd, 0, TempReg, doubleValue); - ssPushNativeRegisterDoubleFloat(doubleValue); - extA = 0; - return 0; - - case 92: - /* begin genLowcodeLoadArgumentInt16 */ - baseOffset3 = extA; - /* begin allocateRegistersForLowcodeResultInteger: */ - rResult1 = NoReg; - rResult1 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!((rResult1 == NoReg))); - value = rResult1; - loadNativeArgumentAddressto(baseOffset3, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction18 = genoperandoperandoperand(MoveM16rR, 0, TempReg, value); - /* begin SignExtend16R:R: */ - if (value == value) { - /* begin LogicalShiftLeftCq:R: */ - first = genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 16, value); - } - else { - /* begin MoveR:R: */ - first = genoperandoperand(MoveRR, value, value); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 16, value); - } - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, (BytesPerWord * 8) - 16, value); - goto l6; - l6: /* end SignExtend16R:R: */; - ssPushNativeRegister(value); - extA = 0; - return 0; - - case 93: - /* begin genLowcodeLoadArgumentInt32 */ - baseOffset4 = extA; - /* begin allocateRegistersForLowcodeResultInteger: */ - rResult2 = NoReg; - rResult2 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!((rResult2 == NoReg))); - value1 = rResult2; - loadNativeArgumentAddressto(baseOffset4, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperandoperand(MoveM32rR, 0, TempReg, value1); - ssPushNativeRegister(value1); - extA = 0; - return 0; - - case 94: - /* begin genLowcodeLoadArgumentInt64 */ - baseOffset20 = extA; - /* begin allocateRegistersForLowcodeResultInteger2: */ - rResult25 = (rResult26 = NoReg); - rResult25 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - rResult26 = allocateRegNotConflictingWith(1U << rResult25); - assert(!(((rResult25 == NoReg) - || (rResult26 == NoReg)))); - valueLow4 = rResult25; - valueHigh4 = rResult26; - loadNativeArgumentAddressto(baseOffset20, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperandoperand(MoveM32rR, 0, TempReg, valueLow4); - /* begin checkQuickConstant:forInstruction: */ - anInstruction110 = genoperandoperandoperand(MoveM32rR, 4, TempReg, valueHigh4); - ssPushNativeRegistersecondRegister(valueLow4, valueHigh4); - extA = 0; - return 0; - - case 95: - /* begin genLowcodeLoadArgumentInt8 */ - baseOffset5 = extA; - /* begin allocateRegistersForLowcodeResultInteger: */ - rResult3 = NoReg; - rResult3 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!((rResult3 == NoReg))); - value2 = rResult3; - loadNativeArgumentAddressto(baseOffset5, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction24 = genoperandoperandoperand(MoveM8rR, 0, TempReg, value2); - /* begin SignExtend8R:R: */ - if (value2 == value2) { - /* begin LogicalShiftLeftCq:R: */ - first1 = genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 8, value2); - } - else { - /* begin MoveR:R: */ - first1 = genoperandoperand(MoveRR, value2, value2); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 8, value2); - } - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, (BytesPerWord * 8) - 8, value2); - goto l14; - l14: /* end SignExtend8R:R: */; - ssPushNativeRegister(value2); - extA = 0; - return 0; - - case 96: - /* begin genLowcodeLoadArgumentPointer */ - baseOffset6 = extA; - /* begin allocateRegistersForLowcodeResultInteger: */ - rResult4 = NoReg; - rResult4 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!((rResult4 == NoReg))); - pointerResult = rResult4; - loadNativeArgumentAddressto(baseOffset6, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction25 = genoperandoperandoperand(MoveMwrR, 0, TempReg, pointerResult); - ssPushNativeRegister(pointerResult); - extA = 0; - return 0; - - case 97: - /* begin genLowcodeLoadArgumentUInt16 */ - baseOffset7 = extA; - /* begin allocateRegistersForLowcodeResultInteger: */ - rResult5 = NoReg; - rResult5 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!((rResult5 == NoReg))); - value3 = rResult5; - loadNativeArgumentAddressto(baseOffset7, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction26 = genoperandoperandoperand(MoveM16rR, 0, TempReg, value3); - ssPushNativeRegister(value3); - extA = 0; - return 0; - - case 98: - /* begin genLowcodeLoadArgumentUInt32 */ - baseOffset8 = extA; - /* begin allocateRegistersForLowcodeResultInteger: */ - rResult6 = NoReg; - rResult6 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!((rResult6 == NoReg))); - value4 = rResult6; - loadNativeArgumentAddressto(baseOffset8, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction27 = genoperandoperandoperand(MoveM32rR, 0, TempReg, value4); - ssPushNativeRegister(value4); - extA = 0; - return 0; - - case 99: - /* begin genLowcodeLoadArgumentUInt64 */ - baseOffset21 = extA; - /* begin allocateRegistersForLowcodeResultInteger2: */ - rResult27 = (rResult28 = NoReg); - rResult27 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - rResult28 = allocateRegNotConflictingWith(1U << rResult27); - assert(!(((rResult27 == NoReg) - || (rResult28 == NoReg)))); - valueLow5 = rResult27; - valueHigh5 = rResult28; - loadNativeArgumentAddressto(baseOffset21, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction28 = genoperandoperandoperand(MoveM32rR, 0, TempReg, valueLow5); - /* begin checkQuickConstant:forInstruction: */ - anInstruction111 = genoperandoperandoperand(MoveM32rR, 4, TempReg, valueHigh5); - ssPushNativeRegistersecondRegister(valueLow5, valueHigh5); - extA = 0; - return 0; - - case 100: - /* begin genLowcodeLoadArgumentUInt8 */ - baseOffset9 = extA; - /* begin allocateRegistersForLowcodeResultInteger: */ - rResult7 = NoReg; - rResult7 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!((rResult7 == NoReg))); - value5 = rResult7; - loadNativeArgumentAddressto(baseOffset9, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction30 = genoperandoperandoperand(MoveM8rR, 0, TempReg, value5); - ssPushNativeRegister(value5); - extA = 0; - return 0; - - case 101: - /* begin genLowcodeLoadFloat32FromMemory */ - rTop23 = NoReg; - frResult8 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop23 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop23 == NoReg) { - rTop23 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - frResult8 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!(((rTop23 == NoReg) - || (frResult8 == NoReg)))); - pointer2 = rTop23; - value26 = frResult8; - nativePopToReg(ssNativeTop(), pointer2); - ssNativePop(1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction33 = genoperandoperandoperand(MoveM32rRs, 0, pointer2, value26); - ssPushNativeRegisterSingleFloat(value26); - return 0; - - case 102: - /* begin genLowcodeLoadFloat64FromMemory */ - rTop24 = NoReg; - frResult9 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop24 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop24 == NoReg) { - rTop24 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - frResult9 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!(((rTop24 == NoReg) - || (frResult9 == NoReg)))); - pointer3 = rTop24; - value27 = frResult9; - nativePopToReg(ssNativeTop(), pointer3); - ssNativePop(1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction34 = genoperandoperandoperand(MoveM64rRd, 0, pointer3, value27); - ssPushNativeRegisterDoubleFloat(value27); - return 0; - - case 103: - /* begin genLowcodeLoadInt16FromMemory */ - rTop25 = NoReg; - rResult29 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop25 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop25 == NoReg) { - rTop25 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult29 = allocateRegNotConflictingWith(1U << rTop25); - assert(!(((rTop25 == NoReg) - || (rResult29 == NoReg)))); - pointer4 = rTop25; - value28 = rResult29; - nativePopToReg(ssNativeTop(), pointer4); - ssNativePop(1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction35 = genoperandoperandoperand(MoveM16rR, 0, pointer4, value28); - /* begin SignExtend16R:R: */ - if (value28 == value28) { - /* begin LogicalShiftLeftCq:R: */ - first16 = genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 16, value28); - } - else { - /* begin MoveR:R: */ - first16 = genoperandoperand(MoveRR, value28, value28); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 16, value28); - } - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, (BytesPerWord * 8) - 16, value28); - goto l176; - l176: /* end SignExtend16R:R: */; - ssPushNativeRegister(value28); - return 0; - - case 104: - /* begin genLowcodeLoadInt32FromMemory */ - rTop26 = NoReg; - rResult30 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop26 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop26 == NoReg) { - rTop26 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult30 = allocateRegNotConflictingWith(1U << rTop26); - assert(!(((rTop26 == NoReg) - || (rResult30 == NoReg)))); - pointer5 = rTop26; - value29 = rResult30; - nativePopToReg(ssNativeTop(), pointer5); - ssNativePop(1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction36 = genoperandoperandoperand(MoveM32rR, 0, pointer5, value29); - ssPushNativeRegister(value29); - return 0; - - case 105: - /* begin genLowcodeLoadInt64FromMemory */ - /* begin allocateRegistersForLowcodeIntegerResultInteger2: */ - rTop27 = NoReg; - rResult31 = (rResult31 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop27 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop27 == NoReg) { - rTop27 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult31 = allocateRegNotConflictingWith(1U << rTop27); - rResult210 = allocateRegNotConflictingWith((1U << rTop27) | (1U << rResult31)); - assert(!(((rTop27 == NoReg) - || ((rResult31 == NoReg) - || (rResult210 == NoReg))))); - pointer6 = rTop27; - valueLow6 = rResult31; - valueHigh6 = rResult210; - nativePopToReg(ssNativeTop(), pointer6); - ssNativePop(1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction37 = genoperandoperandoperand(MoveM32rR, 0, pointer6, valueLow6); - /* begin checkQuickConstant:forInstruction: */ - anInstruction112 = genoperandoperandoperand(MoveM32rR, 4, pointer6, valueHigh6); - ssPushNativeRegistersecondRegister(valueLow6, valueHigh6); - return 0; - - case 106: - /* begin genLowcodeLoadInt8FromMemory */ - rTop28 = NoReg; - rResult32 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop28 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop28 == NoReg) { - rTop28 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult32 = allocateRegNotConflictingWith(1U << rTop28); - assert(!(((rTop28 == NoReg) - || (rResult32 == NoReg)))); - pointer7 = rTop28; - value31 = rResult32; - nativePopToReg(ssNativeTop(), pointer7); - ssNativePop(1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction38 = genoperandoperandoperand(MoveM8rR, 0, pointer7, value31); - /* begin SignExtend8R:R: */ - if (value31 == value31) { - /* begin LogicalShiftLeftCq:R: */ - first17 = genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 8, value31); - } - else { - /* begin MoveR:R: */ - first17 = genoperandoperand(MoveRR, value31, value31); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 8, value31); - } - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, (BytesPerWord * 8) - 8, value31); - goto l190; - l190: /* end SignExtend8R:R: */; - ssPushNativeRegister(value31); - return 0; - - case 107: - /* begin genLowcodeLoadLocalAddress */ - baseOffset10 = extA; - /* begin allocateRegistersForLowcodeResultInteger: */ - rResult8 = NoReg; - rResult8 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!((rResult8 == NoReg))); - pointer1 = rResult8; - loadNativeLocalAddressto(baseOffset10, pointer1); - ssPushNativeRegister(pointer1); - extA = 0; - return 0; - - case 108: - /* begin genLowcodeLoadLocalFloat32 */ - baseOffset11 = extA; - /* begin allocateRegistersForLowcodeResultFloat: */ - frResult2 = NoReg; - frResult2 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!((frResult2 == NoReg))); - floatValue1 = frResult2; - loadNativeLocalAddressto(baseOffset11, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction39 = genoperandoperandoperand(MoveM32rRs, 0, TempReg, floatValue1); - ssPushNativeRegisterSingleFloat(floatValue1); - extA = 0; - return 0; - - case 109: - /* begin genLowcodeLoadLocalFloat64 */ - baseOffset12 = extA; - /* begin allocateRegistersForLowcodeResultFloat: */ - frResult3 = NoReg; - frResult3 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!((frResult3 == NoReg))); - doubleValue1 = frResult3; - loadNativeLocalAddressto(baseOffset12, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction40 = genoperandoperandoperand(MoveM64rRd, 0, TempReg, doubleValue1); - ssPushNativeRegisterDoubleFloat(doubleValue1); - extA = 0; - return 0; - - case 110: - /* begin genLowcodeLoadLocalInt16 */ - baseOffset13 = extA; - /* begin allocateRegistersForLowcodeResultInteger: */ - rResult9 = NoReg; - rResult9 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!((rResult9 == NoReg))); - value6 = rResult9; - loadNativeLocalAddressto(baseOffset13, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction41 = genoperandoperandoperand(MoveM16rR, 0, TempReg, value6); - /* begin SignExtend16R:R: */ - if (value6 == value6) { - /* begin LogicalShiftLeftCq:R: */ - first2 = genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 16, value6); - } - else { - /* begin MoveR:R: */ - first2 = genoperandoperand(MoveRR, value6, value6); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 16, value6); - } - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, (BytesPerWord * 8) - 16, value6); - goto l27; - l27: /* end SignExtend16R:R: */; - ssPushNativeRegister(value6); - extA = 0; - return 0; - - case 111: - /* begin genLowcodeLoadLocalInt32 */ - baseOffset14 = extA; - /* begin allocateRegistersForLowcodeResultInteger: */ - rResult10 = NoReg; - rResult10 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!((rResult10 == NoReg))); - value7 = rResult10; - loadNativeLocalAddressto(baseOffset14, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction42 = genoperandoperandoperand(MoveM32rR, 0, TempReg, value7); - ssPushNativeRegister(value7); - extA = 0; - return 0; - - case 112: - /* begin genLowcodeLoadLocalInt64 */ - baseOffset22 = extA; - /* begin allocateRegistersForLowcodeResultInteger2: */ - rResult33 = (rResult211 = NoReg); - rResult33 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - rResult211 = allocateRegNotConflictingWith(1U << rResult33); - assert(!(((rResult33 == NoReg) - || (rResult211 == NoReg)))); - valueLow7 = rResult33; - valueHigh7 = rResult211; - loadNativeLocalAddressto(baseOffset22, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction43 = genoperandoperandoperand(MoveM32rR, 0, TempReg, valueLow7); - /* begin checkQuickConstant:forInstruction: */ - anInstruction113 = genoperandoperandoperand(MoveM32rR, 4, TempReg, valueHigh7); - ssPushNativeRegistersecondRegister(valueLow7, valueHigh7); - extA = 0; - return 0; - - case 113: - /* begin genLowcodeLoadLocalInt8 */ - baseOffset15 = extA; - /* begin allocateRegistersForLowcodeResultInteger: */ - rResult11 = NoReg; - rResult11 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!((rResult11 == NoReg))); - value8 = rResult11; - loadNativeLocalAddressto(baseOffset15, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction44 = genoperandoperandoperand(MoveM8rR, 0, TempReg, value8); - /* begin SignExtend8R:R: */ - if (value8 == value8) { - /* begin LogicalShiftLeftCq:R: */ - first3 = genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 8, value8); - } - else { - /* begin MoveR:R: */ - first3 = genoperandoperand(MoveRR, value8, value8); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 8, value8); - } - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, (BytesPerWord * 8) - 8, value8); - goto l34; - l34: /* end SignExtend8R:R: */; - ssPushNativeRegister(value8); - extA = 0; - return 0; - - case 114: - /* begin genLowcodeLoadLocalPointer */ - baseOffset16 = extA; - /* begin allocateRegistersForLowcodeResultInteger: */ - rResult12 = NoReg; - rResult12 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!((rResult12 == NoReg))); - pointerResult1 = rResult12; - loadNativeLocalAddressto(baseOffset16, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction45 = genoperandoperandoperand(MoveMwrR, 0, TempReg, pointerResult1); - ssPushNativeRegister(pointerResult1); - extA = 0; - return 0; - - case 115: - /* begin genLowcodeLoadLocalUInt16 */ - baseOffset17 = extA; - /* begin allocateRegistersForLowcodeResultInteger: */ - rResult13 = NoReg; - rResult13 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!((rResult13 == NoReg))); - value9 = rResult13; - loadNativeLocalAddressto(baseOffset17, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction46 = genoperandoperandoperand(MoveM16rR, 0, TempReg, value9); - ssPushNativeRegister(value9); - extA = 0; - return 0; - - case 116: - /* begin genLowcodeLoadLocalUInt32 */ - baseOffset18 = extA; - /* begin allocateRegistersForLowcodeResultInteger: */ - rResult14 = NoReg; - rResult14 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!((rResult14 == NoReg))); - value10 = rResult14; - loadNativeLocalAddressto(baseOffset18, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction47 = genoperandoperandoperand(MoveM32rR, 0, TempReg, value10); - ssPushNativeRegister(value10); - extA = 0; - return 0; - - case 117: - /* begin genLowcodeLoadLocalUInt64 */ - baseOffset23 = extA; - /* begin allocateRegistersForLowcodeResultInteger2: */ - rResult34 = (rResult212 = NoReg); - rResult34 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - rResult212 = allocateRegNotConflictingWith(1U << rResult34); - assert(!(((rResult34 == NoReg) - || (rResult212 == NoReg)))); - valueLow8 = rResult34; - valueHigh8 = rResult212; - loadNativeLocalAddressto(baseOffset23, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction48 = genoperandoperandoperand(MoveM32rR, 0, TempReg, valueLow8); - /* begin checkQuickConstant:forInstruction: */ - anInstruction114 = genoperandoperandoperand(MoveM32rR, 4, TempReg, valueHigh8); - ssPushNativeRegistersecondRegister(valueLow8, valueHigh8); - extA = 0; - return 0; - - case 118: - /* begin genLowcodeLoadLocalUInt8 */ - baseOffset19 = extA; - /* begin allocateRegistersForLowcodeResultInteger: */ - rResult15 = NoReg; - rResult15 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!((rResult15 == NoReg))); - value11 = rResult15; - loadNativeLocalAddressto(baseOffset19, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction49 = genoperandoperandoperand(MoveM8rR, 0, TempReg, value11); - ssPushNativeRegister(value11); - extA = 0; - return 0; - - case 119: - /* begin genLowcodeLoadObjectAt */ - rTop29 = (rOopTop = NoReg); - topRegisterMask = 0; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop29 = nativeRegisterOrNone(ssNativeTop()); - } - if ((registerOrNone(ssTop())) != NoReg) { - rOopTop = registerOrNone(ssTop()); - /* begin registerMaskFor: */ - topRegisterMask = 1U << rOopTop; - } - if (rTop29 == NoReg) { - rTop29 = allocateRegNotConflictingWith(topRegisterMask); - } - if (rOopTop == NoReg) { - rOopTop = allocateRegNotConflictingWith(1U << rTop29); - } - assert(!(((rTop29 == NoReg) - || (rOopTop == NoReg)))); - fieldIndex = rTop29; - object = rOopTop; - nativePopToReg(ssNativeTop(), fieldIndex); - ssNativePop(1); - popToReg(ssTop(), object); - ssPop(1); - genLcLoadObjectat(object, fieldIndex); - return 0; - - default: - return genLowcodeUnaryInlinePrimitive3(prim); - - } - return 0; -} - - -/* Lowcode instruction generator dispatch */ - - /* StackToRegisterMappingCogit>>#genLowcodeUnaryInlinePrimitive3: */ -static sqInt NoDbgRegParms -genLowcodeUnaryInlinePrimitive3(sqInt prim) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *abstractInstruction11; - AbstractInstruction *abstractInstruction2; - AbstractInstruction *abstractInstruction3; - AbstractInstruction *abstractInstruction4; - sqInt alignedSize; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction110; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction22; - AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction41; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt base; - sqInt base1; - sqInt base2; - sqInt constant; - sqInt constant1; - AbstractInstruction * contJump; - AbstractInstruction * contJump1; - sqInt dest; - sqInt dest1; - sqInt dest2; - AbstractInstruction * falseJump; - AbstractInstruction * falseJump1; - sqInt fieldIndex; - sqInt first; - sqInt first1; - sqInt first2; - sqInt first4; - sqInt first5; - sqInt firstHigh1; - sqInt firstLow1; - sqInt frTop; - sqInt frTop1; - sqInt i1; - sqInt i2; - sqInt i3; - sqInt i4; - sqInt i5; - sqInt i6; - sqInt i7; - sqInt index1; - sqInt nativeValueIndex; - sqInt nativeValueIndex1; - sqInt nativeValueIndex2; - sqInt nativeValueIndex3; - sqInt nextRegisterMask; - sqInt nextRegisterMask1; - sqInt nextRegisterMask2; - sqInt nextRegisterMask3; - sqInt object; - sqInt offset; - sqInt offset1; - sqInt offset2; - sqInt offset3; - sqInt offset4; - sqInt offset5; - sqInt offsetHigh; - sqInt offsetLow; - sqInt pointer; - sqInt pointer1; - sqInt pointer2; - sqInt pointer3; - sqInt pointer4; - sqInt pointer5; - sqInt pointer6; - sqInt pointer7; - sqInt pointer8; - sqInt pointerResult; - sqInt pointerValue7; - sqInt quickConstant; - sqInt reg; - sqInt reg1; - sqInt reg10; - sqInt reg11; - sqInt reg2; - sqInt reg3; - sqInt reg4; - sqInt reg6; - sqInt reg8; - sqInt registerID; - sqInt registerID1; - sqInt registerID2; - sqInt registerID3; - sqInt registerID4; - sqInt reg9; - sqInt result; - sqInt result1; - sqInt resultHigh1; - sqInt resultLow1; - sqInt rNext; - sqInt rNext1; - sqInt rNext10; - sqInt rNext13; - sqInt rNext14; - sqInt rNext15; - sqInt rNext2; - sqInt rNext3; - sqInt rNext4; - sqInt rNext5; - sqInt rNext6; - sqInt rNext7; - sqInt rNext8; - sqInt rNextNext; - sqInt rNextNext1; - sqInt rNextNext2; - sqInt rNextNext3; - sqInt rNextNextNext; - sqInt rNext9; - sqInt rOopTop; - sqInt rResult; - sqInt rResult1; - sqInt rResult2; - sqInt rResult21; - sqInt rResult22; - sqInt rResult3; - sqInt rResult4; - sqInt rResult5; - sqInt rResult6; - sqInt rResult7; - sqInt rResult8; - sqInt rResult9; - sqInt rTop; - sqInt rTop1; - sqInt rTop10; - sqInt rTop14; - sqInt rTop15; - sqInt rTop17; - sqInt rTop18; - sqInt rTop2; - sqInt rTop20; - sqInt rTop21; - sqInt rTop22; - sqInt rTop23; - sqInt rTop24; - sqInt rTop25; - sqInt rTop26; - sqInt rTop27; - sqInt rTop28; - sqInt rTop29; - sqInt rTop3; - sqInt rTop30; - sqInt rTop31; - sqInt rTop32; - sqInt rTop4; - sqInt rTop5; - sqInt rTop6; - sqInt rTop7; - sqInt rTop8; - sqInt rTop9; - sqInt second; - sqInt second1; - sqInt second2; - sqInt second4; - sqInt second5; - sqInt secondHigh1; - sqInt secondLow1; - sqInt size; - sqInt size1; - sqInt size3; - sqInt size4; - sqInt size5; - sqInt sizeHigh; - sqInt sizeLow; - sqInt sizeLow1; - sqInt source; - sqInt source1; - sqInt source2; - sqInt topRegistersMask; - sqInt topRegistersMask1; - sqInt topRegistersMask10; - sqInt topRegistersMask11; - sqInt topRegistersMask12; - sqInt topRegistersMask13; - sqInt topRegistersMask2; - sqInt topRegistersMask3; - sqInt topRegistersMask4; - sqInt topRegistersMask6; - sqInt topRegistersMask8; - sqInt topRegistersMask9; - sqInt value; - sqInt value1; - sqInt value10; - sqInt value11; - sqInt value3; - sqInt value4; - sqInt value6; - sqInt value8; - sqInt valueHigh; - sqInt valueHigh1; - sqInt valueHigh2; - sqInt valueLow; - sqInt valueLow1; - sqInt valueLow2; - sqInt value9; - - sizeLow1 = 0; - switch (prim) { - case 120: - /* begin genLowcodeLoadObjectField */ - fieldIndex = extA; - /* begin allocateRegistersForLowcodeOop: */ - rOopTop = NoReg; - if ((registerOrNone(ssTop())) != NoReg) { - - /* Ensure we are not using a duplicated register. */ - rOopTop = registerOrNone(ssTop()); - index1 = ((simSpillBase < 0) ? 0 : simSpillBase); - for (i1 = index1; i1 <= (simStackPtr); i1 += 1) { - if ((registerOrNone(simStackAt(index1))) == rOopTop) { - goto l2; - } - } - l2: ; - rOopTop = NoReg; - l1: ; - } - if (rOopTop == NoReg) { - rOopTop = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rOopTop == NoReg))); - object = rOopTop; - popToReg(ssTop(), object); - ssPop(1); - genLcLoadObjectfield(object, fieldIndex); - extA = 0; - return 0; - - case 121: - /* begin genLowcodeLoadPointerFromMemory */ - rTop = NoReg; - rResult = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop == NoReg) { - rTop = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult = allocateRegNotConflictingWith(1U << rTop); - assert(!(((rTop == NoReg) - || (rResult == NoReg)))); - pointer = rTop; - pointerResult = rResult; - nativePopToReg(ssNativeTop(), pointer); - ssNativePop(1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, pointer, pointerResult); - ssPushNativeRegister(pointerResult); - return 0; - - case 122: - /* begin genLowcodeLoadUInt16FromMemory */ - rTop1 = NoReg; - rResult1 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop1 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop1 == NoReg) { - rTop1 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult1 = allocateRegNotConflictingWith(1U << rTop1); - assert(!(((rTop1 == NoReg) - || (rResult1 == NoReg)))); - pointer1 = rTop1; - value = rResult1; - nativePopToReg(ssNativeTop(), pointer1); - ssNativePop(1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveM16rR, 0, pointer1, value); - ssPushNativeRegister(value); - return 0; - - case 123: - /* begin genLowcodeLoadUInt32FromMemory */ - rTop2 = NoReg; - rResult2 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop2 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop2 == NoReg) { - rTop2 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult2 = allocateRegNotConflictingWith(1U << rTop2); - assert(!(((rTop2 == NoReg) - || (rResult2 == NoReg)))); - pointer2 = rTop2; - value1 = rResult2; - nativePopToReg(ssNativeTop(), pointer2); - ssNativePop(1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveM32rR, 0, pointer2, value1); - ssPushNativeRegister(value1); - return 0; - - case 0x7C: - /* begin genLowcodeLoadUInt64FromMemory */ - /* begin allocateRegistersForLowcodeIntegerResultInteger2: */ - rTop3 = NoReg; - rResult3 = (rResult3 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop3 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop3 == NoReg) { - rTop3 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult3 = allocateRegNotConflictingWith(1U << rTop3); - rResult21 = allocateRegNotConflictingWith((1U << rTop3) | (1U << rResult3)); - assert(!(((rTop3 == NoReg) - || ((rResult3 == NoReg) - || (rResult21 == NoReg))))); - pointer3 = rTop3; - valueLow = rResult3; - valueHigh = rResult21; - nativePopToReg(ssNativeTop(), pointer3); - ssNativePop(1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperandoperand(MoveM32rR, 0, pointer3, valueLow); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperandoperand(MoveM32rR, 4, pointer3, valueHigh); - ssPushNativeRegistersecondRegister(valueLow, valueHigh); - return 0; - - case 125: - /* begin genLowcodeLoadUInt8FromMemory */ - rTop4 = NoReg; - rResult4 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop4 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop4 == NoReg) { - rTop4 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult4 = allocateRegNotConflictingWith(1U << rTop4); - assert(!(((rTop4 == NoReg) - || (rResult4 == NoReg)))); - pointer4 = rTop4; - value3 = rResult4; - nativePopToReg(ssNativeTop(), pointer4); - ssNativePop(1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperandoperand(MoveM8rR, 0, pointer4, value3); - ssPushNativeRegister(value3); - return 0; - - case 0x7E: - /* begin genLowcodeLocalFrameSize */ - size = extA; - assert(needsFrame); - - /* Align the size to 16 bytes. */ - hasNativeFrame = 1; - - /* Mark the stack frame */ - alignedSize = (size + 15) & -16; - annotateobjRef(gMoveCwR(splObj(LowcodeContextMark), TempReg), splObj(LowcodeContextMark)); - /* begin MoveR:Mw:r: */ - offset = frameOffsetOfNativeFrameMark(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperandoperand(MoveRMwr, TempReg, offset, FPReg); - /* begin checkLiteral:forInstruction: */ - nativeStackPointerAddress(); - anInstruction12 = genoperandoperand(MoveAwR, nativeStackPointerAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperand(AddCqR, 1, TempReg); - /* begin MoveR:Mw:r: */ - offset1 = frameOffsetOfPreviousNativeStackPointer(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction31 = genoperandoperandoperand(MoveRMwr, TempReg, offset1, FPReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction41 = genoperandoperand(SubCqR, alignedSize, TempReg); - /* begin MoveR:Mw:r: */ - offset2 = frameOffsetOfNativeFramePointer(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(MoveRMwr, TempReg, offset2, FPReg); - /* begin MoveR:Mw:r: */ - offset3 = frameOffsetOfNativeStackPointer(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperandoperand(MoveRMwr, TempReg, offset3, FPReg); - /* begin SubCq:R: */ - quickConstant = 1 + (defaultNativeStackFrameSize()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(SubCqR, quickConstant, TempReg); - /* begin checkLiteral:forInstruction: */ - nativeStackPointerAddress(); - anInstruction8 = genoperandoperand(MoveRAw, TempReg, nativeStackPointerAddress()); - extA = 0; - return 0; - - case 0x7F: - /* begin genLowcodeLockRegisters */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i2 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i2 <= simStackPtr; i2 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i2), frameOffsetOfTemporary(i2 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - voidReceiverResultRegContainsSelf(); - return 0; - - case 128: - /* begin genLowcodeLockVM */ - abort(); - return 0; - - case 129: - /* begin genLowcodeMalloc32 */ - rTop28 = NoReg; - rResult8 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop28 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop28 == NoReg) { - rTop28 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult8 = allocateRegNotConflictingWith(1U << rTop28); - assert(!(((rTop28 == NoReg) - || (rResult8 == NoReg)))); - size1 = rTop28; - pointer7 = rResult8; - nativePopToReg(ssNativeTop(), size1); - ssNativePop(1); - /* begin ssFlushAll */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i3 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i3 <= simStackPtr; i3 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i3), frameOffsetOfTemporary(i3 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - voidReceiverResultRegContainsSelf(); - if (size1 != ReceiverResultReg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, size1, ReceiverResultReg); - } - /* begin CallRT: */ - abstractInstruction3 = genoperand(Call, ceMallocTrampoline); - (abstractInstruction3->annotation = IsRelativeCall); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, pointer7); - ssPushNativeRegister(pointer7); - return 0; - - case 130: - /* begin genLowcodeMalloc64 */ - /* begin allocateRegistersForLowcodeInteger2ResultInteger: */ - topRegistersMask12 = 0; - rTop29 = (rNext10 = NoReg); - rResult9 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop29 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext10 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext10 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg10 = (rNext10 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask12 = 1U << reg10; - } - } - if (rTop29 == NoReg) { - rTop29 = allocateRegNotConflictingWith(topRegistersMask12); - } - if (rNext10 == NoReg) { - rNext10 = allocateRegNotConflictingWith(1U << rTop29); - } - assert(!(((rTop29 == NoReg) - || (rNext10 == NoReg)))); - rResult9 = allocateFloatRegNotConflictingWith((1U << rTop29) | (1U << rNext10)); - assert(!((rResult9 == NoReg))); - sizeLow = rTop29; - sizeHigh = rNext10; - pointer8 = rResult9; - nativePopToRegsecondReg(ssNativeTop(), sizeLow, sizeHigh); - ssNativePop(1); - /* begin ssFlushAll */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i4 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i4 <= simStackPtr; i4 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i4), frameOffsetOfTemporary(i4 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - voidReceiverResultRegContainsSelf(); - if (sizeLow != ReceiverResultReg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, sizeLow, ReceiverResultReg); - } - /* begin CallRT: */ - abstractInstruction4 = genoperand(Call, ceMallocTrampoline); - (abstractInstruction4->annotation = IsRelativeCall); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, pointer8); - ssPushNativeRegister(pointer8); - return 0; - - case 131: - /* begin genLowcodeMemcpy32 */ - rTop30 = (rNext13 = (rNextNext2 = NoReg)); - nativeValueIndex2 = 1; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop30 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext13 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext13 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex2))) != NoReg) { - rNext13 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex2)); - if ((nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex2))) != NoReg) { - rNextNext2 = nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex2)); - } - nativeValueIndex2 += 1; - } - } - if (rNextNext2 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex2))) != NoReg) { - rNextNext2 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex2)); - } - } - if (rTop30 == NoReg) { - nextRegisterMask2 = 0; - if (rNext13 != NoReg) { - /* begin registerMaskFor: */ - nextRegisterMask2 = 1U << rNext13; - } - if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1U << rNextNext2); - } - rTop30 = allocateRegNotConflictingWith(nextRegisterMask2); - } - if (rNext13 == NoReg) { - /* begin registerMaskFor: */ - nextRegisterMask2 = 1U << rTop30; - if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1U << rNextNext2); - } - rNext13 = allocateRegNotConflictingWith(nextRegisterMask2); - } - if (rNextNext2 == NoReg) { - /* begin registerMaskFor:and: */ - nextRegisterMask2 = (1U << rTop30) | (1U << rNext13); - rNextNext2 = allocateRegNotConflictingWith(nextRegisterMask2); - } - assert(!(((rTop30 == NoReg) - || ((rNext13 == NoReg) - || (rNextNext2 == NoReg))))); - size3 = rTop30; - source = rNext13; - dest = rNextNext2; - nativePopToReg(ssNativeTop(), size3); - ssNativePop(1); - nativePopToReg(ssNativeTop(), source); - ssNativePop(1); - nativePopToReg(ssNativeTop(), dest); - ssNativePop(1); - /* begin ssFlushAll */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i5 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i5 <= simStackPtr; i5 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i5), frameOffsetOfTemporary(i5 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - voidReceiverResultRegContainsSelf(); - genMemCopytosize(backEnd, source, dest, size3); - return 0; - - case 132: - /* begin genLowcodeMemcpy64 */ - rTop31 = (rNext14 = (rNextNext3 = NoReg)); - nativeValueIndex3 = 1; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop31 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext14 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext14 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex3))) != NoReg) { - rNext14 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex3)); - if ((nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex3))) != NoReg) { - rNextNext3 = nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex3)); - } - nativeValueIndex3 += 1; - } - } - if (rNextNext3 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex3))) != NoReg) { - rNextNext3 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex3)); - } - } - if (rTop31 == NoReg) { - nextRegisterMask3 = 0; - if (rNext14 != NoReg) { - /* begin registerMaskFor: */ - nextRegisterMask3 = 1U << rNext14; - } - if (rNextNext3 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1U << rNextNext3); - } - rTop31 = allocateRegNotConflictingWith(nextRegisterMask3); - } - if (rNext14 == NoReg) { - /* begin registerMaskFor: */ - nextRegisterMask3 = 1U << rTop31; - if (rNextNext3 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1U << rNextNext3); - } - rNext14 = allocateRegNotConflictingWith(nextRegisterMask3); - } - if (rNextNext3 == NoReg) { - /* begin registerMaskFor:and: */ - nextRegisterMask3 = (1U << rTop31) | (1U << rNext14); - rNextNext3 = allocateRegNotConflictingWith(nextRegisterMask3); - } - assert(!(((rTop31 == NoReg) - || ((rNext14 == NoReg) - || (rNextNext3 == NoReg))))); - size4 = rTop31; - source1 = rNext14; - dest1 = rNextNext3; - nativePopToReg(ssNativeTop(), size4); - ssNativePop(1); - nativePopToReg(ssNativeTop(), source1); - ssNativePop(1); - nativePopToReg(ssNativeTop(), dest1); - ssNativePop(1); - /* begin ssFlushAll */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i6 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i6 <= simStackPtr; i6 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i6), frameOffsetOfTemporary(i6 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - voidReceiverResultRegContainsSelf(); - genMemCopytosize(backEnd, source1, dest1, sizeLow1); - return 0; - - case 133: - /* begin genLowcodeMemcpyFixed */ - size5 = extA; - /* begin allocateRegistersForLowcodeInteger2: */ - topRegistersMask13 = 0; - rTop32 = (rNext15 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop32 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext15 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext15 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg11 = (rNext15 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask13 = 1U << reg11; - } - } - if (rTop32 == NoReg) { - rTop32 = allocateRegNotConflictingWith(topRegistersMask13); - } - if (rNext15 == NoReg) { - rNext15 = allocateRegNotConflictingWith(1U << rTop32); - } - assert(!(((rTop32 == NoReg) - || (rNext15 == NoReg)))); - source2 = rTop32; - dest2 = rNext15; - nativePopToReg(ssNativeTop(), source2); - ssNativePop(1); - nativePopToReg(ssNativeTop(), dest2); - ssNativePop(1); - if (size5 == BytesPerWord) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction23 = genoperandoperandoperand(MoveMwrR, 0, source2, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction110 = genoperandoperandoperand(MoveRMwr, TempReg, 0, dest2); - } - else { - /* begin ssFlushAll */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i7 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i7 <= simStackPtr; i7 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i7), frameOffsetOfTemporary(i7 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - voidReceiverResultRegContainsSelf(); - genMemCopytoconstantSize(backEnd, source2, dest2, size5); - } - extA = 0; - return 0; - - case 134: - /* begin genLowcodeMoveFloat32ToPhysical */ - nativeStackPopToReg(ssNativeTop(), extA); - ssNativePop(1); - currentCallCleanUpSize += BytesPerWord; - extA = 0; - return 0; - - case 135: - /* begin genLowcodeMoveFloat64ToPhysical */ - nativeStackPopToReg(ssNativeTop(), extA); - ssNativePop(1); - currentCallCleanUpSize += 8; - extA = 0; - return 0; - - case 136: - /* begin genLowcodeMoveInt32ToPhysical */ - nativeStackPopToReg(ssNativeTop(), extA); - ssNativePop(1); - currentCallCleanUpSize += BytesPerWord; - extA = 0; - return 0; - - case 137: - /* begin genLowcodeMoveInt64ToPhysical */ - nativeStackPopToReg(ssNativeTop(), extA); - ssNativePop(1); - currentCallCleanUpSize += 8; - extA = 0; - return 0; - - case 138: - /* begin genLowcodeMovePointerToPhysical */ - nativeStackPopToReg(ssNativeTop(), extA); - ssNativePop(1); - currentCallCleanUpSize += BytesPerWord; - extA = 0; - return 0; - - case 139: - /* begin genLowcodeMul32 */ - topRegistersMask = 0; - rTop5 = (rNext = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop5 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask = 1U << reg; - } - } - if (rTop5 == NoReg) { - rTop5 = allocateRegNotConflictingWith(topRegistersMask); - } - if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1U << rTop5); - } - assert(!(((rTop5 == NoReg) - || (rNext == NoReg)))); - second = rTop5; - first = rNext; - nativePopToReg(ssNativeTop(), second); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first); - ssNativePop(1); - /* begin MulR:R: */ - genMulRR(backEnd, second, first); - ssPushNativeRegister(first); - return 0; - - case 140: - /* begin genLowcodeMul64 */ - topRegistersMask1 = 0; - rTop6 = (rNext1 = NoReg); - rResult5 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop6 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext1 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext1 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg1 = (rNext1 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask1 = 1U << reg1; - } - } - if (rTop6 == NoReg) { - rTop6 = allocateRegNotConflictingWith(topRegistersMask1); - } - if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop6); - } - assert(!(((rTop6 == NoReg) - || (rNext1 == NoReg)))); - rResult5 = allocateFloatRegNotConflictingWith((1U << rTop6) | (1U << rNext1)); - assert(!((rResult5 == NoReg))); - second1 = rTop6; - first1 = rNext1; - result = rResult5; - nativePopToReg(ssNativeTop(), second1); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first1); - ssNativePop(1); - abort(); - return 0; - - case 141: - /* begin genLowcodeNeg32 */ - rTop7 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop7 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop7 == NoReg) { - rTop7 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rTop7 == NoReg))); - value4 = rTop7; - nativePopToReg(ssNativeTop(), value4); - ssNativePop(1); - /* begin NegateR: */ - genoperand(NegateR, value4); - ssPushNativeRegister(value4); - return 0; - - case 142: - /* begin genLowcodeNeg64 */ - /* begin allocateRegistersForLowcodeInteger2: */ - topRegistersMask2 = 0; - rTop8 = (rNext2 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop8 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext2 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext2 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg2 = (rNext2 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask2 = 1U << reg2; - } - } - if (rTop8 == NoReg) { - rTop8 = allocateRegNotConflictingWith(topRegistersMask2); - } - if (rNext2 == NoReg) { - rNext2 = allocateRegNotConflictingWith(1U << rTop8); - } - assert(!(((rTop8 == NoReg) - || (rNext2 == NoReg)))); - valueLow1 = rTop8; - valueHigh1 = rNext2; - nativePopToRegsecondReg(ssNativeTop(), valueLow1, valueHigh1); - ssNativePop(1); - /* begin NotR: */ - genoperand(NotR, valueLow1); - /* begin NotR: */ - genoperand(NotR, valueHigh1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperand(AddCqR, 1, valueLow1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperand(AddcCqR, 0, valueHigh1); - ssPushNativeRegistersecondRegister(valueLow1, valueHigh1); - return 0; - - case 143: - /* begin genLowcodeNot32 */ - rTop9 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop9 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop9 == NoReg) { - rTop9 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rTop9 == NoReg))); - value6 = rTop9; - nativePopToReg(ssNativeTop(), value6); - ssNativePop(1); - /* begin NotR: */ - genoperand(NotR, value6); - ssPushNativeRegister(value6); - return 0; - - case 144: - /* begin genLowcodeNot64 */ - /* begin allocateRegistersForLowcodeInteger2: */ - topRegistersMask3 = 0; - rTop10 = (rNext3 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop10 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext3 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext3 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg3 = (rNext3 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask3 = 1U << reg3; - } - } - if (rTop10 == NoReg) { - rTop10 = allocateRegNotConflictingWith(topRegistersMask3); - } - if (rNext3 == NoReg) { - rNext3 = allocateRegNotConflictingWith(1U << rTop10); - } - assert(!(((rTop10 == NoReg) - || (rNext3 == NoReg)))); - valueLow2 = rTop10; - valueHigh2 = rNext3; - nativePopToRegsecondReg(ssNativeTop(), valueLow2, valueHigh2); - ssNativePop(1); - /* begin NotR: */ - genoperand(NotR, valueLow2); - /* begin NotR: */ - genoperand(NotR, valueHigh2); - ssPushNativeRegistersecondRegister(valueLow2, valueHigh2); - return 0; - - case 145: - /* begin genLowcodeOr32 */ - topRegistersMask4 = 0; - rTop14 = (rNext4 = NoReg); - rResult6 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop14 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext4 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext4 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg4 = (rNext4 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask4 = 1U << reg4; - } - } - if (rTop14 == NoReg) { - rTop14 = allocateRegNotConflictingWith(topRegistersMask4); - } - if (rNext4 == NoReg) { - rNext4 = allocateRegNotConflictingWith(1U << rTop14); - } - assert(!(((rTop14 == NoReg) - || (rNext4 == NoReg)))); - rResult6 = allocateFloatRegNotConflictingWith((1U << rTop14) | (1U << rNext4)); - assert(!((rResult6 == NoReg))); - second2 = rTop14; - first2 = rNext4; - result1 = rResult6; - nativePopToReg(ssNativeTop(), second2); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first2); - ssNativePop(1); - /* begin OrR:R: */ - genoperandoperand(OrRR, second2, first2); - ssPushNativeRegister(first2); - return 0; - - case 146: - /* begin genLowcodeOr64 */ - /* begin allocateRegistersForLowcodeInteger4: */ - rTop15 = (rNext5 = (rNextNext = (rNextNextNext = NoReg))); - nativeValueIndex = 1; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop15 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext5 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext5 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex))) != NoReg) { - rNext5 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex)); - if ((nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex))) != NoReg) { - rNextNext = nativeRegisterOrNone(ssNativeValue(nativeValueIndex)); - } - nativeValueIndex += 1; - } - } - if (rNextNext == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex))) != NoReg) { - rNextNext = nativeRegisterOrNone(ssNativeValue(nativeValueIndex)); - if ((nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex))) != NoReg) { - rNextNextNext = nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex)); - } - nativeValueIndex += 1; - } - } - if (rNextNextNext == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex))) != NoReg) { - rNextNextNext = nativeRegisterOrNone(ssNativeValue(nativeValueIndex)); - nativeValueIndex += 1; - } - } - if (rTop15 == NoReg) { - nextRegisterMask = 0; - if (rNext5 != NoReg) { - /* begin registerMaskFor: */ - nextRegisterMask = 1U << rNext5; - } - if (rNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNext); - } - if (rNextNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNextNext); - } - rTop15 = allocateRegNotConflictingWith(nextRegisterMask); - } - if (rNext5 == NoReg) { - /* begin registerMaskFor: */ - nextRegisterMask = 1U << rTop15; - if (rNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNext); - } - if (rNextNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNextNext); - } - rNext5 = allocateRegNotConflictingWith(nextRegisterMask); - } - if (rNextNext == NoReg) { - /* begin registerMaskFor:and: */ - nextRegisterMask = (1U << rTop15) | (1U << rNext5); - if (rNextNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNextNext); - } - rNextNext = allocateRegNotConflictingWith(nextRegisterMask); - } - if (rNextNextNext == NoReg) { - /* begin registerMaskFor:and:and: */ - nextRegisterMask = ((1U << rTop15) | (1U << rNext5)) | (1U << rNextNext); - rNextNextNext = allocateRegNotConflictingWith(nextRegisterMask); - } - assert(!(((rTop15 == NoReg) - || ((rNext5 == NoReg) - || ((rNextNext == NoReg) - || (rNextNextNext == NoReg)))))); - secondLow1 = rTop15; - secondHigh1 = rNext5; - firstLow1 = rNextNext; - firstHigh1 = rNextNextNext; - nativePopToRegsecondReg(ssNativeTop(), secondLow1, secondHigh1); - ssNativePop(1); - nativePopToRegsecondReg(ssNativeTop(), firstLow1, firstHigh1); - ssNativePop(1); - /* begin OrR:R: */ - genoperandoperand(OrRR, secondLow1, firstLow1); - /* begin OrR:R: */ - genoperandoperand(OrRR, secondHigh1, firstHigh1); - ssPushNativeRegistersecondRegister(firstLow1, firstHigh1); - return 0; - - case 147: - /* begin genLowcodePerformCallout */ - callSwitchToCStack(); - /* begin checkLiteral:forInstruction: */ - anInstruction14 = genoperandoperand(MoveCwR, extA, TempReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceFFICalloutTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin annotateBytecode: */ - abstractInstruction1 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction1->annotation = HasBytecodePC); - extA = 0; - return 0; - - case 148: - /* begin genLowcodePerformCalloutIndirect */ - nativeStackPopToReg(ssNativeTop(), TempReg); - ssNativePop(1); - callSwitchToCStack(); - /* begin CallRT: */ - abstractInstruction2 = genoperand(Call, ceFFICalloutTrampoline); - (abstractInstruction2->annotation = IsRelativeCall); - /* begin annotateBytecode: */ - abstractInstruction11 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction11->annotation = HasBytecodePC); - return 0; - - case 149: - /* begin genLowcodePushCalloutResultFloat32 */ - cFloatResultToRs(backEnd, DPFPReg0); - ssPushNativeRegisterSingleFloat(DPFPReg0); - return 0; - - case 150: - /* begin genLowcodePushCalloutResultFloat64 */ - cFloatResultToRd(backEnd, DPFPReg0); - ssPushNativeRegisterDoubleFloat(DPFPReg0); - return 0; - - case 151: - /* begin genLowcodePushCalloutResultInt32 */ - genoperandoperand(MoveRR, ABIResultReg, ReceiverResultReg); - ssPushNativeRegister(ReceiverResultReg); - return 0; - - case 152: - /* begin genLowcodePushCalloutResultInt64 */ - genoperandoperand(MoveRR, ABIResultReg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ABIResultRegHigh, Arg0Reg); - ssPushNativeRegistersecondRegister(ReceiverResultReg, Arg0Reg); - return 0; - - case 153: - /* begin genLowcodePushCalloutResultPointer */ - genoperandoperand(MoveRR, ABIResultReg, ReceiverResultReg); - ssPushNativeRegister(ReceiverResultReg); - return 0; - - case 161: - /* begin genLowcodePlaftormCode */ - abort(); - return 0; - - case 162: - /* begin genLowcodePointerAddConstantOffset */ - offset4 = extB; - /* begin allocateRegistersForLowcodeInteger: */ - rTop17 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop17 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop17 == NoReg) { - rTop17 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rTop17 == NoReg))); - base = rTop17; - nativePopToReg(ssNativeTop(), base); - ssNativePop(1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperand(AddCqR, offset4, base); - ssPushNativeRegister(base); - extB = 0; - numExtB = 0; - return 0; - - case 163: - /* begin genLowcodePointerAddOffset32 */ - topRegistersMask6 = 0; - rTop18 = (rNext6 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop18 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext6 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext6 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg6 = (rNext6 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask6 = 1U << reg6; - } - } - if (rTop18 == NoReg) { - rTop18 = allocateRegNotConflictingWith(topRegistersMask6); - } - if (rNext6 == NoReg) { - rNext6 = allocateRegNotConflictingWith(1U << rTop18); - } - assert(!(((rTop18 == NoReg) - || (rNext6 == NoReg)))); - offset5 = rTop18; - base1 = rNext6; - nativePopToReg(ssNativeTop(), offset5); - ssNativePop(1); - nativePopToReg(ssNativeTop(), base1); - ssNativePop(1); - /* begin AddR:R: */ - genoperandoperand(AddRR, offset5, base1); - ssPushNativeRegister(base1); - return 0; - - case 164: - /* begin genLowcodePointerAddOffset64 */ - /* begin allocateRegistersForLowcodeInteger3: */ - rTop20 = (rNext7 = (rNextNext1 = NoReg)); - nativeValueIndex1 = 1; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop20 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext7 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext7 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex1))) != NoReg) { - rNext7 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex1)); - if ((nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex1))) != NoReg) { - rNextNext1 = nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex1)); - } - nativeValueIndex1 += 1; - } - } - if (rNextNext1 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex1))) != NoReg) { - rNextNext1 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex1)); - } - } - if (rTop20 == NoReg) { - nextRegisterMask1 = 0; - if (rNext7 != NoReg) { - /* begin registerMaskFor: */ - nextRegisterMask1 = 1U << rNext7; - } - if (rNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNext1); - } - rTop20 = allocateRegNotConflictingWith(nextRegisterMask1); - } - if (rNext7 == NoReg) { - /* begin registerMaskFor: */ - nextRegisterMask1 = 1U << rTop20; - if (rNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNext1); - } - rNext7 = allocateRegNotConflictingWith(nextRegisterMask1); - } - if (rNextNext1 == NoReg) { - /* begin registerMaskFor:and: */ - nextRegisterMask1 = (1U << rTop20) | (1U << rNext7); - rNextNext1 = allocateRegNotConflictingWith(nextRegisterMask1); - } - assert(!(((rTop20 == NoReg) - || ((rNext7 == NoReg) - || (rNextNext1 == NoReg))))); - offsetLow = rTop20; - offsetHigh = rNext7; - base2 = rNextNext1; - nativePopToRegsecondReg(ssNativeTop(), offsetLow, offsetHigh); - ssNativePop(1); - nativePopToReg(ssNativeTop(), base2); - ssNativePop(1); - /* begin AddR:R: */ - genoperandoperand(AddRR, offsetLow, base2); - ssPushNativeRegister(base2); - return 0; - - case 165: - /* begin genLowcodePointerEqual */ - topRegistersMask8 = 0; - rTop21 = (rNext8 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop21 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext8 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext8 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg8 = (rNext8 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask8 = 1U << reg8; - } - } - if (rTop21 == NoReg) { - rTop21 = allocateRegNotConflictingWith(topRegistersMask8); - } - if (rNext8 == NoReg) { - rNext8 = allocateRegNotConflictingWith(1U << rTop21); - } - assert(!(((rTop21 == NoReg) - || (rNext8 == NoReg)))); - second4 = rTop21; - first4 = rNext8; - nativePopToReg(ssNativeTop(), second4); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first4); - ssNativePop(1); - /* begin CmpR:R: */ - assert(!((second4 == SPReg))); - genoperandoperand(CmpRR, second4, first4); - /* begin JumpNonZero: */ - falseJump = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction16 = genoperandoperand(MoveCqR, 1, first4); - /* begin Jump: */ - contJump = genoperand(Jump, ((sqInt)0)); - jmpTarget(falseJump, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperand(MoveCqR, 0, first4); - jmpTarget(contJump, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(first4); - return 0; - - case 166: - /* begin genLowcodePointerNotEqual */ - topRegistersMask9 = 0; - rTop22 = (rNext9 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop22 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext9 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext9 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg9 = (rNext9 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask9 = 1U << reg9; - } - } - if (rTop22 == NoReg) { - rTop22 = allocateRegNotConflictingWith(topRegistersMask9); - } - if (rNext9 == NoReg) { - rNext9 = allocateRegNotConflictingWith(1U << rTop22); - } - assert(!(((rTop22 == NoReg) - || (rNext9 == NoReg)))); - second5 = rTop22; - first5 = rNext9; - nativePopToReg(ssNativeTop(), second5); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first5); - ssNativePop(1); - /* begin CmpR:R: */ - assert(!((second5 == SPReg))); - genoperandoperand(CmpRR, second5, first5); - /* begin JumpZero: */ - falseJump1 = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction18 = genoperandoperand(MoveCqR, 1, first5); - /* begin Jump: */ - contJump1 = genoperand(Jump, ((sqInt)0)); - jmpTarget(falseJump1, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperand(MoveCqR, 0, first5); - jmpTarget(contJump1, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(first5); - return 0; - - case 167: - /* begin genLowcodePointerToInt32 */ - rTop23 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop23 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop23 == NoReg) { - rTop23 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rTop23 == NoReg))); - pointer5 = rTop23; - nativePopToReg(ssNativeTop(), pointer5); - ssNativePop(1); - ssPushNativeRegister(pointer5); - return 0; - - case 168: - /* begin genLowcodePointerToInt64 */ - /* begin allocateRegistersForLowcodeIntegerResultInteger2: */ - rTop24 = NoReg; - rResult7 = (rResult7 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop24 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop24 == NoReg) { - rTop24 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult7 = allocateRegNotConflictingWith(1U << rTop24); - rResult22 = allocateRegNotConflictingWith((1U << rTop24) | (1U << rResult7)); - assert(!(((rTop24 == NoReg) - || ((rResult7 == NoReg) - || (rResult22 == NoReg))))); - pointer6 = rTop24; - resultLow1 = rResult7; - resultHigh1 = rResult22; - nativePopToReg(ssNativeTop(), pointer6); - ssNativePop(1); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, pointer6, resultLow1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperand(MoveCqR, 0, resultHigh1); - ssPushNativeRegistersecondRegister(resultLow1, resultHigh1); - return 0; - - case 169: - /* begin genLowcodePopFloat32 */ - topRegistersMask10 = 0; - frTop = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop = nativeFloatRegisterOrNone(ssNativeTop()); - } - if (frTop == NoReg) { - frTop = allocateFloatRegNotConflictingWith(topRegistersMask10); - } - assert(!((frTop == NoReg))); - value8 = frTop; - nativePopToReg(ssNativeTop(), value8); - ssNativePop(1); - return 0; - - case 170: - /* begin genLowcodePopFloat64 */ - topRegistersMask11 = 0; - frTop1 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop1 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if (frTop1 == NoReg) { - frTop1 = allocateFloatRegNotConflictingWith(topRegistersMask11); - } - assert(!((frTop1 == NoReg))); - value9 = frTop1; - nativePopToReg(ssNativeTop(), value9); - ssNativePop(1); - return 0; - - case 171: - /* begin genLowcodePopInt32 */ - rTop25 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop25 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop25 == NoReg) { - rTop25 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rTop25 == NoReg))); - value10 = rTop25; - nativePopToReg(ssNativeTop(), value10); - ssNativePop(1); - return 0; - - case 172: - /* begin genLowcodePopInt64 */ - rTop26 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop26 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop26 == NoReg) { - rTop26 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rTop26 == NoReg))); - value11 = rTop26; - nativePopToReg(ssNativeTop(), value11); - ssNativePop(1); - return 0; - - case 173: - /* begin genLowcodePopMultipleNative */ - ssPopNativeSize(extA); - extA = 0; - return 0; - - case 174: - /* begin genLowcodePopPointer */ - rTop27 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop27 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop27 == NoReg) { - rTop27 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rTop27 == NoReg))); - pointerValue7 = rTop27; - nativePopToReg(ssNativeTop(), pointerValue7); - ssNativePop(1); - return 0; - - case 175: - /* begin genLowcodePushConstantUInt32 */ - constant = extA; - ssPushNativeConstantInt32(constant); - extA = 0; - return 0; - - case 176: - /* begin genLowcodePushConstantUInt64 */ - constant1 = extA; - ssPushNativeConstantInt64(constant1); - extA = 0; - return 0; - - case 177: - /* begin genLowcodePushNullPointer */ - ssPushNativeConstantPointer(0); - return 0; - - case 178: - /* begin genLowcodePushOne32 */ - ssPushNativeConstantInt32(1); - return 0; - - case 179: - /* begin genLowcodePushOne64 */ - ssPushNativeConstantInt64(1); - return 0; - - case 180: - /* begin genLowcodePushOneFloat32 */ - ssPushNativeConstantFloat32(1.0); - return 0; - - case 181: - /* begin genLowcodePushOneFloat64 */ - ssPushNativeConstantFloat64(1.0); - return 0; - - case 182: - /* begin genLowcodePushPhysicalFloat32 */ - registerID = extA; - abort(); - extA = 0; - return 0; - - case 183: - /* begin genLowcodePushPhysicalFloat64 */ - registerID1 = extA; - abort(); - extA = 0; - return 0; - - case 184: - /* begin genLowcodePushPhysicalInt32 */ - registerID2 = extA; - abort(); - extA = 0; - return 0; - - case 185: - /* begin genLowcodePushPhysicalInt64 */ - registerID3 = extA; - abort(); - extA = 0; - return 0; - - case 186: - /* begin genLowcodePushPhysicalPointer */ - registerID4 = extA; - abort(); - extA = 0; - return 0; - - default: - return genLowcodeUnaryInlinePrimitive4(prim); - - } - return 0; -} - - -/* Lowcode instruction generator dispatch */ - - /* StackToRegisterMappingCogit>>#genLowcodeUnaryInlinePrimitive4: */ -static sqInt NoDbgRegParms -genLowcodeUnaryInlinePrimitive4(sqInt prim) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction112; - AbstractInstruction *anInstruction113; - AbstractInstruction *anInstruction114; - AbstractInstruction *anInstruction115; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction24; - AbstractInstruction *anInstruction25; - AbstractInstruction *anInstruction26; - AbstractInstruction *anInstruction28; - AbstractInstruction *anInstruction29; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction30; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction32; - AbstractInstruction *anInstruction33; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt baseOffset; - sqInt baseOffset1; - sqInt baseOffset2; - sqInt baseOffset3; - sqInt baseOffset4; - sqInt baseOffset5; - sqInt baseOffset6; - AbstractInstruction * cont; - AbstractInstruction * cont1; - AbstractInstruction * cont2; - AbstractInstruction * contJump; - AbstractInstruction * contJump1; - AbstractInstruction * contJump2; - AbstractInstruction * contJump3; - sqInt doubleValue; - AbstractInstruction * falseJump; - AbstractInstruction * falseJump1; - AbstractInstruction * falseJump2; - AbstractInstruction * falseJump3; - sqInt first; - sqInt first1; - sqInt first10; - sqInt first13; - sqInt first14; - sqInt first15; - sqInt first16; - sqInt first17; - sqInt first18; - sqInt first19; - AbstractInstruction * first2; - sqInt first20; - sqInt first21; - sqInt first22; - sqInt first23; - sqInt first24; - sqInt first25; - AbstractInstruction * first27; - AbstractInstruction * first28; - AbstractInstruction * first29; - AbstractInstruction * first3; - AbstractInstruction * first4; - AbstractInstruction * first6; - sqInt first7; - sqInt firstHigh1; - sqInt firstHigh9; - sqInt firstLow1; - sqInt firstLow9; - sqInt first9; - sqInt floatValue; - sqInt frResult; - sqInt frResult1; - sqInt frResult2; - sqInt frResult3; - sqInt frTop; - sqInt frTop1; - sqInt frTop2; - sqInt frTop3; - AbstractInstruction * isNegative; - AbstractInstruction * isNegative1; - AbstractInstruction * isNegative2; - sqInt memoryPointer; - sqInt nativeValueIndex; - sqInt nativeValueIndex1; - sqInt nativeValueIndex2; - sqInt nextRegisterMask; - sqInt nextRegisterMask1; - sqInt nextRegisterMask2; - sqInt pointer; - sqInt pointer1; - sqInt pointer2; - sqInt pointer3; - sqInt pointer4; - sqInt pointer5; - sqInt pointerValue6; - sqInt pointerValue7; - sqInt reg; - sqInt reg1; - sqInt reg10; - sqInt reg11; - sqInt reg12; - sqInt reg14; - sqInt reg15; - sqInt reg16; - sqInt reg17; - sqInt reg18; - sqInt reg19; - sqInt reg2; - sqInt reg20; - sqInt reg21; - sqInt reg22; - sqInt reg23; - sqInt reg24; - sqInt reg25; - sqInt reg26; - sqInt reg27; - sqInt reg28; - sqInt reg29; - sqInt reg3; - sqInt reg30; - sqInt reg31; - sqInt reg33; - sqInt reg4; - sqInt reg5; - sqInt reg6; - sqInt reg7; - sqInt reg9; - sqInt result; - sqInt result1; - sqInt result10; - sqInt result11; - sqInt result4; - sqInt result5; - sqInt result6; - sqInt result7; - sqInt result8; - sqInt resultHigh2; - sqInt resultHigh3; - sqInt resultLow2; - sqInt resultLow3; - sqInt result9; - sqInt rNext; - sqInt rNext1; - sqInt rNext10; - sqInt rNext12; - sqInt rNext13; - sqInt rNext14; - sqInt rNext16; - sqInt rNext17; - sqInt rNext18; - sqInt rNext19; - sqInt rNext2; - sqInt rNext20; - sqInt rNext21; - sqInt rNext22; - sqInt rNext23; - sqInt rNext24; - sqInt rNext25; - sqInt rNext26; - sqInt rNext27; - sqInt rNext28; - sqInt rNext29; - sqInt rNext3; - sqInt rNext30; - sqInt rNext31; - sqInt rNext32; - sqInt rNext33; - sqInt rNext34; - sqInt rNext35; - sqInt rNext4; - sqInt rNext5; - sqInt rNext6; - sqInt rNext7; - sqInt rNext8; - sqInt rNextNext; - sqInt rNextNext1; - sqInt rNextNext2; - sqInt rNextNextNext; - sqInt rNextNextNext1; - sqInt rNext9; - sqInt rResult; - sqInt rResult1; - sqInt rResult10; - sqInt rResult14; - sqInt rResult15; - sqInt rResult2; - sqInt rResult21; - sqInt rResult3; - sqInt rResult4; - sqInt rResult5; - sqInt rResult6; - sqInt rResult7; - sqInt rResult8; - sqInt rResult9; - sqInt rTop; - sqInt rTop1; - sqInt rTop10; - sqInt rTop14; - sqInt rTop15; - sqInt rTop17; - sqInt rTop18; - sqInt rTop19; - sqInt rTop2; - sqInt rTop20; - sqInt rTop21; - sqInt rTop22; - sqInt rTop23; - sqInt rTop24; - sqInt rTop25; - sqInt rTop26; - sqInt rTop27; - sqInt rTop28; - sqInt rTop29; - sqInt rTop3; - sqInt rTop30; - sqInt rTop31; - sqInt rTop32; - sqInt rTop33; - sqInt rTop34; - sqInt rTop35; - sqInt rTop36; - sqInt rTop37; - sqInt rTop38; - sqInt rTop39; - sqInt rTop4; - sqInt rTop40; - sqInt rTop41; - sqInt rTop42; - sqInt rTop43; - sqInt rTop44; - sqInt rTop45; - sqInt rTop46; - sqInt rTop47; - sqInt rTop48; - sqInt rTop49; - sqInt rTop5; - sqInt rTop50; - sqInt rTop51; - sqInt rTop52; - sqInt rTop53; - sqInt rTop54; - sqInt rTop6; - sqInt rTop7; - sqInt rTop8; - sqInt rTop9; - sqInt second; - sqInt second1; - sqInt second10; - sqInt second11; - sqInt second12; - sqInt second13; - sqInt second14; - sqInt second15; - sqInt second16; - sqInt second17; - sqInt second18; - sqInt second2; - sqInt second4; - sqInt second5; - sqInt second6; - sqInt second7; - sqInt second8; - sqInt secondHigh1; - sqInt secondHigh9; - sqInt secondLow1; - sqInt secondLow9; - sqInt second9; - sqInt shiftAmount; - sqInt shiftAmount1; - sqInt topRegistersMask; - sqInt topRegistersMask1; - sqInt topRegistersMask10; - sqInt topRegistersMask11; - sqInt topRegistersMask12; - sqInt topRegistersMask13; - sqInt topRegistersMask14; - sqInt topRegistersMask16; - sqInt topRegistersMask17; - sqInt topRegistersMask18; - sqInt topRegistersMask19; - sqInt topRegistersMask2; - sqInt topRegistersMask20; - sqInt topRegistersMask21; - sqInt topRegistersMask22; - sqInt topRegistersMask23; - sqInt topRegistersMask24; - sqInt topRegistersMask25; - sqInt topRegistersMask26; - sqInt topRegistersMask27; - sqInt topRegistersMask28; - sqInt topRegistersMask29; - sqInt topRegistersMask3; - sqInt topRegistersMask30; - sqInt topRegistersMask31; - sqInt topRegistersMask32; - sqInt topRegistersMask33; - sqInt topRegistersMask35; - sqInt topRegistersMask4; - sqInt topRegistersMask5; - sqInt topRegistersMask6; - sqInt topRegistersMask7; - sqInt topRegistersMask9; - sqInt value; - sqInt value1; - sqInt value10; - sqInt value11; - sqInt value12; - sqInt value13; - sqInt value14; - sqInt value16; - sqInt value17; - sqInt value18; - sqInt value2; - sqInt value22; - sqInt value23; - sqInt value24; - sqInt value25; - sqInt value26; - sqInt value27; - sqInt value28; - sqInt value29; - sqInt value3; - sqInt value30; - sqInt value31; - sqInt value5; - sqInt value7; - sqInt value8; - sqInt valueHigh1; - sqInt valueHigh10; - sqInt valueHigh2; - sqInt valueHigh3; - sqInt valueHigh4; - sqInt valueHigh5; - sqInt valueHigh6; - sqInt valueHigh7; - sqInt valueLow1; - sqInt valueLow10; - sqInt valueLow2; - sqInt valueLow3; - sqInt valueLow4; - sqInt valueLow5; - sqInt valueLow6; - sqInt valueLow7; - - switch (prim) { - case 187: - /* begin genLowcodePushSessionIdentifier */ - ssPushNativeConstantInt32(getThisSessionID()); - return 0; - - case 188: - /* begin genLowcodePushZero32 */ - ssPushNativeConstantInt32(0); - return 0; - - case 189: - /* begin genLowcodePushZero64 */ - ssPushNativeConstantInt64(0); - return 0; - - case 190: - /* begin genLowcodePushZeroFloat32 */ - ssPushNativeConstantFloat32(0.0); - return 0; - - case 191: - /* begin genLowcodePushZeroFloat64 */ - ssPushNativeConstantFloat64(0.0); - return 0; - - case 192: - /* begin genLowcodeRem32 */ - topRegistersMask = 0; - rTop = (rNext = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask = 1U << reg; - } - } - if (rTop == NoReg) { - rTop = allocateRegNotConflictingWith(topRegistersMask); - } - if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1U << rTop); - } - assert(!(((rTop == NoReg) - || (rNext == NoReg)))); - second = rTop; - first = rNext; - nativePopToReg(ssNativeTop(), second); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first); - ssNativePop(1); - gDivRRQuoRem(second, first, second, first); - ssPushNativeRegister(first); - return 0; - - case 193: - /* begin genLowcodeRem64 */ - topRegistersMask1 = 0; - rTop1 = (rNext1 = NoReg); - rResult = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop1 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext1 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext1 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg1 = (rNext1 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask1 = 1U << reg1; - } - } - if (rTop1 == NoReg) { - rTop1 = allocateRegNotConflictingWith(topRegistersMask1); - } - if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); - } - assert(!(((rTop1 == NoReg) - || (rNext1 == NoReg)))); - rResult = allocateFloatRegNotConflictingWith((1U << rTop1) | (1U << rNext1)); - assert(!((rResult == NoReg))); - second1 = rTop1; - first1 = rNext1; - result = rResult; - nativePopToReg(ssNativeTop(), second1); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first1); - ssNativePop(1); - abort(); - return 0; - - case 194: - /* begin genLowcodeRightShift32 */ - topRegistersMask2 = 0; - rTop2 = (rNext2 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop2 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext2 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext2 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg2 = (rNext2 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask2 = 1U << reg2; - } - } - if (rTop2 == NoReg) { - rTop2 = allocateRegNotConflictingWith(topRegistersMask2); - } - if (rNext2 == NoReg) { - rNext2 = allocateRegNotConflictingWith(1U << rTop2); - } - assert(!(((rTop2 == NoReg) - || (rNext2 == NoReg)))); - shiftAmount = rTop2; - value = rNext2; - nativePopToReg(ssNativeTop(), shiftAmount); - ssNativePop(1); - nativePopToReg(ssNativeTop(), value); - ssNativePop(1); - /* begin LogicalShiftRightR:R: */ - genoperandoperand(LogicalShiftRightRR, shiftAmount, value); - ssPushNativeRegister(value); - return 0; - - case 195: - /* begin genLowcodeRightShift64 */ - topRegistersMask3 = 0; - rTop3 = (rNext3 = NoReg); - rResult1 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop3 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext3 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext3 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg3 = (rNext3 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask3 = 1U << reg3; - } - } - if (rTop3 == NoReg) { - rTop3 = allocateRegNotConflictingWith(topRegistersMask3); - } - if (rNext3 == NoReg) { - rNext3 = allocateRegNotConflictingWith(1U << rTop3); - } - assert(!(((rTop3 == NoReg) - || (rNext3 == NoReg)))); - rResult1 = allocateFloatRegNotConflictingWith((1U << rTop3) | (1U << rNext3)); - assert(!((rResult1 == NoReg))); - shiftAmount1 = rTop3; - value1 = rNext3; - result1 = rResult1; - nativePopToReg(ssNativeTop(), shiftAmount1); - ssNativePop(1); - nativePopToReg(ssNativeTop(), value1); - ssNativePop(1); - abort(); - return 0; - - case 196: - /* begin genLowcodeSignExtend32From16 */ - rTop4 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop4 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop4 == NoReg) { - rTop4 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rTop4 == NoReg))); - value2 = rTop4; - nativePopToReg(ssNativeTop(), value2); - ssNativePop(1); - /* begin SignExtend16R:R: */ - if (value2 == value2) { - /* begin LogicalShiftLeftCq:R: */ - first2 = genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 16, value2); - } - else { - /* begin MoveR:R: */ - first2 = genoperandoperand(MoveRR, value2, value2); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 16, value2); - } - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, (BytesPerWord * 8) - 16, value2); - goto l10; - l10: /* end SignExtend16R:R: */; - ssPushNativeRegister(value2); - return 0; - - case 197: - /* begin genLowcodeSignExtend32From8 */ - rTop5 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop5 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop5 == NoReg) { - rTop5 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rTop5 == NoReg))); - value3 = rTop5; - nativePopToReg(ssNativeTop(), value3); - ssNativePop(1); - /* begin SignExtend8R:R: */ - if (value3 == value3) { - /* begin LogicalShiftLeftCq:R: */ - first3 = genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 8, value3); - } - else { - /* begin MoveR:R: */ - first3 = genoperandoperand(MoveRR, value3, value3); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 8, value3); - } - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, (BytesPerWord * 8) - 8, value3); - goto l16; - l16: /* end SignExtend8R:R: */; - ssPushNativeRegister(value3); - return 0; - - case 198: - /* begin genLowcodeSignExtend64From16 */ - /* begin allocateRegistersForLowcodeInteger2: */ - topRegistersMask4 = 0; - rTop6 = (rNext4 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop6 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext4 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext4 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg4 = (rNext4 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask4 = 1U << reg4; - } - } - if (rTop6 == NoReg) { - rTop6 = allocateRegNotConflictingWith(topRegistersMask4); - } - if (rNext4 == NoReg) { - rNext4 = allocateRegNotConflictingWith(1U << rTop6); - } - assert(!(((rTop6 == NoReg) - || (rNext4 == NoReg)))); - valueLow1 = rTop6; - valueHigh1 = rNext4; - nativePopToRegsecondReg(ssNativeTop(), valueLow1, valueHigh1); - ssNativePop(1); - /* begin SignExtend16R:R: */ - if (valueLow1 == valueLow1) { - /* begin LogicalShiftLeftCq:R: */ - first4 = genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 16, valueLow1); - } - else { - /* begin MoveR:R: */ - first4 = genoperandoperand(MoveRR, valueLow1, valueLow1); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 16, valueLow1); - } - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, (BytesPerWord * 8) - 16, valueLow1); - goto l27; - l27: /* end SignExtend16R:R: */; - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, valueLow1); - /* begin JumpLess: */ - isNegative = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, 0, valueHigh1); - /* begin Jump: */ - cont = genoperand(Jump, ((sqInt)0)); - jmpTarget(isNegative, checkQuickConstantforInstruction(-1, genoperandoperand(MoveCqR, -1, valueHigh1))); - jmpTarget(cont, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegistersecondRegister(valueLow1, valueHigh1); - return 0; - - case 199: - /* begin genLowcodeSignExtend64From32 */ - /* begin allocateRegistersForLowcodeIntegerResultInteger2: */ - rTop7 = NoReg; - rResult3 = (rResult3 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop7 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop7 == NoReg) { - rTop7 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult3 = allocateRegNotConflictingWith(1U << rTop7); - rResult2 = allocateRegNotConflictingWith((1U << rTop7) | (1U << rResult3)); - assert(!(((rTop7 == NoReg) - || ((rResult3 == NoReg) - || (rResult2 == NoReg))))); - value5 = rTop7; - resultLow2 = rResult3; - resultHigh2 = rResult2; - nativePopToReg(ssNativeTop(), value5); - ssNativePop(1); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, value5, resultLow2); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(CmpCqR, 0, value5); - /* begin JumpLess: */ - isNegative1 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperand(MoveCqR, 0, resultHigh2); - /* begin Jump: */ - cont1 = genoperand(Jump, ((sqInt)0)); - jmpTarget(isNegative1, checkQuickConstantforInstruction(-1, genoperandoperand(MoveCqR, -1, resultHigh2))); - jmpTarget(cont1, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegistersecondRegister(resultLow2, resultHigh2); - return 0; - - case 200: - /* begin genLowcodeSignExtend64From8 */ - /* begin allocateRegistersForLowcodeInteger2ResultInteger2: */ - topRegistersMask5 = 0; - rTop8 = (rNext5 = NoReg); - rResult4 = (rResult21 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop8 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext5 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext5 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg5 = (rNext5 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask5 = 1U << reg5; - } - } - if (rTop8 == NoReg) { - rTop8 = allocateRegNotConflictingWith(topRegistersMask5); - } - if (rNext5 == NoReg) { - rNext5 = allocateRegNotConflictingWith(1U << rTop8); - } - assert(!(((rTop8 == NoReg) - || (rNext5 == NoReg)))); - rResult4 = allocateFloatRegNotConflictingWith((1U << rTop8) | (1U << rNext5)); - rResult21 = allocateFloatRegNotConflictingWith(((1U << rTop8) | (1U << rNext5)) | (1U << rResult4)); - assert(!(((rResult4 == NoReg) - || (rResult21 == NoReg)))); - valueLow2 = rTop8; - valueHigh2 = rNext5; - resultLow3 = rResult4; - resultHigh3 = rResult21; - nativePopToRegsecondReg(ssNativeTop(), valueLow2, valueHigh2); - ssNativePop(1); - /* begin SignExtend8R:R: */ - if (valueLow2 == valueLow2) { - /* begin LogicalShiftLeftCq:R: */ - first6 = genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 8, valueLow2); - } - else { - /* begin MoveR:R: */ - first6 = genoperandoperand(MoveRR, valueLow2, valueLow2); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 8, valueLow2); - } - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, (BytesPerWord * 8) - 8, valueLow2); - goto l56; - l56: /* end SignExtend8R:R: */; - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(CmpCqR, 0, valueLow2); - /* begin JumpLess: */ - isNegative2 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperand(MoveCqR, 0, valueHigh2); - /* begin Jump: */ - cont2 = genoperand(Jump, ((sqInt)0)); - jmpTarget(isNegative2, checkQuickConstantforInstruction(-1, genoperandoperand(MoveCqR, -1, valueHigh2))); - jmpTarget(cont2, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegistersecondRegister(valueLow2, valueHigh2); - return 0; - - case 201: - /* begin genLowcodeStoreFloat32ToMemory */ - - /* Integer registers */ - frTop = (rTop9 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop9 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop9 == NoReg) { - rTop9 = allocateRegNotConflictingWith(0); - } - if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { - frTop = nativeFloatRegisterOrNone(ssNativeValue(1)); - } - if (frTop == NoReg) { - frTop = allocateFloatRegNotConflictingWith(0); - } - assert(!(((frTop == NoReg) - || (rTop9 == NoReg)))); - floatValue = frTop; - pointer = rTop9; - nativePopToReg(ssNativeTop(), pointer); - ssNativePop(1); - nativePopToReg(ssNativeTop(), floatValue); - ssNativePop(1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperandoperand(MoveRsM32r, floatValue, 0, pointer); - return 0; - - case 202: - /* begin genLowcodeStoreFloat64ToMemory */ - - /* Integer registers */ - frTop1 = (rTop10 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop10 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop10 == NoReg) { - rTop10 = allocateRegNotConflictingWith(0); - } - if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { - frTop1 = nativeFloatRegisterOrNone(ssNativeValue(1)); - } - if (frTop1 == NoReg) { - frTop1 = allocateFloatRegNotConflictingWith(0); - } - assert(!(((frTop1 == NoReg) - || (rTop10 == NoReg)))); - doubleValue = frTop1; - pointer1 = rTop10; - nativePopToReg(ssNativeTop(), pointer1); - ssNativePop(1); - nativePopToReg(ssNativeTop(), doubleValue); - ssNativePop(1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(MoveRdM64r, doubleValue, 0, pointer1); - return 0; - - case 203: - /* begin genLowcodeStoreInt16ToMemory */ - topRegistersMask6 = 0; - rTop14 = (rNext6 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop14 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext6 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext6 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg6 = (rNext6 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask6 = 1U << reg6; - } - } - if (rTop14 == NoReg) { - rTop14 = allocateRegNotConflictingWith(topRegistersMask6); - } - if (rNext6 == NoReg) { - rNext6 = allocateRegNotConflictingWith(1U << rTop14); - } - assert(!(((rTop14 == NoReg) - || (rNext6 == NoReg)))); - pointer2 = rTop14; - value7 = rNext6; - nativePopToReg(ssNativeTop(), pointer2); - ssNativePop(1); - nativePopToReg(ssNativeTop(), value7); - ssNativePop(1); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, value7, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperandoperand(MoveRM16r, TempReg, 0, pointer2); - return 0; - - case 204: - /* begin genLowcodeStoreInt32ToMemory */ - topRegistersMask7 = 0; - rTop15 = (rNext7 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop15 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext7 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext7 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg7 = (rNext7 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask7 = 1U << reg7; - } - } - if (rTop15 == NoReg) { - rTop15 = allocateRegNotConflictingWith(topRegistersMask7); - } - if (rNext7 == NoReg) { - rNext7 = allocateRegNotConflictingWith(1U << rTop15); - } - assert(!(((rTop15 == NoReg) - || (rNext7 == NoReg)))); - pointer3 = rTop15; - value8 = rNext7; - nativePopToReg(ssNativeTop(), pointer3); - ssNativePop(1); - nativePopToReg(ssNativeTop(), value8); - ssNativePop(1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveRM32r, value8, 0, pointer3); - return 0; - - case 205: - /* begin genLowcodeStoreInt64ToMemory */ - /* begin allocateRegistersForLowcodeInteger3: */ - rTop17 = (rNext8 = (rNextNext = NoReg)); - nativeValueIndex = 1; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop17 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext8 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext8 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex))) != NoReg) { - rNext8 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex)); - if ((nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex))) != NoReg) { - rNextNext = nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex)); - } - nativeValueIndex += 1; - } - } - if (rNextNext == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex))) != NoReg) { - rNextNext = nativeRegisterOrNone(ssNativeValue(nativeValueIndex)); - } - } - if (rTop17 == NoReg) { - nextRegisterMask = 0; - if (rNext8 != NoReg) { - /* begin registerMaskFor: */ - nextRegisterMask = 1U << rNext8; - } - if (rNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNext); - } - rTop17 = allocateRegNotConflictingWith(nextRegisterMask); - } - if (rNext8 == NoReg) { - /* begin registerMaskFor: */ - nextRegisterMask = 1U << rTop17; - if (rNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNext); - } - rNext8 = allocateRegNotConflictingWith(nextRegisterMask); - } - if (rNextNext == NoReg) { - /* begin registerMaskFor:and: */ - nextRegisterMask = (1U << rTop17) | (1U << rNext8); - rNextNext = allocateRegNotConflictingWith(nextRegisterMask); - } - assert(!(((rTop17 == NoReg) - || ((rNext8 == NoReg) - || (rNextNext == NoReg))))); - pointer4 = rTop17; - valueLow3 = rNext8; - valueHigh3 = rNextNext; - nativePopToReg(ssNativeTop(), pointer4); - ssNativePop(1); - nativePopToRegsecondReg(ssNativeTop(), valueLow3, valueHigh3); - ssNativePop(1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperandoperand(MoveRM32r, valueLow3, 0, pointer4); - /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperandoperand(MoveRM32r, valueHigh3, 4, pointer4); - return 0; - - case 206: - /* begin genLowcodeStoreInt8ToMemory */ - topRegistersMask9 = 0; - rTop18 = (rNext9 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop18 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext9 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext9 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg9 = (rNext9 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask9 = 1U << reg9; - } - } - if (rTop18 == NoReg) { - rTop18 = allocateRegNotConflictingWith(topRegistersMask9); - } - if (rNext9 == NoReg) { - rNext9 = allocateRegNotConflictingWith(1U << rTop18); - } - assert(!(((rTop18 == NoReg) - || (rNext9 == NoReg)))); - pointer5 = rTop18; - value10 = rNext9; - nativePopToReg(ssNativeTop(), pointer5); - ssNativePop(1); - nativePopToReg(ssNativeTop(), value10); - ssNativePop(1); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, value10, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperandoperand(MoveRM8r, TempReg, 0, pointer5); - return 0; - - case 207: - /* begin genLowcodeStoreLocalFloat32 */ - baseOffset = extA; - /* begin allocateRegistersForLowcodeFloat: */ - topRegistersMask10 = 0; - frTop2 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop2 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if (frTop2 == NoReg) { - frTop2 = allocateFloatRegNotConflictingWith(topRegistersMask10); - } - assert(!((frTop2 == NoReg))); - value11 = frTop2; - nativePopToReg(ssNativeTop(), value11); - ssNativePop(1); - loadNativeLocalAddressto(baseOffset, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveRsM32r, value11, 0, TempReg); - extA = 0; - return 0; - - case 208: - /* begin genLowcodeStoreLocalFloat64 */ - baseOffset1 = extA; - /* begin allocateRegistersForLowcodeFloat: */ - topRegistersMask11 = 0; - frTop3 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop3 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if (frTop3 == NoReg) { - frTop3 = allocateFloatRegNotConflictingWith(topRegistersMask11); - } - assert(!((frTop3 == NoReg))); - value12 = frTop3; - nativePopToReg(ssNativeTop(), value12); - ssNativePop(1); - loadNativeLocalAddressto(baseOffset1, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperandoperand(MoveRdM64r, value12, 0, TempReg); - extA = 0; - return 0; - - case 209: - /* begin genLowcodeStoreLocalInt16 */ - baseOffset2 = extA; - /* begin allocateRegistersForLowcodeInteger: */ - rTop19 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop19 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop19 == NoReg) { - rTop19 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rTop19 == NoReg))); - value13 = rTop19; - nativePopToReg(ssNativeTop(), value13); - ssNativePop(1); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, value13, TempReg); - loadNativeLocalAddressto(baseOffset2, value13); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperandoperand(MoveRM16r, TempReg, 0, value13); - extA = 0; - return 0; - - case 210: - /* begin genLowcodeStoreLocalInt32 */ - baseOffset3 = extA; - /* begin allocateRegistersForLowcodeInteger: */ - rTop20 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop20 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop20 == NoReg) { - rTop20 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rTop20 == NoReg))); - value14 = rTop20; - nativePopToReg(ssNativeTop(), value14); - ssNativePop(1); - loadNativeLocalAddressto(baseOffset3, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction16 = genoperandoperandoperand(MoveRM32r, value14, 0, TempReg); - extA = 0; - return 0; - - case 211: - /* begin genLowcodeStoreLocalInt64 */ - baseOffset4 = extA; - /* begin allocateRegistersForLowcodeInteger2: */ - topRegistersMask12 = 0; - rTop21 = (rNext10 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop21 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext10 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext10 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg10 = (rNext10 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask12 = 1U << reg10; - } - } - if (rTop21 == NoReg) { - rTop21 = allocateRegNotConflictingWith(topRegistersMask12); - } - if (rNext10 == NoReg) { - rNext10 = allocateRegNotConflictingWith(1U << rTop21); - } - assert(!(((rTop21 == NoReg) - || (rNext10 == NoReg)))); - valueLow4 = rTop21; - valueHigh4 = rNext10; - nativePopToRegsecondReg(ssNativeTop(), valueLow4, valueHigh4); - ssNativePop(1); - loadNativeLocalAddressto(baseOffset4, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperandoperand(MoveRM32r, valueLow4, 0, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction18 = genoperandoperandoperand(MoveRM32r, valueHigh4, 4, TempReg); - extA = 0; - return 0; - - case 212: - /* begin genLowcodeStoreLocalInt8 */ - baseOffset5 = extA; - /* begin allocateRegistersForLowcodeInteger: */ - rTop22 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop22 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop22 == NoReg) { - rTop22 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rTop22 == NoReg))); - value16 = rTop22; - nativePopToReg(ssNativeTop(), value16); - ssNativePop(1); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, value16, TempReg); - loadNativeLocalAddressto(baseOffset5, value16); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperandoperand(MoveRM8r, TempReg, 0, value16); - extA = 0; - return 0; - - case 213: - /* begin genLowcodeStoreLocalPointer */ - baseOffset6 = extA; - /* begin allocateRegistersForLowcodeInteger: */ - rTop23 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop23 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop23 == NoReg) { - rTop23 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rTop23 == NoReg))); - pointerValue6 = rTop23; - nativePopToReg(ssNativeTop(), pointerValue6); - ssNativePop(1); - loadNativeLocalAddressto(baseOffset6, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperandoperand(MoveRMwr, pointerValue6, 0, TempReg); - extA = 0; - return 0; - - case 214: - /* begin genLowcodeStorePointerToMemory */ - topRegistersMask13 = 0; - rTop24 = (rNext12 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop24 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext12 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext12 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg11 = (rNext12 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask13 = 1U << reg11; - } - } - if (rTop24 == NoReg) { - rTop24 = allocateRegNotConflictingWith(topRegistersMask13); - } - if (rNext12 == NoReg) { - rNext12 = allocateRegNotConflictingWith(1U << rTop24); - } - assert(!(((rTop24 == NoReg) - || (rNext12 == NoReg)))); - memoryPointer = rTop24; - pointerValue7 = rNext12; - nativePopToReg(ssNativeTop(), memoryPointer); - ssNativePop(1); - nativePopToReg(ssNativeTop(), pointerValue7); - ssNativePop(1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction23 = genoperandoperandoperand(MoveRMwr, pointerValue7, 0, memoryPointer); - return 0; - - case 215: - /* begin genLowcodeSub32 */ - topRegistersMask14 = 0; - rTop25 = (rNext13 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop25 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext13 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext13 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg12 = (rNext13 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask14 = 1U << reg12; - } - } - if (rTop25 == NoReg) { - rTop25 = allocateRegNotConflictingWith(topRegistersMask14); - } - if (rNext13 == NoReg) { - rNext13 = allocateRegNotConflictingWith(1U << rTop25); - } - assert(!(((rTop25 == NoReg) - || (rNext13 == NoReg)))); - second2 = rTop25; - first7 = rNext13; - nativePopToReg(ssNativeTop(), second2); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first7); - ssNativePop(1); - /* begin SubR:R: */ - genoperandoperand(SubRR, second2, first7); - ssPushNativeRegister(first7); - return 0; - - case 216: - /* begin genLowcodeSub64 */ - /* begin allocateRegistersForLowcodeInteger4: */ - rTop26 = (rNext14 = (rNextNext1 = (rNextNextNext = NoReg))); - nativeValueIndex1 = 1; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop26 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext14 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext14 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex1))) != NoReg) { - rNext14 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex1)); - if ((nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex1))) != NoReg) { - rNextNext1 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex1)); - } - nativeValueIndex1 += 1; - } - } - if (rNextNext1 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex1))) != NoReg) { - rNextNext1 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex1)); - if ((nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex1))) != NoReg) { - rNextNextNext = nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex1)); - } - nativeValueIndex1 += 1; - } - } - if (rNextNextNext == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex1))) != NoReg) { - rNextNextNext = nativeRegisterOrNone(ssNativeValue(nativeValueIndex1)); - nativeValueIndex1 += 1; - } - } - if (rTop26 == NoReg) { - nextRegisterMask1 = 0; - if (rNext14 != NoReg) { - /* begin registerMaskFor: */ - nextRegisterMask1 = 1U << rNext14; - } - if (rNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNext1); - } - if (rNextNextNext != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNextNext); - } - rTop26 = allocateRegNotConflictingWith(nextRegisterMask1); - } - if (rNext14 == NoReg) { - /* begin registerMaskFor: */ - nextRegisterMask1 = 1U << rTop26; - if (rNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNext1); - } - if (rNextNextNext != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNextNext); - } - rNext14 = allocateRegNotConflictingWith(nextRegisterMask1); - } - if (rNextNext1 == NoReg) { - /* begin registerMaskFor:and: */ - nextRegisterMask1 = (1U << rTop26) | (1U << rNext14); - if (rNextNextNext != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNextNext); - } - rNextNext1 = allocateRegNotConflictingWith(nextRegisterMask1); - } - if (rNextNextNext == NoReg) { - /* begin registerMaskFor:and:and: */ - nextRegisterMask1 = ((1U << rTop26) | (1U << rNext14)) | (1U << rNextNext1); - rNextNextNext = allocateRegNotConflictingWith(nextRegisterMask1); - } - assert(!(((rTop26 == NoReg) - || ((rNext14 == NoReg) - || ((rNextNext1 == NoReg) - || (rNextNextNext == NoReg)))))); - secondLow1 = rTop26; - secondHigh1 = rNext14; - firstLow1 = rNextNext1; - firstHigh1 = rNextNextNext; - nativePopToRegsecondReg(ssNativeTop(), secondLow1, secondHigh1); - ssNativePop(1); - nativePopToRegsecondReg(ssNativeTop(), firstLow1, firstHigh1); - ssNativePop(1); - /* begin SubR:R: */ - genoperandoperand(SubRR, secondLow1, firstLow1); - /* begin SubbR:R: */ - genoperandoperand(SubbRR, secondHigh1, firstHigh1); - ssPushNativeRegistersecondRegister(firstLow1, firstHigh1); - return 0; - - case 217: - /* begin genLowcodeTruncate32To16 */ - rTop27 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop27 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop27 == NoReg) { - rTop27 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rTop27 == NoReg))); - value17 = rTop27; - nativePopToReg(ssNativeTop(), value17); - ssNativePop(1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction24 = genoperandoperand(AndCqR, 0xFFFF, value17); - ssPushNativeRegister(value17); - return 0; - - case 218: - /* begin genLowcodeTruncate32To8 */ - rTop28 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop28 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop28 == NoReg) { - rTop28 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rTop28 == NoReg))); - value18 = rTop28; - nativePopToReg(ssNativeTop(), value18); - ssNativePop(1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction25 = genoperandoperand(AndCqR, 0xFF, value18); - ssPushNativeRegister(value18); - return 0; - - case 219: - /* begin genLowcodeTruncate64To16 */ - /* begin allocateRegistersForLowcodeInteger2: */ - topRegistersMask16 = 0; - rTop29 = (rNext16 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop29 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext16 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext16 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg14 = (rNext16 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask16 = 1U << reg14; - } - } - if (rTop29 == NoReg) { - rTop29 = allocateRegNotConflictingWith(topRegistersMask16); - } - if (rNext16 == NoReg) { - rNext16 = allocateRegNotConflictingWith(1U << rTop29); - } - assert(!(((rTop29 == NoReg) - || (rNext16 == NoReg)))); - valueLow5 = rTop29; - valueHigh5 = rNext16; - nativePopToRegsecondReg(ssNativeTop(), valueLow5, valueHigh5); - ssNativePop(1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction26 = genoperandoperand(AndCqR, 0xFFFF, valueLow5); - ssPushNativeRegister(valueLow5); - return 0; - - case 220: - /* begin genLowcodeTruncate64To32 */ - /* begin allocateRegistersForLowcodeInteger2: */ - topRegistersMask17 = 0; - rTop30 = (rNext17 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop30 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext17 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext17 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg15 = (rNext17 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask17 = 1U << reg15; - } - } - if (rTop30 == NoReg) { - rTop30 = allocateRegNotConflictingWith(topRegistersMask17); - } - if (rNext17 == NoReg) { - rNext17 = allocateRegNotConflictingWith(1U << rTop30); - } - assert(!(((rTop30 == NoReg) - || (rNext17 == NoReg)))); - valueLow6 = rTop30; - valueHigh6 = rNext17; - nativePopToRegsecondReg(ssNativeTop(), valueLow6, valueHigh6); - ssNativePop(1); - ssPushNativeRegister(valueLow6); - return 0; - - case 221: - /* begin genLowcodeTruncate64To8 */ - /* begin allocateRegistersForLowcodeInteger2ResultInteger: */ - topRegistersMask18 = 0; - rTop31 = (rNext18 = NoReg); - rResult5 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop31 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext18 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext18 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg16 = (rNext18 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask18 = 1U << reg16; - } - } - if (rTop31 == NoReg) { - rTop31 = allocateRegNotConflictingWith(topRegistersMask18); - } - if (rNext18 == NoReg) { - rNext18 = allocateRegNotConflictingWith(1U << rTop31); - } - assert(!(((rTop31 == NoReg) - || (rNext18 == NoReg)))); - rResult5 = allocateFloatRegNotConflictingWith((1U << rTop31) | (1U << rNext18)); - assert(!((rResult5 == NoReg))); - valueLow7 = rTop31; - valueHigh7 = rNext18; - result4 = rResult5; - nativePopToRegsecondReg(ssNativeTop(), valueLow7, valueHigh7); - ssNativePop(1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction28 = genoperandoperand(AndCqR, 0xFF, valueLow7); - ssPushNativeRegister(valueLow7); - return 0; - - case 222: - /* begin genLowcodeUdiv32 */ - topRegistersMask19 = 0; - rTop32 = (rNext19 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop32 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext19 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext19 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg17 = (rNext19 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask19 = 1U << reg17; - } - } - if (rTop32 == NoReg) { - rTop32 = allocateRegNotConflictingWith(topRegistersMask19); - } - if (rNext19 == NoReg) { - rNext19 = allocateRegNotConflictingWith(1U << rTop32); - } - assert(!(((rTop32 == NoReg) - || (rNext19 == NoReg)))); - second4 = rTop32; - first9 = rNext19; - nativePopToReg(ssNativeTop(), second4); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first9); - ssNativePop(1); - gDivRRQuoRem(second4, first9, first9, second4); - ssPushNativeRegister(first9); - return 0; - - case 223: - /* begin genLowcodeUdiv64 */ - topRegistersMask20 = 0; - rTop33 = (rNext20 = NoReg); - rResult6 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop33 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext20 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext20 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg18 = (rNext20 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask20 = 1U << reg18; - } - } - if (rTop33 == NoReg) { - rTop33 = allocateRegNotConflictingWith(topRegistersMask20); - } - if (rNext20 == NoReg) { - rNext20 = allocateRegNotConflictingWith(1U << rTop33); - } - assert(!(((rTop33 == NoReg) - || (rNext20 == NoReg)))); - rResult6 = allocateFloatRegNotConflictingWith((1U << rTop33) | (1U << rNext20)); - assert(!((rResult6 == NoReg))); - second5 = rTop33; - first10 = rNext20; - result5 = rResult6; - nativePopToReg(ssNativeTop(), second5); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first10); - ssNativePop(1); - abort(); - return 0; - - case 224: - /* begin genLowcodeUint32Great */ - topRegistersMask21 = 0; - rTop34 = (rNext21 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop34 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext21 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext21 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg19 = (rNext21 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask21 = 1U << reg19; - } - } - if (rTop34 == NoReg) { - rTop34 = allocateRegNotConflictingWith(topRegistersMask21); - } - if (rNext21 == NoReg) { - rNext21 = allocateRegNotConflictingWith(1U << rTop34); - } - assert(!(((rTop34 == NoReg) - || (rNext21 == NoReg)))); - second6 = rTop34; - first13 = rNext21; - nativePopToReg(ssNativeTop(), second6); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first13); - ssNativePop(1); - /* begin CmpR:R: */ - assert(!((second6 == SPReg))); - genoperandoperand(CmpRR, second6, first13); - /* begin JumpBelowOrEqual: */ - falseJump = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction29 = genoperandoperand(MoveCqR, 1, first13); - /* begin Jump: */ - contJump = genoperand(Jump, ((sqInt)0)); - jmpTarget(falseJump, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction112 = genoperandoperand(MoveCqR, 0, first13); - jmpTarget(contJump, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(first13); - return 0; - - case 225: - /* begin genLowcodeUint32GreatEqual */ - topRegistersMask22 = 0; - rTop35 = (rNext22 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop35 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext22 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext22 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg20 = (rNext22 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask22 = 1U << reg20; - } - } - if (rTop35 == NoReg) { - rTop35 = allocateRegNotConflictingWith(topRegistersMask22); - } - if (rNext22 == NoReg) { - rNext22 = allocateRegNotConflictingWith(1U << rTop35); - } - assert(!(((rTop35 == NoReg) - || (rNext22 == NoReg)))); - second7 = rTop35; - first14 = rNext22; - nativePopToReg(ssNativeTop(), second7); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first14); - ssNativePop(1); - /* begin CmpR:R: */ - assert(!((second7 == SPReg))); - genoperandoperand(CmpRR, second7, first14); - /* begin JumpBelow: */ - falseJump1 = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction30 = genoperandoperand(MoveCqR, 1, first14); - /* begin Jump: */ - contJump1 = genoperand(Jump, ((sqInt)0)); - jmpTarget(falseJump1, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction113 = genoperandoperand(MoveCqR, 0, first14); - jmpTarget(contJump1, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(first14); - return 0; - - case 226: - /* begin genLowcodeUint32Less */ - topRegistersMask23 = 0; - rTop36 = (rNext23 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop36 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext23 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext23 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg21 = (rNext23 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask23 = 1U << reg21; - } - } - if (rTop36 == NoReg) { - rTop36 = allocateRegNotConflictingWith(topRegistersMask23); - } - if (rNext23 == NoReg) { - rNext23 = allocateRegNotConflictingWith(1U << rTop36); - } - assert(!(((rTop36 == NoReg) - || (rNext23 == NoReg)))); - second8 = rTop36; - first15 = rNext23; - nativePopToReg(ssNativeTop(), second8); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first15); - ssNativePop(1); - /* begin CmpR:R: */ - assert(!((second8 == SPReg))); - genoperandoperand(CmpRR, second8, first15); - /* begin JumpAboveOrEqual: */ - falseJump2 = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction31 = genoperandoperand(MoveCqR, 1, first15); - /* begin Jump: */ - contJump2 = genoperand(Jump, ((sqInt)0)); - jmpTarget(falseJump2, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction114 = genoperandoperand(MoveCqR, 0, first15); - jmpTarget(contJump2, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(first15); - return 0; - - case 227: - /* begin genLowcodeUint32LessEqual */ - topRegistersMask24 = 0; - rTop37 = (rNext24 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop37 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext24 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext24 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg22 = (rNext24 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask24 = 1U << reg22; - } - } - if (rTop37 == NoReg) { - rTop37 = allocateRegNotConflictingWith(topRegistersMask24); - } - if (rNext24 == NoReg) { - rNext24 = allocateRegNotConflictingWith(1U << rTop37); - } - assert(!(((rTop37 == NoReg) - || (rNext24 == NoReg)))); - second9 = rTop37; - first16 = rNext24; - nativePopToReg(ssNativeTop(), second9); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first16); - ssNativePop(1); - /* begin CmpR:R: */ - assert(!((second9 == SPReg))); - genoperandoperand(CmpRR, second9, first16); - /* begin JumpAbove: */ - falseJump3 = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction32 = genoperandoperand(MoveCqR, 1, first16); - /* begin Jump: */ - contJump3 = genoperand(Jump, ((sqInt)0)); - jmpTarget(falseJump3, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction115 = genoperandoperand(MoveCqR, 0, first16); - jmpTarget(contJump3, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(first16); - return 0; - - case 228: - /* begin genLowcodeUint32ToFloat32 */ - rTop38 = NoReg; - frResult = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop38 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop38 == NoReg) { - rTop38 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - frResult = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!(((rTop38 == NoReg) - || (frResult == NoReg)))); - value22 = rTop38; - result6 = frResult; - nativePopToReg(ssNativeTop(), value22); - ssNativePop(1); - /* begin ConvertR:Rs: */ - genoperandoperand(ConvertRRs, value22, result6); - ssPushNativeRegisterSingleFloat(result6); - return 0; - - case 229: - /* begin genLowcodeUint32ToFloat64 */ - rTop39 = NoReg; - frResult1 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop39 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop39 == NoReg) { - rTop39 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - frResult1 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!(((rTop39 == NoReg) - || (frResult1 == NoReg)))); - value23 = rTop39; - result7 = frResult1; - nativePopToReg(ssNativeTop(), value23); - ssNativePop(1); - /* begin ConvertR:Rd: */ - genoperandoperand(ConvertRRd, value23, result7); - ssPushNativeRegisterDoubleFloat(result7); - return 0; - - case 230: - /* begin genLowcodeUint64Great */ - topRegistersMask25 = 0; - rTop40 = (rNext25 = NoReg); - rResult7 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop40 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext25 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext25 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg23 = (rNext25 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask25 = 1U << reg23; - } - } - if (rTop40 == NoReg) { - rTop40 = allocateRegNotConflictingWith(topRegistersMask25); - } - if (rNext25 == NoReg) { - rNext25 = allocateRegNotConflictingWith(1U << rTop40); - } - assert(!(((rTop40 == NoReg) - || (rNext25 == NoReg)))); - rResult7 = allocateFloatRegNotConflictingWith((1U << rTop40) | (1U << rNext25)); - assert(!((rResult7 == NoReg))); - second10 = rTop40; - first17 = rNext25; - value24 = rResult7; - nativePopToReg(ssNativeTop(), second10); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first17); - ssNativePop(1); - abort(); - return 0; - - case 231: - /* begin genLowcodeUint64GreatEqual */ - topRegistersMask26 = 0; - rTop41 = (rNext26 = NoReg); - rResult8 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop41 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext26 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext26 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg24 = (rNext26 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask26 = 1U << reg24; - } - } - if (rTop41 == NoReg) { - rTop41 = allocateRegNotConflictingWith(topRegistersMask26); - } - if (rNext26 == NoReg) { - rNext26 = allocateRegNotConflictingWith(1U << rTop41); - } - assert(!(((rTop41 == NoReg) - || (rNext26 == NoReg)))); - rResult8 = allocateFloatRegNotConflictingWith((1U << rTop41) | (1U << rNext26)); - assert(!((rResult8 == NoReg))); - second11 = rTop41; - first18 = rNext26; - value25 = rResult8; - nativePopToReg(ssNativeTop(), second11); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first18); - ssNativePop(1); - abort(); - return 0; - - case 232: - /* begin genLowcodeUint64Less */ - topRegistersMask27 = 0; - rTop42 = (rNext27 = NoReg); - rResult9 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop42 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext27 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext27 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg25 = (rNext27 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask27 = 1U << reg25; - } - } - if (rTop42 == NoReg) { - rTop42 = allocateRegNotConflictingWith(topRegistersMask27); - } - if (rNext27 == NoReg) { - rNext27 = allocateRegNotConflictingWith(1U << rTop42); - } - assert(!(((rTop42 == NoReg) - || (rNext27 == NoReg)))); - rResult9 = allocateFloatRegNotConflictingWith((1U << rTop42) | (1U << rNext27)); - assert(!((rResult9 == NoReg))); - second12 = rTop42; - first19 = rNext27; - value26 = rResult9; - nativePopToReg(ssNativeTop(), second12); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first19); - ssNativePop(1); - abort(); - return 0; - - case 233: - /* begin genLowcodeUint64LessEqual */ - topRegistersMask28 = 0; - rTop43 = (rNext28 = NoReg); - rResult10 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop43 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext28 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext28 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg26 = (rNext28 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask28 = 1U << reg26; - } - } - if (rTop43 == NoReg) { - rTop43 = allocateRegNotConflictingWith(topRegistersMask28); - } - if (rNext28 == NoReg) { - rNext28 = allocateRegNotConflictingWith(1U << rTop43); - } - assert(!(((rTop43 == NoReg) - || (rNext28 == NoReg)))); - rResult10 = allocateFloatRegNotConflictingWith((1U << rTop43) | (1U << rNext28)); - assert(!((rResult10 == NoReg))); - second13 = rTop43; - first20 = rNext28; - value27 = rResult10; - nativePopToReg(ssNativeTop(), second13); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first20); - ssNativePop(1); - abort(); - return 0; - - case 234: - /* begin genLowcodeUint64ToFloat32 */ - rTop44 = NoReg; - frResult2 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop44 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop44 == NoReg) { - rTop44 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - frResult2 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!(((rTop44 == NoReg) - || (frResult2 == NoReg)))); - value28 = rTop44; - result8 = frResult2; - nativePopToReg(ssNativeTop(), value28); - ssNativePop(1); - abort(); - return 0; - - case 235: - /* begin genLowcodeUint64ToFloat64 */ - rTop45 = NoReg; - frResult3 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop45 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop45 == NoReg) { - rTop45 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - frResult3 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!(((rTop45 == NoReg) - || (frResult3 == NoReg)))); - value29 = rTop45; - result9 = frResult3; - nativePopToReg(ssNativeTop(), value29); - ssNativePop(1); - abort(); - return 0; - - case 236: - /* begin genLowcodeUmul32 */ - topRegistersMask29 = 0; - rTop46 = (rNext29 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop46 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext29 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext29 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg27 = (rNext29 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask29 = 1U << reg27; - } - } - if (rTop46 == NoReg) { - rTop46 = allocateRegNotConflictingWith(topRegistersMask29); - } - if (rNext29 == NoReg) { - rNext29 = allocateRegNotConflictingWith(1U << rTop46); - } - assert(!(((rTop46 == NoReg) - || (rNext29 == NoReg)))); - second14 = rTop46; - first21 = rNext29; - nativePopToReg(ssNativeTop(), second14); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first21); - ssNativePop(1); - /* begin MulR:R: */ - genMulRR(backEnd, second14, first21); - ssPushNativeRegister(first21); - return 0; - - case 237: - /* begin genLowcodeUmul64 */ - topRegistersMask30 = 0; - rTop47 = (rNext30 = NoReg); - rResult14 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop47 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext30 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext30 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg28 = (rNext30 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask30 = 1U << reg28; - } - } - if (rTop47 == NoReg) { - rTop47 = allocateRegNotConflictingWith(topRegistersMask30); - } - if (rNext30 == NoReg) { - rNext30 = allocateRegNotConflictingWith(1U << rTop47); - } - assert(!(((rTop47 == NoReg) - || (rNext30 == NoReg)))); - rResult14 = allocateFloatRegNotConflictingWith((1U << rTop47) | (1U << rNext30)); - assert(!((rResult14 == NoReg))); - second15 = rTop47; - first22 = rNext30; - result10 = rResult14; - nativePopToReg(ssNativeTop(), second15); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first22); - ssNativePop(1); - abort(); - return 0; - - case 238: - return 0 /* genLowcodeUnlockRegisters */; - - case 239: - /* begin genLowcodeUnlockVM */ - abort(); - return 0; - - case 240: - /* begin genLowcodeUrem32 */ - topRegistersMask31 = 0; - rTop48 = (rNext31 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop48 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext31 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext31 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg29 = (rNext31 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask31 = 1U << reg29; - } - } - if (rTop48 == NoReg) { - rTop48 = allocateRegNotConflictingWith(topRegistersMask31); - } - if (rNext31 == NoReg) { - rNext31 = allocateRegNotConflictingWith(1U << rTop48); - } - assert(!(((rTop48 == NoReg) - || (rNext31 == NoReg)))); - second16 = rTop48; - first23 = rNext31; - nativePopToReg(ssNativeTop(), second16); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first23); - ssNativePop(1); - gDivRRQuoRem(second16, first23, second16, first23); - ssPushNativeRegister(first23); - return 0; - - case 241: - /* begin genLowcodeUrem64 */ - topRegistersMask32 = 0; - rTop49 = (rNext32 = NoReg); - rResult15 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop49 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext32 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext32 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg30 = (rNext32 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask32 = 1U << reg30; - } - } - if (rTop49 == NoReg) { - rTop49 = allocateRegNotConflictingWith(topRegistersMask32); - } - if (rNext32 == NoReg) { - rNext32 = allocateRegNotConflictingWith(1U << rTop49); - } - assert(!(((rTop49 == NoReg) - || (rNext32 == NoReg)))); - rResult15 = allocateFloatRegNotConflictingWith((1U << rTop49) | (1U << rNext32)); - assert(!((rResult15 == NoReg))); - second17 = rTop49; - first24 = rNext32; - result11 = rResult15; - nativePopToReg(ssNativeTop(), second17); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first24); - ssNativePop(1); - abort(); - return 0; - - case 242: - /* begin genLowcodeXor32 */ - topRegistersMask33 = 0; - rTop50 = (rNext33 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop50 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext33 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext33 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg31 = (rNext33 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask33 = 1U << reg31; - } - } - if (rTop50 == NoReg) { - rTop50 = allocateRegNotConflictingWith(topRegistersMask33); - } - if (rNext33 == NoReg) { - rNext33 = allocateRegNotConflictingWith(1U << rTop50); - } - assert(!(((rTop50 == NoReg) - || (rNext33 == NoReg)))); - second18 = rTop50; - first25 = rNext33; - nativePopToReg(ssNativeTop(), second18); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first25); - ssNativePop(1); - /* begin XorR:R: */ - genoperandoperand(XorRR, second18, first25); - ssPushNativeRegister(first25); - return 0; - - case 243: - /* begin genLowcodeXor64 */ - /* begin allocateRegistersForLowcodeInteger4: */ - rTop51 = (rNext34 = (rNextNext2 = (rNextNextNext1 = NoReg))); - nativeValueIndex2 = 1; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop51 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext34 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext34 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex2))) != NoReg) { - rNext34 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex2)); - if ((nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex2))) != NoReg) { - rNextNext2 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex2)); - } - nativeValueIndex2 += 1; - } - } - if (rNextNext2 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex2))) != NoReg) { - rNextNext2 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex2)); - if ((nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex2))) != NoReg) { - rNextNextNext1 = nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex2)); - } - nativeValueIndex2 += 1; - } - } - if (rNextNextNext1 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex2))) != NoReg) { - rNextNextNext1 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex2)); - nativeValueIndex2 += 1; - } - } - if (rTop51 == NoReg) { - nextRegisterMask2 = 0; - if (rNext34 != NoReg) { - /* begin registerMaskFor: */ - nextRegisterMask2 = 1U << rNext34; - } - if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1U << rNextNext2); - } - if (rNextNextNext1 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1U << rNextNextNext1); - } - rTop51 = allocateRegNotConflictingWith(nextRegisterMask2); - } - if (rNext34 == NoReg) { - /* begin registerMaskFor: */ - nextRegisterMask2 = 1U << rTop51; - if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1U << rNextNext2); - } - if (rNextNextNext1 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1U << rNextNextNext1); - } - rNext34 = allocateRegNotConflictingWith(nextRegisterMask2); - } - if (rNextNext2 == NoReg) { - /* begin registerMaskFor:and: */ - nextRegisterMask2 = (1U << rTop51) | (1U << rNext34); - if (rNextNextNext1 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1U << rNextNextNext1); - } - rNextNext2 = allocateRegNotConflictingWith(nextRegisterMask2); - } - if (rNextNextNext1 == NoReg) { - /* begin registerMaskFor:and:and: */ - nextRegisterMask2 = ((1U << rTop51) | (1U << rNext34)) | (1U << rNextNext2); - rNextNextNext1 = allocateRegNotConflictingWith(nextRegisterMask2); - } - assert(!(((rTop51 == NoReg) - || ((rNext34 == NoReg) - || ((rNextNext2 == NoReg) - || (rNextNextNext1 == NoReg)))))); - secondLow9 = rTop51; - secondHigh9 = rNext34; - firstLow9 = rNextNext2; - firstHigh9 = rNextNextNext1; - nativePopToRegsecondReg(ssNativeTop(), secondLow9, secondHigh9); - ssNativePop(1); - nativePopToRegsecondReg(ssNativeTop(), firstLow9, firstHigh9); - ssNativePop(1); - /* begin XorR:R: */ - genoperandoperand(XorRR, secondLow9, firstLow9); - /* begin XorR:R: */ - genoperandoperand(XorRR, secondHigh9, firstHigh9); - ssPushNativeRegistersecondRegister(firstLow9, firstHigh9); - return 0; - - case 244: - /* begin genLowcodeZeroExtend32From16 */ - rTop52 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop52 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop52 == NoReg) { - rTop52 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rTop52 == NoReg))); - value30 = rTop52; - nativePopToReg(ssNativeTop(), value30); - ssNativePop(1); - /* begin ZeroExtend16R:R: */ - if (value30 == value30) { - /* begin LogicalShiftLeftCq:R: */ - first27 = genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 16, value30); - } - else { - /* begin MoveR:R: */ - first27 = genoperandoperand(MoveRR, value30, value30); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 16, value30); - } - /* begin LogicalShiftRightCq:R: */ - genoperandoperand(LogicalShiftRightCqR, (BytesPerWord * 8) - 16, value30); - goto l214; - genoperandoperand(ZeroExtend16RR, value30, value30); - l214: /* end ZeroExtend16R:R: */; - ssPushNativeRegister(value30); - return 0; - - case 245: - /* begin genLowcodeZeroExtend32From8 */ - rTop53 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop53 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop53 == NoReg) { - rTop53 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rTop53 == NoReg))); - value31 = rTop53; - nativePopToReg(ssNativeTop(), value31); - ssNativePop(1); - /* begin ZeroExtend8R:R: */ - if (value31 == value31) { - /* begin LogicalShiftLeftCq:R: */ - first28 = genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 8, value31); - } - else { - /* begin MoveR:R: */ - first28 = genoperandoperand(MoveRR, value31, value31); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 8, value31); - } - /* begin LogicalShiftRightCq:R: */ - genoperandoperand(LogicalShiftRightCqR, (BytesPerWord * 8) - 8, value31); - goto l220; - genoperandoperand(ZeroExtend8RR, value31, value31); - l220: /* end ZeroExtend8R:R: */; - ssPushNativeRegister(value31); - return 0; - - case 246: - /* begin genLowcodeZeroExtend64From16 */ - /* begin allocateRegistersForLowcodeInteger2: */ - topRegistersMask35 = 0; - rTop54 = (rNext35 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop54 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext35 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext35 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg33 = (rNext35 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask35 = 1U << reg33; - } - } - if (rTop54 == NoReg) { - rTop54 = allocateRegNotConflictingWith(topRegistersMask35); - } - if (rNext35 == NoReg) { - rNext35 = allocateRegNotConflictingWith(1U << rTop54); - } - assert(!(((rTop54 == NoReg) - || (rNext35 == NoReg)))); - valueLow10 = rTop54; - valueHigh10 = rNext35; - nativePopToRegsecondReg(ssNativeTop(), valueLow10, valueHigh10); - ssNativePop(1); - /* begin ZeroExtend16R:R: */ - if (valueLow10 == valueLow10) { - /* begin LogicalShiftLeftCq:R: */ - first29 = genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 16, valueLow10); - } - else { - /* begin MoveR:R: */ - first29 = genoperandoperand(MoveRR, valueLow10, valueLow10); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 16, valueLow10); - } - /* begin LogicalShiftRightCq:R: */ - genoperandoperand(LogicalShiftRightCqR, (BytesPerWord * 8) - 16, valueLow10); - goto l230; - genoperandoperand(ZeroExtend16RR, valueLow10, valueLow10); - l230: /* end ZeroExtend16R:R: */; - /* begin checkQuickConstant:forInstruction: */ - anInstruction33 = genoperandoperand(MoveCqR, 0, valueHigh10); - ssPushNativeRegistersecondRegister(valueLow10, valueHigh10); - return 0; - - default: - return genLowcodeUnaryInlinePrimitive5(prim); - - } - return 0; -} - - -/* Lowcode instruction generator dispatch */ - - /* StackToRegisterMappingCogit>>#genLowcodeUnaryInlinePrimitive5: */ -static sqInt NoDbgRegParms -genLowcodeUnaryInlinePrimitive5(sqInt prim) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction * first2; - sqInt reg; - sqInt resultHigh; - sqInt resultLow; - sqInt rNext; - sqInt rResult; - sqInt rResult2; - sqInt rTop; - sqInt rTop2; - sqInt topRegistersMask; - sqInt value; - sqInt valueHigh; - sqInt valueLow; - - switch (prim) { - case 247: - /* begin genLowcodeZeroExtend64From32 */ - /* begin allocateRegistersForLowcodeIntegerResultInteger2: */ - rTop = NoReg; - rResult = (rResult = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop == NoReg) { - rTop = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult = allocateRegNotConflictingWith(1U << rTop); - rResult2 = allocateRegNotConflictingWith((1U << rTop) | (1U << rResult)); - assert(!(((rTop == NoReg) - || ((rResult == NoReg) - || (rResult2 == NoReg))))); - value = rTop; - resultLow = rResult; - resultHigh = rResult2; - nativePopToReg(ssNativeTop(), value); - ssNativePop(1); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, value, resultLow); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 0, resultHigh); - ssPushNativeRegistersecondRegister(resultLow, resultHigh); - return 0; - - case 0xF8: - /* begin genLowcodeZeroExtend64From8 */ - /* begin allocateRegistersForLowcodeInteger2: */ - topRegistersMask = 0; - rTop2 = (rNext = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop2 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask = 1U << reg; - } - } - if (rTop2 == NoReg) { - rTop2 = allocateRegNotConflictingWith(topRegistersMask); - } - if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1U << rTop2); - } - assert(!(((rTop2 == NoReg) - || (rNext == NoReg)))); - valueLow = rTop2; - valueHigh = rNext; - nativePopToRegsecondReg(ssNativeTop(), valueLow, valueHigh); - ssNativePop(1); - /* begin ZeroExtend8R:R: */ - if (valueLow == valueLow) { - /* begin LogicalShiftLeftCq:R: */ - first2 = genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 8, valueLow); - } - else { - /* begin MoveR:R: */ - first2 = genoperandoperand(MoveRR, valueLow, valueLow); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 8, valueLow); - } - /* begin LogicalShiftRightCq:R: */ - genoperandoperand(LogicalShiftRightCqR, (BytesPerWord * 8) - 8, valueLow); - goto l17; - genoperandoperand(ZeroExtend8RR, valueLow, valueLow); - l17: /* end ZeroExtend8R:R: */; - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, 0, valueHigh); - ssPushNativeRegistersecondRegister(valueLow, valueHigh); - return 0; - - default: - return EncounteredUnknownBytecode; - - } - return 0; -} - - -/* Lowcode instruction generator dispatch */ - - /* StackToRegisterMappingCogit>>#genLowcodeUnaryInlinePrimitive: */ -static sqInt NoDbgRegParms -genLowcodeUnaryInlinePrimitive(sqInt prim) -{ - AbstractInstruction *abstractInstruction; - sqInt alignment; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction110; - AbstractInstruction *anInstruction111; - AbstractInstruction *anInstruction112; - AbstractInstruction *anInstruction113; - AbstractInstruction *anInstruction114; - AbstractInstruction *anInstruction115; - AbstractInstruction *anInstruction116; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction22; - AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction24; - AbstractInstruction *anInstruction25; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt base; - sqInt base1; - sqInt check; - AbstractInstruction * contJump; - AbstractInstruction * contJump1; - AbstractInstruction * contJump10; - AbstractInstruction * contJump11; - AbstractInstruction * contJump2; - AbstractInstruction * contJump3; - AbstractInstruction * contJump4; - AbstractInstruction * contJump5; - AbstractInstruction * contJump6; - AbstractInstruction * contJump7; - AbstractInstruction * contJump8; - AbstractInstruction * contJump9; - sqInt dup2; - sqInt dup21; - sqInt dup22; - sqInt dup24; - sqInt dup2High; - sqInt dup2Low; - sqInt expectedSession; - AbstractInstruction * falseJump; - AbstractInstruction * falseJump1; - AbstractInstruction * falseJump10; - AbstractInstruction * falseJump11; - AbstractInstruction * falseJump2; - AbstractInstruction * falseJump3; - AbstractInstruction * falseJump4; - AbstractInstruction * falseJump5; - AbstractInstruction * falseJump6; - AbstractInstruction * falseJump7; - AbstractInstruction * falseJump8; - AbstractInstruction * falseJump9; - sqInt first; - sqInt first10; - sqInt first11; - sqInt first12; - sqInt first13; - sqInt first14; - sqInt first15; - sqInt first16; - sqInt first17; - sqInt first18; - sqInt first19; - sqInt first2; - sqInt first20; - sqInt first21; - sqInt first22; - sqInt first23; - sqInt first24; - sqInt first25; - sqInt first4; - sqInt first5; - sqInt first6; - sqInt first7; - sqInt first8; - sqInt firstHigh; - sqInt firstHigh1; - sqInt firstLow; - sqInt firstLow1; - sqInt first9; - sqInt frNext; - sqInt frNext1; - sqInt frNext10; - sqInt frNext11; - sqInt frNext2; - sqInt frNext3; - sqInt frNext4; - sqInt frNext5; - sqInt frNext6; - sqInt frNext7; - sqInt frNext8; - sqInt frNext9; - sqInt frResult; - sqInt frResult1; - sqInt frResult2; - sqInt frResult3; - sqInt frTop; - sqInt frTop1; - sqInt frTop10; - sqInt frTop11; - sqInt frTop12; - sqInt frTop13; - sqInt frTop14; - sqInt frTop15; - sqInt frTop16; - sqInt frTop17; - sqInt frTop18; - sqInt frTop19; - sqInt frTop2; - sqInt frTop20; - sqInt frTop21; - sqInt frTop22; - sqInt frTop3; - sqInt frTop4; - sqInt frTop5; - sqInt frTop6; - sqInt frTop7; - sqInt frTop8; - sqInt frTop9; - sqInt function; - sqInt index; - sqInt index1; - sqInt nativeValueIndex; - sqInt nativeValueIndex1; - sqInt nativeValueIndex2; - sqInt nativeValueIndex3; - sqInt nativeValueIndex4; - sqInt newValue; - sqInt nextRegisterMask; - sqInt nextRegisterMask1; - sqInt nextRegisterMask2; - sqInt nextRegisterMask3; - sqInt nextRegisterMask4; - sqInt offset; - sqInt offset1; - sqInt oldValue; - sqInt pointerValue; - sqInt reg; - sqInt reg10; - sqInt reg11; - sqInt reg12; - sqInt reg13; - sqInt reg14; - sqInt reg15; - sqInt reg16; - sqInt reg17; - sqInt reg18; - sqInt reg19; - sqInt reg2; - sqInt reg20; - sqInt reg21; - sqInt reg22; - sqInt reg23; - sqInt reg24; - sqInt reg25; - sqInt reg26; - sqInt reg27; - sqInt reg28; - sqInt reg29; - sqInt reg3; - sqInt reg5; - sqInt reg6; - sqInt reg7; - sqInt reg8; - sqInt registerID; - sqInt reg9; - sqInt result; - sqInt result1; - sqInt result2; - sqInt result3; - sqInt result4; - sqInt result5; - sqInt result6; - sqInt result7; - sqInt result8; - sqInt rNext; - sqInt rNext10; - sqInt rNext12; - sqInt rNext13; - sqInt rNext14; - sqInt rNext15; - sqInt rNext16; - sqInt rNext17; - sqInt rNext18; - sqInt rNext19; - sqInt rNext2; - sqInt rNext20; - sqInt rNext21; - sqInt rNext22; - sqInt rNext3; - sqInt rNext4; - sqInt rNext5; - sqInt rNext6; - sqInt rNext7; - sqInt rNext8; - sqInt rNextNext; - sqInt rNextNext1; - sqInt rNextNext2; - sqInt rNextNext3; - sqInt rNextNext4; - sqInt rNextNextNext; - sqInt rNextNextNext1; - sqInt rNextNextNext2; - sqInt rNextNextNext3; - sqInt rNext9; - sqInt rResult; - sqInt rResult1; - sqInt rResult10; - sqInt rResult12; - sqInt rResult13; - sqInt rResult14; - sqInt rResult15; - sqInt rResult16; - sqInt rResult17; - sqInt rResult18; - sqInt rResult19; - sqInt rResult2; - sqInt rResult20; - sqInt rResult21; - sqInt rResult22; - sqInt rResult23; - sqInt rResult24; - sqInt rResult3; - sqInt rResult4; - sqInt rResult5; - sqInt rResult6; - sqInt rResult7; - sqInt rResult8; - sqInt rResult9; - sqInt rTop; - sqInt rTop10; - sqInt rTop13; - sqInt rTop14; - sqInt rTop15; - sqInt rTop17; - sqInt rTop18; - sqInt rTop19; - sqInt rTop2; - sqInt rTop20; - sqInt rTop21; - sqInt rTop22; - sqInt rTop23; - sqInt rTop24; - sqInt rTop25; - sqInt rTop26; - sqInt rTop27; - sqInt rTop3; - sqInt rTop4; - sqInt rTop5; - sqInt rTop6; - sqInt rTop7; - sqInt rTop8; - sqInt rTop9; - sqInt scale; - sqInt scale1; - sqInt second; - sqInt second10; - sqInt second11; - sqInt second12; - sqInt second13; - sqInt second14; - sqInt second15; - sqInt second16; - sqInt second17; - sqInt second18; - sqInt second19; - sqInt second2; - sqInt second20; - sqInt second21; - sqInt second22; - sqInt second23; - sqInt second24; - sqInt second25; - sqInt second4; - sqInt second5; - sqInt second6; - sqInt second7; - sqInt second8; - sqInt secondHigh; - sqInt secondHigh1; - sqInt secondLow; - sqInt secondLow1; - sqInt second9; - sqInt shiftAmount; - sqInt shiftAmount1; - sqInt singleFloatValue; - sqInt size; - sqInt sizeHigh; - sqInt sizeLow; - sqInt topRegistersMask; - sqInt topRegistersMask10; - sqInt topRegistersMask11; - sqInt topRegistersMask12; - sqInt topRegistersMask13; - sqInt topRegistersMask14; - sqInt topRegistersMask15; - sqInt topRegistersMask16; - sqInt topRegistersMask17; - sqInt topRegistersMask18; - sqInt topRegistersMask19; - sqInt topRegistersMask2; - sqInt topRegistersMask20; - sqInt topRegistersMask21; - sqInt topRegistersMask22; - sqInt topRegistersMask23; - sqInt topRegistersMask24; - sqInt topRegistersMask25; - sqInt topRegistersMask26; - sqInt topRegistersMask27; - sqInt topRegistersMask28; - sqInt topRegistersMask29; - sqInt topRegistersMask3; - sqInt topRegistersMask30; - sqInt topRegistersMask31; - sqInt topRegistersMask32; - sqInt topRegistersMask5; - sqInt topRegistersMask6; - sqInt topRegistersMask7; - sqInt topRegistersMask8; - sqInt topRegistersMask9; - sqInt value; - sqInt value1; - sqInt value10; - sqInt value11; - sqInt value12; - sqInt value13; - sqInt value14; - sqInt value15; - sqInt value16; - sqInt value17; - sqInt value18; - sqInt value19; - sqInt value2; - sqInt value20; - sqInt value21; - sqInt value22; - sqInt value23; - sqInt value24; - sqInt value25; - sqInt value26; - sqInt value3; - sqInt value4; - sqInt value5; - sqInt value7; - sqInt value8; - sqInt valueHigh1; - sqInt valueLow1; - sqInt value9; - - switch (prim) { - case 0: - /* begin genLowcodeAdd32 */ - topRegistersMask = 0; - rTop = (rNext = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg = (rNext = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask = 1U << reg; - } - } - if (rTop == NoReg) { - rTop = allocateRegNotConflictingWith(topRegistersMask); - } - if (rNext == NoReg) { - rNext = allocateRegNotConflictingWith(1U << rTop); - } - assert(!(((rTop == NoReg) - || (rNext == NoReg)))); - second = rTop; - first = rNext; - nativePopToReg(ssNativeTop(), second); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first); - ssNativePop(1); - /* begin AddR:R: */ - genoperandoperand(AddRR, second, first); - ssPushNativeRegister(first); - return 0; - - case 1: - /* begin genLowcodeAdd64 */ - /* begin allocateRegistersForLowcodeInteger4: */ - rTop2 = (rNext2 = (rNextNext = (rNextNextNext = NoReg))); - nativeValueIndex = 1; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop2 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext2 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext2 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex))) != NoReg) { - rNext2 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex)); - if ((nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex))) != NoReg) { - rNextNext = nativeRegisterOrNone(ssNativeValue(nativeValueIndex)); - } - nativeValueIndex += 1; - } - } - if (rNextNext == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex))) != NoReg) { - rNextNext = nativeRegisterOrNone(ssNativeValue(nativeValueIndex)); - if ((nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex))) != NoReg) { - rNextNextNext = nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex)); - } - nativeValueIndex += 1; - } - } - if (rNextNextNext == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex))) != NoReg) { - rNextNextNext = nativeRegisterOrNone(ssNativeValue(nativeValueIndex)); - nativeValueIndex += 1; - } - } - if (rTop2 == NoReg) { - nextRegisterMask = 0; - if (rNext2 != NoReg) { - /* begin registerMaskFor: */ - nextRegisterMask = 1U << rNext2; - } - if (rNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNext); - } - if (rNextNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNextNext); - } - rTop2 = allocateRegNotConflictingWith(nextRegisterMask); - } - if (rNext2 == NoReg) { - /* begin registerMaskFor: */ - nextRegisterMask = 1U << rTop2; - if (rNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNext); - } - if (rNextNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNextNext); - } - rNext2 = allocateRegNotConflictingWith(nextRegisterMask); - } - if (rNextNext == NoReg) { - /* begin registerMaskFor:and: */ - nextRegisterMask = (1U << rTop2) | (1U << rNext2); - if (rNextNextNext != NoReg) { - nextRegisterMask = nextRegisterMask | (1U << rNextNextNext); - } - rNextNext = allocateRegNotConflictingWith(nextRegisterMask); - } - if (rNextNextNext == NoReg) { - /* begin registerMaskFor:and:and: */ - nextRegisterMask = ((1U << rTop2) | (1U << rNext2)) | (1U << rNextNext); - rNextNextNext = allocateRegNotConflictingWith(nextRegisterMask); - } - assert(!(((rTop2 == NoReg) - || ((rNext2 == NoReg) - || ((rNextNext == NoReg) - || (rNextNextNext == NoReg)))))); - secondLow = rTop2; - secondHigh = rNext2; - firstLow = rNextNext; - firstHigh = rNextNextNext; - nativePopToRegsecondReg(ssNativeTop(), secondLow, secondHigh); - ssNativePop(1); - nativePopToRegsecondReg(ssNativeTop(), firstLow, firstHigh); - ssNativePop(1); - /* begin AddR:R: */ - genoperandoperand(AddRR, secondLow, firstLow); - /* begin AddcR:R: */ - genoperandoperand(AddcRR, secondHigh, firstHigh); - ssPushNativeRegistersecondRegister(firstLow, firstHigh); - return 0; - - case 2: - /* begin genLowcodeAlloca32 */ - rTop3 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop3 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop3 == NoReg) { - rTop3 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - assert(!((rTop3 == NoReg))); - size = rTop3; - nativePopToReg(ssNativeTop(), size); - ssNativePop(1); - /* begin checkLiteral:forInstruction: */ - nativeStackPointerAddress(); - anInstruction = genoperandoperand(MoveAwR, nativeStackPointerAddress(), TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, size, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, -16, TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, size); - /* begin checkLiteral:forInstruction: */ - nativeStackPointerAddress(); - anInstruction2 = genoperandoperand(MoveRAw, size, nativeStackPointerAddress()); - ssPushNativeRegister(size); - return 0; - - case 3: - /* begin genLowcodeAlloca64 */ - /* begin allocateRegistersForLowcodeInteger2: */ - topRegistersMask2 = 0; - rTop4 = (rNext3 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop4 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext3 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext3 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg2 = (rNext3 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask2 = 1U << reg2; - } - } - if (rTop4 == NoReg) { - rTop4 = allocateRegNotConflictingWith(topRegistersMask2); - } - if (rNext3 == NoReg) { - rNext3 = allocateRegNotConflictingWith(1U << rTop4); - } - assert(!(((rTop4 == NoReg) - || (rNext3 == NoReg)))); - sizeLow = rTop4; - sizeHigh = rNext3; - nativePopToRegsecondReg(ssNativeTop(), sizeLow, sizeHigh); - ssNativePop(1); - /* begin SubR:R: */ - genoperandoperand(SubRR, sizeLow, SPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SPReg, sizeLow); - ssPushNativeRegister(sizeLow); - return 0; - - case 4: - /* begin genLowcodeAnd32 */ - topRegistersMask3 = 0; - rTop5 = (rNext4 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop5 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext4 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext4 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg3 = (rNext4 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask3 = 1U << reg3; - } - } - if (rTop5 == NoReg) { - rTop5 = allocateRegNotConflictingWith(topRegistersMask3); - } - if (rNext4 == NoReg) { - rNext4 = allocateRegNotConflictingWith(1U << rTop5); - } - assert(!(((rTop5 == NoReg) - || (rNext4 == NoReg)))); - second2 = rTop5; - first2 = rNext4; - nativePopToReg(ssNativeTop(), second2); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first2); - ssNativePop(1); - /* begin AndR:R: */ - genoperandoperand(AndRR, second2, first2); - ssPushNativeRegister(first2); - return 0; - - case 5: - /* begin genLowcodeAnd64 */ - /* begin allocateRegistersForLowcodeInteger4: */ - rTop6 = (rNext5 = (rNextNext1 = (rNextNextNext1 = NoReg))); - nativeValueIndex1 = 1; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop6 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext5 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext5 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex1))) != NoReg) { - rNext5 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex1)); - if ((nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex1))) != NoReg) { - rNextNext1 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex1)); - } - nativeValueIndex1 += 1; - } - } - if (rNextNext1 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex1))) != NoReg) { - rNextNext1 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex1)); - if ((nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex1))) != NoReg) { - rNextNextNext1 = nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex1)); - } - nativeValueIndex1 += 1; - } - } - if (rNextNextNext1 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex1))) != NoReg) { - rNextNextNext1 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex1)); - nativeValueIndex1 += 1; - } - } - if (rTop6 == NoReg) { - nextRegisterMask1 = 0; - if (rNext5 != NoReg) { - /* begin registerMaskFor: */ - nextRegisterMask1 = 1U << rNext5; - } - if (rNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNext1); - } - if (rNextNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNextNext1); - } - rTop6 = allocateRegNotConflictingWith(nextRegisterMask1); - } - if (rNext5 == NoReg) { - /* begin registerMaskFor: */ - nextRegisterMask1 = 1U << rTop6; - if (rNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNext1); - } - if (rNextNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNextNext1); - } - rNext5 = allocateRegNotConflictingWith(nextRegisterMask1); - } - if (rNextNext1 == NoReg) { - /* begin registerMaskFor:and: */ - nextRegisterMask1 = (1U << rTop6) | (1U << rNext5); - if (rNextNextNext1 != NoReg) { - nextRegisterMask1 = nextRegisterMask1 | (1U << rNextNextNext1); - } - rNextNext1 = allocateRegNotConflictingWith(nextRegisterMask1); - } - if (rNextNextNext1 == NoReg) { - /* begin registerMaskFor:and:and: */ - nextRegisterMask1 = ((1U << rTop6) | (1U << rNext5)) | (1U << rNextNext1); - rNextNextNext1 = allocateRegNotConflictingWith(nextRegisterMask1); - } - assert(!(((rTop6 == NoReg) - || ((rNext5 == NoReg) - || ((rNextNext1 == NoReg) - || (rNextNextNext1 == NoReg)))))); - secondLow1 = rTop6; - secondHigh1 = rNext5; - firstLow1 = rNextNext1; - firstHigh1 = rNextNextNext1; - nativePopToRegsecondReg(ssNativeTop(), secondLow1, secondHigh1); - ssNativePop(1); - nativePopToRegsecondReg(ssNativeTop(), firstLow1, firstHigh1); - ssNativePop(1); - /* begin AndR:R: */ - genoperandoperand(AndRR, secondLow1, firstLow1); - /* begin AndR:R: */ - genoperandoperand(AndRR, secondHigh1, firstHigh1); - ssPushNativeRegistersecondRegister(firstLow1, firstHigh1); - return 0; - - case 6: - /* begin genLowcodeArithmeticRightShift32 */ - topRegistersMask5 = 0; - rTop7 = (rNext6 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop7 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext6 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext6 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg5 = (rNext6 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask5 = 1U << reg5; - } - } - if (rTop7 == NoReg) { - rTop7 = allocateRegNotConflictingWith(topRegistersMask5); - } - if (rNext6 == NoReg) { - rNext6 = allocateRegNotConflictingWith(1U << rTop7); - } - assert(!(((rTop7 == NoReg) - || (rNext6 == NoReg)))); - shiftAmount = rTop7; - value = rNext6; - nativePopToReg(ssNativeTop(), shiftAmount); - ssNativePop(1); - nativePopToReg(ssNativeTop(), value); - ssNativePop(1); - /* begin ArithmeticShiftRightR:R: */ - genoperandoperand(ArithmeticShiftRightRR, shiftAmount, value); - ssPushNativeRegister(value); - return 0; - - case 7: - /* begin genLowcodeArithmeticRightShift64 */ - topRegistersMask6 = 0; - rTop8 = (rNext7 = NoReg); - rResult = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop8 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext7 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext7 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg6 = (rNext7 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask6 = 1U << reg6; - } - } - if (rTop8 == NoReg) { - rTop8 = allocateRegNotConflictingWith(topRegistersMask6); - } - if (rNext7 == NoReg) { - rNext7 = allocateRegNotConflictingWith(1U << rTop8); - } - assert(!(((rTop8 == NoReg) - || (rNext7 == NoReg)))); - rResult = allocateFloatRegNotConflictingWith((1U << rTop8) | (1U << rNext7)); - assert(!((rResult == NoReg))); - shiftAmount1 = rTop8; - value1 = rNext7; - result = rResult; - nativePopToReg(ssNativeTop(), shiftAmount1); - ssNativePop(1); - nativePopToReg(ssNativeTop(), value1); - ssNativePop(1); - abort(); - return 0; - - case 8: - /* begin genLowcodeBeginCall */ - alignment = extA; - beginHighLevelCall(alignment); - extA = 0; - return 0; - - case 9: - /* begin genLowcodeCallArgumentFloat32 */ - nativeStackPopToReg(ssNativeTop(), DPFPReg0); - ssNativePop(1); - /* begin checkQuickConstant:forInstruction: */ - -BytesPerWord; - anInstruction3 = genoperandoperandoperand(MoveRsM32r, DPFPReg0, -BytesPerWord, SPReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperand(SubCqR, BytesPerWord, SPReg); - currentCallCleanUpSize += BytesPerWord; - return 0; - - case 10: - /* begin genLowcodeCallArgumentFloat64 */ - nativeStackPopToReg(ssNativeTop(), DPFPReg0); - ssNativePop(1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperandoperand(MoveRdM64r, DPFPReg0, -8, SPReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperand(SubCqR, 8, SPReg); - currentCallCleanUpSize += 8; - return 0; - - case 11: - /* begin genLowcodeCallArgumentInt32 */ - nativeStackPopToReg(ssNativeTop(), TempReg); - ssNativePop(1); - /* begin PushR: */ - genoperand(PushR, TempReg); - currentCallCleanUpSize += BytesPerWord; - return 0; - - case 12: - /* begin genLowcodeCallArgumentInt64 */ - nativeStackPopToRegsecondReg(ssNativeTop(), TempReg, ReceiverResultReg); - ssNativePop(1); - /* begin PushR: */ - genoperand(PushR, TempReg); - /* begin PushR: */ - genoperand(PushR, ReceiverResultReg); - currentCallCleanUpSize += 8; - return 0; - - case 13: - /* begin genLowcodeCallArgumentPointer */ - nativeStackPopToReg(ssNativeTop(), TempReg); - ssNativePop(1); - /* begin PushR: */ - genoperand(PushR, TempReg); - currentCallCleanUpSize += BytesPerWord; - return 0; - - case 14: - /* begin genLowcodeCallArgumentSpace */ - anInstruction5 = genoperandoperand(SubCqR, extA, SPReg); - currentCallCleanUpSize += extA; - extA = 0; - return 0; - - case 15: - /* begin genLowcodeCallArgumentStructure */ - nativeStackPopToReg(ssNativeTop(), TempReg); - ssNativePop(1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(SubCqR, extA, SPReg); - - /* Copy the structure */ - currentCallCleanUpSize += extA; - genMemCopytoconstantSize(backEnd, TempReg, SPReg, extA); - extA = 0; - return 0; - - case 16: - /* begin genLowcodeCallInstruction */ - function = extA; - /* begin CallRT: */ - abstractInstruction = genoperand(Call, function); - (abstractInstruction->annotation = IsRelativeCall); - extA = 0; - return 0; - - case 17: - /* begin genLowcodeCallPhysical */ - registerID = extA; - /* begin CallR: */ - genoperand(CallR, registerID); - extA = 0; - return 0; - - case 18: - /* begin genLowcodeCheckSessionIdentifier */ - expectedSession = extA; - ssPushNativeConstantInt32((expectedSession == (getThisSessionID()) - ? 1 - : 0)); - extA = 0; - return 0; - - case 19: - /* begin genLowcodeCompareAndSwap32 */ - rTop9 = (rNext8 = (rNextNext2 = NoReg)); - nativeValueIndex2 = 1; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop9 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext8 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext8 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex2))) != NoReg) { - rNext8 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex2)); - if ((nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex2))) != NoReg) { - rNextNext2 = nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex2)); - } - nativeValueIndex2 += 1; - } - } - if (rNextNext2 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex2))) != NoReg) { - rNextNext2 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex2)); - } - } - if (rTop9 == NoReg) { - nextRegisterMask2 = 0; - if (rNext8 != NoReg) { - /* begin registerMaskFor: */ - nextRegisterMask2 = 1U << rNext8; - } - if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1U << rNextNext2); - } - rTop9 = allocateRegNotConflictingWith(nextRegisterMask2); - } - if (rNext8 == NoReg) { - /* begin registerMaskFor: */ - nextRegisterMask2 = 1U << rTop9; - if (rNextNext2 != NoReg) { - nextRegisterMask2 = nextRegisterMask2 | (1U << rNextNext2); - } - rNext8 = allocateRegNotConflictingWith(nextRegisterMask2); - } - if (rNextNext2 == NoReg) { - /* begin registerMaskFor:and: */ - nextRegisterMask2 = (1U << rTop9) | (1U << rNext8); - rNextNext2 = allocateRegNotConflictingWith(nextRegisterMask2); - } - assert(!(((rTop9 == NoReg) - || ((rNext8 == NoReg) - || (rNextNext2 == NoReg))))); - rResult1 = allocateRegNotConflictingWith(((1U << rTop9) | (1U << rNext8)) | (1U << rNextNext2)); - assert(!((rResult1 == NoReg))); - newValue = rTop9; - oldValue = rNext8; - check = rNextNext2; - value2 = rResult1; - nativePopToReg(ssNativeTop(), newValue); - ssNativePop(1); - nativePopToReg(ssNativeTop(), oldValue); - ssNativePop(1); - nativePopToReg(ssNativeTop(), check); - ssNativePop(1); - abort(); - return 0; - - case 20: - /* begin genLowcodeDiv32 */ - topRegistersMask7 = 0; - rTop10 = (rNext9 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop10 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext9 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext9 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg7 = (rNext9 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask7 = 1U << reg7; - } - } - if (rTop10 == NoReg) { - rTop10 = allocateRegNotConflictingWith(topRegistersMask7); - } - if (rNext9 == NoReg) { - rNext9 = allocateRegNotConflictingWith(1U << rTop10); - } - assert(!(((rTop10 == NoReg) - || (rNext9 == NoReg)))); - second4 = rTop10; - first4 = rNext9; - nativePopToReg(ssNativeTop(), second4); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first4); - ssNativePop(1); - gDivRRQuoRem(second4, first4, first4, second4); - ssPushNativeRegister(first4); - return 0; - - case 21: - /* begin genLowcodeDiv64 */ - topRegistersMask8 = 0; - rTop13 = (rNext10 = NoReg); - rResult2 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop13 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext10 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext10 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg8 = (rNext10 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask8 = 1U << reg8; - } - } - if (rTop13 == NoReg) { - rTop13 = allocateRegNotConflictingWith(topRegistersMask8); - } - if (rNext10 == NoReg) { - rNext10 = allocateRegNotConflictingWith(1U << rTop13); - } - assert(!(((rTop13 == NoReg) - || (rNext10 == NoReg)))); - rResult2 = allocateFloatRegNotConflictingWith((1U << rTop13) | (1U << rNext10)); - assert(!((rResult2 == NoReg))); - second5 = rTop13; - first5 = rNext10; - result1 = rResult2; - nativePopToReg(ssNativeTop(), second5); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first5); - ssNativePop(1); - abort(); - return 0; - - case 22: - /* begin genLowcodeDuplicateFloat32 */ - frTop = NoReg; - - /* Float argument */ - frResult = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop = nativeFloatRegisterOrNone(ssNativeTop()); - } - if (frTop == NoReg) { - frTop = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - } - frResult = allocateFloatRegNotConflictingWith(1U << frTop); - assert(!(((frTop == NoReg) - || (frResult == NoReg)))); - value3 = frTop; - dup2 = frResult; - nativePopToReg(ssNativeTop(), value3); - ssNativePop(1); - /* begin MoveRs:Rs: */ - genoperandoperand(MoveRsRs, value3, dup2); - ssPushNativeRegisterSingleFloat(value3); - ssPushNativeRegisterSingleFloat(dup2); - return 0; - - case 23: - /* begin genLowcodeDuplicateFloat64 */ - frTop1 = NoReg; - - /* Float argument */ - frResult1 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop1 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if (frTop1 == NoReg) { - frTop1 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - } - frResult1 = allocateFloatRegNotConflictingWith(1U << frTop1); - assert(!(((frTop1 == NoReg) - || (frResult1 == NoReg)))); - value4 = frTop1; - dup21 = frResult1; - nativePopToReg(ssNativeTop(), value4); - ssNativePop(1); - /* begin MoveRd:Rd: */ - genoperandoperand(MoveRdRd, value4, dup21); - ssPushNativeRegisterDoubleFloat(value4); - ssPushNativeRegisterDoubleFloat(dup21); - return 0; - - case 24: - /* begin genLowcodeDuplicateInt32 */ - rTop14 = NoReg; - rResult3 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop14 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop14 == NoReg) { - rTop14 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult3 = allocateRegNotConflictingWith(1U << rTop14); - assert(!(((rTop14 == NoReg) - || (rResult3 == NoReg)))); - value5 = rTop14; - dup22 = rResult3; - nativePopToReg(ssNativeTop(), value5); - ssNativePop(1); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, value5, dup22); - ssPushNativeRegister(value5); - ssPushNativeRegister(dup22); - return 0; - - case 25: - /* begin genLowcodeDuplicateInt64 */ - /* begin allocateRegistersForLowcodeInteger2ResultInteger2: */ - topRegistersMask9 = 0; - rTop15 = (rNext12 = NoReg); - rResult4 = (rResult21 = NoReg); - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop15 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext12 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext12 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg9 = (rNext12 = nativeRegisterOrNone(ssNativeValue(1))); - topRegistersMask9 = 1U << reg9; - } - } - if (rTop15 == NoReg) { - rTop15 = allocateRegNotConflictingWith(topRegistersMask9); - } - if (rNext12 == NoReg) { - rNext12 = allocateRegNotConflictingWith(1U << rTop15); - } - assert(!(((rTop15 == NoReg) - || (rNext12 == NoReg)))); - rResult4 = allocateFloatRegNotConflictingWith((1U << rTop15) | (1U << rNext12)); - rResult21 = allocateFloatRegNotConflictingWith(((1U << rTop15) | (1U << rNext12)) | (1U << rResult4)); - assert(!(((rResult4 == NoReg) - || (rResult21 == NoReg)))); - valueLow1 = rTop15; - valueHigh1 = rNext12; - dup2Low = rResult4; - dup2High = rResult21; - nativePopToRegsecondReg(ssNativeTop(), valueLow1, valueHigh1); - ssNativePop(1); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, valueLow1, dup2Low); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, valueHigh1, dup2High); - ssPushNativeRegistersecondRegister(valueLow1, valueHigh1); - ssPushNativeRegistersecondRegister(dup2Low, dup2High); - return 0; - - case 26: - /* begin genLowcodeDuplicatePointer */ - rTop17 = NoReg; - rResult5 = NoReg; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop17 = nativeRegisterOrNone(ssNativeTop()); - } - if (rTop17 == NoReg) { - rTop17 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult5 = allocateRegNotConflictingWith(1U << rTop17); - assert(!(((rTop17 == NoReg) - || (rResult5 == NoReg)))); - pointerValue = rTop17; - dup24 = rResult5; - nativePopToReg(ssNativeTop(), pointerValue); - ssNativePop(1); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, pointerValue, dup24); - ssPushNativeRegister(pointerValue); - ssPushNativeRegister(dup24); - return 0; - - case 27: - /* begin genLowcodeEffectiveAddress32 */ - rTop18 = (rNext13 = (rNextNext3 = (rNextNextNext2 = NoReg))); - nativeValueIndex3 = 1; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop18 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext13 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext13 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex3))) != NoReg) { - rNext13 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex3)); - if ((nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex3))) != NoReg) { - rNextNext3 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex3)); - } - nativeValueIndex3 += 1; - } - } - if (rNextNext3 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex3))) != NoReg) { - rNextNext3 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex3)); - if ((nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex3))) != NoReg) { - rNextNextNext2 = nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex3)); - } - nativeValueIndex3 += 1; - } - } - if (rNextNextNext2 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex3))) != NoReg) { - rNextNextNext2 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex3)); - nativeValueIndex3 += 1; - } - } - if (rTop18 == NoReg) { - nextRegisterMask3 = 0; - if (rNext13 != NoReg) { - /* begin registerMaskFor: */ - nextRegisterMask3 = 1U << rNext13; - } - if (rNextNext3 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1U << rNextNext3); - } - if (rNextNextNext2 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1U << rNextNextNext2); - } - rTop18 = allocateRegNotConflictingWith(nextRegisterMask3); - } - if (rNext13 == NoReg) { - /* begin registerMaskFor: */ - nextRegisterMask3 = 1U << rTop18; - if (rNextNext3 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1U << rNextNext3); - } - if (rNextNextNext2 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1U << rNextNextNext2); - } - rNext13 = allocateRegNotConflictingWith(nextRegisterMask3); - } - if (rNextNext3 == NoReg) { - /* begin registerMaskFor:and: */ - nextRegisterMask3 = (1U << rTop18) | (1U << rNext13); - if (rNextNextNext2 != NoReg) { - nextRegisterMask3 = nextRegisterMask3 | (1U << rNextNextNext2); - } - rNextNext3 = allocateRegNotConflictingWith(nextRegisterMask3); - } - if (rNextNextNext2 == NoReg) { - /* begin registerMaskFor:and:and: */ - nextRegisterMask3 = ((1U << rTop18) | (1U << rNext13)) | (1U << rNextNext3); - rNextNextNext2 = allocateRegNotConflictingWith(nextRegisterMask3); - } - assert(!(((rTop18 == NoReg) - || ((rNext13 == NoReg) - || ((rNextNext3 == NoReg) - || (rNextNextNext2 == NoReg)))))); - offset = rTop18; - scale = rNext13; - index = rNextNext3; - base = rNextNextNext2; - nativePopToReg(ssNativeTop(), offset); - ssNativePop(1); - nativePopToReg(ssNativeTop(), scale); - ssNativePop(1); - nativePopToReg(ssNativeTop(), index); - ssNativePop(1); - nativePopToReg(ssNativeTop(), base); - ssNativePop(1); - /* begin MulR:R: */ - genMulRR(backEnd, scale, index); - /* begin AddR:R: */ - genoperandoperand(AddRR, index, base); - /* begin AddR:R: */ - genoperandoperand(AddRR, offset, base); - ssPushNativeRegister(base); - return 0; - - case 28: - /* begin genLowcodeEffectiveAddress64 */ - rTop19 = (rNext14 = (rNextNext4 = (rNextNextNext3 = NoReg))); - rResult6 = NoReg; - nativeValueIndex4 = 1; - if ((nativeRegisterOrNone(ssNativeTop())) != NoReg) { - rTop19 = nativeRegisterOrNone(ssNativeTop()); - if ((nativeRegisterSecondOrNone(ssNativeTop())) != NoReg) { - rNext14 = nativeRegisterSecondOrNone(ssNativeTop()); - } - } - if (rNext14 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex4))) != NoReg) { - rNext14 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex4)); - if ((nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex4))) != NoReg) { - rNextNext4 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex4)); - } - nativeValueIndex4 += 1; - } - } - if (rNextNext4 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex4))) != NoReg) { - rNextNext4 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex4)); - if ((nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex4))) != NoReg) { - rNextNextNext3 = nativeRegisterSecondOrNone(ssNativeValue(nativeValueIndex4)); - } - nativeValueIndex4 += 1; - } - } - if (rNextNextNext3 == NoReg) { - if ((nativeRegisterOrNone(ssNativeValue(nativeValueIndex4))) != NoReg) { - rNextNextNext3 = nativeRegisterOrNone(ssNativeValue(nativeValueIndex4)); - nativeValueIndex4 += 1; - } - } - if (rTop19 == NoReg) { - nextRegisterMask4 = 0; - if (rNext14 != NoReg) { - /* begin registerMaskFor: */ - nextRegisterMask4 = 1U << rNext14; - } - if (rNextNext4 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1U << rNextNext4); - } - if (rNextNextNext3 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1U << rNextNextNext3); - } - rTop19 = allocateRegNotConflictingWith(nextRegisterMask4); - } - if (rNext14 == NoReg) { - /* begin registerMaskFor: */ - nextRegisterMask4 = 1U << rTop19; - if (rNextNext4 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1U << rNextNext4); - } - if (rNextNextNext3 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1U << rNextNextNext3); - } - rNext14 = allocateRegNotConflictingWith(nextRegisterMask4); - } - if (rNextNext4 == NoReg) { - /* begin registerMaskFor:and: */ - nextRegisterMask4 = (1U << rTop19) | (1U << rNext14); - if (rNextNextNext3 != NoReg) { - nextRegisterMask4 = nextRegisterMask4 | (1U << rNextNextNext3); - } - rNextNext4 = allocateRegNotConflictingWith(nextRegisterMask4); - } - if (rNextNextNext3 == NoReg) { - /* begin registerMaskFor:and:and: */ - nextRegisterMask4 = ((1U << rTop19) | (1U << rNext14)) | (1U << rNextNext4); - rNextNextNext3 = allocateRegNotConflictingWith(nextRegisterMask4); - } - assert(!(((rTop19 == NoReg) - || ((rNext14 == NoReg) - || ((rNextNext4 == NoReg) - || (rNextNextNext3 == NoReg)))))); - rResult6 = allocateRegNotConflictingWith((((1U << rTop19) | (1U << rNext14)) | (1U << rNextNext4)) | (1U << rNextNextNext3)); - offset1 = rTop19; - scale1 = rNext14; - index1 = rNextNext4; - base1 = rNextNextNext3; - result2 = rResult6; - nativePopToReg(ssNativeTop(), offset1); - ssNativePop(1); - nativePopToReg(ssNativeTop(), scale1); - ssNativePop(1); - nativePopToReg(ssNativeTop(), index1); - ssNativePop(1); - nativePopToReg(ssNativeTop(), base1); - ssNativePop(1); - abort(); - return 0; - - case 29: - /* begin genLowcodeEndCall */ - endHighLevelCallWithCleanup(); - return 0; - - case 30: - /* begin genLowcodeEndCallNoCleanup */ - endHighLevelCallWithoutCleanup(); - return 0; - - case 0x1F: - /* begin genLowcodeFloat32Add */ - topRegistersMask10 = 0; - rTop20 = (rNext15 = NoReg); - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - rTop20 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg10 = (rNext15 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask10 = 1U << reg10; - } - if (rTop20 == NoReg) { - rTop20 = allocateFloatRegNotConflictingWith(topRegistersMask10); - } - if (rNext15 == NoReg) { - rNext15 = allocateFloatRegNotConflictingWith(1U << rTop20); - } - assert(!(((rTop20 == NoReg) - || (rNext15 == NoReg)))); - second6 = rTop20; - first6 = rNext15; - nativePopToReg(ssNativeTop(), second6); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first6); - ssNativePop(1); - /* begin AddRs:Rs: */ - genoperandoperand(AddRsRs, second6, first6); - ssPushNativeRegisterSingleFloat(first6); - return 0; - - case 32: - /* begin genLowcodeFloat32Div */ - topRegistersMask11 = 0; - rTop21 = (rNext16 = NoReg); - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - rTop21 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg11 = (rNext16 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask11 = 1U << reg11; - } - if (rTop21 == NoReg) { - rTop21 = allocateFloatRegNotConflictingWith(topRegistersMask11); - } - if (rNext16 == NoReg) { - rNext16 = allocateFloatRegNotConflictingWith(1U << rTop21); - } - assert(!(((rTop21 == NoReg) - || (rNext16 == NoReg)))); - second7 = rTop21; - first7 = rNext16; - nativePopToReg(ssNativeTop(), second7); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first7); - ssNativePop(1); - /* begin DivRs:Rs: */ - genoperandoperand(DivRsRs, second7, first7); - ssPushNativeRegisterSingleFloat(first7); - return 0; - - case 33: - /* begin genLowcodeFloat32Equal */ - topRegistersMask12 = 0; - frTop2 = (frNext = NoReg); - rResult7 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop2 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg12 = (frNext = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask12 = 1U << reg12; - } - if (frTop2 == NoReg) { - frTop2 = allocateFloatRegNotConflictingWith(topRegistersMask12); - } - if (frNext == NoReg) { - frNext = allocateFloatRegNotConflictingWith(1U << frTop2); - } - rResult7 = allocateRegNotConflictingWith(0); - assert(!(((frTop2 == NoReg) - || ((frNext == NoReg) - || (rResult7 == NoReg))))); - second8 = frTop2; - first8 = frNext; - value7 = rResult7; - nativePopToReg(ssNativeTop(), second8); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first8); - ssNativePop(1); - /* begin CmpRs:Rs: */ - genoperandoperand(CmpRsRs, second8, first8); - - /* True result */ - falseJump = gJumpFPNotEqual(0); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(MoveCqR, 1, value7); - /* begin Jump: */ - contJump = genoperand(Jump, ((sqInt)0)); - jmpTarget(falseJump, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperand(MoveCqR, 0, value7); - jmpTarget(contJump, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(value7); - return 0; - - case 34: - /* begin genLowcodeFloat32Great */ - topRegistersMask13 = 0; - frTop3 = (frNext1 = NoReg); - rResult8 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop3 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg13 = (frNext1 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask13 = 1U << reg13; - } - if (frTop3 == NoReg) { - frTop3 = allocateFloatRegNotConflictingWith(topRegistersMask13); - } - if (frNext1 == NoReg) { - frNext1 = allocateFloatRegNotConflictingWith(1U << frTop3); - } - rResult8 = allocateRegNotConflictingWith(0); - assert(!(((frTop3 == NoReg) - || ((frNext1 == NoReg) - || (rResult8 == NoReg))))); - second9 = frTop3; - first9 = frNext1; - value8 = rResult8; - nativePopToReg(ssNativeTop(), second9); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first9); - ssNativePop(1); - /* begin CmpRs:Rs: */ - genoperandoperand(CmpRsRs, second9, first9); - - /* True result */ - falseJump1 = gJumpFPLessOrEqual(0); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(MoveCqR, 1, value8); - /* begin Jump: */ - contJump1 = genoperand(Jump, ((sqInt)0)); - jmpTarget(falseJump1, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(MoveCqR, 0, value8); - jmpTarget(contJump1, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(value8); - return 0; - - case 35: - /* begin genLowcodeFloat32GreatEqual */ - topRegistersMask14 = 0; - frTop4 = (frNext2 = NoReg); - rResult9 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop4 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg14 = (frNext2 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask14 = 1U << reg14; - } - if (frTop4 == NoReg) { - frTop4 = allocateFloatRegNotConflictingWith(topRegistersMask14); - } - if (frNext2 == NoReg) { - frNext2 = allocateFloatRegNotConflictingWith(1U << frTop4); - } - rResult9 = allocateRegNotConflictingWith(0); - assert(!(((frTop4 == NoReg) - || ((frNext2 == NoReg) - || (rResult9 == NoReg))))); - second10 = frTop4; - first10 = frNext2; - value9 = rResult9; - nativePopToReg(ssNativeTop(), second10); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first10); - ssNativePop(1); - /* begin CmpRs:Rs: */ - genoperandoperand(CmpRsRs, second10, first10); - - /* True result */ - falseJump2 = gJumpFPLess(0); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(MoveCqR, 1, value9); - /* begin Jump: */ - contJump2 = genoperand(Jump, ((sqInt)0)); - jmpTarget(falseJump2, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperand(MoveCqR, 0, value9); - jmpTarget(contJump2, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(value9); - return 0; - - case 36: - /* begin genLowcodeFloat32Less */ - topRegistersMask15 = 0; - frTop5 = (frNext3 = NoReg); - rResult10 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop5 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg15 = (frNext3 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask15 = 1U << reg15; - } - if (frTop5 == NoReg) { - frTop5 = allocateFloatRegNotConflictingWith(topRegistersMask15); - } - if (frNext3 == NoReg) { - frNext3 = allocateFloatRegNotConflictingWith(1U << frTop5); - } - rResult10 = allocateRegNotConflictingWith(0); - assert(!(((frTop5 == NoReg) - || ((frNext3 == NoReg) - || (rResult10 == NoReg))))); - second11 = frTop5; - first11 = frNext3; - value10 = rResult10; - nativePopToReg(ssNativeTop(), second11); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first11); - ssNativePop(1); - /* begin CmpRs:Rs: */ - genoperandoperand(CmpRsRs, second11, first11); - - /* True result */ - falseJump3 = gJumpFPGreaterOrEqual(0); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperand(MoveCqR, 1, value10); - /* begin Jump: */ - contJump3 = genoperand(Jump, ((sqInt)0)); - jmpTarget(falseJump3, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction16 = genoperandoperand(MoveCqR, 0, value10); - jmpTarget(contJump3, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(value10); - return 0; - - case 37: - /* begin genLowcodeFloat32LessEqual */ - topRegistersMask16 = 0; - frTop6 = (frNext4 = NoReg); - rResult12 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop6 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg16 = (frNext4 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask16 = 1U << reg16; - } - if (frTop6 == NoReg) { - frTop6 = allocateFloatRegNotConflictingWith(topRegistersMask16); - } - if (frNext4 == NoReg) { - frNext4 = allocateFloatRegNotConflictingWith(1U << frTop6); - } - rResult12 = allocateRegNotConflictingWith(0); - assert(!(((frTop6 == NoReg) - || ((frNext4 == NoReg) - || (rResult12 == NoReg))))); - second12 = frTop6; - first12 = frNext4; - value11 = rResult12; - nativePopToReg(ssNativeTop(), second12); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first12); - ssNativePop(1); - /* begin CmpRs:Rs: */ - genoperandoperand(CmpRsRs, second12, first12); - - /* True result */ - falseJump4 = gJumpFPGreater(0); - /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperand(MoveCqR, 1, value11); - /* begin Jump: */ - contJump4 = genoperand(Jump, ((sqInt)0)); - jmpTarget(falseJump4, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction18 = genoperandoperand(MoveCqR, 0, value11); - jmpTarget(contJump4, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(value11); - return 0; - - case 38: - /* begin genLowcodeFloat32Mul */ - topRegistersMask17 = 0; - rTop22 = (rNext17 = NoReg); - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - rTop22 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg17 = (rNext17 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask17 = 1U << reg17; - } - if (rTop22 == NoReg) { - rTop22 = allocateFloatRegNotConflictingWith(topRegistersMask17); - } - if (rNext17 == NoReg) { - rNext17 = allocateFloatRegNotConflictingWith(1U << rTop22); - } - assert(!(((rTop22 == NoReg) - || (rNext17 == NoReg)))); - second13 = rTop22; - first13 = rNext17; - nativePopToReg(ssNativeTop(), second13); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first13); - ssNativePop(1); - /* begin MulRs:Rs: */ - genoperandoperand(MulRsRs, second13, first13); - ssPushNativeRegisterSingleFloat(first13); - return 0; - - case 39: - /* begin genLowcodeFloat32Neg */ - frTop7 = NoReg; - - /* Float argument */ - frResult2 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop7 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if (frTop7 == NoReg) { - frTop7 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - } - frResult2 = allocateFloatRegNotConflictingWith(1U << frTop7); - assert(!(((frTop7 == NoReg) - || (frResult2 == NoReg)))); - value12 = frTop7; - result3 = frResult2; - nativePopToReg(ssNativeTop(), value12); - ssNativePop(1); - /* begin XorRs:Rs: */ - genoperandoperand(XorRsRs, result3, result3); - /* begin SubRs:Rs: */ - genoperandoperand(SubRsRs, value12, result3); - ssPushNativeRegisterSingleFloat(result3); - return 0; - - case 40: - /* begin genLowcodeFloat32NotEqual */ - topRegistersMask18 = 0; - frTop8 = (frNext5 = NoReg); - rResult13 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop8 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg18 = (frNext5 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask18 = 1U << reg18; - } - if (frTop8 == NoReg) { - frTop8 = allocateFloatRegNotConflictingWith(topRegistersMask18); - } - if (frNext5 == NoReg) { - frNext5 = allocateFloatRegNotConflictingWith(1U << frTop8); - } - rResult13 = allocateRegNotConflictingWith(0); - assert(!(((frTop8 == NoReg) - || ((frNext5 == NoReg) - || (rResult13 == NoReg))))); - second14 = frTop8; - first14 = frNext5; - value13 = rResult13; - nativePopToReg(ssNativeTop(), second14); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first14); - ssNativePop(1); - /* begin CmpRs:Rs: */ - genoperandoperand(CmpRsRs, second14, first14); - - /* True result */ - falseJump5 = gJumpFPEqual(0); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperand(MoveCqR, 1, value13); - /* begin Jump: */ - contJump5 = genoperand(Jump, ((sqInt)0)); - jmpTarget(falseJump5, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction110 = genoperandoperand(MoveCqR, 0, value13); - jmpTarget(contJump5, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(value13); - return 0; - - case 41: - /* begin genLowcodeFloat32Sqrt */ - topRegistersMask19 = 0; - frTop9 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop9 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if (frTop9 == NoReg) { - frTop9 = allocateFloatRegNotConflictingWith(topRegistersMask19); - } - assert(!((frTop9 == NoReg))); - value14 = frTop9; - nativePopToReg(ssNativeTop(), value14); - ssNativePop(1); - /* begin SqrtRs: */ - genoperand(SqrtRs, value14); - ssPushNativeRegisterSingleFloat(value14); - return 0; - - case 42: - /* begin genLowcodeFloat32Sub */ - topRegistersMask20 = 0; - rTop23 = (rNext18 = NoReg); - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - rTop23 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg19 = (rNext18 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask20 = 1U << reg19; - } - if (rTop23 == NoReg) { - rTop23 = allocateFloatRegNotConflictingWith(topRegistersMask20); - } - if (rNext18 == NoReg) { - rNext18 = allocateFloatRegNotConflictingWith(1U << rTop23); - } - assert(!(((rTop23 == NoReg) - || (rNext18 == NoReg)))); - second15 = rTop23; - first15 = rNext18; - nativePopToReg(ssNativeTop(), second15); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first15); - ssNativePop(1); - /* begin SubRs:Rs: */ - genoperandoperand(SubRsRs, second15, first15); - ssPushNativeRegisterSingleFloat(first15); - return 0; - - case 43: - /* begin genLowcodeFloat32ToFloat64 */ - topRegistersMask21 = 0; - frTop10 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop10 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if (frTop10 == NoReg) { - frTop10 = allocateFloatRegNotConflictingWith(topRegistersMask21); - } - assert(!((frTop10 == NoReg))); - singleFloatValue = frTop10; - nativePopToReg(ssNativeTop(), singleFloatValue); - ssNativePop(1); - /* begin ConvertRs:Rd: */ - genoperandoperand(ConvertRsRd, singleFloatValue, singleFloatValue); - ssPushNativeRegisterDoubleFloat(singleFloatValue); - return 0; - - case 44: - /* begin genLowcodeFloat32ToInt32 */ - frTop11 = NoReg; - - /* Float argument */ - rResult14 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop11 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if (frTop11 == NoReg) { - frTop11 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult14 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!(((frTop11 == NoReg) - || (rResult14 == NoReg)))); - value15 = frTop11; - result4 = rResult14; - nativePopToReg(ssNativeTop(), value15); - ssNativePop(1); - /* begin ConvertRs:R: */ - genoperandoperand(ConvertRsR, value15, result4); - ssPushNativeRegister(result4); - return 0; - - case 45: - /* begin genLowcodeFloat32ToInt64 */ - frTop12 = NoReg; - - /* Float argument */ - rResult15 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop12 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if (frTop12 == NoReg) { - frTop12 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult15 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!(((frTop12 == NoReg) - || (rResult15 == NoReg)))); - value16 = frTop12; - result5 = rResult15; - nativePopToReg(ssNativeTop(), value16); - ssNativePop(1); - abort(); - return 0; - - case 46: - /* begin genLowcodeFloat32ToUInt32 */ - frTop13 = NoReg; - - /* Float argument */ - rResult16 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop13 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if (frTop13 == NoReg) { - frTop13 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult16 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!(((frTop13 == NoReg) - || (rResult16 == NoReg)))); - value17 = frTop13; - result6 = rResult16; - nativePopToReg(ssNativeTop(), value17); - ssNativePop(1); - /* begin ConvertRs:R: */ - genoperandoperand(ConvertRsR, value17, result6); - ssPushNativeRegister(result6); - return 0; - - case 47: - /* begin genLowcodeFloat32ToUInt64 */ - frTop14 = NoReg; - - /* Float argument */ - rResult17 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop14 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if (frTop14 == NoReg) { - frTop14 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - } - rResult17 = allocateRegNotConflictingWith(0 /* emptyRegisterMask */); - assert(!(((frTop14 == NoReg) - || (rResult17 == NoReg)))); - value18 = frTop14; - result7 = rResult17; - nativePopToReg(ssNativeTop(), value18); - ssNativePop(1); - abort(); - return 0; - - case 48: - /* begin genLowcodeFloat64Add */ - topRegistersMask22 = 0; - rTop24 = (rNext19 = NoReg); - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - rTop24 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg20 = (rNext19 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask22 = 1U << reg20; - } - if (rTop24 == NoReg) { - rTop24 = allocateFloatRegNotConflictingWith(topRegistersMask22); - } - if (rNext19 == NoReg) { - rNext19 = allocateFloatRegNotConflictingWith(1U << rTop24); - } - assert(!(((rTop24 == NoReg) - || (rNext19 == NoReg)))); - second16 = rTop24; - first16 = rNext19; - nativePopToReg(ssNativeTop(), second16); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first16); - ssNativePop(1); - /* begin AddRd:Rd: */ - genoperandoperand(AddRdRd, second16, first16); - ssPushNativeRegisterDoubleFloat(first16); - return 0; - - case 49: - /* begin genLowcodeFloat64Div */ - topRegistersMask23 = 0; - rTop25 = (rNext20 = NoReg); - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - rTop25 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg21 = (rNext20 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask23 = 1U << reg21; - } - if (rTop25 == NoReg) { - rTop25 = allocateFloatRegNotConflictingWith(topRegistersMask23); - } - if (rNext20 == NoReg) { - rNext20 = allocateFloatRegNotConflictingWith(1U << rTop25); - } - assert(!(((rTop25 == NoReg) - || (rNext20 == NoReg)))); - second17 = rTop25; - first17 = rNext20; - nativePopToReg(ssNativeTop(), second17); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first17); - ssNativePop(1); - /* begin DivRd:Rd: */ - genoperandoperand(DivRdRd, second17, first17); - ssPushNativeRegisterDoubleFloat(first17); - return 0; - - case 50: - /* begin genLowcodeFloat64Equal */ - topRegistersMask24 = 0; - frTop15 = (frNext6 = NoReg); - rResult18 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop15 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg22 = (frNext6 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask24 = 1U << reg22; - } - if (frTop15 == NoReg) { - frTop15 = allocateFloatRegNotConflictingWith(topRegistersMask24); - } - if (frNext6 == NoReg) { - frNext6 = allocateFloatRegNotConflictingWith(1U << frTop15); - } - rResult18 = allocateRegNotConflictingWith(0); - assert(!(((frTop15 == NoReg) - || ((frNext6 == NoReg) - || (rResult18 == NoReg))))); - second18 = frTop15; - first18 = frNext6; - value19 = rResult18; - nativePopToReg(ssNativeTop(), second18); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first18); - ssNativePop(1); - /* begin CmpRd:Rd: */ - genoperandoperand(CmpRdRd, second18, first18); - - /* True result */ - falseJump6 = gJumpFPNotEqual(0); - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperand(MoveCqR, 1, value19); - /* begin Jump: */ - contJump6 = genoperand(Jump, ((sqInt)0)); - jmpTarget(falseJump6, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction111 = genoperandoperand(MoveCqR, 0, value19); - jmpTarget(contJump6, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(value19); - return 0; - - case 51: - /* begin genLowcodeFloat64Great */ - topRegistersMask25 = 0; - frTop16 = (frNext7 = NoReg); - rResult19 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop16 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg23 = (frNext7 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask25 = 1U << reg23; - } - if (frTop16 == NoReg) { - frTop16 = allocateFloatRegNotConflictingWith(topRegistersMask25); - } - if (frNext7 == NoReg) { - frNext7 = allocateFloatRegNotConflictingWith(1U << frTop16); - } - rResult19 = allocateRegNotConflictingWith(0); - assert(!(((frTop16 == NoReg) - || ((frNext7 == NoReg) - || (rResult19 == NoReg))))); - second19 = frTop16; - first19 = frNext7; - value20 = rResult19; - nativePopToReg(ssNativeTop(), second19); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first19); - ssNativePop(1); - /* begin CmpRd:Rd: */ - genoperandoperand(CmpRdRd, second19, first19); - - /* True result */ - falseJump7 = gJumpFPLessOrEqual(0); - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperand(MoveCqR, 1, value20); - /* begin Jump: */ - contJump7 = genoperand(Jump, ((sqInt)0)); - jmpTarget(falseJump7, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction112 = genoperandoperand(MoveCqR, 0, value20); - jmpTarget(contJump7, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(value20); - return 0; - - case 52: - /* begin genLowcodeFloat64GreatEqual */ - topRegistersMask26 = 0; - frTop17 = (frNext8 = NoReg); - rResult20 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop17 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg24 = (frNext8 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask26 = 1U << reg24; - } - if (frTop17 == NoReg) { - frTop17 = allocateFloatRegNotConflictingWith(topRegistersMask26); - } - if (frNext8 == NoReg) { - frNext8 = allocateFloatRegNotConflictingWith(1U << frTop17); - } - rResult20 = allocateRegNotConflictingWith(0); - assert(!(((frTop17 == NoReg) - || ((frNext8 == NoReg) - || (rResult20 == NoReg))))); - second20 = frTop17; - first20 = frNext8; - value21 = rResult20; - nativePopToReg(ssNativeTop(), second20); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first20); - ssNativePop(1); - /* begin CmpRd:Rd: */ - genoperandoperand(CmpRdRd, second20, first20); - - /* True result */ - falseJump8 = gJumpFPLess(0); - /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperand(MoveCqR, 1, value21); - /* begin Jump: */ - contJump8 = genoperand(Jump, ((sqInt)0)); - jmpTarget(falseJump8, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction113 = genoperandoperand(MoveCqR, 0, value21); - jmpTarget(contJump8, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(value21); - return 0; - - case 53: - /* begin genLowcodeFloat64Less */ - topRegistersMask27 = 0; - frTop18 = (frNext9 = NoReg); - rResult22 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop18 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg25 = (frNext9 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask27 = 1U << reg25; - } - if (frTop18 == NoReg) { - frTop18 = allocateFloatRegNotConflictingWith(topRegistersMask27); - } - if (frNext9 == NoReg) { - frNext9 = allocateFloatRegNotConflictingWith(1U << frTop18); - } - rResult22 = allocateRegNotConflictingWith(0); - assert(!(((frTop18 == NoReg) - || ((frNext9 == NoReg) - || (rResult22 == NoReg))))); - second21 = frTop18; - first21 = frNext9; - value22 = rResult22; - nativePopToReg(ssNativeTop(), second21); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first21); - ssNativePop(1); - /* begin CmpRd:Rd: */ - genoperandoperand(CmpRdRd, second21, first21); - - /* True result */ - falseJump9 = gJumpFPGreaterOrEqual(0); - /* begin checkQuickConstant:forInstruction: */ - anInstruction23 = genoperandoperand(MoveCqR, 1, value22); - /* begin Jump: */ - contJump9 = genoperand(Jump, ((sqInt)0)); - jmpTarget(falseJump9, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction114 = genoperandoperand(MoveCqR, 0, value22); - jmpTarget(contJump9, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(value22); - return 0; - - case 54: - /* begin genLowcodeFloat64LessEqual */ - topRegistersMask28 = 0; - frTop19 = (frNext10 = NoReg); - rResult23 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop19 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg26 = (frNext10 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask28 = 1U << reg26; - } - if (frTop19 == NoReg) { - frTop19 = allocateFloatRegNotConflictingWith(topRegistersMask28); - } - if (frNext10 == NoReg) { - frNext10 = allocateFloatRegNotConflictingWith(1U << frTop19); - } - rResult23 = allocateRegNotConflictingWith(0); - assert(!(((frTop19 == NoReg) - || ((frNext10 == NoReg) - || (rResult23 == NoReg))))); - second22 = frTop19; - first22 = frNext10; - value23 = rResult23; - nativePopToReg(ssNativeTop(), second22); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first22); - ssNativePop(1); - /* begin CmpRd:Rd: */ - genoperandoperand(CmpRdRd, second22, first22); - - /* True result */ - falseJump10 = gJumpFPGreater(0); - /* begin checkQuickConstant:forInstruction: */ - anInstruction24 = genoperandoperand(MoveCqR, 1, value23); - /* begin Jump: */ - contJump10 = genoperand(Jump, ((sqInt)0)); - jmpTarget(falseJump10, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction115 = genoperandoperand(MoveCqR, 0, value23); - jmpTarget(contJump10, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(value23); - return 0; - - case 55: - /* begin genLowcodeFloat64Mul */ - topRegistersMask29 = 0; - rTop26 = (rNext21 = NoReg); - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - rTop26 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg27 = (rNext21 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask29 = 1U << reg27; - } - if (rTop26 == NoReg) { - rTop26 = allocateFloatRegNotConflictingWith(topRegistersMask29); - } - if (rNext21 == NoReg) { - rNext21 = allocateFloatRegNotConflictingWith(1U << rTop26); - } - assert(!(((rTop26 == NoReg) - || (rNext21 == NoReg)))); - second23 = rTop26; - first23 = rNext21; - nativePopToReg(ssNativeTop(), second23); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first23); - ssNativePop(1); - /* begin MulRd:Rd: */ - genoperandoperand(MulRdRd, second23, first23); - ssPushNativeRegisterDoubleFloat(first23); - return 0; - - case 56: - /* begin genLowcodeFloat64Neg */ - frTop20 = NoReg; - - /* Float argument */ - frResult3 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop20 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if (frTop20 == NoReg) { - frTop20 = allocateFloatRegNotConflictingWith(0 /* emptyRegisterMask */); - } - frResult3 = allocateFloatRegNotConflictingWith(1U << frTop20); - assert(!(((frTop20 == NoReg) - || (frResult3 == NoReg)))); - value24 = frTop20; - result8 = frResult3; - nativePopToReg(ssNativeTop(), value24); - ssNativePop(1); - /* begin XorRd:Rd: */ - genoperandoperand(XorRdRd, result8, result8); - /* begin SubRd:Rd: */ - genoperandoperand(SubRdRd, value24, result8); - ssPushNativeRegisterDoubleFloat(result8); - return 0; - - case 57: - /* begin genLowcodeFloat64NotEqual */ - topRegistersMask30 = 0; - frTop21 = (frNext11 = NoReg); - rResult24 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop21 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg28 = (frNext11 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask30 = 1U << reg28; - } - if (frTop21 == NoReg) { - frTop21 = allocateFloatRegNotConflictingWith(topRegistersMask30); - } - if (frNext11 == NoReg) { - frNext11 = allocateFloatRegNotConflictingWith(1U << frTop21); - } - rResult24 = allocateRegNotConflictingWith(0); - assert(!(((frTop21 == NoReg) - || ((frNext11 == NoReg) - || (rResult24 == NoReg))))); - second24 = frTop21; - first24 = frNext11; - value25 = rResult24; - nativePopToReg(ssNativeTop(), second24); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first24); - ssNativePop(1); - /* begin CmpRd:Rd: */ - genoperandoperand(CmpRdRd, second24, first24); - - /* True result */ - falseJump11 = gJumpFPEqual(0); - /* begin checkQuickConstant:forInstruction: */ - anInstruction25 = genoperandoperand(MoveCqR, 1, value25); - /* begin Jump: */ - contJump11 = genoperand(Jump, ((sqInt)0)); - jmpTarget(falseJump11, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction116 = genoperandoperand(MoveCqR, 0, value25); - jmpTarget(contJump11, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushNativeRegister(value25); - return 0; - - case 58: - /* begin genLowcodeFloat64Sqrt */ - topRegistersMask31 = 0; - frTop22 = NoReg; - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - frTop22 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if (frTop22 == NoReg) { - frTop22 = allocateFloatRegNotConflictingWith(topRegistersMask31); - } - assert(!((frTop22 == NoReg))); - value26 = frTop22; - nativePopToReg(ssNativeTop(), value26); - ssNativePop(1); - /* begin SqrtRd: */ - genoperand(SqrtRd, value26); - ssPushNativeRegisterDoubleFloat(value26); - return 0; - - case 59: - /* begin genLowcodeFloat64Sub */ - topRegistersMask32 = 0; - rTop27 = (rNext22 = NoReg); - if ((nativeFloatRegisterOrNone(ssNativeTop())) != NoReg) { - rTop27 = nativeFloatRegisterOrNone(ssNativeTop()); - } - if ((nativeFloatRegisterOrNone(ssNativeValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg29 = (rNext22 = nativeFloatRegisterOrNone(ssNativeValue(1))); - topRegistersMask32 = 1U << reg29; - } - if (rTop27 == NoReg) { - rTop27 = allocateFloatRegNotConflictingWith(topRegistersMask32); - } - if (rNext22 == NoReg) { - rNext22 = allocateFloatRegNotConflictingWith(1U << rTop27); - } - assert(!(((rTop27 == NoReg) - || (rNext22 == NoReg)))); - second25 = rTop27; - first25 = rNext22; - nativePopToReg(ssNativeTop(), second25); - ssNativePop(1); - nativePopToReg(ssNativeTop(), first25); - ssNativePop(1); - /* begin SubRd:Rd: */ - genoperandoperand(SubRdRd, second25, first25); - ssPushNativeRegisterDoubleFloat(first25); - return 0; - - default: - return genLowcodeUnaryInlinePrimitive2(prim); - - } - return 0; -} - - /* StackToRegisterMappingCogit>>#genMarshalledSend:numArgs:sendTable: */ -static sqInt NoDbgRegParms -genMarshalledSendnumArgssendTable(sqInt selectorIndex, sqInt numArgs, sqInt *sendTable) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt annotation; - - assert(needsFrame); - /* begin annotationForSendTable: */ - if (sendTable == ordinarySendTrampolines) { - annotation = IsSendCall; - goto l2; - } - if (sendTable == directedSuperSendTrampolines) { - annotation = IsDirectedSuperSend; - goto l2; - } - if (sendTable == directedSuperBindingSendTrampolines) { - annotation = IsDirectedSuperBindingSend; - goto l2; - } - assert(sendTable == superSendTrampolines); - annotation = IsSuperSend; - l2: /* end annotationForSendTable: */; - if ((annotation == IsSuperSend) - || (((annotation >= IsDirectedSuperSend) && (annotation <= IsDirectedSuperBindingSend)))) { - genEnsureOopInRegNotForwardedscratchReg(ReceiverResultReg, TempReg); - } - if (numArgs >= (NumSendTrampolines - 1)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, numArgs, SendNumArgsReg); - } - if (((annotation >= IsDirectedSuperSend) && (annotation <= IsDirectedSuperBindingSend))) { - /* begin genMoveConstant:R: */ - if (shouldAnnotateObjectReference(tempOop)) { - annotateobjRef(checkLiteralforInstruction(tempOop, genoperandoperand(MoveCwR, tempOop, TempReg)), tempOop); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, tempOop, TempReg); - } - } - genLoadInlineCacheWithSelector(selectorIndex); - ((genoperand(Call, sendTable[((numArgs < (NumSendTrampolines - 1)) ? numArgs : (NumSendTrampolines - 1))]))->annotation = annotation); - /* begin voidReceiverOptStatus */ - ((simSelf())->liveRegister = NoReg); - return ssPushRegister(ReceiverResultReg); -} - - -/* Generate the abort for a method. This abort performs either a call of - ceSICMiss: to handle a single-in-line cache miss or a call of - ceStackOverflow: to handle a - stack overflow. It distinguishes the two by testing ResultReceiverReg. If - the register is zero then this is a stack-overflow because a) the receiver - has already - been pushed and so can be set to zero before calling the abort, and b) the - receiver must always contain an object (and hence be non-zero) on SIC - miss. */ - - /* StackToRegisterMappingCogit>>#genMethodAbortTrampolineFor: */ -static usqInt NoDbgRegParms -genMethodAbortTrampolineFor(sqInt numArgs) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *jumpSICMiss; - - zeroOpcodeIndex(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, ReceiverResultReg); - /* begin JumpNonZero: */ - jumpSICMiss = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveR:Mw:r: */ - anInstruction = genoperandoperandoperand(MoveRMwr, LinkReg, 0, SPReg); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(ceStackOverflow, 1, SendNumArgsReg, null, null, null, 0 /* emptyRegisterMask */, 0, NoReg); - jmpTarget(jumpSICMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genPushRegisterArgsForAbortMissNumArgs(backEnd, numArgs); - return genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceSICMiss, trampolineNamenumRegArgs("ceMethodAbort", numArgs), 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 0, NoReg, 1); -} - - -/* Generate the abort for a PIC. This abort performs either a call of - ceInterpretMethodFromPIC:receiver: to handle invoking an uncogged - target or a call of ceMNUFromPICMNUMethod:receiver: to handle an - MNU dispatch in a closed PIC. It distinguishes the two by testing - ClassReg. If the register is zero then this is an MNU. */ - - /* StackToRegisterMappingCogit>>#genPICAbortTrampolineFor: */ -static usqInt NoDbgRegParms -genPICAbortTrampolineFor(sqInt numArgs) -{ - zeroOpcodeIndex(); - genPushRegisterArgsForAbortMissNumArgs(backEnd, numArgs); - return genInnerPICAbortTrampoline(trampolineNamenumRegArgs("cePICAbort", numArgs)); -} - - /* StackToRegisterMappingCogit>>#genPICMissTrampolineFor: */ -static usqInt NoDbgRegParms -genPICMissTrampolineFor(sqInt numArgs) -{ - usqInt startAddress; - - startAddress = methodZoneBase; - zeroOpcodeIndex(); - genPushRegisterArgsForNumArgsscratchReg(backEnd, numArgs, SendNumArgsReg); - genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceCPICMissreceiver, trampolineNamenumRegArgs("cePICMiss", numArgs), 2, ClassReg, ReceiverResultReg, null, null, 0 /* emptyRegisterMask */, 1, NoReg, 1); - return startAddress; -} - - /* StackToRegisterMappingCogit>>#genPopStackBytecode */ -static sqInt -genPopStackBytecode(void) -{ - AbstractInstruction *anInstruction; - - if (((ssTop())->spilled)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, BytesPerWord, SPReg); - } - ssPop(1); - return 0; -} - - -/* Check the argument count. Fail if wrong. - Get the method from the outerContext and see if it is cogged. If so, jump - to the - block entry or the no-context-switch entry, as appropriate, and we're - done. If not, - invoke the interpreter primitive. */ -/* Check the argument count. Fail if wrong. - Get the method from the outerContext and see if it is cogged. If so, jump - to the - block entry or the no-context-switch entry, as appropriate, and we're - done. If not, - invoke the interpreter primitive. - Override to push the register args first. */ - - /* StackToRegisterMappingCogit>>#genPrimitiveClosureValue */ -static sqInt -genPrimitiveClosureValue(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *jumpBCMethod; - AbstractInstruction *jumpFail1; - AbstractInstruction *jumpFail2; - AbstractInstruction *jumpFail3; - AbstractInstruction *jumpFail4; - AbstractInstruction *jumpFailNArgs; - sqInt offset; - void (*primitiveRoutine)(void); - sqInt result; - - genPushRegisterArgs(); - genLoadSlotsourceRegdestReg(ClosureNumArgsIndex, ReceiverResultReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)methodOrBlockNumArgs << 1) | 1); - anInstruction1 = genoperandoperand(CmpCqR, (((usqInt)methodOrBlockNumArgs << 1) | 1), TempReg); - /* begin JumpNonZero: */ - jumpFailNArgs = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(ClosureOuterContextIndex, ReceiverResultReg, ClassReg); - jumpFail1 = genJumpImmediate(ClassReg); - genGetCompactClassIndexNonImmOfinto(ClassReg, TempReg); - genCmpClassMethodContextCompactIndexR(TempReg); - /* begin JumpNonZero: */ - jumpFail2 = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(MethodIndex, ClassReg, SendNumArgsReg); - jumpFail3 = genJumpImmediate(SendNumArgsReg); - genGetFormatOfinto(SendNumArgsReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction2 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), TempReg); - /* begin JumpLess: */ - jumpFail4 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - genLoadSlotsourceRegdestReg(HeaderIndex, SendNumArgsReg, ClassReg); - jumpBCMethod = genJumpImmediate(ClassReg); - /* begin MoveM16:r:R: */ - offset = offsetof(CogMethod, blockEntryOffset); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperandoperand(MoveM16rR, offset, ClassReg, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, ClassReg, TempReg); - primitiveRoutine = functionPointerForCompiledMethodprimitiveIndexprimitivePropertyFlagsInto(methodObj, primitiveIndex, null); - if (primitiveRoutine == primitiveClosureValueNoContextSwitch) { - if (blockNoContextSwitchOffset == null) { - return NotFullyInitialized; - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, blockNoContextSwitchOffset, TempReg); - } - /* begin JumpR: */ - genoperand(JumpR, TempReg); - jmpTarget(jumpBCMethod, jmpTarget(jumpFail1, jmpTarget(jumpFail2, jmpTarget(jumpFail3, jmpTarget(jumpFail4, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))))); - if (((result = compileInterpreterPrimitiveflags(primitiveRoutine, primitivePropertyFlags(primitiveIndex)))) < 0) { - return result; - } - jmpTarget(jumpFailNArgs, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - -/* Check the argument count. Fail if wrong. - Get the method from the outerContext and see if it is cogged. If so, jump - to the - block entry or the no-context-switch entry, as appropriate, and we're - done. If not, - invoke the interpreter primitive. */ -/* Override to push the register args first. */ - - /* StackToRegisterMappingCogit>>#genPrimitiveFullClosureValue */ -static sqInt -genPrimitiveFullClosureValue(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *jumpBCMethod; - AbstractInstruction *jumpFail4; - AbstractInstruction *jumpFailImmediateMethod; - AbstractInstruction *jumpFailNArgs; - void (*primitiveRoutine)(void); - sqInt quickConstant; - sqInt result; - - genPushRegisterArgs(); - genLoadSlotsourceRegdestReg(ClosureNumArgsIndex, ReceiverResultReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)methodOrBlockNumArgs << 1) | 1); - anInstruction = genoperandoperand(CmpCqR, (((usqInt)methodOrBlockNumArgs << 1) | 1), TempReg); - /* begin JumpNonZero: */ - jumpFailNArgs = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(FullClosureCompiledBlockIndex, ReceiverResultReg, SendNumArgsReg); - jumpFailImmediateMethod = genJumpImmediate(SendNumArgsReg); - genGetFormatOfinto(SendNumArgsReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction1 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), TempReg); - /* begin JumpLess: */ - jumpFail4 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - genLoadSlotsourceRegdestReg(HeaderIndex, SendNumArgsReg, ClassReg); - jumpBCMethod = genJumpImmediate(ClassReg); - primitiveRoutine = functionPointerForCompiledMethodprimitiveIndexprimitivePropertyFlagsInto(methodObj, primitiveIndex, null); - /* begin AddCq:R: */ - quickConstant = (primitiveRoutine == primitiveFullClosureValueNoContextSwitch - ? fullBlockNoContextSwitchEntryOffset() - : fullBlockEntryOffset()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AddCqR, quickConstant, ClassReg); - /* begin JumpR: */ - genoperand(JumpR, ClassReg); - jmpTarget(jumpBCMethod, jmpTarget(jumpFailImmediateMethod, jmpTarget(jumpFail4, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))); - if (((result = compileInterpreterPrimitiveflags(primitiveRoutine, primitivePropertyFlags(primitiveIndex)))) < 0) { - return result; - } - jmpTarget(jumpFailNArgs, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - -/* Generate an in-line perform primitive. The lookup code requires the - selector to be in Arg0Reg. - adjustArgumentsForPerform: adjusts the arguments once - genLookupForPerformNumArgs: has generated the code for the lookup. */ - - /* StackToRegisterMappingCogit>>#genPrimitivePerform */ -static sqInt -genPrimitivePerform(void) -{ - AbstractInstruction *anInstruction; - sqInt offset; - - if (methodOrBlockNumArgs > 2 /* numRegArgs */) { - /* begin MoveMw:r:R: */ - offset = (methodOrBlockNumArgs - 1) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, SPReg, Arg0Reg); - } - return genLookupForPerformNumArgs(methodOrBlockNumArgs); -} - - /* StackToRegisterMappingCogit>>#genPushActiveContextBytecode */ -static sqInt -genPushActiveContextBytecode(void) -{ - assert(needsFrame); - voidReceiverResultRegContainsSelf(); - /* begin ssAllocateCallReg:and:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg) | (1U << SendNumArgsReg)) | (1U << ClassReg)), simStackPtr, simNativeStackPtr); - genGetActiveContextNumArgslargeinBlock(methodOrBlockNumArgs, methodNeedsLargeContext(methodObj), inBlock); - return ssPushRegister(ReceiverResultReg); -} - - -/* Block compilation. At this point in the method create the block. Note its - start and defer generating code for it until after the method and any - other preceding - blocks. The block's actual code will be compiled later. */ -/* 143 10001111 llllkkkk jjjjjjjj iiiiiiii Push Closure Num Copied llll Num - Args kkkk BlockSize jjjjjjjjiiiiiiii */ - - /* StackToRegisterMappingCogit>>#genPushClosureCopyCopiedValuesBytecode */ -static sqInt -genPushClosureCopyCopiedValuesBytecode(void) -{ - sqInt i; - sqInt numArgs; - sqInt numCopied; - sqInt reg; - sqInt startpc; - - assert(needsFrame); - startpc = bytecodePC + (((generatorAt(byte0))->numBytes)); - addBlockStartAtnumArgsnumCopiedspan(startpc, (numArgs = byte1 & 15), (numCopied = ((usqInt)(byte1)) >> 4), (((sqInt)((usqInt)(byte2) << 8))) + byte3); - /* begin genInlineClosure:numArgs:numCopied: */ - assert(getActiveContextAllocatesInMachineCode()); - voidReceiverResultRegContainsSelf(); - /* begin ssAllocateCallReg:and:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg) | (1U << SendNumArgsReg)) | (1U << ClassReg)), simStackPtr, simNativeStackPtr); - genNoPopCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(startpc + 1, numArgs, numCopied, methodOrBlockNumArgs, methodNeedsLargeContext(methodObj), inBlock); - for (i = 1; i <= numCopied; i += 1) { - reg = ssStorePoptoPreferredReg(1, TempReg); - genStoreSourceRegslotIndexintoNewObjectInDestReg(reg, (ClosureFirstCopiedValueIndex + numCopied) - i, ReceiverResultReg); - } - ssPushRegister(ReceiverResultReg); - return 0; -} - - -/* */ -/* Override to avoid the BytecodeSetHasDirectedSuperSend check, which is - unnecessary here given the simulation stack. */ - - /* StackToRegisterMappingCogit>>#genPushLiteralIndex: */ -static sqInt NoDbgRegParms -genPushLiteralIndex(sqInt literalIndex) -{ - sqInt literal; - - literal = getLiteral(literalIndex); - return genPushLiteral(literal); -} - - /* StackToRegisterMappingCogit>>#genPushLiteralVariable: */ -static sqInt NoDbgRegParms -genPushLiteralVariable(sqInt literalIndex) -{ - AbstractInstruction *anInstruction; - sqInt association; - sqInt bcpc; - BytecodeDescriptor *descriptor1; - sqInt eA; - sqInt eB; - sqInt freeReg; - sqInt savedB0; - sqInt savedB1; - sqInt savedB2; - sqInt savedB3; - sqInt savedEA; - sqInt savedEB; - sqInt savedNEB; - - - /* If followed by a directed super send bytecode, avoid generating any code yet. - The association will be passed to the directed send trampoline in a register - and fully dereferenced only when first linked. It will be ignored in later sends. */ - association = getLiteral(literalIndex); - assert(!(directedSendUsesBinding)); - /* begin nextDescriptorExtensionsAndNextPCInto: */ - descriptor1 = generatorAt(byte0); - savedB0 = byte0; - savedB1 = byte1; - savedB2 = byte2; - savedB3 = byte3; - savedEA = extA; - savedEB = extB; - savedNEB = numExtB; - bcpc = bytecodePC + ((descriptor1->numBytes)); - do { - if (bcpc > endPC) { - goto l1; - } - byte0 = (fetchByteofObject(bcpc, methodObj)) + bytecodeSetOffset; - descriptor1 = generatorAt(byte0); - loadSubsequentBytesForDescriptorat(descriptor1, bcpc); - if (!((descriptor1->isExtension))) { - eA = extA; - eB = extB; - extA = savedEA; - extB = savedEB; - numExtB = savedNEB; - byte0 = savedB0; - byte1 = savedB1; - byte2 = savedB2; - byte3 = savedB3; - if ((descriptor1 != null) - && ((((descriptor1->generator)) == genExtSendSuperBytecode) - && (eB >= 64))) { - ssPushConstant(association); - directedSendUsesBinding = 1; - return 0; - } - goto l1; - } - ((descriptor1->generator))(); - bcpc += (descriptor1->numBytes); - } while(1); - l1: /* end nextDescriptorExtensionsAndNextPCInto: */; - - /* N.B. Do _not_ use ReceiverResultReg to avoid overwriting receiver in assignment in frameless methods. */ - /* So far descriptors are not rich enough to describe the entire dereference so generate the register - load but don't push the result. There is an order-of-evaluation issue if we defer the dereference. */ - freeReg = allocateRegNotConflictingWith(0); - /* begin genMoveConstant:R: */ - if (shouldAnnotateObjectReference(association)) { - annotateobjRef(checkLiteralforInstruction(association, genoperandoperand(MoveCwR, association, TempReg)), association); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, association, TempReg); - } - genLoadSlotsourceRegdestReg(ValueIndex, TempReg, freeReg); - ssPushRegister(freeReg); - return 0; -} - - /* StackToRegisterMappingCogit>>#genPushLiteral: */ -static sqInt NoDbgRegParms -genPushLiteral(sqInt literal) -{ - return ssPushConstant(literal); -} - - /* StackToRegisterMappingCogit>>#genPushMaybeContextReceiverVariable: */ -static sqInt NoDbgRegParms -genPushMaybeContextReceiverVariable(sqInt slotIndex) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *jmpDone; - AbstractInstruction *jmpSingle; - - /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); - ensureReceiverResultRegContainsSelf(); - /* begin genPushMaybeContextSlotIndex: */ - assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { - - /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ - voidReceiverResultRegContainsSelf(); - } - if (slotIndex == InstructionPointerIndex) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, slotIndex, SendNumArgsReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceFetchContextInstVarTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - return ssPushRegister(SendNumArgsReg); - } - genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); - jmpSingle = genJumpNotSmallIntegerInScratchReg(TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, slotIndex, SendNumArgsReg); - /* begin CallRT: */ - abstractInstruction1 = genoperand(Call, ceFetchContextInstVarTrampoline); - (abstractInstruction1->annotation = IsRelativeCall); - /* begin Jump: */ - jmpDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jmpSingle, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genLoadSlotsourceRegdestReg(slotIndex, ReceiverResultReg, SendNumArgsReg); - jmpTarget(jmpDone, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return ssPushRegister(SendNumArgsReg); -} - - /* StackToRegisterMappingCogit>>#genPushNewArrayBytecode */ -static sqInt -genPushNewArrayBytecode(void) -{ - sqInt i; - sqInt i1; - int popValues; - sqInt size; - - assert(needsFrame); - voidReceiverResultRegContainsSelf(); - if ((popValues = byte1 > 0x7F)) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i1 <= simStackPtr; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - } - else { - /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); - } - size = byte1 & 0x7F; - if (!popValues) { - if (tryCollapseTempVectorInitializationOfSize(size)) { - return 0; - } - } - genNewArrayOfSizeinitialized(size, !popValues); - if (popValues) { - for (i = (size - 1); i >= 0; i += -1) { - /* begin PopR: */ - genoperand(PopR, TempReg); - genStoreSourceRegslotIndexintoNewObjectInDestReg(TempReg, i, ReceiverResultReg); - } - ssPop(size); - } - return ssPushRegister(ReceiverResultReg); -} - - /* StackToRegisterMappingCogit>>#genPushReceiverBytecode */ -static sqInt -genPushReceiverBytecode(void) -{ - if ((((simSelf())->liveRegister)) == ReceiverResultReg) { - return ssPushRegister(ReceiverResultReg); - } - return ssPushDesc(ssSelfDescriptor()); -} - - /* StackToRegisterMappingCogit>>#genPushReceiverVariable: */ -static sqInt NoDbgRegParms -genPushReceiverVariable(sqInt index) -{ - ensureReceiverResultRegContainsSelf(); - return ssPushBaseoffset(ReceiverResultReg, slotOffsetOfInstVarIndex(index)); -} - - -/* Ensure that the register args are pushed before the retpc for methods with - arity <= self numRegArgs. - */ -/* This isn't as clumsy on a RISC. But putting the receiver and - args above the return address means the CoInterpreter has a - single machine-code frame format which saves us a lot of work. */ - - /* StackToRegisterMappingCogit>>#genPushRegisterArgs */ -static void -genPushRegisterArgs(void) -{ - if (!(regArgsHaveBeenPushed - || (methodOrBlockNumArgs > 2 /* numRegArgs */))) { - genPushRegisterArgsForNumArgsscratchReg(backEnd, methodOrBlockNumArgs, SendNumArgsReg); - regArgsHaveBeenPushed = 1; - } -} - - /* StackToRegisterMappingCogit>>#genPushRemoteTempLongBytecode */ -static sqInt -genPushRemoteTempLongBytecode(void) -{ - AbstractInstruction *anInstruction; - sqInt offset; - sqInt regMask; - sqInt remoteTempReg; - sqInt tempVectReg; - - tempVectReg = allocateRegNotConflictingWith(0); - /* begin MoveMw:r:R: */ - offset = frameOffsetOfTemporary(byte2); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, FPReg, tempVectReg); - /* begin availableRegOrNoneNotConflictingWith: */ - regMask = 1U << tempVectReg; - remoteTempReg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); - if (remoteTempReg == NoReg) { - remoteTempReg = tempVectReg; - } - genLoadSlotsourceRegdestReg(byte1, tempVectReg, remoteTempReg); - return ssPushRegister(remoteTempReg); -} - - -/* If a frameless method (not a block), only argument temps can be accessed. - This is assured by the use of needsFrameIfMod16GENumArgs: in pushTemp. */ - - /* StackToRegisterMappingCogit>>#genPushTemporaryVariable: */ -static sqInt NoDbgRegParms -genPushTemporaryVariable(sqInt index) -{ - assert((inBlock > 0) - || (needsFrame - || (index < methodOrBlockNumArgs))); - return ssPushDesc(simStack[index + 1]); -} - - -/* In a frameless method ReceiverResultReg already contains self. - In a frameful method, ReceiverResultReg /may/ contain self. */ - - /* StackToRegisterMappingCogit>>#genReturnReceiver */ -static sqInt -genReturnReceiver(void) -{ - if (needsFrame) { - if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { - /* begin putSelfInReceiverResultReg */ - storeToReg(simSelf(), ReceiverResultReg); - } - } - return genUpArrowReturn(); -} - - /* StackToRegisterMappingCogit>>#genReturnTopFromBlock */ -static sqInt -genReturnTopFromBlock(void) -{ - assert(inBlock > 0); - popToReg(ssTop(), ReceiverResultReg); - ssPop(1); - return genBlockReturn(); -} - - /* StackToRegisterMappingCogit>>#genReturnTopFromMethod */ -static sqInt -genReturnTopFromMethod(void) -{ - popToReg(ssTop(), ReceiverResultReg); - ssPop(1); - return genUpArrowReturn(); -} - - /* StackToRegisterMappingCogit>>#genSendDirectedSuper:numArgs: */ -static sqInt NoDbgRegParms -genSendDirectedSupernumArgs(sqInt selectorIndex, sqInt numArgs) -{ - sqInt result; - - assert((((ssTop())->type)) == SSConstant); - tempOop = ((ssTop())->constant); - ssPop(1); - marshallSendArguments(numArgs); - result = genMarshalledSendnumArgssendTable(selectorIndex, numArgs, (directedSendUsesBinding - ? directedSuperBindingSendTrampolines - : directedSuperSendTrampolines)); - directedSendUsesBinding = 0; - return result; -} - - /* StackToRegisterMappingCogit>>#genSendSuper:numArgs: */ -static sqInt NoDbgRegParms -genSendSupernumArgs(sqInt selectorIndex, sqInt numArgs) -{ - marshallSendArguments(numArgs); - return genMarshalledSendnumArgssendTable(selectorIndex, numArgs, superSendTrampolines); -} - - -/* Generate a trampoline with four arguments. - Hack: a negative value indicates an abstract register, a non-negative - value indicates a constant. */ - - /* StackToRegisterMappingCogit>>#genSendTrampolineFor:numArgs:called:arg:arg:arg:arg: */ -static usqInt NoDbgRegParms -genSendTrampolineFornumArgscalledargargargarg(void *aRoutine, sqInt numArgs, char *aString, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3) -{ - sqInt routine; - usqInt startAddress; - - startAddress = methodZoneBase; - zeroOpcodeIndex(); - genPushRegisterArgsForNumArgsscratchReg(backEnd, numArgs, SendNumArgsReg); - /* begin selectorIndexDereferenceRoutine */ - routine = null; - if (!(routine == null)) { - - /* Explicitly save LinkReg via ExtraReg2; it's presumably faster than pushing/popping */ - /* begin MoveR:R: */ - genoperandoperand(MoveRR, LinkReg, Extra2Reg); - /* begin Call: */ - genoperand(Call, routine); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Extra2Reg, LinkReg); - } - genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(aRoutine, aString, 4, regOrConst0, regOrConst1, regOrConst2, regOrConst3, 0 /* emptyRegisterMask */, 1, NoReg, 1); - return startAddress; -} - - /* StackToRegisterMappingCogit>>#genSend:numArgs: */ -static sqInt NoDbgRegParms -genSendnumArgs(sqInt selectorIndex, sqInt numArgs) -{ - marshallSendArguments(numArgs); - return genMarshalledSendnumArgssendTable(selectorIndex, numArgs, ordinarySendTrampolines); -} - - /* StackToRegisterMappingCogit>>#genSpecialSelectorArithmetic */ -static sqInt -genSpecialSelectorArithmetic(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - sqInt argInt; - int argIsConst; - sqInt argIsInt; - sqInt i; - sqInt index; - AbstractInstruction *jumpContinue; - AbstractInstruction *jumpNotSmallInts; - BytecodeDescriptor *primDescriptor; - sqInt rcvrInt; - int rcvrIsConst; - sqInt rcvrIsInt; - sqInt result; - - primDescriptor = generatorAt(byte0); - argIsInt = ((argIsConst = (((ssTop())->type)) == SSConstant)) - && ((((argInt = ((ssTop())->constant))) & 1)); - rcvrIsInt = (((rcvrIsConst = (((ssValue(1))->type)) == SSConstant)) - && ((((rcvrInt = ((ssValue(1))->constant))) & 1))) - || ((mclassIsSmallInteger()) - && (isSameEntryAs(ssValue(1), simSelf()))); - if (argIsInt - && (rcvrIsInt - && (rcvrIsConst))) { - rcvrInt = (rcvrInt >> 1); - argInt = (argInt >> 1); - switch ((primDescriptor->opcode)) { - case AddRR: - result = rcvrInt + argInt; - break; - case SubRR: - result = rcvrInt - argInt; - break; - case AndRR: - result = rcvrInt & argInt; - break; - case OrRR: - result = rcvrInt | argInt; - break; - default: - error("Case not found and no otherwise clause"); - } - if (isIntegerValue(result)) { - - /* Must annotate the bytecode for correct pc mapping. */ - return (ssPop(2), - ssPushAnnotatedConstant((((usqInt)result << 1) | 1))); - } - return genSpecialSelectorSend(); - } - if ((rcvrIsConst - && (!rcvrIsInt)) - || (argIsConst - && (!argIsInt))) { - return genSpecialSelectorSend(); - } - if (!(argIsInt - || (rcvrIsInt))) { - return genSpecialSelectorSend(); - } - if (argIsInt) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= (simStackPtr - 2)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 2)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 2))); i <= (simStackPtr - 2); i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 2) + 1; - } - popToReg(ssValue(1), ReceiverResultReg); - ssPop(2); - } - else { - marshallSendArguments(1); - } - jumpNotSmallInts = (!(rcvrIsInt - && (argIsInt)) - ? (argIsInt - ? genJumpNotSmallInteger(ReceiverResultReg) - : (rcvrIsInt - ? genJumpNotSmallInteger(Arg0Reg) - : (/* begin genJumpNotSmallIntegersIn:and:scratch: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg), - /* begin AndR:R: */ - genoperandoperand(AndRR, Arg0Reg, TempReg), - genJumpNotSmallIntegerInScratchReg(TempReg)))) - : 0); - switch ((primDescriptor->opcode)) { - case AddRR: - if (argIsInt) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, argInt - ConstZero, ReceiverResultReg); - /* begin JumpNoOverflow: */ - jumpContinue = genConditionalBranchoperand(JumpNoOverflow, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(SubCqR, argInt - ConstZero, ReceiverResultReg); - } - else { - genRemoveSmallIntegerTagsInScratchReg(ReceiverResultReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - /* begin JumpNoOverflow: */ - jumpContinue = genConditionalBranchoperand(JumpNoOverflow, ((sqInt)0)); - if (rcvrIsInt - && (rcvrIsConst)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, rcvrInt, ReceiverResultReg); - } - else { - /* begin SubR:R: */ - genoperandoperand(SubRR, Arg0Reg, ReceiverResultReg); - genSetSmallIntegerTagsIn(ReceiverResultReg); - } - } - break; - case SubRR: - if (argIsInt) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(SubCqR, argInt - ConstZero, ReceiverResultReg); - /* begin JumpNoOverflow: */ - jumpContinue = genConditionalBranchoperand(JumpNoOverflow, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(AddCqR, argInt - ConstZero, ReceiverResultReg); - } - else { - genRemoveSmallIntegerTagsInScratchReg(Arg0Reg); - /* begin SubR:R: */ - genoperandoperand(SubRR, Arg0Reg, ReceiverResultReg); - /* begin JumpNoOverflow: */ - jumpContinue = genConditionalBranchoperand(JumpNoOverflow, ((sqInt)0)); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - genSetSmallIntegerTagsIn(Arg0Reg); - } - break; - case AndRR: - if (argIsInt) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(AndCqR, argInt, ReceiverResultReg); - } - else { - /* begin AndR:R: */ - genoperandoperand(AndRR, Arg0Reg, ReceiverResultReg); - } - jumpContinue = (!(jumpNotSmallInts == null) - ? (/* begin Jump: */ - genoperand(Jump, ((sqInt)0))) - : 0); - break; - case OrRR: - if (argIsInt) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(OrCqR, argInt, ReceiverResultReg); - } - else { - /* begin OrR:R: */ - genoperandoperand(OrRR, Arg0Reg, ReceiverResultReg); - } - jumpContinue = (!(jumpNotSmallInts == null) - ? (/* begin Jump: */ - genoperand(Jump, ((sqInt)0))) - : 0); - break; - default: - error("Case not found and no otherwise clause"); - } - if (jumpNotSmallInts == null) { - if (!jumpContinue) { - - /* overflow cannot happen */ - /* begin annotateInstructionForBytecode */ - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (abstractInstruction->annotation = HasBytecodePC); - ssPushRegister(ReceiverResultReg); - return 0; - } - } - else { - jmpTarget(jumpNotSmallInts, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - if (argIsInt) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(MoveCqR, argInt, Arg0Reg); - } - index = byte0 - ( -#if MULTIPLEBYTECODESETS - (bytecodeSetOffset == 0x100 - ? AltFirstSpecialSelector + 0x100 - : FirstSpecialSelector) -#else - FirstSpecialSelector -#endif - ); - genMarshalledSendnumArgssendTable((-index) - 1, 1, ordinarySendTrampolines); - jmpTarget(jumpContinue, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - /* StackToRegisterMappingCogit>>#genSpecialSelectorClass */ -static sqInt -genSpecialSelectorClass(void) -{ - sqInt requiredReg1; - sqInt topReg; - - topReg = registerOrNone(ssTop()); - ssPop(1); - if ((topReg == NoReg) - || (topReg == ClassReg)) { - /* begin ssAllocateRequiredReg:and: */ - requiredReg1 = (topReg = SendNumArgsReg); - ssAllocateRequiredRegMaskupThroughupThroughNative((1U << requiredReg1) | (1U << ClassReg), simStackPtr, simNativeStackPtr); - } - else { - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr, simNativeStackPtr); - } - ssPush(1); - popToReg(ssTop(), topReg); - genGetClassObjectOfintoscratchRegmayBeAForwarder(topReg, ClassReg, TempReg, mayBeAForwarder(ssTop())); - return (ssPop(1), - ssPushRegister(ClassReg)); -} - - /* StackToRegisterMappingCogit>>#genSpecialSelectorComparison */ -static sqInt -genSpecialSelectorComparison(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt argInt; - sqInt argIsIntConst; - BytecodeDescriptor *branchDescriptor; - BytecodeDescriptor *branchDescriptor1; - sqInt i; - sqInt index; - sqInt inlineCAB; - AbstractInstruction *jumpNotSmallInts; - void *jumpTarget; - sqInt nExts; - sqInt nextPC; - sqInt nextPC1; - sqInt postBranchPC; - sqInt postBranchPC1; - BytecodeDescriptor *primDescriptor; - BytecodeDescriptor *primDescriptor1; - int rcvrIsConst; - sqInt rcvrIsInt; - sqInt targetBytecodePC; - sqInt targetPC; - - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= (simStackPtr - 2)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 2)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 2))); i <= (simStackPtr - 2); i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 2) + 1; - } - primDescriptor = generatorAt(byte0); - argIsIntConst = ((((ssTop())->type)) == SSConstant) - && ((((argInt = ((ssTop())->constant))) & 1)); - rcvrIsInt = (((rcvrIsConst = (((ssValue(1))->type)) == SSConstant)) - && (((((ssValue(1))->constant)) & 1))) - || ((mclassIsSmallInteger()) - && (isSameEntryAs(ssValue(1), simSelf()))); - if (argIsIntConst - && (rcvrIsInt - && (rcvrIsConst))) { - return genStaticallyResolvedSpecialSelectorComparison(); - } - /* begin extractMaybeBranchDescriptorInto: */ - primDescriptor1 = generatorAt(byte0); - nextPC1 = bytecodePC + ((primDescriptor1->numBytes)); - nExts = 0; - while (1) { - while (1) { - /* begin generatorForPC: */ - branchDescriptor1 = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC1, methodObj))); - if (!((branchDescriptor1->isExtension))) break; - nExts += 1; - nextPC1 += (branchDescriptor1->numBytes); - } - /* begin isUnconditionalBranch */ - if (!((isBranch(branchDescriptor1)) - && (!(((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse)))))) break; - nextPC1 = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - } - targetBytecodePC = (postBranchPC1 = 0); - if (((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse))) { - targetBytecodePC = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - postBranchPC1 = eventualTargetOf(nextPC1 + ((branchDescriptor1->numBytes))); - } - else { - nextPC1 = bytecodePC + ((primDescriptor1->numBytes)); - } - branchDescriptor = branchDescriptor1; - nextPC = nextPC1; - postBranchPC = postBranchPC1; - targetPC = targetBytecodePC; - - /* Further, only interested in inlining = and ~= if there's a SmallInteger constant involved. - The relational operators successfully statically predict SmallIntegers; the equality operators do not. */ - inlineCAB = ((branchDescriptor->isBranchTrue)) - || ((branchDescriptor->isBranchFalse)); - if (inlineCAB - && ((((primDescriptor->opcode)) == JumpZero) - || (((primDescriptor->opcode)) == JumpNonZero))) { - inlineCAB = argIsIntConst - || (rcvrIsInt); - } - if (!inlineCAB) { - return genSpecialSelectorSend(); - } - if (argIsIntConst) { - popToReg(ssValue(1), ReceiverResultReg); - ssPop(2); - } - else { - marshallSendArguments(1); - } - jumpNotSmallInts = (!(rcvrIsInt - && (argIsIntConst)) - ? (argIsIntConst - ? genJumpNotSmallInteger(ReceiverResultReg) - : (rcvrIsInt - ? genJumpNotSmallInteger(Arg0Reg) - : (/* begin genJumpNotSmallIntegersIn:and:scratch: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg), - /* begin AndR:R: */ - genoperandoperand(AndRR, Arg0Reg, TempReg), - genJumpNotSmallIntegerInScratchReg(TempReg)))) - : 0); - if (argIsIntConst) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, argInt, ReceiverResultReg); - } - else { - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, ReceiverResultReg); - } - genConditionalBranchoperand(((branchDescriptor->isBranchTrue) - ? (primDescriptor->opcode) - : inverseBranchFor((primDescriptor->opcode))), ((usqInt)(ensureNonMergeFixupAt(targetPC)))); - /* begin Jump: */ - jumpTarget = ensureNonMergeFixupAt(postBranchPC); - genoperand(Jump, ((sqInt)jumpTarget)); - if (!jumpNotSmallInts) { - /* begin annotateInstructionForBytecode */ - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (abstractInstruction->annotation = HasBytecodePC); - ensureFixupAt(postBranchPC); - ensureFixupAt(targetPC); - deadCode = 1; - return 0; - } - jmpTarget(jumpNotSmallInts, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (argIsIntConst) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, argInt, Arg0Reg); - } - index = byte0 - ( -#if MULTIPLEBYTECODESETS - (bytecodeSetOffset == 0x100 - ? AltFirstSpecialSelector + 0x100 - : FirstSpecialSelector) -#else - FirstSpecialSelector -#endif - ); - return genMarshalledSendnumArgssendTable((-index) - 1, 1, ordinarySendTrampolines); -} - - -/* Assumes both operands are ints */ - - /* StackToRegisterMappingCogit>>#genStaticallyResolvedSpecialSelectorComparison */ -static sqInt -genStaticallyResolvedSpecialSelectorComparison(void) -{ - sqInt argInt; - BytecodeDescriptor *primDescriptor; - sqInt rcvrInt; - int result; - - primDescriptor = generatorAt(byte0); - argInt = ((ssTop())->constant); - rcvrInt = ((ssValue(1))->constant); - switch ((primDescriptor->opcode)) { - case JumpLess: - result = rcvrInt < argInt; - break; - case JumpLessOrEqual: - result = rcvrInt <= argInt; - break; - case JumpGreater: - result = rcvrInt > argInt; - break; - case JumpGreaterOrEqual: - result = rcvrInt >= argInt; - break; - case JumpZero: - result = rcvrInt == argInt; - break; - case JumpNonZero: - result = rcvrInt != argInt; - break; - default: - error("Case not found and no otherwise clause"); - } - ssPop(2); - return ssPushAnnotatedConstant((result - ? trueObject() - : falseObject())); -} - - -/* We need a frame because the association has to be in ReceiverResultReg for - the various trampolines - and ReceiverResultReg holds only the receiver in frameless methods. - */ - - /* StackToRegisterMappingCogit>>#genStorePop:LiteralVariable:needsStoreCheck:needsImmutabilityCheck: */ -static sqInt NoDbgRegParms -genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt litVarIndex, sqInt needsStoreCheck, sqInt needsImmCheck) -{ - AbstractInstruction *anInstruction; - sqInt association; - sqInt i; - sqInt topReg; - - assert(needsFrame); - /* begin genLoadLiteralVariable:in: */ - association = getLiteral(litVarIndex); - voidReceiverResultRegContainsSelf(); - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); - /* begin genMoveConstant:R: */ - if (shouldAnnotateObjectReference(association)) { - annotateobjRef(checkLiteralforInstruction(association, genoperandoperand(MoveCwR, association, ReceiverResultReg)), association); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, association, ReceiverResultReg); - } - /* begin genGenericStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr:needsImmutabilityCheck: */ -# if IMMUTABILITY - if (needsImmCheck) { - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); - ssStoreAndReplacePoptoReg(popBoolean, ClassReg); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0); - } -# endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); - ssStorePoptoReg(popBoolean, topReg); - return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); -} - - -/* The reason we need a frame here is that assigning to an inst var of a - context may - involve wholesale reorganization of stack pages, and the only way to - preserve the - execution state of an activation in that case is if it has a frame. */ - - /* StackToRegisterMappingCogit>>#genStorePop:MaybeContextReceiverVariable:needsStoreCheck:needsImmutabilityCheck: */ -static sqInt NoDbgRegParms -genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt slotIndex, sqInt needsStoreCheck, sqInt needsImmCheck) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *abstractInstruction2; - AbstractInstruction *abstractInstruction3; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt i; - AbstractInstruction *immutabilityFailure; - AbstractInstruction *mutableJump; - - immutabilityFailure = ((AbstractInstruction *) 0); - assert(needsFrame); - ssFlushUpThroughReceiverVariable(slotIndex); - ensureReceiverResultRegContainsSelf(); - /* begin genGenericStorePop:MaybeContextSlotIndex:needsStoreCheck:needsRestoreRcvr:needsImmutabilityCheck: */ - assert(needsFrame); -# if IMMUTABILITY - if (needsImmCheck) { - mutableJump = genJumpMutablescratchReg(ReceiverResultReg, TempReg); - /* begin genStoreTrampolineCall: */ - assert(IMMUTABILITY); - if (slotIndex >= (NumStoreTrampolines - 1)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, slotIndex, TempReg); - /* begin CallRT: */ - abstractInstruction3 = genoperand(Call, ceStoreTrampolines[NumStoreTrampolines - 1]); - (abstractInstruction3->annotation = IsRelativeCall); - } - else { - /* begin CallRT: */ - abstractInstruction1 = genoperand(Call, ceStoreTrampolines[slotIndex]); - (abstractInstruction1->annotation = IsRelativeCall); - } - /* begin annotateBytecode: */ - abstractInstruction2 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction2->annotation = HasBytecodePC); - /* begin putSelfInReceiverResultReg */ - storeToReg(simSelf(), ReceiverResultReg); - /* begin Jump: */ - immutabilityFailure = genoperand(Jump, ((sqInt)0)); - jmpTarget(mutableJump, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } -# endif // IMMUTABILITY - ssPop(1); - /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); - ssPush(1); - genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); - ssStoreAndReplacePoptoReg(popBoolean, ClassReg); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, slotIndex, SendNumArgsReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceStoreContextInstVarTrampoline); - (abstractInstruction->annotation = IsRelativeCall); -# if IMMUTABILITY - if (needsImmCheck) { - jmpTarget(immutabilityFailure, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } -# endif - return 0; -} - - /* StackToRegisterMappingCogit>>#genStorePop:ReceiverVariable:needsStoreCheck:needsImmutabilityCheck: */ -static sqInt NoDbgRegParms -genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt slotIndex, sqInt needsStoreCheck, sqInt needsImmCheck) -{ - sqInt i; - sqInt needsImmCheck1; - sqInt needsStoreCheck1; - sqInt topReg; - - ssFlushUpThroughReceiverVariable(slotIndex); - ensureReceiverResultRegContainsSelf(); - /* begin genGenericStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr:needsImmutabilityCheck: */ - needsStoreCheck1 = (!useTwoPaths) - && (needsStoreCheck); - needsImmCheck1 = needsImmCheck - && (!useTwoPaths); -# if IMMUTABILITY - if (needsImmCheck1) { - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); - ssStoreAndReplacePoptoReg(popBoolean, ClassReg); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck1, 1); - } -# endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); - ssStorePoptoReg(popBoolean, topReg); - return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck1); -} - - -/* The only reason we assert needsFrame here is that in a frameless method - ReceiverResultReg must and does contain only self, but the ceStoreCheck - trampoline expects the target of the store to be in ReceiverResultReg. So - in a frameless method we would have a conflict between the receiver and - the temote temp store, unless we we smart enough to realise that - ReceiverResultReg was unused after the literal variable store, unlikely - given that methods return self by default. */ - - /* StackToRegisterMappingCogit>>#genStorePop:RemoteTemp:At:needsStoreCheck: */ -static sqInt NoDbgRegParms -genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt remoteTempIndex, sqInt needsStoreCheck) -{ - AbstractInstruction *anInstruction; - sqInt offset; - sqInt topReg; - - assert(needsFrame); - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); - voidReceiverResultRegContainsSelf(); - /* begin MoveMw:r:R: */ - offset = frameOffsetOfTemporary(remoteTempIndex); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, FPReg, ReceiverResultReg); - /* begin genGenericStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr:needsImmutabilityCheck: */ -# if IMMUTABILITY - -# endif - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); - ssStorePoptoReg(popBoolean, topReg); - return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); -} - - /* StackToRegisterMappingCogit>>#genStorePop:TemporaryVariable: */ -static sqInt NoDbgRegParms -genStorePopTemporaryVariable(sqInt popBoolean, sqInt tempIndex) -{ - AbstractInstruction *anInstruction; - sqInt offset; - sqInt reg; - - ssFlushUpThroughTemporaryVariable(tempIndex); - reg = ssStorePoptoPreferredReg(popBoolean, TempReg); - /* begin MoveR:Mw:r: */ - offset = frameOffsetOfTemporary(tempIndex); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveRMwr, reg, offset, FPReg); - ((simStackAt(tempIndex + 1))->bcptr = bytecodePC); - return 0; -} - - -/* Generate a method return from within a method or a block. - Frameless method activation looks like - CISCs (x86): - receiver - args - sp-> ret pc. - RISCs (ARM): - receiver - args - ret pc in LR. - A fully framed activation is described in CoInterpreter - class>initializeFrameIndices. Return pops receiver and arguments off the - stack. Callee pushes the result. */ - - /* StackToRegisterMappingCogit>>#genUpArrowReturn */ -static sqInt -genUpArrowReturn(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - sqInt i; - sqInt offset; - - - /* can't fall through */ - deadCode = 1; - if (inBlock > 0) { - assert(needsFrame); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceNonLocalReturnTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin annotateBytecode: */ - abstractInstruction1 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction1->annotation = HasBytecodePC); - return 0; - } - if ( -# if IMMUTABILITY - needsFrame - && (!useTwoPaths) -# else - needsFrame -# endif - ) { - if (hasNativeFrame) { - leaveNativeFrame(); - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, FPReg, SPReg); - /* begin PopR: */ - genoperand(PopR, FPReg); - /* begin PopR: */ - genoperand(PopR, LinkReg); - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - else { - /* begin RetN: */ - offset = ((methodOrBlockNumArgs > 2 /* numRegArgs */) - || (regArgsHaveBeenPushed) - ? (methodOrBlockNumArgs + 1) * BytesPerWord - : 0); - genoperand(RetN, offset); - } - return 0; -} - - /* StackToRegisterMappingCogit>>#genVanillaInlinedIdenticalOrNotIf: */ -static sqInt NoDbgRegParms -genVanillaInlinedIdenticalOrNotIf(sqInt orNot) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - int argIsConstant; - sqInt argNeedsReg; - sqInt argReg; - sqInt argReg1; - BytecodeDescriptor *branchDescriptor; - BytecodeDescriptor *branchDescriptor1; - sqInt constant; - sqInt constant1; - sqInt i; - void *jumpTarget; - void *jumpTarget1; - void *jumpTarget2; - void *jumpTarget3; - sqInt nExts; - sqInt nextPC; - sqInt nextPC1; - sqInt postBranchPC; - sqInt postBranchPC1; - BytecodeDescriptor *primDescriptor; - sqInt rcvrIsConstant; - sqInt rcvrNeedsReg; - sqInt rcvrReg; - sqInt rcvrReg1; - sqInt reg; - sqInt rNext1; - sqInt rTop1; - sqInt targetBytecodePC; - sqInt targetPC; - sqInt topRegistersMask; - - /* begin extractMaybeBranchDescriptorInto: */ - primDescriptor = generatorAt(byte0); - nextPC1 = bytecodePC + ((primDescriptor->numBytes)); - nExts = 0; - while (1) { - while (1) { - /* begin generatorForPC: */ - branchDescriptor1 = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC1, methodObj))); - if (!((branchDescriptor1->isExtension))) break; - nExts += 1; - nextPC1 += (branchDescriptor1->numBytes); - } - /* begin isUnconditionalBranch */ - if (!((isBranch(branchDescriptor1)) - && (!(((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse)))))) break; - nextPC1 = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - } - targetBytecodePC = (postBranchPC1 = 0); - if (((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse))) { - targetBytecodePC = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - postBranchPC1 = eventualTargetOf(nextPC1 + ((branchDescriptor1->numBytes))); - } - else { - nextPC1 = bytecodePC + ((primDescriptor->numBytes)); - } - branchDescriptor = branchDescriptor1; - nextPC = nextPC1; - postBranchPC = postBranchPC1; - targetPC = targetBytecodePC; - - /* They can't be both constants to use correct machine opcodes. - However annotable constants can't be resolved statically, hence we need to careful. */ - argIsConstant = (((ssTop())->type)) == SSConstant; - rcvrIsConstant = (!argIsConstant) - && ((((ssValue(1))->type)) == SSConstant); - /* begin allocateEqualsEqualsRegistersArgNeedsReg:rcvrNeedsReg:into: */ - argNeedsReg = !argIsConstant; - rcvrNeedsReg = !rcvrIsConstant; - assert(argNeedsReg - || (rcvrNeedsReg)); - argReg1 = (rcvrReg1 = NoReg); - if (argNeedsReg) { - if (rcvrNeedsReg) { - /* begin allocateRegForStackTopTwoEntriesInto: */ - topRegistersMask = 0; - rTop1 = (rNext1 = NoReg); - if ((registerOrNone(ssTop())) != NoReg) { - rTop1 = registerOrNone(ssTop()); - } - if ((registerOrNone(ssValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; - } - if (rTop1 == NoReg) { - rTop1 = allocateRegNotConflictingWith(topRegistersMask); - } - if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); - } - assert(!(((rTop1 == NoReg) - || (rNext1 == NoReg)))); - argReg1 = rTop1; - rcvrReg1 = rNext1; - popToReg(ssTop(), argReg1); - popToReg(ssValue(1), rcvrReg1); - } - else { - argReg1 = allocateRegForStackEntryAtnotConflictingWith(0, 0); - popToReg(ssTop(), argReg1); - if (((ssValue(1))->spilled)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AddCqR, BytesPerWord, SPReg); - } - } - } - else { - assert(rcvrNeedsReg); - assert(!((((ssTop())->spilled)))); - rcvrReg1 = allocateRegForStackEntryAtnotConflictingWith(1, 0); - popToReg(ssValue(1), rcvrReg1); - } - assert(!((argNeedsReg - && (argReg1 == NoReg)))); - assert(!((rcvrNeedsReg - && (rcvrReg1 == NoReg)))); - rcvrReg = rcvrReg1; - argReg = argReg1; - if (!(((branchDescriptor->isBranchTrue)) - || ((branchDescriptor->isBranchFalse)))) { - return genIdenticalNoBranchArgIsConstantrcvrIsConstantargRegrcvrRegorNotIf(argIsConstant, rcvrIsConstant, argReg, rcvrReg, orNot); - } - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= (simStackPtr - 2)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 2)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 2))); i <= (simStackPtr - 2); i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 2) + 1; - } - /* begin genCmpArgIsConstant:rcvrIsConstant:argReg:rcvrReg: */ - assert((argReg != NoReg) - || (rcvrReg != NoReg)); - if (argIsConstant) { - /* begin genCmpConstant:R: */ - constant = ((ssTop())->constant); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(CmpCwR, constant, rcvrReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, constant, rcvrReg); - } - } - else { - if (rcvrIsConstant) { - /* begin genCmpConstant:R: */ - constant1 = ((ssValue(1))->constant); - if (shouldAnnotateObjectReference(constant1)) { - annotateobjRef(checkLiteralforInstruction(constant1, genoperandoperand(CmpCwR, constant1, argReg)), constant1); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, constant1, argReg); - } - } - else { - /* begin CmpR:R: */ - assert(!((argReg == SPReg))); - genoperandoperand(CmpRR, argReg, rcvrReg); - } - } - ssPop(2); - if ((((fixupAt(nextPC))->targetInstruction)) == 0) { - - /* The next instruction is dead. we can skip it. */ - deadCode = 1; - ensureFixupAt(targetPC); - ensureFixupAt(postBranchPC); - } - else { - assert(!(deadCode)); - } - if (orNot == ((branchDescriptor->isBranchTrue))) { - - /* a == b ifFalse: ... or a ~~ b ifTrue: ... jump on equal to post-branch pc */ - ensureNonMergeFixupAt(targetPC); - /* begin JumpZero: */ - jumpTarget = ensureNonMergeFixupAt(postBranchPC); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget)); - /* begin Jump: */ - jumpTarget1 = ensureNonMergeFixupAt(targetPC); - genoperand(Jump, ((sqInt)jumpTarget1)); - } - else { - - /* orNot is true for ~~ */ - /* a == b ifTrue: ... or a ~~ b ifFalse: ... jump on equal to target pc */ - /* begin JumpZero: */ - jumpTarget2 = ensureNonMergeFixupAt(targetPC); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget2)); - /* begin Jump: */ - jumpTarget3 = ensureNonMergeFixupAt(postBranchPC); - genoperand(Jump, ((sqInt)jumpTarget3)); - } - if (!deadCode) { - ssPushConstant(trueObject()); - } - return 0; -} - - /* StackToRegisterMappingCogit>>#initSimStackForFramefulMethod: */ -static void NoDbgRegParms -initSimStackForFramefulMethod(sqInt startpc) -{ - CogSimStackEntry * cascade0; - CogSimStackEntry *desc; - sqInt i; - - - /* N.B. Includes num args */ - simStackPtr = methodOrBlockNumTemps; - simSpillBase = methodOrBlockNumTemps + 1; - simNativeSpillBase = (simNativeStackPtr = -1); - simNativeStackSize = 0; - cascade0 = simSelf(); - (cascade0->type = SSBaseOffset); - (cascade0->spilled = 1); - (cascade0->registerr = FPReg); - (cascade0->offset = FoxMFReceiver); - (cascade0->liveRegister = NoReg); - for (i = 1; i <= methodOrBlockNumArgs; i += 1) { - desc = simStackAt(i); - (desc->type = SSBaseOffset); - (desc->spilled = 1); - (desc->registerr = FPReg); - (desc->offset = FoxCallerSavedIP + (((methodOrBlockNumArgs - i) + 1) * BytesPerWord)); - (desc->bcptr = startpc); - } - for (i = (methodOrBlockNumArgs + 1); i <= simStackPtr; i += 1) { - desc = simStackAt(i); - (desc->type = SSBaseOffset); - (desc->spilled = 1); - (desc->registerr = FPReg); - (desc->offset = FoxMFReceiver - ((i - methodOrBlockNumArgs) * BytesPerWord)); - (desc->bcptr = startpc); - } -} - - -/* The register receiver (the closure itself) and args are pushed by the - closure value primitive(s) - and hence a frameless block has all arguments and copied values pushed to - the stack. However, - the method receiver (self) is put in the ReceiverResultReg by the block - entry. - */ - - /* StackToRegisterMappingCogit>>#initSimStackForFramelessBlock: */ -static void NoDbgRegParms -initSimStackForFramelessBlock(sqInt startpc) -{ - CogSimStackEntry * cascade0; - CogSimStackEntry *desc; - sqInt i; - - cascade0 = simSelf(); - (cascade0->type = SSRegister); - (cascade0->spilled = 0); - (cascade0->registerr = ReceiverResultReg); - (cascade0->liveRegister = ReceiverResultReg); - assert(methodOrBlockNumTemps >= methodOrBlockNumArgs); - for (i = 1; i <= methodOrBlockNumTemps; i += 1) { - desc = simStackAt(i); - (desc->type = SSBaseOffset); - (desc->spilled = 1); - (desc->registerr = SPReg); - (desc->offset = (methodOrBlockNumArgs - i) * BytesPerWord); - (desc->bcptr = startpc); - } - - /* N.B. Includes num args */ - simStackPtr = methodOrBlockNumTemps; - simSpillBase = methodOrBlockNumTemps + 1; - simNativeSpillBase = (simNativeStackPtr = -1); - simNativeStackSize = 0; -} - - /* StackToRegisterMappingCogit>>#initSimStackForFramelessMethod: */ -static void NoDbgRegParms -initSimStackForFramelessMethod(sqInt startpc) -{ - CogSimStackEntry * cascade0; - CogSimStackEntry *desc; - sqInt i; - - cascade0 = simSelf(); - (cascade0->type = SSRegister); - (cascade0->spilled = 0); - (cascade0->registerr = ReceiverResultReg); - (cascade0->liveRegister = ReceiverResultReg); - assert(methodOrBlockNumTemps == methodOrBlockNumArgs); - assert((numRegArgs()) <= 2); - if (((methodOrBlockNumArgs >= 1) && (methodOrBlockNumArgs <= 2 /* numRegArgs */))) { - desc = simStackAt(1); - (desc->type = SSRegister); - (desc->spilled = 0); - (desc->registerr = Arg0Reg); - (desc->bcptr = startpc); - if (methodOrBlockNumArgs > 1) { - desc = simStackAt(2); - (desc->type = SSRegister); - (desc->spilled = 0); - (desc->registerr = Arg1Reg); - (desc->bcptr = startpc); - } - } - else { - for (i = 1; i <= methodOrBlockNumArgs; i += 1) { - desc = simStackAt(i); - (desc->type = SSBaseOffset); - (desc->registerr = SPReg); - (desc->spilled = 1); - (desc->offset = (methodOrBlockNumArgs - i) * BytesPerWord); - (desc->bcptr = startpc); - } - } - simStackPtr = methodOrBlockNumArgs; - simSpillBase = methodOrBlockNumArgs + 1; - simNativeSpillBase = (simNativeStackPtr = -1); - simNativeStackSize = 0; -} - - -/* Do not inline (inBlock access) */ - - /* StackToRegisterMappingCogit>>#isNonForwarderReceiver: */ -static sqInt NoDbgRegParms -isNonForwarderReceiver(sqInt reg) -{ - return ((((simSelf())->liveRegister)) == ReceiverResultReg) - && ((inBlock == 0) - && (reg == ReceiverResultReg)); -} - - /* StackToRegisterMappingCogit>>#leaveNativeFrame */ -static void -leaveNativeFrame(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - sqInt offset; - - assert(needsFrame); - /* begin MoveMw:r:R: */ - offset = frameOffsetOfPreviousNativeStackPointer(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, FPReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(SubCqR, 1, TempReg); - /* begin checkLiteral:forInstruction: */ - nativeStackPointerAddress(); - anInstruction2 = genoperandoperand(MoveRAw, TempReg, nativeStackPointerAddress()); -} - - /* StackToRegisterMappingCogit>>#liveFloatRegisters */ -static sqInt -liveFloatRegisters(void) -{ - sqInt i; - sqInt regsSet; - - regsSet = 0; - for (i = (((simSpillBase < 0) ? 0 : simSpillBase)); i <= simStackPtr; i += 1) { - regsSet = regsSet | 0 /* floatRegisterMask */; - } - for (i = (((simNativeSpillBase < 0) ? 0 : simNativeSpillBase)); i <= simNativeStackPtr; i += 1) { - regsSet = regsSet | (nativeFloatRegisterMask(simNativeStackAt(i))); - } - return regsSet; -} - - /* StackToRegisterMappingCogit>>#liveRegisters */ -static sqInt -liveRegisters(void) -{ - sqInt i; - sqInt regsSet; - - if (needsFrame) { - regsSet = 0; - } - else { - /* begin registerMaskFor: */ - regsSet = 1U << ReceiverResultReg; - if ((methodOrBlockNumArgs <= 2 /* numRegArgs */) - && (methodOrBlockNumArgs > 0)) { - regsSet = regsSet | (1U << Arg0Reg); - if (methodOrBlockNumArgs > 1) { - regsSet = regsSet | (1U << Arg1Reg); - } - } - } - for (i = (((simSpillBase < 0) ? 0 : simSpillBase)); i <= simStackPtr; i += 1) { - regsSet = regsSet | (registerMask(simStackAt(i))); - } - for (i = (((simNativeSpillBase < 0) ? 0 : simNativeSpillBase)); i <= simNativeStackPtr; i += 1) { - regsSet = regsSet | (nativeRegisterMask(simNativeStackAt(i))); - } - return regsSet; -} - - -/* insert nops for dead code that is mapped so that bc - to mc mapping is not many to one */ - - /* StackToRegisterMappingCogit>>#mapDeadDescriptorIfNeeded: */ -static sqInt NoDbgRegParms -mapDeadDescriptorIfNeeded(BytecodeDescriptor *descriptor) -{ - AbstractInstruction *abstractInstruction; - - flag("annotateInstruction"); - if (((descriptor->isMapped)) - || ((inBlock > 0) - && ((descriptor->isMappedInBlock)))) { - /* begin annotateBytecode: */ - abstractInstruction = gen(Nop); - (abstractInstruction->annotation = HasBytecodePC); - } - return 0; -} - - -/* Spill everything on the simulated stack that needs spilling (that below - receiver and arguments). - Marshall receiver and arguments to stack and/or registers depending on arg - count. If the args don't fit in registers push receiver and args (spill - everything), but still assign - the receiver to ReceiverResultReg. */ - - /* StackToRegisterMappingCogit>>#marshallSendArguments: */ -static void NoDbgRegParms -marshallSendArguments(sqInt numArgs) -{ - sqInt anyRefs; - CogSimStackEntry * cascade0; - sqInt i; - sqInt i1; - sqInt i2; - sqInt numSpilled; - - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= ((simStackPtr - numArgs) - 1)) { - for (i2 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < ((simStackPtr - numArgs) - 1)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : ((simStackPtr - numArgs) - 1))); i2 < (simStackPtr - numArgs); i2 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i2), frameOffsetOfTemporary(i2 - 1), FPReg); - } - simSpillBase = ((simStackPtr - numArgs) - 1) + 1; - } - if (numArgs > 2 /* numRegArgs */) { - - /* If there are no spills and no references to ReceiverResultReg - the fetch of ReceiverResultReg from the stack can be avoided - by assigning directly to ReceiverResultReg and pushing it. */ - numSpilled = numberOfSpillsInTopNItems(numArgs + 1); - anyRefs = anyReferencesToRegisterinTopNItems(ReceiverResultReg, numArgs + 1); - if ((numSpilled > 0) - || (anyRefs)) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - storeToReg(simStackAt(simStackPtr - numArgs), ReceiverResultReg); - } - else { - cascade0 = simStackAt(simStackPtr - numArgs); - storeToReg(cascade0, ReceiverResultReg); - (cascade0->type = SSRegister); - (cascade0->registerr = ReceiverResultReg); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i1 <= simStackPtr; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - } - } - else { - - /* Move the args to the register arguments, being careful to do - so last to first so e.g. previous contents don't get overwritten. - Also check for any arg registers in use by other args. */ - if (numArgs > 0) { - if (numArgs > 1) { - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 2, simNativeStackPtr); - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg1Reg, simStackPtr - 1, simNativeStackPtr); - } - else { - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); - } - } - if (numArgs > 1) { - popToReg(simStackAt(simStackPtr), Arg1Reg); - } - if (numArgs > 0) { - popToReg(simStackAt((simStackPtr - numArgs) + 1), Arg0Reg); - } - popToReg(simStackAt(simStackPtr - numArgs), ReceiverResultReg); - } - ssPop(numArgs + 1); -} - - -/* For assert checking; or rather for avoiding assert fails when dealing with - the hack for block temps in the SqueakV3PlusClosures bytecode set. - */ - - /* StackToRegisterMappingCogit>>#maybeCompilingFirstPassOfBlockWithInitialPushNil */ -static sqInt -maybeCompilingFirstPassOfBlockWithInitialPushNil(void) -{ - return (inBlock == InVanillaBlock) - && ((methodOrBlockNumTemps > methodOrBlockNumArgs) - && (compilationPass == 1)); -} - - -/* If this bytecode has a fixup, some kind of merge needs to be done. There - are 4 cases: - 1) the bytecode has no fixup (fixup isNotAFixup) - do nothing - 2) the bytecode has a non merge fixup - the fixup has needsNonMergeFixup. - The code generating non merge fixup (currently only special selector code) - is responsible - for the merge so no need to do it. - We set deadCode to false as the instruction can be reached from jumps. - 3) the bytecode has a merge fixup, but execution flow *cannot* fall - through to the merge point. - the fixup has needsMergeFixup and deadCode = true. - ignores the current simStack as it does not mean anything - restores the simStack to the state the jumps to the merge point expects it - to be. - 4) the bytecode has a merge fixup and execution flow *can* fall through to - the merge point. - the fixup has needsMergeFixup and deadCode = false. - flushes the stack to the stack pointer so the fall through execution path - simStack is - in the state the merge point expects it to be. - restores the simStack to the state the jumps to the merge point expects it - to be. - - In addition, if this is a backjump merge point, we patch the fixup to hold - the current simStackPtr - for later assertions. */ - - /* StackToRegisterMappingCogit>>#mergeWithFixupIfRequired: */ -static sqInt NoDbgRegParms -mergeWithFixupIfRequired(BytecodeFixup *fixup) -{ - CogSimStackEntry * cascade0; - sqInt i; - sqInt i1; - - /* begin assertCorrectSimStackPtr */ - assert((simSpillBase >= methodOrBlockNumTemps) - || ((maybeCompilingFirstPassOfBlockWithInitialPushNil()) - && (simSpillBase > methodOrBlockNumArgs))); - if (needsFrame - && (simSpillBase > 0)) { - assert((((simStackAt(simSpillBase - 1))->spilled)) == 1); - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); - } - if (((fixup->targetInstruction)) == 0) { - return 0; - } - if ((((usqInt)((fixup->targetInstruction)))) == NeedsNonMergeFixupFlag) { - deadCode = 0; - return 0; - } - assert(isMergeFixup(fixup)); - traceMerge(fixup); - if (deadCode) { - - /* case 3 */ - /* Would like to assert fixup simStackPtr >= methodOrBlockNumTemps - but can't because of the initialNils hack. */ - assert((((fixup->simStackPtr)) >= methodOrBlockNumTemps) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - simStackPtr = (fixup->simStackPtr); - simNativeStackPtr = (fixup->simNativeStackPtr); - simNativeStackSize = (fixup->simNativeStackSize); - } - else { - - /* case 4 */ - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - } - deadCode = 0; - if ((fixup->isTargetOfBackwardBranch)) { - (fixup->simStackPtr = simStackPtr); - (fixup->simNativeStackPtr = simNativeStackPtr); - (fixup->simNativeStackSize = simNativeStackSize); - } - (fixup->targetInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(simStackPtr == ((fixup->simStackPtr))); - assert(simNativeStackPtr == ((fixup->simNativeStackPtr))); - assert(simNativeStackSize == ((fixup->simNativeStackSize))); - /* begin restoreSimStackAtMergePoint: */ - ((simSelf())->liveRegister = NoReg); - for (i1 = (methodOrBlockNumTemps + 1); i1 <= simStackPtr; i1 += 1) { - cascade0 = simStackAt(i1); - (cascade0->type = SSSpill); - (cascade0->offset = FoxMFReceiver - ((i1 - methodOrBlockNumArgs) * BytesPerOop)); - (cascade0->registerr = FPReg); - (cascade0->spilled = 1); - } - simSpillBase = simStackPtr + 1; - for (i1 = 0; i1 <= simNativeStackPtr; i1 += 1) { - ensureIsMarkedAsSpilled(simNativeStackAt(i1)); - } - simNativeSpillBase = simNativeStackPtr + 1; - return 0; -} - - /* StackToRegisterMappingCogit>>#methodAbortTrampolineFor: */ -static sqInt NoDbgRegParms -methodAbortTrampolineFor(sqInt numArgs) -{ - return methodAbortTrampolines[((numArgs < (3)) ? numArgs : (3))]; -} - - -/* This is a hook for subclasses to filter out methods they can't deal with. */ -/* Frameless methods with local temporaries cause problems, - mostly in asserts, and yet they matter not at all for performance. - Shun them. */ - - /* StackToRegisterMappingCogit>>#methodFoundInvalidPostScan */ -static sqInt -methodFoundInvalidPostScan(void) -{ - if (!needsFrame) { - return methodOrBlockNumTemps > methodOrBlockNumArgs; - } - return 0; -} - - /* StackToRegisterMappingCogit>>#needsFrameIfMod16GENumArgs: */ -static sqInt NoDbgRegParms -needsFrameIfMod16GENumArgs(sqInt stackDelta) -{ - return (byte0 % 16) >= methodOrBlockNumArgs; -} - - -/* As of August 2013, the code generator can't deal with spills in frameless - methods (the - issue is to do with the stack offset to get at an argument, which is - changed when there's a spill). - In e.g. TextColor>>#dominates: other ^other class == self class the second - send of class - needs also rto allocate a register that the first one used, but the first - one's register can't be - spilled. So avoid this by only allowing class to be sent if the stack - contains a single element. */ - - /* StackToRegisterMappingCogit>>#needsFrameIfStackGreaterThanOne: */ -static sqInt NoDbgRegParms -needsFrameIfStackGreaterThanOne(sqInt stackDelta) -{ - return stackDelta > 1; -} - - /* StackToRegisterMappingCogit>>#numberOfSpillsInTopNItems: */ -static sqInt NoDbgRegParms -numberOfSpillsInTopNItems(sqInt n) -{ - sqInt i; - - for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { - if ((((simStackAt(i))->type)) == SSSpill) { - return n - (simStackPtr - i); - } - } - return 0; -} - - /* StackToRegisterMappingCogit>>#picAbortTrampolineFor: */ -static sqInt NoDbgRegParms -picAbortTrampolineFor(sqInt numArgs) -{ - return picAbortTrampolines[((numArgs < (3)) ? numArgs : (3))]; -} - - /* StackToRegisterMappingCogit>>#prevInstIsPCAnnotated */ -static sqInt -prevInstIsPCAnnotated(void) -{ - sqInt prevIndex; - AbstractInstruction *prevInst; - - if (!(opcodeIndex > 0)) { - return 0; - } - prevIndex = opcodeIndex - 1; - while (1) { - if (prevIndex <= 0) { - return 0; - } - prevInst = abstractInstructionAt(prevIndex); - if (isPCMappedAnnotation((!((prevInst->annotation)) - ? 0 - : (prevInst->annotation)))) { - return 1; - } - if (!(((prevInst->opcode)) == Label)) break; - prevIndex -= 1; - } - return 0; -} - - -/* Used to mark ReceiverResultReg as dead or not containing simSelf. - Used when the simStack has already been flushed, e.g. for sends. */ - - /* StackToRegisterMappingCogit>>#receiverIsInReceiverResultReg */ -static sqInt -receiverIsInReceiverResultReg(void) -{ - return (((simSelf())->liveRegister)) == ReceiverResultReg; -} - - -/* When a block must be recompiled due to overestimating the - numInitialNils fixups must be restored, which means rescannning - since backward branches need their targets initialized. */ - - /* StackToRegisterMappingCogit>>#reinitializeFixupsFrom:through: */ -static void NoDbgRegParms -reinitializeFixupsFromthrough(sqInt start, sqInt end) -{ - BytecodeDescriptor *descriptor; - sqInt distance; - BytecodeFixup * fixup; - sqInt nExts; - sqInt pc; - BytecodeFixup * self_in_reinitialize; - sqInt targetPC; - - pc = start; - nExts = 0; - while (pc <= end) { - /* begin reinitialize */ - self_in_reinitialize = fixupAtIndex(pc - initialPC); - (self_in_reinitialize->targetInstruction) = 0; - (self_in_reinitialize->simStackPtr) = 0; - (self_in_reinitialize->simNativeStackPtr) = ((self_in_reinitialize->simNativeStackSize) = 0); - byte0 = (fetchByteofObject(pc, methodObj)) + bytecodeSetOffset; - descriptor = generatorAt(byte0); - if ((isBranch(descriptor)) - && ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, pc, nExts, methodObj)) < 0))) { - /* begin spanFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, pc, nExts, methodObj); - targetPC = (pc + ((descriptor->numBytes))) + distance; - /* begin initializeFixupAt: */ - fixup = fixupAtIndex(targetPC - initialPC); - /* begin initializeFixup: */ - (fixup->targetInstruction) = ((AbstractInstruction *) NeedsMergeFixupFlag); - /* begin setIsBackwardBranchFixup */ - (fixup->isTargetOfBackwardBranch) = 1; - } - if ((descriptor->isBlockCreation)) { - /* begin spanFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, pc, nExts, methodObj); - pc = (pc + ((descriptor->numBytes))) + distance; - } - else { - pc += (descriptor->numBytes); - } - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } -} - - -/* Scan the block to determine if the block needs a frame or not */ - - /* StackToRegisterMappingCogit>>#scanBlock: */ -static sqInt NoDbgRegParms -scanBlock(BlockStart *blockStart) -{ - BytecodeDescriptor *descriptor; - sqInt end; - sqInt framelessStackDelta; - sqInt nExts; - sqInt numPushNils; - sqInt (* const numPushNilsFunction)(struct _BytecodeDescriptor *,sqInt,sqInt,sqInt) = squeakV3orSistaV1NumPushNils; - sqInt pc; - sqInt pushingNils; - - needsFrame = 0; - hasNativeFrame = 0; - prevBCDescriptor = null; - methodOrBlockNumArgs = (blockStart->numArgs); - inBlock = InVanillaBlock; - pc = (blockStart->startpc); - end = ((blockStart->startpc)) + ((blockStart->span)); - framelessStackDelta = (nExts = (extA = (numExtB = (extB = 0)))); - pushingNils = 1; - while (pc < end) { - byte0 = (fetchByteofObject(pc, methodObj)) + bytecodeSetOffset; - descriptor = generatorAt(byte0); - if ((descriptor->isExtension)) { - loadSubsequentBytesForDescriptorat(descriptor, pc); - ((descriptor->generator))(); - } - if (!needsFrame) { - if ((((descriptor->needsFrameFunction)) == null) - || (((descriptor->needsFrameFunction))(framelessStackDelta))) { - needsFrame = 1; - } - else { - framelessStackDelta += (descriptor->stackDelta); - } - } - /* begin maybeNoteDescriptor:blockStart: */ - if ((descriptor->isInstVarRef)) { - (blockStart->hasInstVarRef = 1); - } - if (pushingNils - && (!((descriptor->isExtension)))) { - - /* Count the initial number of pushed nils acting as temp initializers. We can't tell - whether an initial pushNil is an operand reference or a temp initializer, except - when the pushNil is a jump target (has a fixup), which never happens: - self systemNavigation browseAllSelect: - [:m| | ebc | - (ebc := m embeddedBlockClosures - select: [:ea| ea decompile statements first isMessage] - thenCollect: [:ea| ea decompile statements first selector]) notEmpty - and: [(#(whileTrue whileFalse whileTrue: whileFalse:) intersection: ebc) notEmpty]] - or if the bytecode set has a push multiple nils bytecode. We simply count initial nils. - Rarely we may end up over-estimating. We will correct by checking the stack depth - at the end of the block in compileBlockBodies. */ - if (((numPushNils = numPushNilsFunction(descriptor, pc, nExts, methodObj))) > 0) { - assert(((descriptor->numBytes)) == 1); - (blockStart->numInitialNils = ((blockStart->numInitialNils)) + numPushNils); - } - else { - pushingNils = 0; - } - } - /* begin nextBytecodePCFor:at:exts:in: */ - pc = (pc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? ((descriptor->spanFunction))(descriptor, pc, nExts, methodObj) - : 0)); - if ((descriptor->isExtension)) { - nExts += 1; - } - else { - nExts = (extA = (numExtB = (extB = 0))); - } - prevBCDescriptor = descriptor; - } - if (!needsFrame) { - assert((framelessStackDelta >= 0) - && (((blockStart->numInitialNils)) >= framelessStackDelta)); - (blockStart->numInitialNils = ((blockStart->numInitialNils)) - framelessStackDelta); - } - return 0; -} - - -/* Scan the method (and all embedded blocks) to determine - - what the last bytecode is; extra bytes at the end of a method are used - to encode things like source pointers or temp names - - if the method needs a frame or not - - what are the targets of any backward branches. - - how many blocks it creates - Answer the block count or on error a negative error code */ - - /* StackToRegisterMappingCogit>>#scanMethod */ -static sqInt -scanMethod(void) -{ - BytecodeDescriptor *descriptor; - sqInt distance; - BytecodeFixup * fixup; - sqInt framelessStackDelta; - sqInt latestContinuation; - sqInt nExts; - sqInt numBlocks; - sqInt pc; - sqInt seenInstVarStore; - sqInt targetPC; - - needsFrame = (useTwoPaths = (seenInstVarStore = 0)); - hasNativeFrame = 0; - prevBCDescriptor = null; - if ((primitiveIndex > 0) - && (isQuickPrimitiveIndex(primitiveIndex))) { - return 0; - } - pc = (latestContinuation = initialPC); - numBlocks = (framelessStackDelta = (nExts = (extA = (numExtB = (extB = 0))))); - while (pc <= endPC) { - byte0 = (fetchByteofObject(pc, methodObj)) + bytecodeSetOffset; - descriptor = generatorAt(byte0); - if ((descriptor->isExtension)) { - if (((descriptor->opcode)) == Nop) { - - /* unknown bytecode tag; see Cogit class>>#generatorTableFrom: */ - return EncounteredUnknownBytecode; - } - loadSubsequentBytesForDescriptorat(descriptor, pc); - ((descriptor->generator))(); - } - if (((descriptor->isReturn)) - && (pc >= latestContinuation)) { - endPC = pc; - } - if (!needsFrame) { - if ((((descriptor->needsFrameFunction)) == null) - || (((descriptor->needsFrameFunction))(framelessStackDelta))) { - - /* With immutability we win simply by avoiding a frame build if the receiver is young and not immutable. */ -# if IMMUTABILITY - if ((descriptor->is1ByteInstVarStore)) { - useTwoPaths = 1; - } - else { - needsFrame = 1; - useTwoPaths = 0; - } -# else // IMMUTABILITY - needsFrame = 1; - useTwoPaths = 0; -# endif - } - else { - - /* Without immutability we win if there are two or more stores and the receiver is new. */ - framelessStackDelta += (descriptor->stackDelta); -# if IMMUTABILITY -# else - if ((descriptor->is1ByteInstVarStore)) { - if (seenInstVarStore) { - useTwoPaths = 1; - } - else { - seenInstVarStore = 1; - } - } -# endif // IMMUTABILITY - } - } - if (isBranch(descriptor)) { - /* begin spanFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, pc, nExts, methodObj); - targetPC = (pc + ((descriptor->numBytes))) + distance; - if ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, pc, nExts, methodObj)) < 0)) { - /* begin initializeFixupAt: */ - fixup = fixupAtIndex(targetPC - initialPC); - /* begin initializeFixup: */ - (fixup->targetInstruction) = ((AbstractInstruction *) NeedsMergeFixupFlag); - /* begin setIsBackwardBranchFixup */ - (fixup->isTargetOfBackwardBranch) = 1; - } - else { - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - } - /* begin maybeDealWithUnsafeJumpForDescriptor:pc:latestContinuation: */ - /* latestContinuation = */ latestContinuation; - if ((descriptor->isBlockCreation)) { - numBlocks += 1; - /* begin spanFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, pc, nExts, methodObj); - targetPC = (pc + ((descriptor->numBytes))) + distance; - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - pc += (descriptor->numBytes); - nExts = ((descriptor->isExtension) - ? nExts + 1 - : (extA = (numExtB = (extB = 0)))); - prevBCDescriptor = descriptor; - } - return numBlocks; -} - - /* StackToRegisterMappingCogit>>#squeakV3orSistaV1PushNilSize:numInitialNils: */ -static sqInt NoDbgRegParms -squeakV3orSistaV1PushNilSizenumInitialNils(sqInt aMethodObj, sqInt numInitialNils) -{ - return (methodUsesAlternateBytecodeSet(aMethodObj) - ? /* begin sistaV1PushNilSize:numInitialNils: */ numInitialNils - : numInitialNils); -} - - /* StackToRegisterMappingCogit>>#squeakV3orSistaV1:Num:Push:Nils: */ -static sqInt NoDbgRegParms -squeakV3orSistaV1NumPushNils(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - return (bytecodeSetOffset == 0 - ? (((descriptor->generator)) == genPushConstantNilBytecode - ? 1 - : 0) - : (/* begin sistaV1:Num:Push:Nils: */ - (((descriptor->generator)) == genPushConstantNilBytecode - ? 1 - : 0))); -} - - /* StackToRegisterMappingCogit>>#ssAllocateRequiredFloatRegMask:upThrough:upThroughNative: */ -static void NoDbgRegParms -ssAllocateRequiredFloatRegMaskupThroughupThroughNative(sqInt requiredRegsMask, sqInt stackPtr, sqInt nativeStackPtr) -{ - sqInt i; - sqInt i1; - sqInt lastRequired; - sqInt lastRequiredNative; - sqInt liveRegs; - - lastRequired = -1; - - /* compute live regs while noting the last occurrence of required regs. - If these are not free we must spill from simSpillBase to last occurrence. - Note we are conservative here; we could allocate FPReg in frameless methods. */ - lastRequiredNative = -1; - liveRegs = NoReg; - for (i = (((simSpillBase < 0) ? 0 : simSpillBase)); i <= stackPtr; i += 1) { - liveRegs = liveRegs | (registerMask(simStackAt(i))); - if ((0 /* floatRegisterMask */ & requiredRegsMask) != 0) { - lastRequired = i; - } - } - assert(lastRequiredNative == simNativeStackPtr); - for (i = (((simNativeSpillBase < 0) ? 0 : simNativeSpillBase)); i <= nativeStackPtr; i += 1) { - liveRegs = liveRegs | (nativeRegisterMask(simNativeStackAt(i))); - if ((0 /* floatRegisterMask */ & requiredRegsMask) != 0) { - lastRequiredNative = i; - } - } - if (!((liveRegs & requiredRegsMask) == 0)) { - - /* Some live, must spill */ - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= lastRequired) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < lastRequired) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : lastRequired)); i1 <= lastRequired; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = lastRequired + 1; - } - assert(((liveFloatRegisters()) & requiredRegsMask) == 0); - } -} - - /* StackToRegisterMappingCogit>>#ssAllocateRequiredFloatReg: */ -static void NoDbgRegParms -ssAllocateRequiredFloatReg(sqInt requiredReg) -{ - ssAllocateRequiredFloatRegMaskupThroughupThroughNative(1U << requiredReg, simStackPtr, simNativeStackPtr); -} - - /* StackToRegisterMappingCogit>>#ssAllocateRequiredRegMask:upThrough:upThroughNative: */ -static void NoDbgRegParms -ssAllocateRequiredRegMaskupThroughupThroughNative(sqInt requiredRegsMask, sqInt stackPtr, sqInt nativeStackPtr) -{ - sqInt i; - sqInt i1; - sqInt lastRequired; - sqInt lastRequiredNative; - sqInt liveRegs; - - lastRequired = -1; - - /* compute live regs while noting the last occurrence of required regs. - If these are not free we must spill from simSpillBase to last occurrence. - Note we are conservative here; we could allocate FPReg in frameless methods. */ - lastRequiredNative = -1; - /* begin registerMaskFor:and: */ - liveRegs = (1U << FPReg) | (1U << SPReg); - for (i = (((simSpillBase < 0) ? 0 : simSpillBase)); i <= stackPtr; i += 1) { - liveRegs = liveRegs | (registerMask(simStackAt(i))); - if ((((registerMask(simStackAt(i))) & requiredRegsMask) != 0)) { - lastRequired = i; - } - } - assert(nativeStackPtr == simNativeStackPtr); - for (i = (((simNativeSpillBase < 0) ? 0 : simNativeSpillBase)); i <= nativeStackPtr; i += 1) { - liveRegs = liveRegs | (nativeRegisterMask(simNativeStackAt(i))); - if ((((nativeRegisterMask(simNativeStackAt(i))) & requiredRegsMask) != 0)) { - lastRequiredNative = i; - } - } - if (((liveRegs & requiredRegsMask) != 0)) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= lastRequired) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < lastRequired) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : lastRequired)); i1 <= lastRequired; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = lastRequired + 1; - } - assert(!(((((liveRegisters()) & requiredRegsMask) != 0)))); - } -} - - -/* Any occurrences on the stack of the value being stored (which is the top - of stack) - must be flushed, and hence any values colder than them stack. */ - - /* StackToRegisterMappingCogit>>#ssFlushUpThroughReceiverVariable: */ -static void NoDbgRegParms -ssFlushUpThroughReceiverVariable(sqInt slotIndex) -{ - sqInt i; - sqInt index; - - ssNativeFlushTo(simNativeStackPtr); - /* begin ssFlushUpThrough: */ - assert(simSpillBase >= 0); - for (index = (simStackPtr - 1); index >= simSpillBase; index += -1) { - if (((((simStackAt(index))->type)) == SSBaseOffset) - && (((((simStackAt(index))->registerr)) == ReceiverResultReg) - && ((((simStackAt(index))->offset)) == (slotOffsetOfInstVarIndex(slotIndex))))) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= index) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < index) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : index)); i <= index; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = index + 1; - } - goto l1; - } - } - l1: /* end ssFlushUpThrough: */; -} - - -/* Any occurrences on the stack of the value being stored (which is the top - of stack) - must be flushed, and hence any values colder than them stack. */ - - /* StackToRegisterMappingCogit>>#ssFlushUpThroughTemporaryVariable: */ -static void NoDbgRegParms -ssFlushUpThroughTemporaryVariable(sqInt tempIndex) -{ - sqInt i; - sqInt index; - sqInt offset; - - ssNativeFlushTo(simNativeStackPtr); - offset = ((simStackAt(tempIndex + 1))->offset); - assert(offset == (frameOffsetOfTemporary(tempIndex))); - /* begin ssFlushUpThrough: */ - assert(simSpillBase >= 0); - for (index = (simStackPtr - 1); index >= simSpillBase; index += -1) { - if (((((simStackAt(index))->type)) == SSBaseOffset) - && (((((simStackAt(index))->registerr)) == FPReg) - && ((((simStackAt(index))->offset)) == offset))) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= index) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < index) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : index)); i <= index; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = index + 1; - } - goto l1; - } - } - l1: /* end ssFlushUpThrough: */; -} - - /* StackToRegisterMappingCogit>>#ssNativeFlushTo: */ -static void NoDbgRegParms -ssNativeFlushTo(sqInt index) -{ - sqInt allocatedScratchRegister; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - sqInt i; - sqInt loadedPointer; - sqInt offset; - sqInt offset1; - - if (simNativeSpillBase <= index) { - loadedPointer = 0; - allocatedScratchRegister = 0; - for (i = (((simNativeSpillBase < 0) ? 0 : simNativeSpillBase)); i <= index; i += 1) { - if (!loadedPointer) { - /* begin MoveMw:r:R: */ - offset = frameOffsetOfNativeFramePointer(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, FPReg, TempReg); - loadedPointer = 1; - } - if ((spillingNeedsScratchRegister(simNativeStackAt(i))) - && (!allocatedScratchRegister)) { - /* begin PushR: */ - genoperand(PushR, FPReg); - allocatedScratchRegister = 1; - } - ensureSpilledSPscratchRegister(simNativeStackAt(i), TempReg, FPReg); - } - simNativeSpillBase = index + 1; - if (allocatedScratchRegister) { - /* begin PopR: */ - genoperand(PopR, FPReg); - } - if (loadedPointer) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(SubCqR, simNativeStackSize, TempReg); - /* begin MoveR:Mw:r: */ - offset1 = frameOffsetOfNativeStackPointer(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveRMwr, TempReg, offset1, FPReg); - } - } -} - - /* StackToRegisterMappingCogit>>#ssNativePop: */ -static void NoDbgRegParms -ssNativePop(sqInt n) -{ - assert((simNativeStackPtr - n) >= -1); - simNativeStackPtr -= n; - if (simNativeStackPtr >= 0) { - simNativeStackSize = ((ssNativeTop())->offset); - } - else { - simNativeStackSize = 0; - } -} - - /* StackToRegisterMappingCogit>>#ssNativePush: */ -static void NoDbgRegParms -ssNativePush(sqInt n) -{ - simNativeStackPtr += n; -} - - /* StackToRegisterMappingCogit>>#ssNativeTop */ -static CogSimStackNativeEntry * -ssNativeTop(void) -{ - assert(simNativeStackPtr >= 0); - return simNativeStackAt(simNativeStackPtr); -} - - /* StackToRegisterMappingCogit>>#ssNativeValue: */ -static CogSimStackNativeEntry * NoDbgRegParms -ssNativeValue(sqInt n) -{ - return simNativeStackAt(simNativeStackPtr - n); -} - - /* StackToRegisterMappingCogit>>#ssPopNativeSize: */ -static void NoDbgRegParms -ssPopNativeSize(sqInt popSize) -{ - sqInt popCount; - sqInt poppingSize; - sqInt stackPosition; - - poppingSize = 0; - stackPosition = simNativeStackPtr; - while ((poppingSize < popSize) - && (stackPosition >= 0)) { - poppingSize += stackSpillSize(simNativeStackAt(stackPosition)); - stackPosition -= 1; - } - assert(poppingSize == popSize); - popCount = simNativeStackPtr - stackPosition; - ssNativePop(popCount); -} - - /* StackToRegisterMappingCogit>>#ssPop: */ -static void NoDbgRegParms -ssPop(sqInt n) -{ - sqInt i; - - assert(((simStackPtr - n) >= methodOrBlockNumTemps) - || (((!needsFrame) - && ((simStackPtr - n) >= 0)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil()))); - simStackPtr -= n; - /* begin updateSimSpillBase */ - assert(((simSpillBase > methodOrBlockNumTemps) - && (simStackPtr >= methodOrBlockNumTemps)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - if (simSpillBase > simStackPtr) { - simSpillBase = simStackPtr + 1; - while (((simSpillBase - 1) > methodOrBlockNumTemps) - && (!(((simStackAt(simSpillBase - 1))->spilled)))) { - simSpillBase -= 1; - } - } - else { - while ((((simStackAt(simSpillBase))->spilled)) - && (simSpillBase <= simStackPtr)) { - simSpillBase += 1; - } - } - for (i = (methodOrBlockNumTemps + 1); i <= ((((simSpillBase - 1) < simStackPtr) ? (simSpillBase - 1) : simStackPtr)); i += 1) { - assert((((simStackAt(i))->spilled)) == 1); - } - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); -} - - /* StackToRegisterMappingCogit>>#ssPushAnnotatedConstant: */ -static sqInt NoDbgRegParms -ssPushAnnotatedConstant(sqInt literal) -{ - AbstractInstruction *abstractInstruction; - - ssPushConstant(literal); - /* begin annotateInstructionForBytecode */ - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (abstractInstruction->annotation = HasBytecodePC); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushBase:offset: */ -static sqInt NoDbgRegParms -ssPushBaseoffset(sqInt reg, sqInt offset) -{ - CogSimStackEntry * cascade0; - sqInt i; - - ssPush(1); - cascade0 = ssTop(); - (cascade0->type = SSBaseOffset); - (cascade0->spilled = 0); - (cascade0->registerr = reg); - (cascade0->offset = offset); - (cascade0->bcptr = bytecodePC); - /* begin updateSimSpillBase */ - assert(((simSpillBase > methodOrBlockNumTemps) - && (simStackPtr >= methodOrBlockNumTemps)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - if (simSpillBase > simStackPtr) { - simSpillBase = simStackPtr + 1; - while (((simSpillBase - 1) > methodOrBlockNumTemps) - && (!(((simStackAt(simSpillBase - 1))->spilled)))) { - simSpillBase -= 1; - } - } - else { - while ((((simStackAt(simSpillBase))->spilled)) - && (simSpillBase <= simStackPtr)) { - simSpillBase += 1; - } - } - for (i = (methodOrBlockNumTemps + 1); i <= ((((simSpillBase - 1) < simStackPtr) ? (simSpillBase - 1) : simStackPtr)); i += 1) { - assert((((simStackAt(i))->spilled)) == 1); - } - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushConstant: */ -static sqInt NoDbgRegParms -ssPushConstant(sqInt literal) -{ - CogSimStackEntry * cascade0; - sqInt i; - - ssPush(1); - cascade0 = ssTop(); - (cascade0->type = SSConstant); - (cascade0->spilled = 0); - (cascade0->constant = literal); - (cascade0->bcptr = bytecodePC); - /* begin updateSimSpillBase */ - assert(((simSpillBase > methodOrBlockNumTemps) - && (simStackPtr >= methodOrBlockNumTemps)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - if (simSpillBase > simStackPtr) { - simSpillBase = simStackPtr + 1; - while (((simSpillBase - 1) > methodOrBlockNumTemps) - && (!(((simStackAt(simSpillBase - 1))->spilled)))) { - simSpillBase -= 1; - } - } - else { - while ((((simStackAt(simSpillBase))->spilled)) - && (simSpillBase <= simStackPtr)) { - simSpillBase += 1; - } - } - for (i = (methodOrBlockNumTemps + 1); i <= ((((simSpillBase - 1) < simStackPtr) ? (simSpillBase - 1) : simStackPtr)); i += 1) { - assert((((simStackAt(i))->spilled)) == 1); - } - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushDesc: */ -static sqInt NoDbgRegParms -ssPushDesc(SimStackEntry simStackEntry) -{ - sqInt i; - - if (((simStackEntry.type)) == SSSpill) { - (simStackEntry.type = SSBaseOffset); - } - (simStackEntry.spilled = 0); - (simStackEntry.bcptr = bytecodePC); - simStack[(simStackPtr += 1)] = simStackEntry; - /* begin updateSimSpillBase */ - assert(((simSpillBase > methodOrBlockNumTemps) - && (simStackPtr >= methodOrBlockNumTemps)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - if (simSpillBase > simStackPtr) { - simSpillBase = simStackPtr + 1; - while (((simSpillBase - 1) > methodOrBlockNumTemps) - && (!(((simStackAt(simSpillBase - 1))->spilled)))) { - simSpillBase -= 1; - } - } - else { - while ((((simStackAt(simSpillBase))->spilled)) - && (simSpillBase <= simStackPtr)) { - simSpillBase += 1; - } - } - for (i = (methodOrBlockNumTemps + 1); i <= ((((simSpillBase - 1) < simStackPtr) ? (simSpillBase - 1) : simStackPtr)); i += 1) { - assert((((simStackAt(i))->spilled)) == 1); - } - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushNativeConstantFloat32: */ -static sqInt NoDbgRegParms -ssPushNativeConstantFloat32(float aFloat32) -{ - CogSimStackNativeEntry * cascade0; - - ssNativePush(1); - if (simNativeSpillBase > simNativeStackPtr) { - simNativeSpillBase = ((simNativeStackPtr < 0) ? 0 : simNativeStackPtr); - } - simNativeStackSize += BytesPerWord; - /* begin ssNativeTop */ - assert(simNativeStackPtr >= 0); - cascade0 = simNativeStackAt(simNativeStackPtr); - (cascade0->type = SSConstantFloat32); - (cascade0->spilled = 0); - (cascade0->offset = simNativeStackSize); - (cascade0->constantFloat32 = aFloat32); - (cascade0->bcptr = bytecodePC); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushNativeConstantFloat64: */ -static sqInt NoDbgRegParms -ssPushNativeConstantFloat64(double aFloat64) -{ - CogSimStackNativeEntry * cascade0; - - ssNativePush(1); - if (simNativeSpillBase > simNativeStackPtr) { - simNativeSpillBase = ((simNativeStackPtr < 0) ? 0 : simNativeStackPtr); - } - simNativeStackSize += 8; - /* begin ssNativeTop */ - assert(simNativeStackPtr >= 0); - cascade0 = simNativeStackAt(simNativeStackPtr); - (cascade0->type = SSConstantFloat64); - (cascade0->spilled = 0); - (cascade0->offset = simNativeStackSize); - (cascade0->constantFloat64 = aFloat64); - (cascade0->bcptr = bytecodePC); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushNativeConstantInt32: */ -static sqInt NoDbgRegParms -ssPushNativeConstantInt32(sqInt anInt32) -{ - CogSimStackNativeEntry * cascade0; - - ssNativePush(1); - if (simNativeSpillBase > simNativeStackPtr) { - simNativeSpillBase = ((simNativeStackPtr < 0) ? 0 : simNativeStackPtr); - } - simNativeStackSize += BytesPerWord; - /* begin ssNativeTop */ - assert(simNativeStackPtr >= 0); - cascade0 = simNativeStackAt(simNativeStackPtr); - (cascade0->type = SSConstantInt32); - (cascade0->spilled = 0); - (cascade0->offset = simNativeStackSize); - (cascade0->constantInt32 = anInt32); - (cascade0->bcptr = bytecodePC); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushNativeConstantInt64: */ -static sqInt NoDbgRegParms -ssPushNativeConstantInt64(sqLong anInt64) -{ - CogSimStackNativeEntry * cascade0; - - ssNativePush(1); - if (simNativeSpillBase > simNativeStackPtr) { - simNativeSpillBase = ((simNativeStackPtr < 0) ? 0 : simNativeStackPtr); - } - simNativeStackSize += 8; - /* begin ssNativeTop */ - assert(simNativeStackPtr >= 0); - cascade0 = simNativeStackAt(simNativeStackPtr); - (cascade0->type = SSConstantInt64); - (cascade0->spilled = 0); - (cascade0->offset = simNativeStackSize); - (cascade0->constantInt64 = anInt64); - (cascade0->bcptr = bytecodePC); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushNativeConstantPointer: */ -static sqInt NoDbgRegParms -ssPushNativeConstantPointer(sqInt aNativePointer) -{ - CogSimStackNativeEntry * cascade0; - - ssNativePush(1); - if (simNativeSpillBase > simNativeStackPtr) { - simNativeSpillBase = ((simNativeStackPtr < 0) ? 0 : simNativeStackPtr); - } - simNativeStackSize += BytesPerWord; - /* begin ssNativeTop */ - assert(simNativeStackPtr >= 0); - cascade0 = simNativeStackAt(simNativeStackPtr); - (cascade0->type = SSConstantNativePointer); - (cascade0->spilled = 0); - (cascade0->offset = simNativeStackSize); - (cascade0->constantNativePointer = aNativePointer); - (cascade0->bcptr = bytecodePC); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushNativeRegisterDoubleFloat: */ -static sqInt NoDbgRegParms -ssPushNativeRegisterDoubleFloat(sqInt reg) -{ - CogSimStackNativeEntry * cascade0; - - ssNativePush(1); - if (simNativeSpillBase > simNativeStackPtr) { - simNativeSpillBase = ((simNativeStackPtr < 0) ? 0 : simNativeStackPtr); - } - simNativeStackSize += 8; - /* begin ssNativeTop */ - assert(simNativeStackPtr >= 0); - cascade0 = simNativeStackAt(simNativeStackPtr); - (cascade0->type = SSRegisterDoubleFloat); - (cascade0->spilled = 0); - (cascade0->offset = simNativeStackSize); - (cascade0->registerr = reg); - (cascade0->bcptr = bytecodePC); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushNativeRegisterSingleFloat: */ -static sqInt NoDbgRegParms -ssPushNativeRegisterSingleFloat(sqInt reg) -{ - CogSimStackNativeEntry * cascade0; - - ssNativePush(1); - if (simNativeSpillBase > simNativeStackPtr) { - simNativeSpillBase = ((simNativeStackPtr < 0) ? 0 : simNativeStackPtr); - } - simNativeStackSize += BytesPerWord; - /* begin ssNativeTop */ - assert(simNativeStackPtr >= 0); - cascade0 = simNativeStackAt(simNativeStackPtr); - (cascade0->type = SSRegisterSingleFloat); - (cascade0->spilled = 0); - (cascade0->offset = simNativeStackSize); - (cascade0->registerr = reg); - (cascade0->bcptr = bytecodePC); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushNativeRegister: */ -static sqInt NoDbgRegParms -ssPushNativeRegister(sqInt reg) -{ - CogSimStackNativeEntry * cascade0; - - ssNativePush(1); - if (simNativeSpillBase > simNativeStackPtr) { - simNativeSpillBase = ((simNativeStackPtr < 0) ? 0 : simNativeStackPtr); - } - simNativeStackSize += BytesPerWord; - /* begin ssNativeTop */ - assert(simNativeStackPtr >= 0); - cascade0 = simNativeStackAt(simNativeStackPtr); - (cascade0->type = SSNativeRegister); - (cascade0->spilled = 0); - (cascade0->offset = simNativeStackSize); - (cascade0->registerr = reg); - (cascade0->bcptr = bytecodePC); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushNativeRegister:secondRegister: */ -static sqInt NoDbgRegParms -ssPushNativeRegistersecondRegister(sqInt reg, sqInt secondReg) -{ - CogSimStackNativeEntry * cascade0; - - ssNativePush(1); - if (simNativeSpillBase > simNativeStackPtr) { - simNativeSpillBase = ((simNativeStackPtr < 0) ? 0 : simNativeStackPtr); - } - simNativeStackSize += 8; - /* begin ssNativeTop */ - assert(simNativeStackPtr >= 0); - cascade0 = simNativeStackAt(simNativeStackPtr); - (cascade0->type = SSRegisterPair); - (cascade0->spilled = 0); - (cascade0->offset = simNativeStackSize); - (cascade0->registerr = reg); - (cascade0->registerSecond = secondReg); - (cascade0->bcptr = bytecodePC); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushRegister: */ -static sqInt NoDbgRegParms -ssPushRegister(sqInt reg) -{ - CogSimStackEntry * cascade0; - sqInt i; - - ssPush(1); - cascade0 = ssTop(); - (cascade0->type = SSRegister); - (cascade0->spilled = 0); - (cascade0->registerr = reg); - (cascade0->bcptr = bytecodePC); - /* begin updateSimSpillBase */ - assert(((simSpillBase > methodOrBlockNumTemps) - && (simStackPtr >= methodOrBlockNumTemps)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - if (simSpillBase > simStackPtr) { - simSpillBase = simStackPtr + 1; - while (((simSpillBase - 1) > methodOrBlockNumTemps) - && (!(((simStackAt(simSpillBase - 1))->spilled)))) { - simSpillBase -= 1; - } - } - else { - while ((((simStackAt(simSpillBase))->spilled)) - && (simSpillBase <= simStackPtr)) { - simSpillBase += 1; - } - } - for (i = (methodOrBlockNumTemps + 1); i <= ((((simSpillBase - 1) < simStackPtr) ? (simSpillBase - 1) : simStackPtr)); i += 1) { - assert((((simStackAt(i))->spilled)) == 1); - } - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPush: */ -static void NoDbgRegParms -ssPush(sqInt n) -{ - simStackPtr += n; -} - - /* StackToRegisterMappingCogit>>#ssSelfDescriptor */ -static SimStackEntry -ssSelfDescriptor(void) -{ - return simStack[0]; -} - - -/* In addition to ssStorePop:toReg:, if this is a store and not - a popInto I change the simulated stack to use the register - for the top value */ - - /* StackToRegisterMappingCogit>>#ssStoreAndReplacePop:toReg: */ -static void NoDbgRegParms -ssStoreAndReplacePoptoReg(sqInt popBoolean, sqInt reg) -{ - char topSpilled; - - topSpilled = ((ssTop())->spilled); - ssStorePoptoReg(popBoolean - || (topSpilled), reg); - if (!popBoolean) { - if (!topSpilled) { - ssPop(1); - } - ssPushRegister(reg); - } -} - - -/* Store or pop the top simulated stack entry to a register. - Use preferredReg if the entry is not itself a register. - Answer the actual register the result ends up in. */ - - /* StackToRegisterMappingCogit>>#ssStorePop:toPreferredReg: */ -static sqInt NoDbgRegParms -ssStorePoptoPreferredReg(sqInt popBoolean, sqInt preferredReg) -{ - sqInt actualReg; - - actualReg = preferredReg; - if ((((ssTop())->type)) == SSRegister) { - assert(!(((ssTop())->spilled))); - actualReg = ((ssTop())->registerr); - } - ssStorePoptoReg(popBoolean, actualReg); - return actualReg; -} - - -/* Store or pop the top simulated stack entry to a register. - N.B.: popToReg: and storeToReg: does not generate anything if - it moves a register to the same register. */ - - /* StackToRegisterMappingCogit>>#ssStorePop:toReg: */ -static void NoDbgRegParms -ssStorePoptoReg(sqInt popBoolean, sqInt reg) -{ - if (popBoolean) { - popToReg(ssTop(), reg); - ssPop(1); - } - else { - storeToReg(ssTop(), reg); - } -} - - /* StackToRegisterMappingCogit>>#ssTop */ -static CogSimStackEntry * -ssTop(void) -{ - return simStackAt(simStackPtr); -} - - /* StackToRegisterMappingCogit>>#ssValue: */ -static CogSimStackEntry * NoDbgRegParms -ssValue(sqInt n) -{ - return simStackAt(simStackPtr - n); -} - - /* StackToRegisterMappingCogit>>#stackEntryIsBoolean: */ -static sqInt NoDbgRegParms -stackEntryIsBoolean(CogSimStackEntry *simStackEntry) -{ - return (((simStackEntry->type)) == SSConstant) - && ((((simStackEntry->constant)) == (trueObject())) - || (((simStackEntry->constant)) == (falseObject()))); -} - - -/* Answer if the stack is valid up to, but not including, simSpillBase. */ - - /* StackToRegisterMappingCogit>>#tempsValidAndVolatileEntriesSpilled */ -static sqInt -tempsValidAndVolatileEntriesSpilled(void) -{ - sqInt culprit; - sqInt i; - - culprit = 0; - for (i = 1; i <= methodOrBlockNumTemps; i += 1) { - if (!(((((simStackAt(i))->type)) == SSBaseOffset) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil()))) { - if (!culprit) { - culprit = i; - } - return 0; - } - } - for (i = (methodOrBlockNumTemps + 1); i < simSpillBase; i += 1) { - if (!(((simStackAt(i))->spilled))) { - if (!culprit) { - culprit = i; - } - return 0; - } - } - return 1; -} - - -/* If the sequence of bytecodes is - push: (Array new: 1) - popIntoTemp: tempIndex - pushConstant: const or pushTemp: n - popIntoTemp: 0 inVectorAt: tempIndex - collapse this into - tempAt: tempIndex put: {const or temp} - and answer true, otherwise answer false. - One might think that we should look for a sequence of more than - one pushes and pops but this is extremely rare. - Exclude pushRcvr: n to avoid potential complications with context inst - vars. */ - - /* StackToRegisterMappingCogit>>#tryCollapseTempVectorInitializationOfSize: */ -static sqInt NoDbgRegParms -tryCollapseTempVectorInitializationOfSize(sqInt slots) -{ - sqInt pc; - sqInt pc1; - sqInt pc2; - BytecodeDescriptor *pushArrayDesc; - BytecodeDescriptor *pushValueDesc; - sqInt reg; - sqInt remoteTempIndex; - BytecodeDescriptor *storeArrayDesc; - BytecodeDescriptor *storeValueDesc; - sqInt tempIndex; - - if (slots != 1) { - return 0; - } - /* begin generatorForPC: */ - pushArrayDesc = generatorAt(bytecodeSetOffset + (fetchByteofObject(bytecodePC, methodObj))); - assert(((pushArrayDesc->generator)) == genPushNewArrayBytecode); - /* begin generatorForPC: */ - pc = bytecodePC + ((pushArrayDesc->numBytes)); - storeArrayDesc = generatorAt(bytecodeSetOffset + (fetchByteofObject(pc, methodObj))); - if (((storeArrayDesc->generator)) == genStoreAndPopTemporaryVariableBytecode) { - tempIndex = (fetchByteofObject(bytecodePC + ((pushArrayDesc->numBytes)), methodObj)) & 7; - } - else { - if (!(((storeArrayDesc->generator)) == genLongStoreAndPopTemporaryVariableBytecode)) { - return 0; - } - tempIndex = fetchByteofObject((bytecodePC + ((pushArrayDesc->numBytes))) + 1, methodObj); - } - /* begin generatorForPC: */ - pc1 = (bytecodePC + ((pushArrayDesc->numBytes))) + ((storeArrayDesc->numBytes)); - pushValueDesc = generatorAt(bytecodeSetOffset + (fetchByteofObject(pc1, methodObj))); - if (!((((pushValueDesc->generator)) == genPushLiteralConstantBytecode) - || ((((pushValueDesc->generator)) == genPushQuickIntegerConstantBytecode) - || (((pushValueDesc->generator)) == genPushTemporaryVariableBytecode)))) { - return 0; - } - /* begin generatorForPC: */ - pc2 = ((bytecodePC + ((pushArrayDesc->numBytes))) + ((storeArrayDesc->numBytes))) + ((pushValueDesc->numBytes)); - storeValueDesc = generatorAt(bytecodeSetOffset + (fetchByteofObject(pc2, methodObj))); - remoteTempIndex = fetchByteofObject((((bytecodePC + ((pushArrayDesc->numBytes))) + ((storeArrayDesc->numBytes))) + ((pushValueDesc->numBytes))) + 2, methodObj); - if (!((((storeValueDesc->generator)) == genStoreAndPopRemoteTempLongBytecode) - && (tempIndex == remoteTempIndex))) { - return 0; - } - genNewArrayOfSizeinitialized(1, 0); - evaluateat(pushValueDesc, (bytecodePC + ((pushArrayDesc->numBytes))) + ((storeArrayDesc->numBytes))); - reg = ssStorePoptoPreferredReg(1, TempReg); - genStoreSourceRegslotIndexintoNewObjectInDestReg(reg, 0, ReceiverResultReg); - ssPushRegister(ReceiverResultReg); - evaluateat(storeArrayDesc, bytecodePC + ((pushArrayDesc->numBytes))); - - /* + pushArrayDesc numBytes this gets added by nextBytecodePCFor:at:exts:in: */ - bytecodePC = ((bytecodePC + ((storeArrayDesc->numBytes))) + ((pushValueDesc->numBytes))) + ((storeValueDesc->numBytes)); - return 1; -} - - /* StackToRegisterMappingCogit>>#violatesEnsureSpilledSpillAssert */ -static sqInt -violatesEnsureSpilledSpillAssert(void) -{ - return 1; -} - - -/* Used when ReceiverResultReg is allocated for other than simSelf, and - there may be references to ReceiverResultReg which need to be spilled. */ - - /* StackToRegisterMappingCogit>>#voidReceiverResultRegContainsSelf */ -static void -voidReceiverResultRegContainsSelf(void) -{ - sqInt i; - sqInt i1; - sqInt spillIndex; - - /* begin voidReceiverOptStatus */ - ((simSelf())->liveRegister = NoReg); - spillIndex = 0; - for (i = ((((methodOrBlockNumTemps + 1) < simSpillBase) ? simSpillBase : (methodOrBlockNumTemps + 1))); i <= simStackPtr; i += 1) { - if ((registerOrNone(simStackAt(i))) == ReceiverResultReg) { - spillIndex = i; - } - } - if (spillIndex > 0) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - ssNativeFlushTo(simNativeStackPtr); - if (simSpillBase <= spillIndex) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < spillIndex) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : spillIndex)); i1 <= spillIndex; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = spillIndex + 1; - } - } -} diff --git a/spurlowcodesrc/vm/cointerp.c b/spurlowcodesrc/vm/cointerp.c index 50cade258d..97600917e8 100644 --- a/spurlowcodesrc/vm/cointerp.c +++ b/spurlowcodesrc/vm/cointerp.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - CoInterpreter VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CoInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 " __DATE__ ; +static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -490,6 +490,7 @@ extern sqInt ceSendabovetonumArgs(sqInt selector, sqInt methodClass, sqInt rcvr, extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern sqInt ceSistaTrap(void); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethod); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); @@ -671,7 +672,6 @@ static void primitiveExitCriticalSection(void); static void primitiveFlushCacheByMethod(void); static void primitiveFlushCacheBySelector(void); extern usqInt primitiveFunctionPointerAddress(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); EXPORT(sqInt) primitiveMethodPCData(void); static void primitiveMethodXray(void); EXPORT(void) primitiveMinimumUnusedHeadroom(void); @@ -1195,7 +1195,6 @@ static sqInt NoDbgRegParms isPureBitsFormat(sqInt format); extern sqInt isReallyYoung(sqInt oop); static sqInt NoDbgRegParms isRemembered(sqInt objOop); static sqInt NoDbgRegParms isSegmentBridge(sqInt objOop); -static sqInt NoDbgRegParms isSemaphoreOop(sqInt anOop); extern sqInt isShorts(sqInt oop); extern sqInt isUnambiguouslyForwarder(sqInt objOop); extern sqInt isUnmarked(sqInt objOop); @@ -1262,7 +1261,7 @@ static sqInt NoDbgRegParms num64BitUnitsOf(sqInt objOop); static sqInt NoDbgRegParms numBytesOfBitsformat(sqInt objOop, sqInt format); static sqInt NoDbgRegParms numBytesOfBytes(sqInt objOop); extern sqInt numBytesOf(sqInt objOop); -extern sqInt numPointerSlotsOf(sqInt objOop); +extern usqInt numPointerSlotsOf(sqInt objOop); static usqInt NoDbgRegParms numSlotsOfAny(sqInt objOop); extern usqInt numSlotsOf(sqInt objOop); static sqInt NoDbgRegParms numStrongSlotsOfInephemeral(sqInt objOop); @@ -1425,7 +1424,6 @@ EXPORT(sqInt) callbackLeave(sqInt cbID); extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHeader); extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkForEventsMayContextSwitch(sqInt mayContextSwitch); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); @@ -1713,7 +1711,6 @@ static sqInt NoDbgRegParms updateDisplayLeftTopRightBottom(sqInt l, sqInt t, sqI static sqInt NoDbgRegParms validBCPCinMethod(sqInt thePC, usqInt aMethod); static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, char *fp); static sqInt validStackPageBaseFrames(void); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt wakeHighestPriority(void); static sqInt NeverInline writeImageFileIO(void); static usqInt NoDbgRegParms cloneContext(sqInt aContext); @@ -1736,7 +1733,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1813,15 +1809,14 @@ _iss usqInt lastMobileObject; _iss sqInt tempOop; _iss sqInt numClassTablePages; _iss sqInt lkupClass; -_iss sqInt futureSurvivorStart; _iss sqInt profileProcess; -_iss sqInt profileSemaphore; +_iss sqInt futureSurvivorStart; _iss sqInt mournQueue; _iss sqInt numRememberedEphemerons; +_iss sqInt profileMethod; _iss sqInt jmpDepth; _iss sqInt mobileStart; -_iss sqInt profileMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; +_iss sqInt profileSemaphore; _iss sqInt growHeadroom; _iss sqInt tenureThreshold; _iss sqInt lastCoggableInterpretedBlockMethod; @@ -1829,7 +1824,6 @@ _iss sqInt lastUncoggableInterpretedBlockMethod; _iss char * objStackInvalidBecause; _iss sqInt sweepIndex; _iss sqInt ephemeronList; -_iss sqInt longRunningPrimitiveCheckMethod; _iss sqInt tenureCriterion; _iss usqInt totalHeapSizeIncludingBridges; _iss sqInt becomeEffectsFlags; @@ -1885,7 +1879,6 @@ _iss sqInt freeSpaceCheckOopToIgnore; _iss usqInt heapSizeAtPreviousGC; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss sqInt methodDictLinearSearchLimit; _iss sqInt statGrowMemory; _iss sqInt statMaxPageCountWhenMapping; @@ -1897,7 +1890,6 @@ _iss sqInt extraFramesToMoveOnOverflow; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; _iss sqInt inFFIFlags; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss sqInt refCountToShrinkRT; _iss sqInt signalLowSpace; @@ -1927,16 +1919,14 @@ _iss sqInt preferredPinningSegment; _iss sqInt statCoalesces; _iss sqInt theUnknownShort; _iss usqLong nextWakeupUsecs; -_iss usqLong statGCEndUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; -_iss usqLong statCheckForEvents; -_iss usqLong gcStartUsecs; _iss sqLong oldSpaceUsePriorToScavenge; +_iss usqLong statGCEndUsecs; _iss usqLong statIOProcessEvents; +_iss usqLong gcStartUsecs; _iss usqLong statAllocatedBytes; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statCompactionUsecs; _iss usqLong statForceInterruptCheck; _iss usqLong statFullGCUsecs; @@ -1950,9 +1940,11 @@ _iss usqLong statSweepUsecs; _iss usqLong statCodeCompactionUsecs; _iss usqLong statSGCDeltaUsecs; _iss usqLong gcSweepEndUsecs; -_iss usqLong longRunningPrimitiveGCUsecs; _iss usqLong statIGCDeltaUsecs; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; _iss usqLong statFGCDeltaUsecs; _iss usqLong statIncrGCUsecs; _iss SpurContiguousObjStack savedFirstFieldsSpace; @@ -2629,7 +2621,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Open Smalltalk Cog[Spur] VM [CoInterpreterPrimitives VMMaker.oscog-eem.3024]"; +const char *interpreterVersion = "Open Smalltalk Cog[Spur] VM [CoInterpreterPrimitives VMMaker.oscog-eem.3031]"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */; char primitiveDoMixedArithmetic = 1; char expensiveAsserts = 0; @@ -35088,6 +35080,27 @@ ceStackOverflow(sqInt contextSwitchIfNotNil) error("should not be reached"); } + +/* A primitive has succeeded and the nextProfileTick has been reached (all + done in machine code). + Now take a sample. c.f. checkProfileTick: */ + + /* CoInterpreter>>#ceTakeProfileSample: */ +void +ceTakeProfileSample(CogMethod *aCogMethod) +{ DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt objOop; + sqInt objOop1; + + /* begin fetchPointer:ofObject: */ + objOop1 = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(SchedulerAssociation) << (shiftForWord()))))); + objOop = longAt((objOop1 + BaseHeaderSize) + (((int)((usqInt)(ValueIndex) << (shiftForWord()))))); + GIV(profileProcess) = longAt((objOop + BaseHeaderSize) + (((int)((usqInt)(ActiveProcessIndex) << (shiftForWord()))))); + GIV(profileMethod) = (aCogMethod->methodObject); + forceInterruptCheck(); + GIV(nextProfileTick) = 0; +} + /* CoInterpreter>>#ceTraceBlockActivation */ void ceTraceBlockActivation(void) @@ -37086,24 +37099,6 @@ void forceInterruptCheckFromHeartbeat(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; sqLowLevelMFence(); if (GIV(deferSmash)) { GIV(deferredSmash) = 1; @@ -43564,56 +43559,6 @@ primitiveFunctionPointerAddress(void) return ((usqInt)((&primitiveFunctionPointer))); } - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* CoInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; - int flushState; - sqInt sema; - char *sp; - - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (sema == GIV(nilObj)) { - flushState = GIV(longRunningPrimitiveCheckSemaphore) != null; - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - flushState = GIV(longRunningPrimitiveCheckSemaphore) == null; - if (!(((!(sema & (tagMask())))) - && (((longAt(sema)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(ClassSemaphore) << (shiftForWord())))))))))) { - return (GIV(primFailCode) = PrimErrBadArgument); - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(longRunningPrimitiveCheckSemaphore) == null)) - || (((stackValue(0)) == GIV(longRunningPrimitiveCheckSemaphore)) - && (isSemaphoreOop(sema)))); - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - if (flushState) { - ceInvokeInterpret(); - } - return 0; -} - /* CoInterpreterPrimitives>>#primitiveMethodPCData */ EXPORT(sqInt) primitiveMethodPCData(void) @@ -43926,14 +43871,9 @@ primitiveObjectAtPut(void) EXPORT(sqInt) primitiveProfileSemaphore(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; int flushState; sqInt sema; - char *sp; - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); if (sema == GIV(nilObj)) { flushState = GIV(profileSemaphore) != GIV(nilObj); @@ -43945,28 +43885,21 @@ primitiveProfileSemaphore(void) return (GIV(primFailCode) = PrimErrBadArgument); } } + GIV(profileSemaphore) = sema; /* If we've switched profiling on or off we must void machine code (and machine code pcs in contexts) since we will start or stop testing the profile clock in machine code primitive invocations, and so generate slightly different code from here on in. */ - GIV(profileSemaphore) = sema; - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(profileSemaphore) == (nilObject()))) - || (((stackValue(0)) == GIV(profileSemaphore)) - && (isSemaphoreOop(sema)))); - } GIV(profileProcess) = (GIV(profileMethod) = GIV(nilObj)); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; if (flushState) { - ceInvokeInterpret(); + flushExternalPrimitives(); + } + else { + /* begin methodReturnReceiver */ + assert(!((failed()))); + /* begin pop: */ + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; } return 0; } @@ -52671,26 +52604,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -53459,7 +53394,7 @@ primitiveInvokeObjectAsMethod(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt i; sqInt lookupClassTag; - usqInt runArgs; + sqInt runArgs; sqInt runReceiver; char *sp; char *sp1; @@ -55396,15 +55331,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -55422,15 +55352,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -55454,39 +55379,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((integerPointer & 1)) { - deltaTicks = (integerPointer >> 1); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((deltaTicks & 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 1)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -58923,7 +58827,7 @@ followForwardedObjectFieldstoDepth(sqInt objOop, sqInt depth) sqInt header1; sqInt i; sqInt numLiterals; - sqInt numSlots; + usqInt numSlots; usqInt numSlots1; sqInt oop; sqInt referent; @@ -66258,7 +66162,7 @@ copyObjtoAddrstopAtsavedFirstFieldsindex(sqInt objOop, sqInt segAddr, sqInt endS sqInt iLimiT; sqInt methodHeader; sqInt numLiterals; - sqInt numMediatedSlots; + usqInt numMediatedSlots; usqInt numSlots; usqInt numSlots1; sqInt oop; @@ -66290,7 +66194,7 @@ copyObjtoAddrstopAtsavedFirstFieldsindex(sqInt objOop, sqInt segAddr, sqInt endS here but that requires access to framePointer. */ /* begin numSlotsOfMarriedContext: */ contextSize = stackPointerIndexForFrame(frameOfMarriedContext(objOop)); - numMediatedSlots = CtxtTempFrameStart + contextSize; + numMediatedSlots = ((sqInt) (CtxtTempFrameStart + contextSize)); for (i1 = 0; i1 < numMediatedSlots; i1 += 1) { oop = fetchPointerofMarriedContext(i1, objOop); assert(!(isOopForwarded(copy))); @@ -69636,14 +69540,6 @@ isSegmentBridge(sqInt objOop) return ((longAt(objOop)) & (classIndexMask())) == (segmentBridgePun()); } - /* SpurMemoryManager>>#isSemaphoreOop: */ -static sqInt NoDbgRegParms -isSemaphoreOop(sqInt anOop) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - return ((!(anOop & (tagMask())))) - && (((longAt(anOop)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(ClassSemaphore) << (shiftForWord())))))))); -} - /* Answer if the argument contains only indexable 16-bit half words (no oops). See comment in formatOf: @@ -71911,8 +71807,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) sqInt referent; sqInt referent1; sqInt referent2; - sqInt referent3; - sqInt referent4; sqInt sizeOfUnusedEden; StackPage *thePage; @@ -72040,38 +71934,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - if ((!((longAt(GIV(longRunningPrimitiveCheckMethod))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckMethod))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((GIV(longRunningPrimitiveCheckMethod) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent3 & (tagMask())))) - && ((!((longAt(referent3)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((referent3 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckMethod) = referent3; - } - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - if ((!((longAt(GIV(longRunningPrimitiveCheckSemaphore))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckSemaphore))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((GIV(longRunningPrimitiveCheckSemaphore) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent4 & (tagMask())))) - && ((!((longAt(referent4)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((referent4 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckSemaphore) = referent4; - } - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -72759,7 +72621,7 @@ numBytesOf(sqInt objOop) Works with CompiledMethods, as well as ordinary objects. */ /* SpurMemoryManager>>#numPointerSlotsOf: */ -sqInt +usqInt numPointerSlotsOf(sqInt objOop) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt contextSize; @@ -75754,7 +75616,7 @@ printReferencesTo(sqInt anOop) assert((ReceiverIndex + ((sp >> 1))) < (lengthOf(obj1))); contextSize = (sp >> 1); l9: /* end fetchStackPointerOf: */; - i = CtxtTempFrameStart + contextSize; + i = ((usqInt) (CtxtTempFrameStart + contextSize)); goto l10; } /* begin numSlotsOf: */ @@ -75787,7 +75649,7 @@ printReferencesTo(sqInt anOop) /* begin literalCountOfMethodHeader: */ assert((header & 1)); numLiterals = ((header >> 1)) & AlternateHeaderNumLiteralsMask; - i = numLiterals + LiteralStart; + i = ((usqInt) (numLiterals + LiteralStart)); l10: /* end numPointerSlotsOf: */; while (((i -= 1)) >= 0) { if (anOop == (longAt((obj1 + BaseHeaderSize) + (((sqInt)((usqInt)(i) << (shiftForWord()))))))) { @@ -78941,10 +78803,10 @@ updatePointers(void) sqInt numLiterals1; sqInt numLiterals2; sqInt numLiterals3; - sqInt numPointerSlots; - sqInt numPointerSlots1; - sqInt numPointerSlots2; - sqInt numPointerSlots3; + usqInt numPointerSlots; + usqInt numPointerSlots1; + usqInt numPointerSlots2; + usqInt numPointerSlots3; usqInt numSlots; usqInt numSlots1; usqInt numSlots11; @@ -79522,7 +79384,7 @@ updatePointersInsavedFirstFieldPointer(sqInt obj, sqInt firstFieldPtr) assert((ReceiverIndex + ((sp >> 1))) < (lengthOf(obj))); contextSize = (sp >> 1); l6: /* end fetchStackPointerOf: */; - numPointerSlots = CtxtTempFrameStart + contextSize; + numPointerSlots = ((usqInt) (CtxtTempFrameStart + contextSize)); goto l10; } /* begin numSlotsOf: */ @@ -79552,7 +79414,7 @@ updatePointersInsavedFirstFieldPointer(sqInt obj, sqInt firstFieldPtr) /* begin literalCountOfMethodHeader: */ assert((header & 1)); numLiterals = ((header >> 1)) & AlternateHeaderNumLiteralsMask; - numPointerSlots = numLiterals + LiteralStart; + numPointerSlots = ((usqInt) (numLiterals + LiteralStart)); l10: /* end numPointerSlotsWhileCompactingOf:withFormat:savedFirstFieldPointer: */; if ((fmt <= 5 /* lastPointerFormat */) && (numPointerSlots > 0)) { @@ -80103,7 +79965,7 @@ prepareForSnapshot(void) sqInt limit; sqInt newEndOfMemory; sqInt next; - sqInt node; + usqInt node; SpurSegmentInfo *seg; sqInt smallChild; sqInt treeNode; @@ -80934,33 +80796,6 @@ checkAllAccessibleObjectsOkay(void) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -81051,9 +80886,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { /* begin signalLowSpace: */ GIV(signalLowSpace) = 0; @@ -86147,23 +85979,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i = 1; i <= GIV(jmpDepth); i += 1) { oop = GIV(suspendedCallbacks)[i]; @@ -90074,8 +89889,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -90104,18 +89919,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -93348,22 +93165,6 @@ validStackPageBaseFrames(void) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Return the highest priority process that is ready to run. To save time looking at many empty lists before finding a runnable process the VM maintains a variable holding the @@ -95993,74 +95794,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((addressCouldBeObj(lrpcm)) - && ((!(((longAt(lrpcm)) & (classIndexMask())) == (isFreeObjectClassIndexPun()))) - && (((((usqInt)((longAt(lrpcm)))) >> (formatShift())) & (formatMask())) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - assert(!(isForwarded(result))); - if ((assert(isNonImmediate(result)), - oopisGreaterThanOrEqualTo(result, GIV(oldSpaceStart)))) { - - /* most stores into young objects */ - if (((!(lrpcm & (tagMask())))) - && (oopisLessThan(lrpcm, GIV(newSpaceLimit)))) { - /* begin possibleRootStoreInto: */ - if (!(((((usqInt)((longAt(result)))) >> (rememberedBitShift())) & 1) != 0)) { - remember(result); - } - } - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 1) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 1) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -98554,15 +98287,13 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveGreaterOrEqualLargeIntegers\000\377\000", (void*)primitiveGreaterOrEqualLargeIntegers}, {(void*)_m, "primitiveGreaterThanLargeIntegers\000\377\000", (void*)primitiveGreaterThanLargeIntegers}, {(void*)_m, "primitiveHeartbeatFrequency\000\377\000", (void*)primitiveHeartbeatFrequency}, - {(void*)_m, "primitiveHighResClock\000\377\000", (void*)primitiveHighResClock}, + {(void*)_m, "primitiveHighResClock\000\377\001", (void*)primitiveHighResClock}, {(void*)_m, "primitiveImageFormatVersion\000\377\000", (void*)primitiveImageFormatVersion}, {(void*)_m, "primitiveInterruptChecksPerMSec\000\377\000", (void*)primitiveInterruptChecksPerMSec}, {(void*)_m, "primitiveIsBigEnder\000\377\000", (void*)primitiveIsBigEnder}, {(void*)_m, "primitiveIsWindowObscured\000\377\000", (void*)primitiveIsWindowObscured}, {(void*)_m, "primitiveLessOrEqualLargeIntegers\000\377\000", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers\000\377\000", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive\000\377\000", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore\000\000\000", (void*)primitiveLongRunningPrimitiveSemaphore}, {(void*)_m, "primitiveMethodPCData\000\000\000", (void*)primitiveMethodPCData}, {(void*)_m, "primitiveMillisecondClockMask\000\377\000", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveMinimumUnusedHeadroom\000\377\000", (void*)primitiveMinimumUnusedHeadroom}, @@ -98570,10 +98301,10 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveMultiplyLargeIntegers\000\000\000", (void*)primitiveMultiplyLargeIntegers}, {(void*)_m, "primitiveNotEqualLargeIntegers\000\377\000", (void*)primitiveNotEqualLargeIntegers}, {(void*)_m, "primitivePathToUsing\000\000\000", (void*)primitivePathToUsing}, - {(void*)_m, "primitiveProfilePrimitive\000\377\000", (void*)primitiveProfilePrimitive}, - {(void*)_m, "primitiveProfileSample\000\377\000", (void*)primitiveProfileSample}, + {(void*)_m, "primitiveProfilePrimitive\000\377\001", (void*)primitiveProfilePrimitive}, + {(void*)_m, "primitiveProfileSample\000\377\001", (void*)primitiveProfileSample}, {(void*)_m, "primitiveProfileSemaphore\000\000\000", (void*)primitiveProfileSemaphore}, - {(void*)_m, "primitiveProfileStart\000\000\000", (void*)primitiveProfileStart}, + {(void*)_m, "primitiveProfileStart\000\000\001", (void*)primitiveProfileStart}, {(void*)_m, "primitiveQuoLargeIntegers\000\000\000", (void*)primitiveQuoLargeIntegers}, {(void*)_m, "primitiveRemLargeIntegers\000\000\000", (void*)primitiveRemLargeIntegers}, {(void*)_m, "primitiveScreenDepth\000\377\000", (void*)primitiveScreenDepth}, diff --git a/spurlowcodesrc/vm/cointerp.h b/spurlowcodesrc/vm/cointerp.h index 791d00da8a..4e259dd493 100644 --- a/spurlowcodesrc/vm/cointerp.h +++ b/spurlowcodesrc/vm/cointerp.h @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ @@ -50,6 +50,7 @@ extern sqInt ceSendabovetonumArgs(sqInt selector, sqInt methodClass, sqInt rcvr, extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern sqInt ceSistaTrap(void); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethod); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); @@ -249,7 +250,7 @@ extern sqInt minSlotsForShortening(void); extern sqInt nilObject(void); extern sqInt nonIndexablePointerFormat(void); extern sqInt numBytesOf(sqInt objOop); -extern sqInt numPointerSlotsOf(sqInt objOop); +extern usqInt numPointerSlotsOf(sqInt objOop); extern usqInt numSlotsOf(sqInt objOop); extern sqInt numStrongSlotsOfWeakling(sqInt objOop); extern sqInt objectAfter(sqInt objOop); diff --git a/spurlowcodesrc/vm/gcc3x-cointerp.c b/spurlowcodesrc/vm/gcc3x-cointerp.c index d2fccae4f0..e4ec652aa4 100644 --- a/spurlowcodesrc/vm/gcc3x-cointerp.c +++ b/spurlowcodesrc/vm/gcc3x-cointerp.c @@ -2,11 +2,11 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - CoInterpreter VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CoInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 " __DATE__ ; +static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -493,6 +493,7 @@ extern sqInt ceSendabovetonumArgs(sqInt selector, sqInt methodClass, sqInt rcvr, extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern sqInt ceSistaTrap(void); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethod); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); @@ -674,7 +675,6 @@ static void primitiveExitCriticalSection(void); static void primitiveFlushCacheByMethod(void); static void primitiveFlushCacheBySelector(void); extern usqInt primitiveFunctionPointerAddress(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); EXPORT(sqInt) primitiveMethodPCData(void); static void primitiveMethodXray(void); EXPORT(void) primitiveMinimumUnusedHeadroom(void); @@ -1198,7 +1198,6 @@ static sqInt NoDbgRegParms isPureBitsFormat(sqInt format); extern sqInt isReallyYoung(sqInt oop); static sqInt NoDbgRegParms isRemembered(sqInt objOop); static sqInt NoDbgRegParms isSegmentBridge(sqInt objOop); -static sqInt NoDbgRegParms isSemaphoreOop(sqInt anOop); extern sqInt isShorts(sqInt oop); extern sqInt isUnambiguouslyForwarder(sqInt objOop); extern sqInt isUnmarked(sqInt objOop); @@ -1265,7 +1264,7 @@ static sqInt NoDbgRegParms num64BitUnitsOf(sqInt objOop); static sqInt NoDbgRegParms numBytesOfBitsformat(sqInt objOop, sqInt format); static sqInt NoDbgRegParms numBytesOfBytes(sqInt objOop); extern sqInt numBytesOf(sqInt objOop); -extern sqInt numPointerSlotsOf(sqInt objOop); +extern usqInt numPointerSlotsOf(sqInt objOop); static usqInt NoDbgRegParms numSlotsOfAny(sqInt objOop); extern usqInt numSlotsOf(sqInt objOop); static sqInt NoDbgRegParms numStrongSlotsOfInephemeral(sqInt objOop); @@ -1428,7 +1427,6 @@ EXPORT(sqInt) callbackLeave(sqInt cbID); extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHeader); extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkForEventsMayContextSwitch(sqInt mayContextSwitch); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); @@ -1716,7 +1714,6 @@ static sqInt NoDbgRegParms updateDisplayLeftTopRightBottom(sqInt l, sqInt t, sqI static sqInt NoDbgRegParms validBCPCinMethod(sqInt thePC, usqInt aMethod); static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, char *fp); static sqInt validStackPageBaseFrames(void); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt wakeHighestPriority(void); static sqInt NeverInline writeImageFileIO(void); static usqInt NoDbgRegParms cloneContext(sqInt aContext); @@ -1739,7 +1736,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1816,15 +1812,14 @@ _iss usqInt lastMobileObject; _iss sqInt tempOop; _iss sqInt numClassTablePages; _iss sqInt lkupClass; -_iss sqInt futureSurvivorStart; _iss sqInt profileProcess; -_iss sqInt profileSemaphore; +_iss sqInt futureSurvivorStart; _iss sqInt mournQueue; _iss sqInt numRememberedEphemerons; +_iss sqInt profileMethod; _iss sqInt jmpDepth; _iss sqInt mobileStart; -_iss sqInt profileMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; +_iss sqInt profileSemaphore; _iss sqInt growHeadroom; _iss sqInt tenureThreshold; _iss sqInt lastCoggableInterpretedBlockMethod; @@ -1832,7 +1827,6 @@ _iss sqInt lastUncoggableInterpretedBlockMethod; _iss char * objStackInvalidBecause; _iss sqInt sweepIndex; _iss sqInt ephemeronList; -_iss sqInt longRunningPrimitiveCheckMethod; _iss sqInt tenureCriterion; _iss usqInt totalHeapSizeIncludingBridges; _iss sqInt becomeEffectsFlags; @@ -1888,7 +1882,6 @@ _iss sqInt freeSpaceCheckOopToIgnore; _iss usqInt heapSizeAtPreviousGC; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss sqInt methodDictLinearSearchLimit; _iss sqInt statGrowMemory; _iss sqInt statMaxPageCountWhenMapping; @@ -1900,7 +1893,6 @@ _iss sqInt extraFramesToMoveOnOverflow; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; _iss sqInt inFFIFlags; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss sqInt refCountToShrinkRT; _iss sqInt signalLowSpace; @@ -1930,16 +1922,14 @@ _iss sqInt preferredPinningSegment; _iss sqInt statCoalesces; _iss sqInt theUnknownShort; _iss usqLong nextWakeupUsecs; -_iss usqLong statGCEndUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; -_iss usqLong statCheckForEvents; -_iss usqLong gcStartUsecs; _iss sqLong oldSpaceUsePriorToScavenge; +_iss usqLong statGCEndUsecs; _iss usqLong statIOProcessEvents; +_iss usqLong gcStartUsecs; _iss usqLong statAllocatedBytes; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statCompactionUsecs; _iss usqLong statForceInterruptCheck; _iss usqLong statFullGCUsecs; @@ -1953,9 +1943,11 @@ _iss usqLong statSweepUsecs; _iss usqLong statCodeCompactionUsecs; _iss usqLong statSGCDeltaUsecs; _iss usqLong gcSweepEndUsecs; -_iss usqLong longRunningPrimitiveGCUsecs; _iss usqLong statIGCDeltaUsecs; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; _iss usqLong statFGCDeltaUsecs; _iss usqLong statIncrGCUsecs; _iss SpurContiguousObjStack savedFirstFieldsSpace; @@ -2632,7 +2624,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Open Smalltalk Cog[Spur] VM [CoInterpreterPrimitives VMMaker.oscog-eem.3024]"; +const char *interpreterVersion = "Open Smalltalk Cog[Spur] VM [CoInterpreterPrimitives VMMaker.oscog-eem.3031]"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */; char primitiveDoMixedArithmetic = 1; char expensiveAsserts = 0; @@ -35097,6 +35089,27 @@ ceStackOverflow(sqInt contextSwitchIfNotNil) error("should not be reached"); } + +/* A primitive has succeeded and the nextProfileTick has been reached (all + done in machine code). + Now take a sample. c.f. checkProfileTick: */ + + /* CoInterpreter>>#ceTakeProfileSample: */ +void +ceTakeProfileSample(CogMethod *aCogMethod) +{ DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt objOop; + sqInt objOop1; + + /* begin fetchPointer:ofObject: */ + objOop1 = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(SchedulerAssociation) << (shiftForWord()))))); + objOop = longAt((objOop1 + BaseHeaderSize) + (((int)((usqInt)(ValueIndex) << (shiftForWord()))))); + GIV(profileProcess) = longAt((objOop + BaseHeaderSize) + (((int)((usqInt)(ActiveProcessIndex) << (shiftForWord()))))); + GIV(profileMethod) = (aCogMethod->methodObject); + forceInterruptCheck(); + GIV(nextProfileTick) = 0; +} + /* CoInterpreter>>#ceTraceBlockActivation */ void ceTraceBlockActivation(void) @@ -37095,24 +37108,6 @@ void forceInterruptCheckFromHeartbeat(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; sqLowLevelMFence(); if (GIV(deferSmash)) { GIV(deferredSmash) = 1; @@ -43573,56 +43568,6 @@ primitiveFunctionPointerAddress(void) return ((usqInt)((&primitiveFunctionPointer))); } - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* CoInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; - int flushState; - sqInt sema; - char *sp; - - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (sema == GIV(nilObj)) { - flushState = GIV(longRunningPrimitiveCheckSemaphore) != null; - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - flushState = GIV(longRunningPrimitiveCheckSemaphore) == null; - if (!(((!(sema & (tagMask())))) - && (((longAt(sema)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(ClassSemaphore) << (shiftForWord())))))))))) { - return (GIV(primFailCode) = PrimErrBadArgument); - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(longRunningPrimitiveCheckSemaphore) == null)) - || (((stackValue(0)) == GIV(longRunningPrimitiveCheckSemaphore)) - && (isSemaphoreOop(sema)))); - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - if (flushState) { - ceInvokeInterpret(); - } - return 0; -} - /* CoInterpreterPrimitives>>#primitiveMethodPCData */ EXPORT(sqInt) primitiveMethodPCData(void) @@ -43935,14 +43880,9 @@ primitiveObjectAtPut(void) EXPORT(sqInt) primitiveProfileSemaphore(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; int flushState; sqInt sema; - char *sp; - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); if (sema == GIV(nilObj)) { flushState = GIV(profileSemaphore) != GIV(nilObj); @@ -43954,28 +43894,21 @@ primitiveProfileSemaphore(void) return (GIV(primFailCode) = PrimErrBadArgument); } } + GIV(profileSemaphore) = sema; /* If we've switched profiling on or off we must void machine code (and machine code pcs in contexts) since we will start or stop testing the profile clock in machine code primitive invocations, and so generate slightly different code from here on in. */ - GIV(profileSemaphore) = sema; - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(profileSemaphore) == (nilObject()))) - || (((stackValue(0)) == GIV(profileSemaphore)) - && (isSemaphoreOop(sema)))); - } GIV(profileProcess) = (GIV(profileMethod) = GIV(nilObj)); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; if (flushState) { - ceInvokeInterpret(); + flushExternalPrimitives(); + } + else { + /* begin methodReturnReceiver */ + assert(!((failed()))); + /* begin pop: */ + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; } return 0; } @@ -52680,26 +52613,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -53468,7 +53403,7 @@ primitiveInvokeObjectAsMethod(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt i; sqInt lookupClassTag; - usqInt runArgs; + sqInt runArgs; sqInt runReceiver; char *sp; char *sp1; @@ -55405,15 +55340,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -55431,15 +55361,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -55463,39 +55388,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((integerPointer & 1)) { - deltaTicks = (integerPointer >> 1); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((deltaTicks & 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 1)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -58932,7 +58836,7 @@ followForwardedObjectFieldstoDepth(sqInt objOop, sqInt depth) sqInt header1; sqInt i; sqInt numLiterals; - sqInt numSlots; + usqInt numSlots; usqInt numSlots1; sqInt oop; sqInt referent; @@ -66267,7 +66171,7 @@ copyObjtoAddrstopAtsavedFirstFieldsindex(sqInt objOop, sqInt segAddr, sqInt endS sqInt iLimiT; sqInt methodHeader; sqInt numLiterals; - sqInt numMediatedSlots; + usqInt numMediatedSlots; usqInt numSlots; usqInt numSlots1; sqInt oop; @@ -66299,7 +66203,7 @@ copyObjtoAddrstopAtsavedFirstFieldsindex(sqInt objOop, sqInt segAddr, sqInt endS here but that requires access to framePointer. */ /* begin numSlotsOfMarriedContext: */ contextSize = stackPointerIndexForFrame(frameOfMarriedContext(objOop)); - numMediatedSlots = CtxtTempFrameStart + contextSize; + numMediatedSlots = ((sqInt) (CtxtTempFrameStart + contextSize)); for (i1 = 0; i1 < numMediatedSlots; i1 += 1) { oop = fetchPointerofMarriedContext(i1, objOop); assert(!(isOopForwarded(copy))); @@ -69645,14 +69549,6 @@ isSegmentBridge(sqInt objOop) return ((longAt(objOop)) & (classIndexMask())) == (segmentBridgePun()); } - /* SpurMemoryManager>>#isSemaphoreOop: */ -static sqInt NoDbgRegParms -isSemaphoreOop(sqInt anOop) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - return ((!(anOop & (tagMask())))) - && (((longAt(anOop)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(ClassSemaphore) << (shiftForWord())))))))); -} - /* Answer if the argument contains only indexable 16-bit half words (no oops). See comment in formatOf: @@ -71920,8 +71816,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) sqInt referent; sqInt referent1; sqInt referent2; - sqInt referent3; - sqInt referent4; sqInt sizeOfUnusedEden; StackPage *thePage; @@ -72049,38 +71943,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - if ((!((longAt(GIV(longRunningPrimitiveCheckMethod))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckMethod))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((GIV(longRunningPrimitiveCheckMethod) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent3 & (tagMask())))) - && ((!((longAt(referent3)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((referent3 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckMethod) = referent3; - } - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - if ((!((longAt(GIV(longRunningPrimitiveCheckSemaphore))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckSemaphore))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((GIV(longRunningPrimitiveCheckSemaphore) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent4 & (tagMask())))) - && ((!((longAt(referent4)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((referent4 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckSemaphore) = referent4; - } - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -72768,7 +72630,7 @@ numBytesOf(sqInt objOop) Works with CompiledMethods, as well as ordinary objects. */ /* SpurMemoryManager>>#numPointerSlotsOf: */ -sqInt +usqInt numPointerSlotsOf(sqInt objOop) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt contextSize; @@ -75763,7 +75625,7 @@ printReferencesTo(sqInt anOop) assert((ReceiverIndex + ((sp >> 1))) < (lengthOf(obj1))); contextSize = (sp >> 1); l9: /* end fetchStackPointerOf: */; - i = CtxtTempFrameStart + contextSize; + i = ((usqInt) (CtxtTempFrameStart + contextSize)); goto l10; } /* begin numSlotsOf: */ @@ -75796,7 +75658,7 @@ printReferencesTo(sqInt anOop) /* begin literalCountOfMethodHeader: */ assert((header & 1)); numLiterals = ((header >> 1)) & AlternateHeaderNumLiteralsMask; - i = numLiterals + LiteralStart; + i = ((usqInt) (numLiterals + LiteralStart)); l10: /* end numPointerSlotsOf: */; while (((i -= 1)) >= 0) { if (anOop == (longAt((obj1 + BaseHeaderSize) + (((sqInt)((usqInt)(i) << (shiftForWord()))))))) { @@ -78950,10 +78812,10 @@ updatePointers(void) sqInt numLiterals1; sqInt numLiterals2; sqInt numLiterals3; - sqInt numPointerSlots; - sqInt numPointerSlots1; - sqInt numPointerSlots2; - sqInt numPointerSlots3; + usqInt numPointerSlots; + usqInt numPointerSlots1; + usqInt numPointerSlots2; + usqInt numPointerSlots3; usqInt numSlots; usqInt numSlots1; usqInt numSlots11; @@ -79531,7 +79393,7 @@ updatePointersInsavedFirstFieldPointer(sqInt obj, sqInt firstFieldPtr) assert((ReceiverIndex + ((sp >> 1))) < (lengthOf(obj))); contextSize = (sp >> 1); l6: /* end fetchStackPointerOf: */; - numPointerSlots = CtxtTempFrameStart + contextSize; + numPointerSlots = ((usqInt) (CtxtTempFrameStart + contextSize)); goto l10; } /* begin numSlotsOf: */ @@ -79561,7 +79423,7 @@ updatePointersInsavedFirstFieldPointer(sqInt obj, sqInt firstFieldPtr) /* begin literalCountOfMethodHeader: */ assert((header & 1)); numLiterals = ((header >> 1)) & AlternateHeaderNumLiteralsMask; - numPointerSlots = numLiterals + LiteralStart; + numPointerSlots = ((usqInt) (numLiterals + LiteralStart)); l10: /* end numPointerSlotsWhileCompactingOf:withFormat:savedFirstFieldPointer: */; if ((fmt <= 5 /* lastPointerFormat */) && (numPointerSlots > 0)) { @@ -80112,7 +79974,7 @@ prepareForSnapshot(void) sqInt limit; sqInt newEndOfMemory; sqInt next; - sqInt node; + usqInt node; SpurSegmentInfo *seg; sqInt smallChild; sqInt treeNode; @@ -80943,33 +80805,6 @@ checkAllAccessibleObjectsOkay(void) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -81060,9 +80895,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { /* begin signalLowSpace: */ GIV(signalLowSpace) = 0; @@ -86156,23 +85988,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i = 1; i <= GIV(jmpDepth); i += 1) { oop = GIV(suspendedCallbacks)[i]; @@ -90083,8 +89898,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -90113,18 +89928,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -93357,22 +93174,6 @@ validStackPageBaseFrames(void) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Return the highest priority process that is ready to run. To save time looking at many empty lists before finding a runnable process the VM maintains a variable holding the @@ -96002,74 +95803,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((addressCouldBeObj(lrpcm)) - && ((!(((longAt(lrpcm)) & (classIndexMask())) == (isFreeObjectClassIndexPun()))) - && (((((usqInt)((longAt(lrpcm)))) >> (formatShift())) & (formatMask())) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - assert(!(isForwarded(result))); - if ((assert(isNonImmediate(result)), - oopisGreaterThanOrEqualTo(result, GIV(oldSpaceStart)))) { - - /* most stores into young objects */ - if (((!(lrpcm & (tagMask())))) - && (oopisLessThan(lrpcm, GIV(newSpaceLimit)))) { - /* begin possibleRootStoreInto: */ - if (!(((((usqInt)((longAt(result)))) >> (rememberedBitShift())) & 1) != 0)) { - remember(result); - } - } - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 1) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 1) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -98563,15 +98296,13 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveGreaterOrEqualLargeIntegers\000\377\000", (void*)primitiveGreaterOrEqualLargeIntegers}, {(void*)_m, "primitiveGreaterThanLargeIntegers\000\377\000", (void*)primitiveGreaterThanLargeIntegers}, {(void*)_m, "primitiveHeartbeatFrequency\000\377\000", (void*)primitiveHeartbeatFrequency}, - {(void*)_m, "primitiveHighResClock\000\377\000", (void*)primitiveHighResClock}, + {(void*)_m, "primitiveHighResClock\000\377\001", (void*)primitiveHighResClock}, {(void*)_m, "primitiveImageFormatVersion\000\377\000", (void*)primitiveImageFormatVersion}, {(void*)_m, "primitiveInterruptChecksPerMSec\000\377\000", (void*)primitiveInterruptChecksPerMSec}, {(void*)_m, "primitiveIsBigEnder\000\377\000", (void*)primitiveIsBigEnder}, {(void*)_m, "primitiveIsWindowObscured\000\377\000", (void*)primitiveIsWindowObscured}, {(void*)_m, "primitiveLessOrEqualLargeIntegers\000\377\000", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers\000\377\000", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive\000\377\000", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore\000\000\000", (void*)primitiveLongRunningPrimitiveSemaphore}, {(void*)_m, "primitiveMethodPCData\000\000\000", (void*)primitiveMethodPCData}, {(void*)_m, "primitiveMillisecondClockMask\000\377\000", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveMinimumUnusedHeadroom\000\377\000", (void*)primitiveMinimumUnusedHeadroom}, @@ -98579,10 +98310,10 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveMultiplyLargeIntegers\000\000\000", (void*)primitiveMultiplyLargeIntegers}, {(void*)_m, "primitiveNotEqualLargeIntegers\000\377\000", (void*)primitiveNotEqualLargeIntegers}, {(void*)_m, "primitivePathToUsing\000\000\000", (void*)primitivePathToUsing}, - {(void*)_m, "primitiveProfilePrimitive\000\377\000", (void*)primitiveProfilePrimitive}, - {(void*)_m, "primitiveProfileSample\000\377\000", (void*)primitiveProfileSample}, + {(void*)_m, "primitiveProfilePrimitive\000\377\001", (void*)primitiveProfilePrimitive}, + {(void*)_m, "primitiveProfileSample\000\377\001", (void*)primitiveProfileSample}, {(void*)_m, "primitiveProfileSemaphore\000\000\000", (void*)primitiveProfileSemaphore}, - {(void*)_m, "primitiveProfileStart\000\000\000", (void*)primitiveProfileStart}, + {(void*)_m, "primitiveProfileStart\000\000\001", (void*)primitiveProfileStart}, {(void*)_m, "primitiveQuoLargeIntegers\000\000\000", (void*)primitiveQuoLargeIntegers}, {(void*)_m, "primitiveRemLargeIntegers\000\000\000", (void*)primitiveRemLargeIntegers}, {(void*)_m, "primitiveScreenDepth\000\377\000", (void*)primitiveScreenDepth}, diff --git a/spurlowcodestack64src/vm/gcc3x-interp.c b/spurlowcodestack64src/vm/gcc3x-interp.c index 8cca012c36..c33731773c 100644 --- a/spurlowcodestack64src/vm/gcc3x-interp.c +++ b/spurlowcodestack64src/vm/gcc3x-interp.c @@ -2,11 +2,11 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - StackInterpreter VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 + StackInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 " __DATE__ ; +static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -1148,7 +1148,6 @@ extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHea extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); static sqInt NoDbgRegParms checkCodeIntegrity(sqInt fullGCFlag); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkForEventsMayContextSwitch(sqInt mayContextSwitch); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); @@ -1478,7 +1477,6 @@ static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, extern sqInt validInstructionPointerinMethodframePointer(usqInt theInstrPointer, usqInt aMethod, char *fp); static sqInt validStackPageBaseFrames(void); static sqInt NoDbgRegParms validStackPageBaseFrame(StackPage *aPage); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt NoDbgRegParms voidVMStateForSnapshotFlushingExternalPrimitivesIf(sqInt flushExtPrims); static sqInt wakeHighestPriority(void); EXPORT(char *) whereIs(sqInt anOop); @@ -1509,8 +1507,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1539,15 +1535,15 @@ _iss char * stackPointer; _iss sqInt primFailCode; _iss usqInt method; _iss StackPage * stackPage; -_iss sqInt nilObj; _iss sqInt argumentCount; +_iss sqInt nilObj; _iss sqInt bytecodeSetSelector; _iss char * framePointer; _iss usqInt freeStart; _iss usqInt oldSpaceStart; _iss sqInt specialObjectsOop; -_iss usqInt newMethod; _iss usqInt pastSpaceStart; +_iss usqInt newMethod; _iss usqInt newSpaceLimit; _iss sqInt messageSelector; _iss usqInt instructionPointer; @@ -1596,8 +1592,6 @@ _iss char * objStackInvalidBecause; _iss sqInt sweepIndex; _iss sqInt ephemeronList; _iss sqInt imageHeaderFlags; -_iss sqInt longRunningPrimitiveCheckMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; _iss sqInt profileSemaphore; _iss sqInt tenureCriterion; _iss usqInt totalHeapSizeIncludingBridges; @@ -1619,20 +1613,16 @@ _iss sqInt numSegInfos; _iss sqInt savedFirstFieldsSpaceNotInOldSpace; _iss sqInt highestRunnableProcessPriority; _iss usqLong nextWakeupUsecs; -_iss usqLong statGCEndUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; _iss sqInt metaclassNumSlots; _iss sqInt shrinkThreshold; -_iss usqLong statCheckForEvents; _iss sqInt statTenures; _iss sqInt weakList; _iss sqInt externalPrimitiveTableFirstFreeIndex; -_iss usqLong gcStartUsecs; _iss sqInt marking; _iss sqLong oldSpaceUsePriorToScavenge; _iss sqInt preemptionYields; _iss sqInt rememberedSetLimit; +_iss usqLong statGCEndUsecs; _iss sqInt statSurvivorCount; _iss sqInt thisClassIndex; _iss sqInt firstFieldOfRememberedSet; @@ -1646,6 +1636,7 @@ _iss sqInt statShrinkMemory; _iss sqInt biasForGC; _iss sqInt edenBytes; _iss sqInt fullScreenFlag; +_iss usqLong gcStartUsecs; _iss usqInt lastHash; _iss sqInt lastMethodCacheProbeWrite; _iss sqInt newFinalization; @@ -1659,9 +1650,9 @@ _iss sqInt freeSpaceCheckOopToIgnore; _iss usqInt heapSizeAtPreviousGC; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statCompactionUsecs; _iss usqLong statForceInterruptCheck; _iss usqLong statFullGCUsecs; @@ -1681,7 +1672,6 @@ _iss sqInt gcSemaphoreIndex; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; _iss sqInt inFFIFlags; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss sqInt methodDictLinearSearchLimit; _iss sqInt refCountToShrinkRT; @@ -1693,7 +1683,6 @@ _iss sqInt bogon; _iss sqInt classByteArrayCompactIndex; _iss usqInt exceptionPC; _iss usqLong gcSweepEndUsecs; -_iss usqLong longRunningPrimitiveGCUsecs; _iss sqInt overflowLimit; _iss StackPage * overflowedPage; _iss sqInt statCompactPassCount; @@ -1712,6 +1701,9 @@ _iss usqInt suspendedCallbacks[MaxJumpBuf + 1 /* 33 */]; _iss usqInt suspendedMethods[MaxJumpBuf + 1 /* 33 */]; _iss jmp_buf jmpBuf[MaxJumpBuf + 1 /* 33 */]; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; _iss sqInt preferredPinningSegment; _iss sqInt statCoalesces; _iss usqLong statFGCDeltaUsecs; @@ -2383,7 +2375,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Open Smalltalk Stack VM [StackInterpreterPrimitives VMMaker.oscog-eem.3022]"; +const char *interpreterVersion = "Open Smalltalk Stack VM [StackInterpreterPrimitives VMMaker.oscog-eem.3031]"; sqInt suppressHeartbeatFlag; int displayWidth; int displayDepth; @@ -32638,26 +32630,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -35689,15 +35683,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -35715,15 +35704,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -35776,39 +35760,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((((integerPointer) & 7) == 1)) { - deltaTicks = (integerPointer >> 3); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((((deltaTicks) & 7) == 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 3)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -53776,8 +53739,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) sqInt referent; sqInt referent1; sqInt referent2; - sqInt referent3; - sqInt referent4; sqInt sizeOfUnusedEden; StackPage *thePage; @@ -53914,38 +53875,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - if ((!((longAt(GIV(longRunningPrimitiveCheckMethod))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckMethod))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((GIV(longRunningPrimitiveCheckMethod) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent3 & (tagMask())))) - && ((!((longAt(referent3)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((referent3 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckMethod) = referent3; - } - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - if ((!((longAt(GIV(longRunningPrimitiveCheckSemaphore))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckSemaphore))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((GIV(longRunningPrimitiveCheckSemaphore) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent4 & (tagMask())))) - && ((!((longAt(referent4)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((referent4 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckSemaphore) = referent4; - } - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -63053,33 +62982,6 @@ checkCodeIntegrity(sqInt fullGCFlag) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -63166,9 +63068,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { /* begin signalLowSpace: */ GIV(signalLowSpace) = 0; @@ -65980,26 +65879,8 @@ forceInterruptCheck(void) /* StackInterpreter>>#forceInterruptCheckFromHeartbeat */ void forceInterruptCheckFromHeartbeat(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT +{ if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; forceInterruptCheck(); } } @@ -68492,23 +68373,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i = 1; i <= GIV(jmpDepth); i += 1) { oop = GIV(suspendedCallbacks)[i]; @@ -72759,8 +72623,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -72789,18 +72653,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -77158,22 +77024,6 @@ validStackPageBaseFrame(StackPage *aPage) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Make sure that all VM state that affects the heap contents is voided so that the heap is ready to be snapshotted. If flushExtPrims is true, flush references to @@ -80268,115 +80118,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((addressCouldBeObj(lrpcm)) - && ((!(((longAt(lrpcm)) & (classIndexMask())) == (isFreeObjectClassIndexPun()))) - && (((((usqInt)((longAt(lrpcm)))) >> (formatShift())) & (formatMask())) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - assert(!(isForwarded(result))); - if ((assert(isNonImmediate(result)), - oopisGreaterThanOrEqualTo(result, GIV(oldSpaceStart)))) { - - /* most stores into young objects */ - if (((!(lrpcm & (tagMask())))) - && (oopisLessThan(lrpcm, GIV(newSpaceLimit)))) { - /* begin possibleRootStoreInto: */ - if (!(((((usqInt)((longAt(result)))) >> (rememberedBitShift())) & 1) != 0)) { - remember(result); - } - } - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 3) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 3) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt sema; - - /* begin stackValue: */ - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (((((sema) & 7) == 1)) - || (GIV(argumentCount) != 1)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - if (sema == GIV(nilObj)) { - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - if (!(((!(sema & (tagMask())))) - && (((longAt(sema)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(ClassSemaphore) << (shiftForWord())))))))))) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -83300,24 +83041,22 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveGreaterOrEqualLargeIntegers\000\377\000", (void*)primitiveGreaterOrEqualLargeIntegers}, {(void*)_m, "primitiveGreaterThanLargeIntegers\000\377\000", (void*)primitiveGreaterThanLargeIntegers}, {(void*)_m, "primitiveHeartbeatFrequency\000\377\000", (void*)primitiveHeartbeatFrequency}, - {(void*)_m, "primitiveHighResClock\000\377\000", (void*)primitiveHighResClock}, + {(void*)_m, "primitiveHighResClock\000\377\001", (void*)primitiveHighResClock}, {(void*)_m, "primitiveImageFormatVersion\000\377\000", (void*)primitiveImageFormatVersion}, {(void*)_m, "primitiveInterruptChecksPerMSec\000\377\000", (void*)primitiveInterruptChecksPerMSec}, {(void*)_m, "primitiveIsBigEnder\000\377\000", (void*)primitiveIsBigEnder}, {(void*)_m, "primitiveIsWindowObscured\000\377\000", (void*)primitiveIsWindowObscured}, {(void*)_m, "primitiveLessOrEqualLargeIntegers\000\377\000", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers\000\377\000", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive\000\377\000", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore\000\000\000", (void*)primitiveLongRunningPrimitiveSemaphore}, {(void*)_m, "primitiveMillisecondClockMask\000\377\000", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveModLargeIntegers\000\000\000", (void*)primitiveModLargeIntegers}, {(void*)_m, "primitiveMultiplyLargeIntegers\000\000\000", (void*)primitiveMultiplyLargeIntegers}, {(void*)_m, "primitiveNotEqualLargeIntegers\000\377\000", (void*)primitiveNotEqualLargeIntegers}, {(void*)_m, "primitivePathToUsing\000\000\000", (void*)primitivePathToUsing}, - {(void*)_m, "primitiveProfilePrimitive\000\377\000", (void*)primitiveProfilePrimitive}, - {(void*)_m, "primitiveProfileSample\000\377\000", (void*)primitiveProfileSample}, + {(void*)_m, "primitiveProfilePrimitive\000\377\001", (void*)primitiveProfilePrimitive}, + {(void*)_m, "primitiveProfileSample\000\377\001", (void*)primitiveProfileSample}, {(void*)_m, "primitiveProfileSemaphore\000\000\000", (void*)primitiveProfileSemaphore}, - {(void*)_m, "primitiveProfileStart\000\000\000", (void*)primitiveProfileStart}, + {(void*)_m, "primitiveProfileStart\000\000\001", (void*)primitiveProfileStart}, {(void*)_m, "primitiveQuoLargeIntegers\000\000\000", (void*)primitiveQuoLargeIntegers}, {(void*)_m, "primitiveRemLargeIntegers\000\000\000", (void*)primitiveRemLargeIntegers}, {(void*)_m, "primitiveScreenDepth\000\377\000", (void*)primitiveScreenDepth}, diff --git a/spurlowcodestack64src/vm/interp.c b/spurlowcodestack64src/vm/interp.c index fa8b5c9c75..594ca9b758 100644 --- a/spurlowcodestack64src/vm/interp.c +++ b/spurlowcodestack64src/vm/interp.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - StackInterpreter VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 + StackInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 " __DATE__ ; +static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -1145,7 +1145,6 @@ extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHea extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); static sqInt NoDbgRegParms checkCodeIntegrity(sqInt fullGCFlag); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkForEventsMayContextSwitch(sqInt mayContextSwitch); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); @@ -1475,7 +1474,6 @@ static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, extern sqInt validInstructionPointerinMethodframePointer(usqInt theInstrPointer, usqInt aMethod, char *fp); static sqInt validStackPageBaseFrames(void); static sqInt NoDbgRegParms validStackPageBaseFrame(StackPage *aPage); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt NoDbgRegParms voidVMStateForSnapshotFlushingExternalPrimitivesIf(sqInt flushExtPrims); static sqInt wakeHighestPriority(void); EXPORT(char *) whereIs(sqInt anOop); @@ -1506,8 +1504,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1536,15 +1532,15 @@ _iss char * stackPointer; _iss sqInt primFailCode; _iss usqInt method; _iss StackPage * stackPage; -_iss sqInt nilObj; _iss sqInt argumentCount; +_iss sqInt nilObj; _iss sqInt bytecodeSetSelector; _iss char * framePointer; _iss usqInt freeStart; _iss usqInt oldSpaceStart; _iss sqInt specialObjectsOop; -_iss usqInt newMethod; _iss usqInt pastSpaceStart; +_iss usqInt newMethod; _iss usqInt newSpaceLimit; _iss sqInt messageSelector; _iss usqInt instructionPointer; @@ -1593,8 +1589,6 @@ _iss char * objStackInvalidBecause; _iss sqInt sweepIndex; _iss sqInt ephemeronList; _iss sqInt imageHeaderFlags; -_iss sqInt longRunningPrimitiveCheckMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; _iss sqInt profileSemaphore; _iss sqInt tenureCriterion; _iss usqInt totalHeapSizeIncludingBridges; @@ -1616,20 +1610,16 @@ _iss sqInt numSegInfos; _iss sqInt savedFirstFieldsSpaceNotInOldSpace; _iss sqInt highestRunnableProcessPriority; _iss usqLong nextWakeupUsecs; -_iss usqLong statGCEndUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; _iss sqInt metaclassNumSlots; _iss sqInt shrinkThreshold; -_iss usqLong statCheckForEvents; _iss sqInt statTenures; _iss sqInt weakList; _iss sqInt externalPrimitiveTableFirstFreeIndex; -_iss usqLong gcStartUsecs; _iss sqInt marking; _iss sqLong oldSpaceUsePriorToScavenge; _iss sqInt preemptionYields; _iss sqInt rememberedSetLimit; +_iss usqLong statGCEndUsecs; _iss sqInt statSurvivorCount; _iss sqInt thisClassIndex; _iss sqInt firstFieldOfRememberedSet; @@ -1643,6 +1633,7 @@ _iss sqInt statShrinkMemory; _iss sqInt biasForGC; _iss sqInt edenBytes; _iss sqInt fullScreenFlag; +_iss usqLong gcStartUsecs; _iss usqInt lastHash; _iss sqInt lastMethodCacheProbeWrite; _iss sqInt newFinalization; @@ -1656,9 +1647,9 @@ _iss sqInt freeSpaceCheckOopToIgnore; _iss usqInt heapSizeAtPreviousGC; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statCompactionUsecs; _iss usqLong statForceInterruptCheck; _iss usqLong statFullGCUsecs; @@ -1678,7 +1669,6 @@ _iss sqInt gcSemaphoreIndex; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; _iss sqInt inFFIFlags; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss sqInt methodDictLinearSearchLimit; _iss sqInt refCountToShrinkRT; @@ -1690,7 +1680,6 @@ _iss sqInt bogon; _iss sqInt classByteArrayCompactIndex; _iss usqInt exceptionPC; _iss usqLong gcSweepEndUsecs; -_iss usqLong longRunningPrimitiveGCUsecs; _iss sqInt overflowLimit; _iss StackPage * overflowedPage; _iss sqInt statCompactPassCount; @@ -1709,6 +1698,9 @@ _iss usqInt suspendedCallbacks[MaxJumpBuf + 1 /* 33 */]; _iss usqInt suspendedMethods[MaxJumpBuf + 1 /* 33 */]; _iss jmp_buf jmpBuf[MaxJumpBuf + 1 /* 33 */]; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; _iss sqInt preferredPinningSegment; _iss sqInt statCoalesces; _iss usqLong statFGCDeltaUsecs; @@ -2380,7 +2372,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Open Smalltalk Stack VM [StackInterpreterPrimitives VMMaker.oscog-eem.3022]"; +const char *interpreterVersion = "Open Smalltalk Stack VM [StackInterpreterPrimitives VMMaker.oscog-eem.3031]"; sqInt suppressHeartbeatFlag; int displayWidth; int displayDepth; @@ -32629,26 +32621,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -35680,15 +35674,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -35706,15 +35695,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -35767,39 +35751,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((((integerPointer) & 7) == 1)) { - deltaTicks = (integerPointer >> 3); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((((deltaTicks) & 7) == 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 3)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -53767,8 +53730,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) sqInt referent; sqInt referent1; sqInt referent2; - sqInt referent3; - sqInt referent4; sqInt sizeOfUnusedEden; StackPage *thePage; @@ -53905,38 +53866,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - if ((!((longAt(GIV(longRunningPrimitiveCheckMethod))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckMethod))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((GIV(longRunningPrimitiveCheckMethod) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent3 & (tagMask())))) - && ((!((longAt(referent3)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((referent3 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckMethod) = referent3; - } - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - if ((!((longAt(GIV(longRunningPrimitiveCheckSemaphore))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckSemaphore))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((GIV(longRunningPrimitiveCheckSemaphore) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent4 & (tagMask())))) - && ((!((longAt(referent4)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((referent4 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckSemaphore) = referent4; - } - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -63044,33 +62973,6 @@ checkCodeIntegrity(sqInt fullGCFlag) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -63157,9 +63059,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { /* begin signalLowSpace: */ GIV(signalLowSpace) = 0; @@ -65971,26 +65870,8 @@ forceInterruptCheck(void) /* StackInterpreter>>#forceInterruptCheckFromHeartbeat */ void forceInterruptCheckFromHeartbeat(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT +{ if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; forceInterruptCheck(); } } @@ -68483,23 +68364,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i = 1; i <= GIV(jmpDepth); i += 1) { oop = GIV(suspendedCallbacks)[i]; @@ -72750,8 +72614,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -72780,18 +72644,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -77149,22 +77015,6 @@ validStackPageBaseFrame(StackPage *aPage) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Make sure that all VM state that affects the heap contents is voided so that the heap is ready to be snapshotted. If flushExtPrims is true, flush references to @@ -80259,115 +80109,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((addressCouldBeObj(lrpcm)) - && ((!(((longAt(lrpcm)) & (classIndexMask())) == (isFreeObjectClassIndexPun()))) - && (((((usqInt)((longAt(lrpcm)))) >> (formatShift())) & (formatMask())) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - assert(!(isForwarded(result))); - if ((assert(isNonImmediate(result)), - oopisGreaterThanOrEqualTo(result, GIV(oldSpaceStart)))) { - - /* most stores into young objects */ - if (((!(lrpcm & (tagMask())))) - && (oopisLessThan(lrpcm, GIV(newSpaceLimit)))) { - /* begin possibleRootStoreInto: */ - if (!(((((usqInt)((longAt(result)))) >> (rememberedBitShift())) & 1) != 0)) { - remember(result); - } - } - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 3) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 3) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt sema; - - /* begin stackValue: */ - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (((((sema) & 7) == 1)) - || (GIV(argumentCount) != 1)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - if (sema == GIV(nilObj)) { - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - if (!(((!(sema & (tagMask())))) - && (((longAt(sema)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(ClassSemaphore) << (shiftForWord())))))))))) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -83291,24 +83032,22 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveGreaterOrEqualLargeIntegers\000\377\000", (void*)primitiveGreaterOrEqualLargeIntegers}, {(void*)_m, "primitiveGreaterThanLargeIntegers\000\377\000", (void*)primitiveGreaterThanLargeIntegers}, {(void*)_m, "primitiveHeartbeatFrequency\000\377\000", (void*)primitiveHeartbeatFrequency}, - {(void*)_m, "primitiveHighResClock\000\377\000", (void*)primitiveHighResClock}, + {(void*)_m, "primitiveHighResClock\000\377\001", (void*)primitiveHighResClock}, {(void*)_m, "primitiveImageFormatVersion\000\377\000", (void*)primitiveImageFormatVersion}, {(void*)_m, "primitiveInterruptChecksPerMSec\000\377\000", (void*)primitiveInterruptChecksPerMSec}, {(void*)_m, "primitiveIsBigEnder\000\377\000", (void*)primitiveIsBigEnder}, {(void*)_m, "primitiveIsWindowObscured\000\377\000", (void*)primitiveIsWindowObscured}, {(void*)_m, "primitiveLessOrEqualLargeIntegers\000\377\000", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers\000\377\000", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive\000\377\000", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore\000\000\000", (void*)primitiveLongRunningPrimitiveSemaphore}, {(void*)_m, "primitiveMillisecondClockMask\000\377\000", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveModLargeIntegers\000\000\000", (void*)primitiveModLargeIntegers}, {(void*)_m, "primitiveMultiplyLargeIntegers\000\000\000", (void*)primitiveMultiplyLargeIntegers}, {(void*)_m, "primitiveNotEqualLargeIntegers\000\377\000", (void*)primitiveNotEqualLargeIntegers}, {(void*)_m, "primitivePathToUsing\000\000\000", (void*)primitivePathToUsing}, - {(void*)_m, "primitiveProfilePrimitive\000\377\000", (void*)primitiveProfilePrimitive}, - {(void*)_m, "primitiveProfileSample\000\377\000", (void*)primitiveProfileSample}, + {(void*)_m, "primitiveProfilePrimitive\000\377\001", (void*)primitiveProfilePrimitive}, + {(void*)_m, "primitiveProfileSample\000\377\001", (void*)primitiveProfileSample}, {(void*)_m, "primitiveProfileSemaphore\000\000\000", (void*)primitiveProfileSemaphore}, - {(void*)_m, "primitiveProfileStart\000\000\000", (void*)primitiveProfileStart}, + {(void*)_m, "primitiveProfileStart\000\000\001", (void*)primitiveProfileStart}, {(void*)_m, "primitiveQuoLargeIntegers\000\000\000", (void*)primitiveQuoLargeIntegers}, {(void*)_m, "primitiveRemLargeIntegers\000\000\000", (void*)primitiveRemLargeIntegers}, {(void*)_m, "primitiveScreenDepth\000\377\000", (void*)primitiveScreenDepth}, diff --git a/spurlowcodestacksrc/vm/gcc3x-interp.c b/spurlowcodestacksrc/vm/gcc3x-interp.c index d5facca6f4..a293713807 100644 --- a/spurlowcodestacksrc/vm/gcc3x-interp.c +++ b/spurlowcodestacksrc/vm/gcc3x-interp.c @@ -2,11 +2,11 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - StackInterpreter VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 + StackInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 " __DATE__ ; +static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -1127,7 +1127,6 @@ extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHea extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); static sqInt NoDbgRegParms checkCodeIntegrity(sqInt fullGCFlag); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkForEventsMayContextSwitch(sqInt mayContextSwitch); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); @@ -1458,7 +1457,6 @@ static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, extern sqInt validInstructionPointerinMethodframePointer(usqInt theInstrPointer, usqInt aMethod, char *fp); static sqInt validStackPageBaseFrames(void); static sqInt NoDbgRegParms validStackPageBaseFrame(StackPage *aPage); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt NoDbgRegParms voidVMStateForSnapshotFlushingExternalPrimitivesIf(sqInt flushExtPrims); static sqInt wakeHighestPriority(void); EXPORT(char *) whereIs(sqInt anOop); @@ -1489,8 +1487,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1526,8 +1522,8 @@ _iss sqInt bytecodeSetSelector; _iss char * framePointer; _iss usqInt oldSpaceStart; _iss sqInt specialObjectsOop; -_iss usqInt newMethod; _iss usqInt pastSpaceStart; +_iss usqInt newMethod; _iss usqInt newSpaceLimit; _iss sqInt messageSelector; _iss usqInt instructionPointer; @@ -1575,8 +1571,6 @@ _iss char * objStackInvalidBecause; _iss sqInt sweepIndex; _iss sqInt ephemeronList; _iss sqInt imageHeaderFlags; -_iss sqInt longRunningPrimitiveCheckMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; _iss sqInt profileSemaphore; _iss sqInt tenureCriterion; _iss usqInt totalHeapSizeIncludingBridges; @@ -1629,7 +1623,6 @@ _iss sqInt freeSpaceCheckOopToIgnore; _iss usqInt heapSizeAtPreviousGC; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss sqInt statGrowMemory; _iss sqInt statMaxPageCountWhenMapping; _iss sqInt statPageCountWhenMappingSum; @@ -1639,7 +1632,6 @@ _iss sqInt gcSemaphoreIndex; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; _iss sqInt inFFIFlags; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss sqInt methodDictLinearSearchLimit; _iss sqInt refCountToShrinkRT; @@ -1669,16 +1661,14 @@ _iss sqInt preferredPinningSegment; _iss sqInt statCoalesces; _iss sqLong nextProfileTick; _iss usqLong nextWakeupUsecs; -_iss usqLong statGCEndUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; -_iss usqLong statCheckForEvents; -_iss usqLong gcStartUsecs; _iss sqLong oldSpaceUsePriorToScavenge; +_iss usqLong statGCEndUsecs; _iss usqLong statIOProcessEvents; +_iss usqLong gcStartUsecs; _iss usqLong statAllocatedBytes; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statCompactionUsecs; _iss usqLong statForceInterruptCheck; _iss usqLong statFullGCUsecs; @@ -1691,9 +1681,11 @@ _iss usqLong statStackPageDivorce; _iss usqLong statSweepUsecs; _iss usqLong statSGCDeltaUsecs; _iss usqLong gcSweepEndUsecs; -_iss usqLong longRunningPrimitiveGCUsecs; _iss usqLong statIGCDeltaUsecs; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; _iss usqLong statFGCDeltaUsecs; _iss usqLong statIncrGCUsecs; _iss SpurContiguousObjStack savedFirstFieldsSpace; @@ -2366,7 +2358,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Open Smalltalk Stack VM [StackInterpreterPrimitives VMMaker.oscog-eem.3022]"; +const char *interpreterVersion = "Open Smalltalk Stack VM [StackInterpreterPrimitives VMMaker.oscog-eem.3031]"; sqInt suppressHeartbeatFlag; char primitiveDoMixedArithmetic = 1; char expensiveAsserts = 0; @@ -33057,26 +33049,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -36173,15 +36167,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -36199,15 +36188,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -36260,39 +36244,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((integerPointer & 1)) { - deltaTicks = (integerPointer >> 1); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((deltaTicks & 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 1)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -53030,8 +52993,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) sqInt referent; sqInt referent1; sqInt referent2; - sqInt referent3; - sqInt referent4; sqInt sizeOfUnusedEden; StackPage *thePage; @@ -53157,38 +53118,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - if ((!((longAt(GIV(longRunningPrimitiveCheckMethod))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckMethod))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((GIV(longRunningPrimitiveCheckMethod) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent3 & (tagMask())))) - && ((!((longAt(referent3)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((referent3 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckMethod) = referent3; - } - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - if ((!((longAt(GIV(longRunningPrimitiveCheckSemaphore))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckSemaphore))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((GIV(longRunningPrimitiveCheckSemaphore) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent4 & (tagMask())))) - && ((!((longAt(referent4)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((referent4 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckSemaphore) = referent4; - } - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -62234,33 +62163,6 @@ checkCodeIntegrity(sqInt fullGCFlag) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -62347,9 +62249,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { /* begin signalLowSpace: */ GIV(signalLowSpace) = 0; @@ -65174,26 +65073,8 @@ forceInterruptCheck(void) /* StackInterpreter>>#forceInterruptCheckFromHeartbeat */ void forceInterruptCheckFromHeartbeat(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT +{ if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; forceInterruptCheck(); } } @@ -67696,23 +67577,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i = 1; i <= GIV(jmpDepth); i += 1) { oop = GIV(suspendedCallbacks)[i]; @@ -71899,8 +71763,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -71929,18 +71793,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -76375,22 +76241,6 @@ validStackPageBaseFrame(StackPage *aPage) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Make sure that all VM state that affects the heap contents is voided so that the heap is ready to be snapshotted. If flushExtPrims is true, flush references to @@ -79604,115 +79454,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((addressCouldBeObj(lrpcm)) - && ((!(((longAt(lrpcm)) & (classIndexMask())) == (isFreeObjectClassIndexPun()))) - && (((((usqInt)((longAt(lrpcm)))) >> (formatShift())) & (formatMask())) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - assert(!(isForwarded(result))); - if ((assert(isNonImmediate(result)), - oopisGreaterThanOrEqualTo(result, GIV(oldSpaceStart)))) { - - /* most stores into young objects */ - if (((!(lrpcm & (tagMask())))) - && (oopisLessThan(lrpcm, GIV(newSpaceLimit)))) { - /* begin possibleRootStoreInto: */ - if (!(((((usqInt)((longAt(result)))) >> (rememberedBitShift())) & 1) != 0)) { - remember(result); - } - } - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 1) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 1) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt sema; - - /* begin stackValue: */ - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (((sema & 1)) - || (GIV(argumentCount) != 1)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - if (sema == GIV(nilObj)) { - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - if (!(((!(sema & (tagMask())))) - && (((longAt(sema)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(ClassSemaphore) << (shiftForWord())))))))))) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -82657,24 +82398,22 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveGreaterOrEqualLargeIntegers\000\377\000", (void*)primitiveGreaterOrEqualLargeIntegers}, {(void*)_m, "primitiveGreaterThanLargeIntegers\000\377\000", (void*)primitiveGreaterThanLargeIntegers}, {(void*)_m, "primitiveHeartbeatFrequency\000\377\000", (void*)primitiveHeartbeatFrequency}, - {(void*)_m, "primitiveHighResClock\000\377\000", (void*)primitiveHighResClock}, + {(void*)_m, "primitiveHighResClock\000\377\001", (void*)primitiveHighResClock}, {(void*)_m, "primitiveImageFormatVersion\000\377\000", (void*)primitiveImageFormatVersion}, {(void*)_m, "primitiveInterruptChecksPerMSec\000\377\000", (void*)primitiveInterruptChecksPerMSec}, {(void*)_m, "primitiveIsBigEnder\000\377\000", (void*)primitiveIsBigEnder}, {(void*)_m, "primitiveIsWindowObscured\000\377\000", (void*)primitiveIsWindowObscured}, {(void*)_m, "primitiveLessOrEqualLargeIntegers\000\377\000", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers\000\377\000", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive\000\377\000", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore\000\000\000", (void*)primitiveLongRunningPrimitiveSemaphore}, {(void*)_m, "primitiveMillisecondClockMask\000\377\000", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveModLargeIntegers\000\000\000", (void*)primitiveModLargeIntegers}, {(void*)_m, "primitiveMultiplyLargeIntegers\000\000\000", (void*)primitiveMultiplyLargeIntegers}, {(void*)_m, "primitiveNotEqualLargeIntegers\000\377\000", (void*)primitiveNotEqualLargeIntegers}, {(void*)_m, "primitivePathToUsing\000\000\000", (void*)primitivePathToUsing}, - {(void*)_m, "primitiveProfilePrimitive\000\377\000", (void*)primitiveProfilePrimitive}, - {(void*)_m, "primitiveProfileSample\000\377\000", (void*)primitiveProfileSample}, + {(void*)_m, "primitiveProfilePrimitive\000\377\001", (void*)primitiveProfilePrimitive}, + {(void*)_m, "primitiveProfileSample\000\377\001", (void*)primitiveProfileSample}, {(void*)_m, "primitiveProfileSemaphore\000\000\000", (void*)primitiveProfileSemaphore}, - {(void*)_m, "primitiveProfileStart\000\000\000", (void*)primitiveProfileStart}, + {(void*)_m, "primitiveProfileStart\000\000\001", (void*)primitiveProfileStart}, {(void*)_m, "primitiveQuoLargeIntegers\000\000\000", (void*)primitiveQuoLargeIntegers}, {(void*)_m, "primitiveRemLargeIntegers\000\000\000", (void*)primitiveRemLargeIntegers}, {(void*)_m, "primitiveScreenDepth\000\377\000", (void*)primitiveScreenDepth}, diff --git a/spurlowcodestacksrc/vm/interp.c b/spurlowcodestacksrc/vm/interp.c index 0b0cc98874..37926022e7 100644 --- a/spurlowcodestacksrc/vm/interp.c +++ b/spurlowcodestacksrc/vm/interp.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - StackInterpreter VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 + StackInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 " __DATE__ ; +static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -1124,7 +1124,6 @@ extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHea extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); static sqInt NoDbgRegParms checkCodeIntegrity(sqInt fullGCFlag); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkForEventsMayContextSwitch(sqInt mayContextSwitch); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); @@ -1455,7 +1454,6 @@ static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, extern sqInt validInstructionPointerinMethodframePointer(usqInt theInstrPointer, usqInt aMethod, char *fp); static sqInt validStackPageBaseFrames(void); static sqInt NoDbgRegParms validStackPageBaseFrame(StackPage *aPage); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt NoDbgRegParms voidVMStateForSnapshotFlushingExternalPrimitivesIf(sqInt flushExtPrims); static sqInt wakeHighestPriority(void); EXPORT(char *) whereIs(sqInt anOop); @@ -1486,8 +1484,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1523,8 +1519,8 @@ _iss sqInt bytecodeSetSelector; _iss char * framePointer; _iss usqInt oldSpaceStart; _iss sqInt specialObjectsOop; -_iss usqInt newMethod; _iss usqInt pastSpaceStart; +_iss usqInt newMethod; _iss usqInt newSpaceLimit; _iss sqInt messageSelector; _iss usqInt instructionPointer; @@ -1572,8 +1568,6 @@ _iss char * objStackInvalidBecause; _iss sqInt sweepIndex; _iss sqInt ephemeronList; _iss sqInt imageHeaderFlags; -_iss sqInt longRunningPrimitiveCheckMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; _iss sqInt profileSemaphore; _iss sqInt tenureCriterion; _iss usqInt totalHeapSizeIncludingBridges; @@ -1626,7 +1620,6 @@ _iss sqInt freeSpaceCheckOopToIgnore; _iss usqInt heapSizeAtPreviousGC; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss sqInt statGrowMemory; _iss sqInt statMaxPageCountWhenMapping; _iss sqInt statPageCountWhenMappingSum; @@ -1636,7 +1629,6 @@ _iss sqInt gcSemaphoreIndex; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; _iss sqInt inFFIFlags; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss sqInt methodDictLinearSearchLimit; _iss sqInt refCountToShrinkRT; @@ -1666,16 +1658,14 @@ _iss sqInt preferredPinningSegment; _iss sqInt statCoalesces; _iss sqLong nextProfileTick; _iss usqLong nextWakeupUsecs; -_iss usqLong statGCEndUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; -_iss usqLong statCheckForEvents; -_iss usqLong gcStartUsecs; _iss sqLong oldSpaceUsePriorToScavenge; +_iss usqLong statGCEndUsecs; _iss usqLong statIOProcessEvents; +_iss usqLong gcStartUsecs; _iss usqLong statAllocatedBytes; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statCompactionUsecs; _iss usqLong statForceInterruptCheck; _iss usqLong statFullGCUsecs; @@ -1688,9 +1678,11 @@ _iss usqLong statStackPageDivorce; _iss usqLong statSweepUsecs; _iss usqLong statSGCDeltaUsecs; _iss usqLong gcSweepEndUsecs; -_iss usqLong longRunningPrimitiveGCUsecs; _iss usqLong statIGCDeltaUsecs; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; _iss usqLong statFGCDeltaUsecs; _iss usqLong statIncrGCUsecs; _iss SpurContiguousObjStack savedFirstFieldsSpace; @@ -2363,7 +2355,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Open Smalltalk Stack VM [StackInterpreterPrimitives VMMaker.oscog-eem.3022]"; +const char *interpreterVersion = "Open Smalltalk Stack VM [StackInterpreterPrimitives VMMaker.oscog-eem.3031]"; sqInt suppressHeartbeatFlag; char primitiveDoMixedArithmetic = 1; char expensiveAsserts = 0; @@ -33048,26 +33040,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -36164,15 +36158,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -36190,15 +36179,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -36251,39 +36235,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((integerPointer & 1)) { - deltaTicks = (integerPointer >> 1); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((deltaTicks & 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 1)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -53021,8 +52984,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) sqInt referent; sqInt referent1; sqInt referent2; - sqInt referent3; - sqInt referent4; sqInt sizeOfUnusedEden; StackPage *thePage; @@ -53148,38 +53109,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - if ((!((longAt(GIV(longRunningPrimitiveCheckMethod))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckMethod))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((GIV(longRunningPrimitiveCheckMethod) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent3 & (tagMask())))) - && ((!((longAt(referent3)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((referent3 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckMethod) = referent3; - } - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - if ((!((longAt(GIV(longRunningPrimitiveCheckSemaphore))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckSemaphore))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((GIV(longRunningPrimitiveCheckSemaphore) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent4 & (tagMask())))) - && ((!((longAt(referent4)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((referent4 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckSemaphore) = referent4; - } - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -62225,33 +62154,6 @@ checkCodeIntegrity(sqInt fullGCFlag) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -62338,9 +62240,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { /* begin signalLowSpace: */ GIV(signalLowSpace) = 0; @@ -65165,26 +65064,8 @@ forceInterruptCheck(void) /* StackInterpreter>>#forceInterruptCheckFromHeartbeat */ void forceInterruptCheckFromHeartbeat(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT +{ if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; forceInterruptCheck(); } } @@ -67687,23 +67568,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i = 1; i <= GIV(jmpDepth); i += 1) { oop = GIV(suspendedCallbacks)[i]; @@ -71890,8 +71754,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -71920,18 +71784,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -76366,22 +76232,6 @@ validStackPageBaseFrame(StackPage *aPage) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Make sure that all VM state that affects the heap contents is voided so that the heap is ready to be snapshotted. If flushExtPrims is true, flush references to @@ -79595,115 +79445,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((addressCouldBeObj(lrpcm)) - && ((!(((longAt(lrpcm)) & (classIndexMask())) == (isFreeObjectClassIndexPun()))) - && (((((usqInt)((longAt(lrpcm)))) >> (formatShift())) & (formatMask())) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - assert(!(isForwarded(result))); - if ((assert(isNonImmediate(result)), - oopisGreaterThanOrEqualTo(result, GIV(oldSpaceStart)))) { - - /* most stores into young objects */ - if (((!(lrpcm & (tagMask())))) - && (oopisLessThan(lrpcm, GIV(newSpaceLimit)))) { - /* begin possibleRootStoreInto: */ - if (!(((((usqInt)((longAt(result)))) >> (rememberedBitShift())) & 1) != 0)) { - remember(result); - } - } - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 1) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 1) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt sema; - - /* begin stackValue: */ - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (((sema & 1)) - || (GIV(argumentCount) != 1)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - if (sema == GIV(nilObj)) { - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - if (!(((!(sema & (tagMask())))) - && (((longAt(sema)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(ClassSemaphore) << (shiftForWord())))))))))) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -82648,24 +82389,22 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveGreaterOrEqualLargeIntegers\000\377\000", (void*)primitiveGreaterOrEqualLargeIntegers}, {(void*)_m, "primitiveGreaterThanLargeIntegers\000\377\000", (void*)primitiveGreaterThanLargeIntegers}, {(void*)_m, "primitiveHeartbeatFrequency\000\377\000", (void*)primitiveHeartbeatFrequency}, - {(void*)_m, "primitiveHighResClock\000\377\000", (void*)primitiveHighResClock}, + {(void*)_m, "primitiveHighResClock\000\377\001", (void*)primitiveHighResClock}, {(void*)_m, "primitiveImageFormatVersion\000\377\000", (void*)primitiveImageFormatVersion}, {(void*)_m, "primitiveInterruptChecksPerMSec\000\377\000", (void*)primitiveInterruptChecksPerMSec}, {(void*)_m, "primitiveIsBigEnder\000\377\000", (void*)primitiveIsBigEnder}, {(void*)_m, "primitiveIsWindowObscured\000\377\000", (void*)primitiveIsWindowObscured}, {(void*)_m, "primitiveLessOrEqualLargeIntegers\000\377\000", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers\000\377\000", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive\000\377\000", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore\000\000\000", (void*)primitiveLongRunningPrimitiveSemaphore}, {(void*)_m, "primitiveMillisecondClockMask\000\377\000", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveModLargeIntegers\000\000\000", (void*)primitiveModLargeIntegers}, {(void*)_m, "primitiveMultiplyLargeIntegers\000\000\000", (void*)primitiveMultiplyLargeIntegers}, {(void*)_m, "primitiveNotEqualLargeIntegers\000\377\000", (void*)primitiveNotEqualLargeIntegers}, {(void*)_m, "primitivePathToUsing\000\000\000", (void*)primitivePathToUsing}, - {(void*)_m, "primitiveProfilePrimitive\000\377\000", (void*)primitiveProfilePrimitive}, - {(void*)_m, "primitiveProfileSample\000\377\000", (void*)primitiveProfileSample}, + {(void*)_m, "primitiveProfilePrimitive\000\377\001", (void*)primitiveProfilePrimitive}, + {(void*)_m, "primitiveProfileSample\000\377\001", (void*)primitiveProfileSample}, {(void*)_m, "primitiveProfileSemaphore\000\000\000", (void*)primitiveProfileSemaphore}, - {(void*)_m, "primitiveProfileStart\000\000\000", (void*)primitiveProfileStart}, + {(void*)_m, "primitiveProfileStart\000\000\001", (void*)primitiveProfileStart}, {(void*)_m, "primitiveQuoLargeIntegers\000\000\000", (void*)primitiveQuoLargeIntegers}, {(void*)_m, "primitiveRemLargeIntegers\000\000\000", (void*)primitiveRemLargeIntegers}, {(void*)_m, "primitiveScreenDepth\000\377\000", (void*)primitiveScreenDepth}, diff --git a/spursista64src/vm/cogit.h b/spursista64src/vm/cogit.h index 2a7c4301df..cbc6c61475 100644 --- a/spursista64src/vm/cogit.h +++ b/spursista64src/vm/cogit.h @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + CCodeGenerator VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ diff --git a/spursista64src/vm/cogitARMv8.c b/spursista64src/vm/cogitARMv8.c index 8fcf14e2d2..ddec9f0cef 100644 --- a/spursista64src/vm/cogitARMv8.c +++ b/spursista64src/vm/cogitARMv8.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + CCodeGenerator VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - SistaCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + SistaCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "SistaCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 " __DATE__ ; +static char __buildInfo[] = "SistaCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__cogitBuildInfo = __buildInfo; @@ -69,18 +69,18 @@ char *__cogitBuildInfo = __buildInfo; #define CArg1Reg 1 #define CArg2Reg 2 #define CArg3Reg 3 -#define CASAL 174 +#define CASAL 176 #define Call 6 #define CallerSavedRegisterMask 0x1F0 #define CallFull 7 -#define CBNZ 175 -#define CBZ 176 +#define CBNZ 177 +#define CBZ 178 #define CC 3 -#define CCMPNE 177 +#define CCMPNE 179 #if !defined(CheckRememberedInTrampoline) /* Allow this to be overridden on the compiler command line */ # define CheckRememberedInTrampoline 0 #endif -#define CLREX 179 +#define CLREX 181 #define ClassArray 7 #define ClassArrayCompactIndex 51 #define ClassBlockClosureCompactIndex 37 @@ -114,8 +114,8 @@ char *__cogitBuildInfo = __buildInfo; #define ConvertRRd 145 #define CounterBytes 4 #define CS 2 -#define CSET 178 -#define DC 167 +#define CSET 180 +#define DC 169 #define DC_CIVAC 14 #define DC_CVAC 16 #define DC_CVAU 19 @@ -123,7 +123,7 @@ char *__cogitBuildInfo = __buildInfo; #define DisplacementMask 0x1F #define DisplacementX2N 0 #define DivRdRd 135 -#define DivRRR 161 +#define DivRRR 163 #define DPFPReg0 0 #define DPFPReg1 1 #define DPFPReg2 2 @@ -132,7 +132,7 @@ char *__cogitBuildInfo = __buildInfo; #define DPFPReg5 5 #define DPFPReg6 6 #define DPFPReg7 7 -#define DSB 170 +#define DSB 172 #define DSB_ALL 3 #define DSB_ISH 2 #define EncounteredUnknownBytecode -6 @@ -167,7 +167,7 @@ char *__cogitBuildInfo = __buildInfo; #define HashMultiplyMask 0xFFFFFFF #define HeaderIndex 0 #define HI 8 -#define IC 168 +#define IC 170 #define IC_IALLU 0 #define IC_IALLUIS 1 #define IC_IVAU 2 @@ -179,7 +179,7 @@ char *__cogitBuildInfo = __buildInfo; #define InstructionPointerIndex 1 #define InsufficientCodeSpace -2 #define InVanillaBlock 1 -#define ISB 171 +#define ISB 173 #define IsAbsPCReference 3 #define IsAnnotationExtension 1 #define IsDirectedSuperBindingSend 10 @@ -227,7 +227,7 @@ char *__cogitBuildInfo = __buildInfo; #define Label 1 #define LargeContextSlots 62 #define LastJump 42 -#define LDAXR 180 +#define LDAXR 182 #define LE 13 #define LinkReg 30 #define Literal 2 @@ -267,7 +267,7 @@ char *__cogitBuildInfo = __buildInfo; #define MoveA32R 45 #define MoveAbR 48 #define MoveAwR 44 -#define MoveAwRR 163 +#define MoveAwRR 165 #define MoveC32R 71 #define MoveCqR 69 #define MoveCwR 70 @@ -276,6 +276,8 @@ char *__cogitBuildInfo = __buildInfo; #define MoveM64rRd 75 #define MoveMbrR 65 #define MoveMwrR 50 +#define MovePerfCnt64RL 159 +#define MovePerfCnt64RRL 158 #define MoveRA32 47 #define MoveRAb 49 #define MoveRAw 46 @@ -286,7 +288,7 @@ char *__cogitBuildInfo = __buildInfo; #define MoveRMbr 66 #define MoveRMwr 51 #define MoveRR 43 -#define MoveRRAw 164 +#define MoveRRAw 166 #define MoveRRd 72 #define MoveRX16rR 60 #define MoveRX32rR 64 @@ -296,17 +298,17 @@ char *__cogitBuildInfo = __buildInfo; #define MoveX32rRR 63 #define MoveXbrRR 67 #define MoveXwrRR 52 -#define MRS_CTR_EL0 172 -#define MRS_ID_AA64ISAR0_EL1 173 -#define MSubRRR 162 +#define MRS_CTR_EL0 174 +#define MRS_ID_AA64ISAR0_EL1 175 +#define MSubRRR 164 #define MULTIPLEBYTECODESETS 1 -#define MulOverflowRRR 159 +#define MulOverflowRRR 161 #define MulRdRd 134 -#define MulRRR 158 +#define MulRRR 160 #define NativePopR 84 -#define NativePopRR 166 +#define NativePopRR 168 #define NativePushR 85 -#define NativePushRR 165 +#define NativePushRR 167 #define NativeRetN 86 #define NativeSPReg 31 #define NE 1 @@ -375,10 +377,11 @@ char *__cogitBuildInfo = __buildInfo; #define SSConstant 2 #define SSRegister 3 #define SSSpill 4 -#define STLR 182 -#define STLXR 181 +#define STLR 184 +#define STLXR 183 #define StackPointerIndex 2 #define Stop 11 +#define SubbRR 121 #define SubCqR 107 #define SubCwR 115 #define SubRdRd 133 @@ -525,7 +528,7 @@ static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self static void NoDbgRegParms cloneLiteralFrom(AbstractInstruction * self_in_cloneLiteralFrom, AbstractInstruction *existingLiteral); static sqInt NoDbgRegParms concretizeAt(AbstractInstruction * self_in_concretizeAt, sqInt actualAddress); static sqInt NoDbgRegParms genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer); -static sqInt NoDbgRegParms genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg); +static sqInt NoDbgRegParms genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg); static AbstractInstruction * NoDbgRegParms genSwapRRScratch(AbstractInstruction * self_in_genSwapRRScratch, sqInt regA, sqInt regB, sqInt regTmp); static void NoDbgRegParms genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister); static void NoDbgRegParms initializeSharableLiteral(AbstractInstruction * self_in_initializeSharableLiteral, sqInt literal); @@ -557,6 +560,7 @@ static sqInt NoDbgRegParms concretizeLoadEffectiveAddressMwrR(AbstractInstructio static sqInt NoDbgRegParms concretizeLogicalOpCqRDest(AbstractInstruction * self_in_concretizeLogicalOpCqRDest, sqInt op, sqInt destReg); static sqInt NoDbgRegParms concretizeMoveCqR(AbstractInstruction * self_in_concretizeMoveCqR); static sqInt NoDbgRegParms concretizeMoveMSrR(AbstractInstruction * self_in_concretizeMoveMSrR, sqInt unitSizeLog2MinusOne); +static sqInt NoDbgRegParms concretizeMovePerfCnt64RL(AbstractInstruction * self_in_concretizeMovePerfCnt64RL); static sqInt NoDbgRegParms concretizeMoveRMSr(AbstractInstruction * self_in_concretizeMoveRMSr, sqInt unitSizeLog2MinusOne); static sqInt NoDbgRegParms concretizeMoveRXSrR(AbstractInstruction * self_in_concretizeMoveRXSrR, sqInt unitSizeLog2MinusOne); static sqInt NoDbgRegParms concretizeMoveXSrRR(AbstractInstruction * self_in_concretizeMoveXSrRR, sqInt unitSizeLog2MinusOne); @@ -818,6 +822,8 @@ static BytecodeDescriptor * loadBytesAndGetDescriptor(void); static void NoDbgRegParms loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc); static AbstractInstruction * NoDbgRegParms gMoveAwR(sqInt address, sqInt reg); static AbstractInstruction * NoDbgRegParms gMoveCwR(sqInt wordConstant, sqInt reg); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters); static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg); static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC); @@ -866,6 +872,7 @@ static void NoDbgRegParms recordGeneratedRunTimeaddress(char *aString, sqInt add extern sqInt recordPrimTraceFunc(void); static void recordRunTimeObjectReferences(void); static sqInt NoDbgRegParms registerMaskFor(sqInt reg); +static sqInt NoDbgRegParms registerMaskForand(sqInt reg1, sqInt reg2); static void NoDbgRegParms relocateCallsAndSelfReferencesInMethod(CogMethod *cogMethod); static void NoDbgRegParms relocateCallsInClosedPIC(CogMethod *cPIC); static sqInt NoDbgRegParms relocateIfCallOrMethodReferencemcpcdelta(sqInt annotation, char *mcpc, CogMethod *refDeltaArg); @@ -1239,6 +1246,7 @@ static sqInt genStoreAndPopReceiverVariableBytecode(void); static sqInt genStoreAndPopRemoteTempLongBytecode(void); static sqInt genStoreAndPopTemporaryVariableBytecode(void); static sqInt genStoreRemoteTempLongBytecode(void); +static void genTakeProfileSample(void); extern sqInt mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj); static sqInt numSpecialSelectors(void); static usqInt NoDbgRegParms pcDataForBlockEntryMethod(sqInt blockEntryMcpc, sqInt cogMethod); @@ -2868,28 +2876,28 @@ addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *an static sqInt NoDbgRegParms availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << DPFPReg0)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg0))) != 0))) { return DPFPReg0; } - if (!(((liveRegsMask & (1U << DPFPReg1)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg1))) != 0))) { return DPFPReg1; } - if (!(((liveRegsMask & (1U << DPFPReg2)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg2))) != 0))) { return DPFPReg2; } - if (!(((liveRegsMask & (1U << DPFPReg3)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg3))) != 0))) { return DPFPReg3; } - if (!(((liveRegsMask & (1U << DPFPReg4)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg4))) != 0))) { return DPFPReg4; } - if (!(((liveRegsMask & (1U << DPFPReg5)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg5))) != 0))) { return DPFPReg5; } - if (!(((liveRegsMask & (1U << DPFPReg6)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg6))) != 0))) { return DPFPReg6; } - if (!(((liveRegsMask & (1U << DPFPReg7)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg7))) != 0))) { return DPFPReg7; } return NoReg; @@ -2904,19 +2912,19 @@ availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegi static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << Arg1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg1Reg))) != 0))) { return Arg1Reg; } - if (!(((liveRegsMask & (1U << Arg0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg0Reg))) != 0))) { return Arg0Reg; } - if (!(((liveRegsMask & (1U << SendNumArgsReg)) != 0))) { + if (!(((liveRegsMask & ((1U << SendNumArgsReg))) != 0))) { return SendNumArgsReg; } - if (!(((liveRegsMask & (1U << ClassReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ClassReg))) != 0))) { return ClassReg; } - if (!(((liveRegsMask & (1U << ReceiverResultReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ReceiverResultReg))) != 0))) { return ReceiverResultReg; } return NoReg; @@ -2978,11 +2986,11 @@ genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer) used immediately afterwards. */ - /* CogAbstractInstruction>>#genLoadStackPointersForFastPrimCall: */ + /* CogAbstractInstruction>>#genLoadStackPointersForPrimCall: */ static sqInt NoDbgRegParms -genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg) +genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg) { - genLoadStackPointers(self_in_genLoadStackPointersForFastPrimCall); + genLoadStackPointers(self_in_genLoadStackPointersForPrimCall); return 0; } @@ -4016,6 +4024,18 @@ concretizeMoveMSrR(AbstractInstruction * self_in_concretizeMoveMSrR, sqInt unitS } +/* D13.8.26 CNTVCT_EL0, Counter-timer Virtual Count register p D13-3774 */ +/* MRS , CNTVCT_EL0 op0:0b11 op1:0b011 CRn:0b1110 CRm:0b0000 op2:0b010 */ + + /* CogARMv8Compiler>>#concretizeMovePerfCnt64RL */ +static sqInt NoDbgRegParms +concretizeMovePerfCnt64RL(AbstractInstruction * self_in_concretizeMovePerfCnt64RL) +{ + ((self_in_concretizeMovePerfCnt64RL->machineCode))[0] = ((3577471040U) + (((self_in_concretizeMovePerfCnt64RL->operands))[0])); + return 4; +} + + /* Mwr/M32r/M16r/Mbr - memory unit whose address is a constant M away from an address in a register */ @@ -5709,6 +5729,9 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) : 0))) + (((sqInt)((usqInt)((offset9 & (0x1FFFFF))) << 3)))) + reg9); return 4; + case MovePerfCnt64RL: + return concretizeMovePerfCnt64RL(self_in_dispatchConcretize); + default: error("Case not found and no otherwise clause"); } @@ -6551,7 +6574,7 @@ genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask) assert(!((registerisInMask(RISCTempReg, regMask)))); nRegs = 0; for (reg = R1; reg <= R17; reg += 1) { - if (((regMask & (1ULL << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0)) { nRegs += 1; } } @@ -6559,7 +6582,7 @@ genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask) ? NoReg : RISCTempReg); for (reg = R1; reg <= R17; reg += 1) { - if (((regMask & (1ULL << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0)) { if (pair == NoReg) { pair = reg; } @@ -6594,7 +6617,7 @@ genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask) assert(!((registerisInMask(RISCTempReg, regMask)))); pair = NoReg; for (reg = R17; reg >= R0; reg += -1) { - if (((regMask & (1ULL << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0)) { if (pair == NoReg) { pair = reg; } @@ -7333,7 +7356,7 @@ rewriteImm19JumpBeforetarget(AbstractInstruction * self_in_rewriteImm19JumpBefor static sqInt NoDbgRegParms rewriteImm26JumpBeforetarget(AbstractInstruction * self_in_rewriteImm26JumpBeforetarget, sqInt followingAddress, sqInt targetAddress) { - sqInt instrOpcode; + usqInt instrOpcode; sqInt mcpc; sqInt offset; @@ -7343,7 +7366,7 @@ rewriteImm26JumpBeforetarget(AbstractInstruction * self_in_rewriteImm26JumpBefor instrOpcode = ((instructionBeforeAddress(self_in_rewriteImm26JumpBeforetarget, followingAddress))) >> 26; assert((instrOpcode == 5) || (instrOpcode == 37)); - codeLong32Atput(mcpc, (((sqInt)((usqInt)(instrOpcode) << 26))) + (((offset) >> 2) & (0x3FFFFFF))); + codeLong32Atput(mcpc, (instrOpcode << 26) + (((offset) >> 2) & (0x3FFFFFF))); return 4; } @@ -10469,7 +10492,7 @@ compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numAr regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1ULL << resultRegOrNone)) - (1ULL << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ } @@ -12078,7 +12101,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) startAddress = methodZoneBase; callerSavedReg = 0; pushedVarBaseReg = 0; - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { /* VarBaseReg is not caller-saved; must save and restore it, either by using an available caller-saved reg or push/pop. */ @@ -12128,7 +12151,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) operandTwo2 = cStackPointerAddress(); checkLiteralforInstruction(operandTwo2, genoperandoperand(MoveRAw, NativeSPReg, operandTwo2)); } - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { if (pushedVarBaseReg) { gNativePopR(VarBaseReg); } @@ -13510,6 +13533,22 @@ gMoveCwR(sqInt wordConstant, sqInt reg) return checkLiteralforInstruction(wordConstant, genoperandoperand(MoveCwR, wordConstant, reg)); } + /* Cogit>>#MovePerfCnt64R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters) +{ + assert(BytesPerWord == 8); + return genoperandoperand(MovePerfCnt64RL, destReg, liveRegisters); +} + + /* Cogit>>#MovePerfCnt64R:R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters) +{ + assert(BytesPerWord == 4); + return genoperandoperandoperand(MovePerfCnt64RRL, destRegLo, destRegHi, liveRegisters); +} + /* Answer the address of the null byte at the end of the method map. */ @@ -15240,11 +15279,21 @@ recordRunTimeObjectReferences(void) } } + +/* N.B. (self registerMaskFor: NoReg) = 0 */ + /* Cogit>>#registerMaskFor: */ static sqInt NoDbgRegParms registerMaskFor(sqInt reg) { - return 1ULL << reg; + return ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); +} + + /* Cogit>>#registerMaskFor:and: */ +static sqInt NoDbgRegParms +registerMaskForand(sqInt reg1, sqInt reg2) +{ + return (1ULL << reg1) | (1ULL << reg2); } /* Cogit>>#relocateCallsAndSelfReferencesInMethod: */ @@ -23369,7 +23418,7 @@ generateObjectRepresentationTrampolines(void) } # endif // IMMUTABILITY ceNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceNewHash", 1, ReceiverResultReg, null, null, null, /* begin emptyRegisterMask */ 0, 1, ReceiverResultReg, 0); - ceInlineNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceInlineNewHash", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, ReceiverResultReg, 0); + ceInlineNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceInlineNewHash", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))), 1, ReceiverResultReg, 0); /* begin genStoreCheckTrampoline */ if (CheckRememberedInTrampoline) { zeroOpcodeIndex(); @@ -23380,7 +23429,7 @@ generateObjectRepresentationTrampolines(void) genoperand(RetN, 0); jmpTarget(jumpSC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); } - ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))), 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), CheckRememberedInTrampoline); ceStoreCheckContextReceiverTrampoline = genStoreCheckContextReceiverTrampoline(); @@ -25832,7 +25881,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jumpRC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg)); jmpTarget(jumpImmutable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); @@ -25848,7 +25897,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* Store check */ jumpImmutable1 = genJumpImmutablescratchReg(ReceiverResultReg, SendNumArgsReg); - compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), 0 /* emptyRegisterMask */); genLoadStackPointers(backEnd()); @@ -25923,7 +25972,7 @@ genStoreValueinstancenumSlots(sqInt value, sqInt destReg, sqInt numSlots) } return 0; } - constReg = allocateRegNotConflictingWith(1ULL << destReg); + constReg = allocateRegNotConflictingWith(((destReg < 0) ? (((usqInt)(1)) >> (-destReg)) : (1ULL << destReg))); if (shouldAnnotateObjectReference(value)) { annotateobjRef(gMoveCwR(value, constReg), value); } @@ -26891,7 +26940,7 @@ registerMask(SimStackEntry * self_in_registerMask) || (((self_in_registerMask->type)) == SSRegister) ? (/* begin registerMaskFor: */ (reg = (self_in_registerMask->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : 0); } @@ -26904,7 +26953,7 @@ registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone) return (((self_in_registerMaskOrNone->type)) == SSRegister ? (/* begin registerMaskFor: */ (reg = (self_in_registerMaskOrNone->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : 0); } @@ -27335,42 +27384,32 @@ compileInterpreterPrimitive(void) static sqInt NoDbgRegParms compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) { + sqInt address; + sqInt address1; sqInt address10; - sqInt address11; - sqInt address12; - sqInt address13; sqInt address2; - sqInt address3; sqInt address4; + sqInt address6; sqInt address7; sqInt address8; sqInt address9; AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; AbstractInstruction *anInstruction4; AbstractInstruction *anInstruction5; AbstractInstruction *anInstruction6; AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction * continuePostSampleNonPrim; - AbstractInstruction * continuePostSamplePrim; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; - AbstractInstruction * jmpSampleNonPrim; - AbstractInstruction * jmpSamplePrim; + AbstractInstruction * jumpToTakeSample; + sqInt liveRegisters; sqInt offset; sqInt offset1; sqInt offset2; - sqInt operand1; - sqInt operand3; sqInt reg; sqInt retpc; - continuePostSampleNonPrim = ((AbstractInstruction *) 0); - continuePostSamplePrim = ((AbstractInstruction *) 0); - jmpSampleNonPrim = ((AbstractInstruction *) 0); - jmpSamplePrim = ((AbstractInstruction *) 0); + jumpToTakeSample = ((AbstractInstruction *) 0); assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); genExternalizePointersForPrimitiveCall(); /* begin genLoadCStackPointersForPrimCall */ @@ -27380,53 +27419,36 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) else { genLoadCStackPointer(backEnd); } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick if so */ - /* begin MoveAw:R: */ - address2 = nextProfileTickAddress(); - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address2, genoperandoperand(MoveAwR, address2, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction)) { - (anInstruction->dependent = locateLiteralsize(0, BytesPerOop)); - } - /* begin JumpNonZero: */ - jmpSampleNonPrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSampleNonPrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } if (recordPrimTraceForMethod(methodObj)) { genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(MoveCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction8)) { - (anInstruction8->dependent = locateLiteralsize(0, BytesPerOop)); + anInstruction4 = genoperandoperand(MoveCqR, 0, TempReg); + if (usesOutOfLineLiteral(anInstruction4)) { + (anInstruction4->dependent = locateLiteralsize(0, BytesPerOop)); } /* begin MoveR:Aw: */ - address11 = primFailCodeAddress(); + address6 = primFailCodeAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address11, genoperandoperand(MoveRAw, TempReg, address11)); + checkLiteralforInstruction(address6, genoperandoperand(MoveRAw, TempReg, address6)); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); - if (usesOutOfLineLiteral(anInstruction1)) { - (anInstruction1->dependent = locateLiteralsize(methodOrBlockNumArgs, BytesPerOop)); + anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); + if (usesOutOfLineLiteral(anInstruction)) { + (anInstruction->dependent = locateLiteralsize(methodOrBlockNumArgs, BytesPerOop)); } } /* begin MoveR:Aw: */ - address12 = argumentCountAddress(); + address7 = argumentCountAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address12, genoperandoperand(MoveRAw, TempReg, address12)); + checkLiteralforInstruction(address7, genoperandoperand(MoveRAw, TempReg, address7)); if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { /* begin MoveCw:R: */ checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg)); /* begin MoveR:Aw: */ - address3 = primitiveFunctionPointerAddress(); + address = primitiveFunctionPointerAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address3, genoperandoperand(MoveRAw, TempReg, address3)); + checkLiteralforInstruction(address, genoperandoperand(MoveRAw, TempReg, address)); } if (((flags & (PrimCallNeedsNewMethod + PrimCallMayEndureCodeCompaction)) != 0)) { @@ -27438,22 +27460,21 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) /* begin MoveMw:r:R: */ offset = offsetof(CogMethod, methodObject); /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - if (usesOutOfLineLiteral(anInstruction2)) { - (anInstruction2->dependent = locateLiteralsize(offset, BytesPerOop)); + anInstruction1 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); + if (usesOutOfLineLiteral(anInstruction1)) { + (anInstruction1->dependent = locateLiteralsize(offset, BytesPerOop)); } /* begin MoveR:Aw: */ - address4 = newMethodAddress(); + address1 = newMethodAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address4, genoperandoperand(MoveRAw, TempReg, address4)); + checkLiteralforInstruction(address1, genoperandoperand(MoveRAw, TempReg, address1)); } /* begin PrefetchAw: */ - address13 = primFailCodeAddress(); + address8 = primFailCodeAddress(); /* begin gen:literal: */ - checkLiteralforInstruction(address13, genoperand(PrefetchAw, address13)); + checkLiteralforInstruction(address8, genoperand(PrefetchAw, address8)); if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - /* Sideways call the C primitive routine so that we return through cePrimReturnEnterCogCode. */ /* On Spur ceActivateFailingPrimitiveMethod: would like to retry if forwarders are found. So insist on PrimCallNeedsPrimitiveFunction being set too. */ assert(((flags & PrimCallNeedsPrimitiveFunction) != 0)); @@ -27466,102 +27487,75 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) checkLiteralforInstruction(retpc, genoperandoperand(MoveCwR, retpc, LR)); /* begin gen:literal: */ checkLiteralforInstruction(((sqInt)(((sqInt)primitiveRoutine))), genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine))))); - jmp = (jmpSamplePrim = (continuePostSamplePrim = null)); + return 0; } - else { - - /* Call the C primitive routine. */ - genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); - /* begin gen:literal: */ - checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperand(CallFull, ((sqInt)primitiveRoutine))); - /* begin genRemoveNArgsFromStack: */ - assert(0 <= 6); - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin MoveAw:R: */ - address7 = nextProfileTickAddress(); - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address7, genoperandoperand(MoveAwR, address7, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(CmpCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction3)) { - (anInstruction3->dependent = locateLiteralsize(0, BytesPerOop)); - } - /* begin JumpNonZero: */ - jmpSamplePrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSamplePrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - maybeCompileRetryOnPrimitiveFail(primitiveIndex); - /* begin MoveAw:R: */ - address8 = instructionPointerAddress(); - reg = LinkReg; - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address8, genoperandoperand(MoveAwR, address8, reg)); - genLoadStackPointers(backEnd); + genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); + /* begin gen:literal: */ + checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperand(CallFull, ((sqInt)primitiveRoutine))); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 6); + maybeCompileRetryOnPrimitiveFail(primitiveIndex); + genLoadStackPointersForPrimCall(backEnd, ClassReg); + /* begin MoveAw:R: */ + address2 = instructionPointerAddress(); + /* begin gen:literal:operand: */ + checkLiteralforInstruction(address2, genoperandoperand(MoveAwR, address2, LinkReg)); + /* begin MoveAw:R: */ + address9 = primFailCodeAddress(); + /* begin gen:literal:operand: */ + checkLiteralforInstruction(address9, genoperandoperand(MoveAwR, address9, TempReg)); + flag("ask concrete code gen if move sets condition codes?"); + /* begin checkQuickConstant:forInstruction: */ + anInstruction5 = genoperandoperand(CmpCqR, 0, TempReg); + if (usesOutOfLineLiteral(anInstruction5)) { + (anInstruction5->dependent = locateLiteralsize(0, BytesPerOop)); + } + /* begin JumpNonZero: */ + jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + reg = Arg0Reg; + gMovePerfCnt64RL(reg, liveRegisters); /* begin MoveAw:R: */ - address9 = primFailCodeAddress(); + address10 = nextProfileTickAddress(); /* begin gen:literal:operand: */ - checkLiteralforInstruction(address9, genoperandoperand(MoveAwR, address9, TempReg)); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction4)) { - (anInstruction4->dependent = locateLiteralsize(0, BytesPerOop)); - } - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset1 = 0; - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); - if (usesOutOfLineLiteral(anInstruction5)) { - (anInstruction5->dependent = locateLiteralsize(offset1, BytesPerOop)); - } - /* begin RetN: */ - genoperand(RetN, BytesPerWord); + checkLiteralforInstruction(address10, genoperandoperand(MoveAwR, address10, Arg1Reg)); + /* begin CmpR:R: */ + assert(!((reg == SPReg))); + genoperandoperand(CmpRR, reg, Arg1Reg); + /* begin JumpGreaterOrEqual: */ + jumpToTakeSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l31; + l31: /* end genCheckForProfileTimerTick: */; } + /* begin MoveMw:r:R: */ + offset1 = 0; + /* begin checkQuickConstant:forInstruction: */ + anInstruction6 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); + if (usesOutOfLineLiteral(anInstruction6)) { + (anInstruction6->dependent = locateLiteralsize(offset1, BytesPerOop)); + } + continueAfterProfileSample = anInstruction6; + /* begin RetN: */ + genoperand(RetN, BytesPerWord); if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* The sample is collected by cePrimReturnEnterCogCode for external calls */ - if (!(jmpSamplePrim == null)) { - - /* Call ceCheckProfileTick: to record sample and then continue. */ - jmpTarget(jmpSamplePrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin gen:literal: */ - operand1 = ((usqIntptr_t)ceCheckProfileTick); - checkLiteralforInstruction(operand1, genoperand(CallFull, operand1)); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSamplePrim)); - } - jmpTarget(jmpSampleNonPrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(MoveCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction6)) { - (anInstruction6->dependent = locateLiteralsize(0, BytesPerOop)); - } - /* begin MoveR:Aw: */ - address10 = newMethodAddress(); - /* begin gen:operand:literal: */ - checkLiteralforInstruction(address10, genoperandoperand(MoveRAw, TempReg, address10)); - /* begin gen:literal: */ - operand3 = ((usqIntptr_t)ceCheckProfileTick); - checkLiteralforInstruction(operand3, genoperand(CallFull, operand3)); + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); + /* begin MoveAw:R: */ + address4 = instructionPointerAddress(); + /* begin gen:literal:operand: */ + checkLiteralforInstruction(address4, genoperandoperand(MoveAwR, address4, LinkReg)); /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSampleNonPrim)); + genoperand(Jump, ((sqInt)continueAfterProfileSample)); } - if (!(jmp == null)) { - - /* Jump to restore of receiver reg and proceed to frame build for failure. */ - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin MoveMw:r:R: */ - offset2 = BytesPerWord * (methodOrBlockNumArgs + (0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); - if (usesOutOfLineLiteral(anInstruction7)) { - (anInstruction7->dependent = locateLiteralsize(offset2, BytesPerOop)); - } + jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + /* begin MoveMw:r:R: */ + offset2 = BytesPerWord * (methodOrBlockNumArgs + (0)); + /* begin checkQuickConstant:forInstruction: */ + anInstruction7 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); + if (usesOutOfLineLiteral(anInstruction7)) { + (anInstruction7->dependent = locateLiteralsize(offset2, BytesPerOop)); } return 0; } @@ -27591,7 +27585,7 @@ compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)) if ((methodOrBlockNumArgs > 2 /* numRegArgs */) || (methodOrBlockNumArgs == 0)) { /* begin registerMaskFor: */ - liveRegsMask = 1U << ReceiverResultReg; + liveRegsMask = (1U << ReceiverResultReg); } else { if (methodOrBlockNumArgs > 1) { @@ -27662,6 +27656,7 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags sqInt address5; sqInt address6; sqInt address7; + sqInt address8; AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; AbstractInstruction *anInstruction10; @@ -27671,15 +27666,20 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags AbstractInstruction *anInstruction8; AbstractInstruction *anInstruction9; sqInt calleeSavedRegisterMask; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; + AbstractInstruction * jumpToTakeSample; sqInt linkRegSaveRegister; + sqInt liveRegisters; sqInt offset; sqInt offset1; sqInt operand1; + sqInt reg; AbstractInstruction * retry; AbstractInstruction * skip; sqInt spRegSaveRegister; + jumpToTakeSample = ((AbstractInstruction *) 0); linkRegSaveRegister = 0; assert(((flags & PrimCallOnSmalltalkStack) != 0)); assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); @@ -27707,14 +27707,14 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags /* begin gen:operand:literal: */ checkLiteralforInstruction(address5, genoperandoperand(MoveRAw, TempReg, address5)); genExternalizeStackPointerForFastPrimitiveCall(); - calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | (1U << ClassReg)) - (1U << ClassReg)); + calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | ((1U << ClassReg))) - ((1U << ClassReg))); linkRegSaveRegister = availableRegisterOrNoneIn(calleeSavedRegisterMask); assert(!((linkRegSaveRegister == NoReg))); /* begin MoveR:R: */ genoperandoperand(MoveRR, LinkReg, linkRegSaveRegister); - calleeSavedRegisterMask = ((calleeSavedRegisterMask | (1ULL << linkRegSaveRegister)) - (1ULL << linkRegSaveRegister)); + calleeSavedRegisterMask = ((calleeSavedRegisterMask | (((linkRegSaveRegister < 0) ? (((usqInt)(1)) >> (-linkRegSaveRegister)) : (1ULL << linkRegSaveRegister)))) - (((linkRegSaveRegister < 0) ? (((usqInt)(1)) >> (-linkRegSaveRegister)) : (1ULL << linkRegSaveRegister)))); spRegSaveRegister = NoReg; - if (!(((ABICalleeSavedRegisterMask & (1U << SPReg)) != 0))) { + if (!(((ABICalleeSavedRegisterMask & ((1U << SPReg))) != 0))) { spRegSaveRegister = availableRegisterOrNoneIn(calleeSavedRegisterMask); assert(!((spRegSaveRegister == NoReg))); /* begin MoveR:R: */ @@ -27728,8 +27728,11 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags else { genLoadNativeSPRegWithAlignedSPReg(backEnd); } + genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); /* begin gen:literal: */ - checkLiteralforInstruction(primitiveRoutine, genoperand(CallFull, primitiveRoutine)); + checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperand(CallFull, ((sqInt)primitiveRoutine))); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 6); /* begin MoveAw:R: */ address6 = primFailCodeAddress(); /* begin gen:literal:operand: */ @@ -27746,10 +27749,27 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags /* begin JumpNonZero: */ jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); genLoadCStackPointer(backEnd); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + reg = Arg0Reg; + gMovePerfCnt64RL(reg, liveRegisters); + /* begin MoveAw:R: */ + address8 = nextProfileTickAddress(); + /* begin gen:literal:operand: */ + checkLiteralforInstruction(address8, genoperandoperand(MoveAwR, address8, Arg1Reg)); + /* begin CmpR:R: */ + assert(!((reg == SPReg))); + genoperandoperand(CmpRR, reg, Arg1Reg); + /* begin JumpGreaterOrEqual: */ + jumpToTakeSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l33; + l33: /* end genCheckForProfileTimerTick: */; + } /* begin MoveAw:R: */ address7 = stackPointerAddress(); /* begin gen:literal:operand: */ - checkLiteralforInstruction(address7, genoperandoperand(MoveAwR, address7, TempReg)); + continueAfterProfileSample = checkLiteralforInstruction(address7, genoperandoperand(MoveAwR, address7, TempReg)); /* begin checkQuickConstant:forInstruction: */ anInstruction1 = genoperandoperandoperand(MoveMwrR, 0, TempReg, ReceiverResultReg); if (usesOutOfLineLiteral(anInstruction1)) { @@ -27760,6 +27780,12 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags genoperandoperand(MoveRR, linkRegSaveRegister, LinkReg); /* begin RetN: */ genoperand(RetN, 0); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); + /* begin Jump: */ + genoperand(Jump, ((sqInt)continueAfterProfileSample)); + } jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); if ((accessorDepthForExternalPrimitiveMethod(methodObj)) >= 0) { @@ -27795,10 +27821,11 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags else { genLoadCStackPointer(backEnd); } + genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); /* begin gen:literal: */ operand1 = ((usqIntptr_t)checkForAndFollowForwardedPrimitiveState); checkLiteralforInstruction(operand1, genoperand(CallFull, operand1)); - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); /* begin checkQuickConstant:forInstruction: */ anInstruction6 = genoperandoperand(CmpCqR, 0, ABIResultReg); if (usesOutOfLineLiteral(anInstruction6)) { @@ -27823,13 +27850,13 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags /* must reload SPReg to undo any alignment change, */ if (((flags & PrimCallOnSmalltalkStackAlign2x) != 0)) { - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); } } genLoadCStackPointer(backEnd); /* begin MoveR:R: */ genoperandoperand(MoveRR, linkRegSaveRegister, LinkReg); - if (((ABICallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((ABICallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* begin MoveMw:r:R: */ offset1 = (methodOrBlockNumArgs + (0)) * BytesPerWord; /* begin checkQuickConstant:forInstruction: */ @@ -28889,23 +28916,24 @@ genPrimitiveHashMultiply(void) static void NoDbgRegParms genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) { - sqInt address2; + sqInt address; sqInt address4; sqInt address6; sqInt address7; sqInt address8; AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction7; + AbstractInstruction *anInstruction4; + AbstractInstruction *anInstruction6; sqInt callTarget; AbstractInstruction *continuePostSample; AbstractInstruction * inst; AbstractInstruction *jmpFail; AbstractInstruction *jmpSample; + sqInt liveRegisters; sqInt quickConstant; sqInt reg; + sqInt reg1; continuePostSample = ((AbstractInstruction *) 0); jmpSample = ((AbstractInstruction *) 0); @@ -28917,41 +28945,43 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) if (usesOutOfLineLiteral(anInstruction)) { (anInstruction->dependent = locateLiteralsize(quickConstant, BytesPerOop)); } - if (profiling) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick: if so. - N.B. nextProfileTick is 64-bits so 32-bit systems need to test both halves. */ - /* begin MoveAw:R: */ - address2 = nextProfileTickAddress(); - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address2, genoperandoperand(MoveAwR, address2, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction1)) { - (anInstruction1->dependent = locateLiteralsize(0, BytesPerOop)); - } - /* begin JumpNonZero: */ - jmpSample = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } /* begin MoveAw:R: */ address6 = primFailCodeAddress(); /* begin gen:literal:operand: */ checkLiteralforInstruction(address6, genoperandoperand(MoveAwR, address6, TempReg)); flag("ask concrete code gen if move sets condition codes?"); /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(CmpCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction7)) { - (anInstruction7->dependent = locateLiteralsize(0, BytesPerOop)); + anInstruction6 = genoperandoperand(CmpCqR, 0, TempReg); + if (usesOutOfLineLiteral(anInstruction6)) { + (anInstruction6->dependent = locateLiteralsize(0, BytesPerOop)); } /* begin JumpNonZero: */ jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (profiling + && (1)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + reg = Arg0Reg; + gMovePerfCnt64RL(reg, liveRegisters); + /* begin MoveAw:R: */ + address = nextProfileTickAddress(); + /* begin gen:literal:operand: */ + checkLiteralforInstruction(address, genoperandoperand(MoveAwR, address, Arg1Reg)); + /* begin CmpR:R: */ + assert(!((reg == SPReg))); + genoperandoperand(CmpRR, reg, Arg1Reg); + /* begin JumpGreaterOrEqual: */ + jmpSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l8; + l8: /* end genCheckForProfileTimerTick: */; + /* begin Label */ + continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); + } genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); - if (usesOutOfLineLiteral(anInstruction2)) { - (anInstruction2->dependent = locateLiteralsize(0, BytesPerOop)); + anInstruction1 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); + if (usesOutOfLineLiteral(anInstruction1)) { + (anInstruction1->dependent = locateLiteralsize(0, BytesPerOop)); } /* begin MoveAw:R: */ address4 = instructionPointerAddress(); @@ -28967,18 +28997,19 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) compileCallFornumArgsargargargargresultRegregsToSave(ceActivateFailingPrimitiveMethod, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); /* begin MoveAw:R: */ address8 = instructionPointerAddress(); - reg = LinkReg; + reg1 = LinkReg; /* begin gen:literal:operand: */ - checkLiteralforInstruction(address8, genoperandoperand(MoveAwR, address8, reg)); + checkLiteralforInstruction(address8, genoperandoperand(MoveAwR, address8, reg1)); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); - if (usesOutOfLineLiteral(anInstruction5)) { - (anInstruction5->dependent = locateLiteralsize(0, BytesPerOop)); + anInstruction4 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); + if (usesOutOfLineLiteral(anInstruction4)) { + (anInstruction4->dependent = locateLiteralsize(0, BytesPerOop)); } /* begin RetN: */ genoperand(RetN, BytesPerWord); - if (profiling) { + if (profiling + && (1)) { /* Call ceCheckProfileTick: to record sample and then continue. newMethod should be up-to-date. Need to save and restore the link reg around this call. */ @@ -29359,6 +29390,23 @@ genStoreRemoteTempLongBytecode(void) && (shouldAnnotateObjectReference(((ssTop())->constant))))); } + /* SimpleStackBasedCogit>>#genTakeProfileSample */ +static void +genTakeProfileSample(void) +{ + sqInt operand1; + + addDependent(methodLabel, annotateAbsolutePCRef(gMoveCwR(((sqInt)methodLabel), ClassReg))); + genMarshallNArgsargargargarg(backEnd, 1, ClassReg, null, null, null); + genLoadNativeSPRegWithAlignedSPReg(backEnd); + /* begin gen:literal: */ + operand1 = ((usqIntptr_t)ceTakeProfileSample); + checkLiteralforInstruction(operand1, genoperand(CallFull, operand1)); + /* begin genRemoveNArgsFromStack: */ + assert(1 <= 6); + genLoadCStackPointer(backEnd); +} + /* Collect the branch and send data for cogMethod, storing it into arrayObj. */ @@ -29728,7 +29776,7 @@ primitiveGeneratorOrNil(void) static sqInt NoDbgRegParms registerisInMask(sqInt reg, sqInt mask) { - return ((mask & (1ULL << reg)) != 0); + return ((mask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0); } /* SimpleStackBasedCogit>>#v3:Block:Code:Size: */ @@ -30402,7 +30450,7 @@ genBinaryAtConstInlinePrimitive(sqInt primIndex) val = ((ssTop())->constant); if (primIndex == 65) { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); rr = ReceiverResultReg; } @@ -30418,10 +30466,10 @@ genBinaryAtConstInlinePrimitive(sqInt primIndex) break; case 65: /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << SendNumArgsReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << SendNumArgsReg), simStackPtr, simNativeStackPtr); /* begin genPushMaybeContextSlotIndex: */ assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ voidReceiverResultRegContainsSelf(); @@ -30511,13 +30559,13 @@ genBinaryAtInlinePrimitive(sqInt primIndex) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -30685,7 +30733,7 @@ genBinaryCompInlinePrimitive(sqInt primIndex) } otherReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); popToReg(ssTop(), otherReg); - resultReg = allocateRegForStackEntryAtnotConflictingWith(1, 1ULL << otherReg); + resultReg = allocateRegForStackEntryAtnotConflictingWith(1, ((otherReg < 0) ? (((usqInt)(1)) >> (-otherReg)) : (1ULL << otherReg))); popToReg(ssValue(1), resultReg); /* begin CmpR:R: */ assert(!((otherReg == SPReg))); @@ -31110,7 +31158,7 @@ genBinarySmiBitShiftLeftInlinePrimitive(void) genoperandoperand(LogicalShiftLeftCqR, quickConstant, rr); } else { - ra = allocateRegForStackEntryAtnotConflictingWith(0, 1ULL << rr); + ra = allocateRegForStackEntryAtnotConflictingWith(0, ((rr < 0) ? (((usqInt)(1)) >> (-rr)) : (1ULL << rr))); popToReg(ssTop(), ra); genConvertSmallIntegerToIntegerInReg(ra); /* begin LogicalShiftLeftR:R: */ @@ -31143,7 +31191,7 @@ genBinarySmiBitShiftRightInlinePrimitive(void) genoperandoperand(ArithmeticShiftRightCqR, quickConstant, rr); } else { - ra = allocateRegForStackEntryAtnotConflictingWith(0, 1ULL << rr); + ra = allocateRegForStackEntryAtnotConflictingWith(0, ((rr < 0) ? (((usqInt)(1)) >> (-rr)) : (1ULL << rr))); popToReg(ssTop(), ra); genConvertSmallIntegerToIntegerInReg(ra); /* begin ArithmeticShiftRightR:R: */ @@ -31248,13 +31296,13 @@ genBinaryVarOpVarSmiInlinePrimitive(sqInt primIndex) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -31325,7 +31373,7 @@ genByteAtPut(void) && (1)) { /* begin registerMaskFor: */ reg = (rTop1 = registerOrNone(ssTop())); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (((registerOrNone(ssValue(1))) != NoReg) && (1)) { @@ -31337,11 +31385,11 @@ genByteAtPut(void) } if (rThird1 == NoReg) { rThird1 = allocateRegNotConflictingWith(topRegistersMask); - topRegistersMask = topRegistersMask | (1ULL << rThird1); + topRegistersMask = topRegistersMask | (((rThird1 < 0) ? (((usqInt)(1)) >> (-rThird1)) : (1ULL << rThird1))); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); - topRegistersMask = topRegistersMask | (1ULL << rTop1); + topRegistersMask = topRegistersMask | (((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } if (rNext1 == NoReg) { rNext1 = allocateRegNotConflictingWith(topRegistersMask); @@ -31704,7 +31752,7 @@ genByteEqualsInlinePrimitive(sqInt prim) if (needLoop) { assert(!(((ssTop())->spilled))); str1Reg = allocateRegForStackEntryAtnotConflictingWith(1, 0 /* emptyRegisterMask */); - str2Reg = allocateRegForStackEntryAtnotConflictingWith(2, 1ULL << str1Reg); + str2Reg = allocateRegForStackEntryAtnotConflictingWith(2, ((str1Reg < 0) ? (((usqInt)(1)) >> (-str1Reg)) : (1ULL << str1Reg))); lenReg = allocateRegForStackEntryAtnotConflictingWith(0, (1ULL << str1Reg) | (1ULL << str2Reg)); popToReg(ssValue(1), str1Reg); popToReg(ssValue(2), str2Reg); @@ -31716,12 +31764,12 @@ genByteEqualsInlinePrimitive(sqInt prim) if (!((((ssValue(1))->type)) == SSConstant)) { str1Reg = allocateRegForStackEntryAtnotConflictingWith(1, mask); popToReg(ssValue(1), str1Reg); - mask = mask | (1ULL << str1Reg); + mask = mask | (((str1Reg < 0) ? (((usqInt)(1)) >> (-str1Reg)) : (1ULL << str1Reg))); } if (!((((ssValue(2))->type)) == SSConstant)) { str2Reg = allocateRegForStackEntryAtnotConflictingWith(2, mask); popToReg(ssValue(2), str2Reg); - mask = mask | (1ULL << str2Reg); + mask = mask | (((str2Reg < 0) ? (((usqInt)(1)) >> (-str2Reg)) : (1ULL << str2Reg))); } extraReg = allocateRegNotConflictingWith(mask); } @@ -31955,7 +32003,7 @@ genCounterTripOnlyJumpIfto(sqInt boolean, sqInt targetBytecodePC) /* We need SendNumArgsReg because of the mustBeBooleanTrampoline */ counterIndex += 1; /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << SendNumArgsReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << SendNumArgsReg), simStackPtr, simNativeStackPtr); /* begin checkQuickConstant:forInstruction: */ anInstruction1 = genoperandoperand(MoveCqR, 1, SendNumArgsReg); if (usesOutOfLineLiteral(anInstruction1)) { @@ -32083,13 +32131,13 @@ genDivInlinePrimitive(sqInt primIndex) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -32418,13 +32466,13 @@ genForwardersInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -32618,13 +32666,13 @@ genForwardersInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg1 = (rNext11 = registerOrNone(ssValue(1))); - topRegistersMask1 = 1ULL << reg1; + topRegistersMask1 = ((reg1 < 0) ? (((usqInt)(1)) >> (-reg1)) : (1ULL << reg1)); } if (rTop11 == NoReg) { rTop11 = allocateRegNotConflictingWith(topRegistersMask1); } if (rNext11 == NoReg) { - rNext11 = allocateRegNotConflictingWith(1ULL << rTop11); + rNext11 = allocateRegNotConflictingWith(((rTop11 < 0) ? (((usqInt)(1)) >> (-rTop11)) : (1ULL << rTop11))); } assert(!(((rTop11 == NoReg) || (rNext11 == NoReg)))); @@ -32678,12 +32726,12 @@ genForwardersInlinedIdenticalOrNotIf(sqInt orNot) } if (argReg == NoReg) { /* begin registerMaskFor: */ - regMask = 1ULL << rcvrReg; + regMask = ((rcvrReg < 0) ? (((usqInt)(1)) >> (-rcvrReg)) : (1ULL << rcvrReg)); } else { if (rcvrReg == NoReg) { /* begin registerMaskFor: */ - regMask = 1ULL << argReg; + regMask = ((argReg < 0) ? (((usqInt)(1)) >> (-argReg)) : (1ULL << argReg)); } else { /* begin registerMaskFor:and: */ @@ -33344,7 +33392,7 @@ genJumpIfto(sqInt boolean, sqInt targetBytecodePC) popToReg(desc, TempReg); ssPop(1); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << SendNumArgsReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << SendNumArgsReg), simStackPtr, simNativeStackPtr); /* begin Label */ retry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); /* begin genExecutionCountLogicInto:counterReg: */ @@ -33809,13 +33857,13 @@ genPointerAtPutConstantMaybeContextstoreCheckimmutabilityCheck(sqInt maybeContex rcvrReg = ReceiverResultReg; } else { - rcvrReg = allocateRegForStackEntryAtnotConflictingWith(2, 1ULL << valReg); + rcvrReg = allocateRegForStackEntryAtnotConflictingWith(2, ((valReg < 0) ? (((usqInt)(1)) >> (-valReg)) : (1ULL << valReg))); } } /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1ULL << valReg, simStackPtr - 2, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((valReg < 0) ? (((usqInt)(1)) >> (-valReg)) : (1ULL << valReg)), simStackPtr - 2, simNativeStackPtr); /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1ULL << rcvrReg, simStackPtr - 3, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((rcvrReg < 0) ? (((usqInt)(1)) >> (-rcvrReg)) : (1ULL << rcvrReg)), simStackPtr - 3, simNativeStackPtr); popToReg(ssTop(), valReg); ssPop(1); if (((ssTop())->spilled)) { @@ -33862,7 +33910,7 @@ genPointerAtPutConstantMaybeContextstoreCheckimmutabilityCheck(sqInt maybeContex # endif // IMMUTABILITY ssPop(1); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ClassReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ssPush(1); genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); ssStoreAndReplacePoptoReg(0, ClassReg); @@ -33895,7 +33943,7 @@ genPointerAtPutConstantMaybeContextstoreCheckimmutabilityCheck(sqInt maybeContex # if IMMUTABILITY if (needsImmCheck) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(0, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -33909,7 +33957,7 @@ genPointerAtPutConstantMaybeContextstoreCheckimmutabilityCheck(sqInt maybeContex return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, indexCst, rcvrReg, TempReg, needsStoreCheck, 0); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1ULL << rcvrReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, ((rcvrReg < 0) ? (((usqInt)(1)) >> (-rcvrReg)) : (1ULL << rcvrReg))); ssStorePoptoReg(0, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, indexCst, rcvrReg, TempReg, needsFrame, needsStoreCheck); } @@ -34185,7 +34233,7 @@ genPointerAtPutStoreCheck(sqInt needsStoreCheck) || ((registerOrNone(ssTop())) != ReceiverResultReg))) { /* begin registerMaskFor: */ reg = (rTop1 = registerOrNone(ssTop())); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (((registerOrNone(ssValue(1))) != NoReg) && ((!needsStoreCheck) @@ -34203,17 +34251,17 @@ genPointerAtPutStoreCheck(sqInt needsStoreCheck) /* Free ReceiverResultReg if it was not free */ rThird1 = ReceiverResultReg; /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); } else { rThird1 = allocateRegNotConflictingWith(topRegistersMask); } - topRegistersMask = topRegistersMask | (1ULL << rThird1); + topRegistersMask = topRegistersMask | (((rThird1 < 0) ? (((usqInt)(1)) >> (-rThird1)) : (1ULL << rThird1))); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); - topRegistersMask = topRegistersMask | (1ULL << rTop1); + topRegistersMask = topRegistersMask | (((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } if (rNext1 == NoReg) { rNext1 = allocateRegNotConflictingWith(topRegistersMask); @@ -34752,7 +34800,7 @@ genUnaryClassPrimitive(void) sqInt topReg; topReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - destReg = allocateRegNotConflictingWith(1ULL << topReg); + destReg = allocateRegNotConflictingWith(((topReg < 0) ? (((usqInt)(1)) >> (-topReg)) : (1ULL << topReg))); popToReg(ssTop(), topReg); /* begin MoveR:R: */ genoperandoperand(MoveRR, topReg, TempReg); @@ -34828,7 +34876,7 @@ genUnaryHashInlinePrimitive(sqInt primIndex) switch (primIndex) { case 20: rcvrReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - resultReg = allocateRegNotConflictingWith(1ULL << rcvrReg); + resultReg = allocateRegNotConflictingWith(((rcvrReg < 0) ? (((usqInt)(1)) >> (-rcvrReg)) : (1ULL << rcvrReg))); popToReg(ssTop(), rcvrReg); genGetIdentityHashresultReg(rcvrReg, resultReg); break; @@ -35019,7 +35067,7 @@ genUnarySizeInlinePrimitive(sqInt primIndex) assert(((primIndex >= 1) && (primIndex <= 6))); rcvrReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - resultReg = allocateRegNotConflictingWith(1ULL << rcvrReg); + resultReg = allocateRegNotConflictingWith(((rcvrReg < 0) ? (((usqInt)(1)) >> (-rcvrReg)) : (1ULL << rcvrReg))); popToReg(ssTop(), rcvrReg); ssPop(1); ssPushRegister(resultReg); @@ -36331,7 +36379,7 @@ anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n) sqInt regMask; /* begin registerMaskFor: */ - regMask = 1ULL << reg; + regMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { if ((((registerMask(simStackAt(i))) & regMask) != 0)) { return 1; @@ -37053,7 +37101,7 @@ ensureReceiverResultRegContainsSelf(void) if (needsFrame) { if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin putSelfInReceiverResultReg */ storeToReg(simSelf(), ReceiverResultReg); ((simSelf())->liveRegister = ReceiverResultReg); @@ -37185,7 +37233,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) && (index < simStackPtr)) { desc = simStackAt(index); if (((desc->type)) == SSRegister) { - if (!(((regMask & (1ULL << ((desc->registerr)))) != 0))) { + if (!(((regMask & (((((desc->registerr)) < 0) ? (((usqInt)(1)) >> (-((desc->registerr)))) : (1ULL << ((desc->registerr)))))) != 0))) { reg = (desc->registerr); } } @@ -37193,7 +37241,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) } assert(!((reg == NoReg))); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1ULL << reg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)), simStackPtr, simNativeStackPtr); return reg; } @@ -38360,11 +38408,11 @@ genPushMaybeContextReceiverVariable(sqInt slotIndex) AbstractInstruction *jmpSingle; /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ensureReceiverResultRegContainsSelf(); /* begin genPushMaybeContextSlotIndex: */ assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ voidReceiverResultRegContainsSelf(); @@ -38423,7 +38471,7 @@ genPushNewArrayBytecode(void) } else { /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << SendNumArgsReg)) | ((1U << ReceiverResultReg))), simStackPtr, simNativeStackPtr); } size = byte1 & 0x7F; if (!popValues) { @@ -38499,7 +38547,7 @@ genPushRemoteTempLongBytecode(void) (anInstruction->dependent = locateLiteralsize(offset, BytesPerOop)); } /* begin availableRegOrNoneNotConflictingWith: */ - regMask = 1ULL << tempVectReg; + regMask = ((tempVectReg < 0) ? (((usqInt)(1)) >> (-tempVectReg)) : (1ULL << tempVectReg)); remoteTempReg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); if (remoteTempReg == NoReg) { remoteTempReg = tempVectReg; @@ -38877,11 +38925,11 @@ genSpecialSelectorClass(void) || (topReg == ClassReg)) { /* begin ssAllocateRequiredReg:and: */ requiredReg1 = (topReg = SendNumArgsReg); - ssAllocateRequiredRegMaskupThroughupThroughNative((1ULL << requiredReg1) | (1U << ClassReg), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((((requiredReg1 < 0) ? (((usqInt)(1)) >> (-requiredReg1)) : (1ULL << requiredReg1))) | ((1U << ClassReg)), simStackPtr, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr, simNativeStackPtr); } ssPush(1); popToReg(ssTop(), topReg); @@ -38953,7 +39001,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean association = getLiteral(litVarIndex); voidReceiverResultRegContainsSelf(); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin genMoveConstant:R: */ if (shouldAnnotateObjectReference(association)) { annotateobjRef(gMoveCwR(association, ReceiverResultReg), association); @@ -38969,7 +39017,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean # if IMMUTABILITY if (needsImmCheck) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -38983,7 +39031,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -39047,7 +39095,7 @@ genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqI # endif // IMMUTABILITY ssPop(1); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ClassReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ssPush(1); genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); @@ -39095,7 +39143,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea # if IMMUTABILITY if (needsImmCheck1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -39109,7 +39157,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck1, 1); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck1); } @@ -39133,7 +39181,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt assert(needsFrame); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); /* begin MoveMw:r:R: */ offset = frameOffsetOfTemporary(remoteTempIndex); @@ -39146,7 +39194,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt # if IMMUTABILITY # endif - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -39337,13 +39385,13 @@ genVanillaInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -39606,12 +39654,12 @@ liveRegisters(void) } else { /* begin registerMaskFor: */ - regsSet = 1U << ReceiverResultReg; + regsSet = (1U << ReceiverResultReg); if ((methodOrBlockNumArgs <= 2 /* numRegArgs */) && (methodOrBlockNumArgs > 0)) { - regsSet = regsSet | (1U << Arg0Reg); + regsSet = regsSet | ((1U << Arg0Reg)); if (methodOrBlockNumArgs > 1) { - regsSet = regsSet | (1U << Arg1Reg); + regsSet = regsSet | ((1U << Arg1Reg)); } } } @@ -39714,13 +39762,13 @@ marshallSendArguments(sqInt numArgs) if (numArgs > 0) { if (numArgs > 1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 2, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 2, simNativeStackPtr); /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg1Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg1Reg), simStackPtr - 1, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 1, simNativeStackPtr); } } if (numArgs > 1) { diff --git a/spursista64src/vm/cogitX64SysV.c b/spursista64src/vm/cogitX64SysV.c index 1a83fabba8..6cc4476717 100644 --- a/spursista64src/vm/cogitX64SysV.c +++ b/spursista64src/vm/cogitX64SysV.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + CCodeGenerator VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - SistaCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + SistaCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "SistaCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 " __DATE__ ; +static char __buildInfo[] = "SistaCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__cogitBuildInfo = __buildInfo; @@ -54,7 +54,7 @@ char *__cogitBuildInfo = __buildInfo; #define ArithmeticShiftRightRR 92 #define BadRegisterSet 1 #define BlockCreationBytecodeSize 4 -#define BSR 167 +#define BSR 169 #define BytecodeSetHasDirectedSuperSend 1 #define CArg0Reg 7 #define CArg1Reg 6 @@ -64,11 +64,11 @@ char *__cogitBuildInfo = __buildInfo; #define CallerSavedRegisterMask 0x2C6 #define CallFull 7 #define CallR 8 -#define CDQ 159 +#define CDQ 161 #if !defined(CheckRememberedInTrampoline) /* Allow this to be overridden on the compiler command line */ # define CheckRememberedInTrampoline 0 #endif -#define CLD 163 +#define CLD 165 #define ClassArray 7 #define ClassArrayCompactIndex 51 #define ClassBlockClosureCompactIndex 37 @@ -91,7 +91,7 @@ char *__cogitBuildInfo = __buildInfo; #define CMMaxUsageCount 7 #define CMMethod 2 #define CMOpenPIC 5 -#define CMPXCHGRMr 172 +#define CMPXCHGRMr 174 #define CmpC32R 113 #define CmpCqR 105 #define CmpCwR 112 @@ -107,7 +107,7 @@ char *__cogitBuildInfo = __buildInfo; #define ConvertRsR 149 #define ConvertRsRd 147 #define CounterBytes 4 -#define CPUID 158 +#define CPUID 160 #define Debug DEBUGVM #define DisplacementMask 0x1F #define DisplacementX2N 0 @@ -151,11 +151,11 @@ char *__cogitBuildInfo = __buildInfo; #define HashMultiplyConstant 1664525 #define HashMultiplyMask 0xFFFFFFF #define HeaderIndex 0 -#define IDIVR 160 +#define IDIVR 162 #if !defined(IMMUTABILITY) /* Allow this to be overridden on the compiler command line */ # define IMMUTABILITY 1 #endif -#define IMULRR 161 +#define IMULRR 163 #define InFullBlock 2 #define InstanceSpecificationIndex 2 #define InstructionPointerIndex 1 @@ -206,11 +206,11 @@ char *__cogitBuildInfo = __buildInfo; #define Label 1 #define LargeContextSlots 62 #define LastJump 42 -#define LFENCE 168 +#define LFENCE 170 #undef LinkReg #define Literal 2 #define LiteralStart 1 -#define LOCK 171 +#define LOCK 173 #define LoadEffectiveAddressMwrR 88 #define LogicalShiftLeftCqR 95 #define LogicalShiftLeftCqRR 129 @@ -234,11 +234,11 @@ char *__cogitBuildInfo = __buildInfo; #define MethodCacheSelector 1 #define MethodIndex 3 #define MethodTooBig -4 -#define MFENCE 169 +#define MFENCE 171 #define MFMethodFlagHasContextFlag 1 #define MFMethodFlagIsBlockFlag 2 -#define MOVSB 165 -#define MOVSQ 166 +#define MOVSB 167 +#define MOVSQ 168 #define ModReg 3 #define ModRegInd 0 #define ModRegRegDisp32 2 @@ -257,10 +257,12 @@ char *__cogitBuildInfo = __buildInfo; #define MoveMbrR 65 #define MoveMs8rR 55 #define MoveMwrR 50 +#define MovePerfCnt64RL 159 +#define MovePerfCnt64RRL 158 #define MoveRA32 47 #define MoveRAb 49 #define MoveRAw 46 -#define MoveRAwNoVBR 174 +#define MoveRAwNoVBR 176 #define MoveRdM64r 76 #define MoveRdR 73 #define MoveRdRd 74 @@ -330,7 +332,7 @@ char *__cogitBuildInfo = __buildInfo; #define RCX 1 #define RDI 7 #define RDX 2 -#define REP 164 +#define REP 166 #define ReceiverIndex 5 #define ReceiverResultReg 2 #define RetN 9 @@ -339,12 +341,12 @@ char *__cogitBuildInfo = __buildInfo; #define RotateRightCqR 98 #define RSI 6 #define RSP 4 -#define SETE 173 +#define SETE 175 #define SelectorCannotInterpret 34 #define SelectorDoesNotUnderstand 20 #define SenderIndex 0 #define SendNumArgsReg 9 -#define SFENCE 170 +#define SFENCE 172 #define ShouldNotJIT -8 #define SIB1 0 #define SIB4 2 @@ -383,7 +385,7 @@ char *__cogitBuildInfo = __buildInfo; #define UnimplementedPrimitive -7 #define ValueIndex 1 #define VarBaseReg 3 -#define XCHGRR 162 +#define XCHGRR 164 #define XMM0L 0 #define XorCwR 118 #define XorRdRd 137 @@ -515,7 +517,7 @@ static sqInt NoDbgRegParms concretizeAt(AbstractInstruction * self_in_concretize static sqInt NoDbgRegParms genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer); static sqInt NoDbgRegParms genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers); static sqInt NoDbgRegParms genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers); -static sqInt NoDbgRegParms genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg); +static sqInt NoDbgRegParms genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg); static sqInt NoDbgRegParms genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers); static void NoDbgRegParms genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister); static void NoDbgRegParms initializeSharableLiteral(AbstractInstruction * self_in_initializeSharableLiteral, sqInt literal); @@ -691,6 +693,8 @@ extern void linkSendAtintooffsetreceiver(sqInt callSiteReturnAddress, CogMethod static BytecodeDescriptor * loadBytesAndGetDescriptor(void); static void NoDbgRegParms loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc); static AbstractInstruction * NoDbgRegParms gMoveCwR(sqInt wordConstant, sqInt reg); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters); static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg); static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC); @@ -1035,6 +1039,7 @@ static sqInt NoDbgRegParms computeShiftRRSize(AbstractInstruction * self_in_comp static sqInt NoDbgRegParms computeSizeOfPushCw(AbstractInstruction * self_in_computeSizeOfPushCw); static sqInt NoDbgRegParms concretizeArithCqRWithROraxOpcode(AbstractInstruction * self_in_concretizeArithCqRWithROraxOpcode, sqInt regOpcode, sqInt raxOpcode); static sqInt NoDbgRegParms concretizeFill32(AbstractInstruction * self_in_concretizeFill32); +static sqInt NoDbgRegParms concretizeMovePerfCnt64RL(AbstractInstruction * self_in_concretizeMovePerfCnt64RL); static sqInt NoDbgRegParms concretizeMoveRX32rR(AbstractInstruction * self_in_concretizeMoveRX32rR); static sqInt NoDbgRegParms concretizeMoveX32rRR(AbstractInstruction * self_in_concretizeMoveX32rRR); static sqInt NoDbgRegParms concretizeOpRR(AbstractInstruction * self_in_concretizeOpRR, sqInt x64opcode); @@ -1179,6 +1184,7 @@ static sqInt genStoreAndPopReceiverVariableBytecode(void); static sqInt genStoreAndPopRemoteTempLongBytecode(void); static sqInt genStoreAndPopTemporaryVariableBytecode(void); static sqInt genStoreRemoteTempLongBytecode(void); +static void genTakeProfileSample(void); extern sqInt mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj); static sqInt numSpecialSelectors(void); static usqInt NoDbgRegParms pcDataForBlockEntryMethod(sqInt blockEntryMcpc, sqInt cogMethod); @@ -2797,28 +2803,28 @@ addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *an static sqInt NoDbgRegParms availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << DPFPReg0)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg0))) != 0))) { return DPFPReg0; } - if (!(((liveRegsMask & (1U << DPFPReg1)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg1))) != 0))) { return DPFPReg1; } - if (!(((liveRegsMask & (1U << DPFPReg2)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg2))) != 0))) { return DPFPReg2; } - if (!(((liveRegsMask & (1U << DPFPReg3)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg3))) != 0))) { return DPFPReg3; } - if (!(((liveRegsMask & (1U << DPFPReg4)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg4))) != 0))) { return DPFPReg4; } - if (!(((liveRegsMask & (1U << DPFPReg5)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg5))) != 0))) { return DPFPReg5; } - if (!(((liveRegsMask & (1U << DPFPReg6)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg6))) != 0))) { return DPFPReg6; } - if (!(((liveRegsMask & (1U << DPFPReg7)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg7))) != 0))) { return DPFPReg7; } return NoReg; @@ -2933,9 +2939,9 @@ genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers) used immediately afterwards. */ - /* CogAbstractInstruction>>#genLoadStackPointersForFastPrimCall: */ + /* CogAbstractInstruction>>#genLoadStackPointersForPrimCall: */ static sqInt NoDbgRegParms -genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg) +genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg) { AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; @@ -5823,7 +5829,7 @@ compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numAr regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1ULL << resultRegOrNone)) - (1ULL << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ regMaskCopy = ((usqInt)regsToSave); @@ -7430,7 +7436,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) startAddress = methodZoneBase; callerSavedReg = 0; pushedVarBaseReg = 0; - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { /* VarBaseReg is not caller-saved; must save and restore it, either by using an available caller-saved reg or push/pop. */ @@ -7463,7 +7469,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) /* begin checkLiteral:forInstruction: */ cStackPointerAddress(); anInstruction3 = genoperandoperand(MoveRAw, TempReg, cStackPointerAddress()); - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { if (pushedVarBaseReg) { gNativePopR(VarBaseReg); } @@ -8747,6 +8753,22 @@ gMoveCwR(sqInt wordConstant, sqInt reg) return anInstruction; } + /* Cogit>>#MovePerfCnt64R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters) +{ + assert(BytesPerWord == 8); + return genoperandoperand(MovePerfCnt64RL, destReg, liveRegisters); +} + + /* Cogit>>#MovePerfCnt64R:R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters) +{ + assert(BytesPerWord == 4); + return genoperandoperandoperand(MovePerfCnt64RRL, destRegLo, destRegHi, liveRegisters); +} + /* Answer the address of the null byte at the end of the method map. */ @@ -10331,11 +10353,14 @@ recordRunTimeObjectReferences(void) } } + +/* N.B. (self registerMaskFor: NoReg) = 0 */ + /* Cogit>>#registerMaskFor: */ static sqInt NoDbgRegParms registerMaskFor(sqInt reg) { - return 1ULL << reg; + return ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } /* Cogit>>#registerMaskFor:and: */ @@ -17435,7 +17460,7 @@ generateObjectRepresentationTrampolines(void) } # endif // IMMUTABILITY ceNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceNewHash", 1, ReceiverResultReg, null, null, null, /* begin emptyRegisterMask */ 0, 1, ReceiverResultReg, 0); - ceInlineNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceInlineNewHash", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, ReceiverResultReg, 0); + ceInlineNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceInlineNewHash", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))), 1, ReceiverResultReg, 0); /* begin genStoreCheckTrampoline */ if (CheckRememberedInTrampoline) { zeroOpcodeIndex(); @@ -17446,7 +17471,7 @@ generateObjectRepresentationTrampolines(void) genoperand(RetN, 0); jmpTarget(jumpSC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); } - ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))), 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), CheckRememberedInTrampoline); ceStoreCheckContextReceiverTrampoline = genStoreCheckContextReceiverTrampoline(); @@ -19419,7 +19444,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jumpRC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg)); jmpTarget(jumpImmutable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); @@ -19435,7 +19460,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* Store check */ jumpImmutable1 = genJumpImmutablescratchReg(ReceiverResultReg, SendNumArgsReg); - compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), 0 /* emptyRegisterMask */); genLoadStackPointers(backEnd()); @@ -19504,7 +19529,7 @@ genStoreValueinstancenumSlots(sqInt value, sqInt destReg, sqInt numSlots) } return 0; } - constReg = allocateRegNotConflictingWith(1ULL << destReg); + constReg = allocateRegNotConflictingWith(((destReg < 0) ? (((usqInt)(1)) >> (-destReg)) : (1ULL << destReg))); if (shouldAnnotateObjectReference(value)) { annotateobjRef(gMoveCwR(value, constReg), value); } @@ -20405,7 +20430,7 @@ registerMask(SimStackEntry * self_in_registerMask) || (((self_in_registerMask->type)) == SSRegister) ? (/* begin registerMaskFor: */ (reg = (self_in_registerMask->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : 0); } @@ -20418,7 +20443,7 @@ registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone) return (((self_in_registerMaskOrNone->type)) == SSRegister ? (/* begin registerMaskFor: */ (reg = (self_in_registerMaskOrNone->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : 0); } @@ -20493,37 +20518,37 @@ isMergeFixup(BytecodeFixup * self_in_isMergeFixup) static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << Extra5Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra5Reg))) != 0))) { return Extra5Reg; } - if (!(((liveRegsMask & (1U << Extra4Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra4Reg))) != 0))) { return Extra4Reg; } - if (!(((liveRegsMask & (1U << Extra3Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra3Reg))) != 0))) { return Extra3Reg; } - if (!(((liveRegsMask & (1U << Extra2Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra2Reg))) != 0))) { return Extra2Reg; } - if (!(((liveRegsMask & (1U << Extra1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra1Reg))) != 0))) { return Extra1Reg; } - if (!(((liveRegsMask & (1U << Extra0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra0Reg))) != 0))) { return Extra0Reg; } - if (!(((liveRegsMask & (1U << Arg1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg1Reg))) != 0))) { return Arg1Reg; } - if (!(((liveRegsMask & (1U << Arg0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg0Reg))) != 0))) { return Arg0Reg; } - if (!(((liveRegsMask & (1U << SendNumArgsReg)) != 0))) { + if (!(((liveRegsMask & ((1U << SendNumArgsReg))) != 0))) { return SendNumArgsReg; } - if (!(((liveRegsMask & (1U << ClassReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ClassReg))) != 0))) { return ClassReg; } - if (!(((liveRegsMask & (1U << ReceiverResultReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ReceiverResultReg))) != 0))) { return ReceiverResultReg; } return NoReg; @@ -21109,6 +21134,11 @@ computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize) ? 1 : 0)); + case MovePerfCnt64RL: + + /* it is easier to calculate the right value by concretizing. We concretize twice, but so what? */ + return concretizeMovePerfCnt64RL(self_in_computeMaximumSize); + default: error("Case not found and no otherwise clause"); } @@ -21200,6 +21230,65 @@ concretizeFill32(AbstractInstruction * self_in_concretizeFill32) return 4; } + +/* Generate code for + 0x0: 50 pushq %rax + 0x1: 52 pushq %rdx + 0x2: 0f 31 rdtsc + 0x4: 48 c1 e2 20 shlq $0x20, %rdx + 0x8: 48 09 d0 orq %rdx, %rax + 0xb: 48 89 f8 movq %rdi, %rax + 0xe: 5a popq %rdx + 0xf: 58 popq %rax + et al */ + + /* CogX64Compiler>>#concretizeMovePerfCnt64RL */ +static sqInt NoDbgRegParms +concretizeMovePerfCnt64RL(AbstractInstruction * self_in_concretizeMovePerfCnt64RL) +{ + usqInt liveRegisters; + sqInt offset; + usqInt reg; + + reg = ((self_in_concretizeMovePerfCnt64RL->operands))[0]; + liveRegisters = ((self_in_concretizeMovePerfCnt64RL->operands))[1]; + offset = 0; + if (((liveRegisters & ((1U << RAX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[0] = 80; + offset += 1; + } + if (((liveRegisters & ((1U << RDX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 82; + offset += 1; + } + assert(!((reg == RDX))); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 15; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 1] = 49; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 2] = (rexRxb(self_in_concretizeMovePerfCnt64RL, 0, 0, RDX)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 3] = 193; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 4] = (modRMRO(self_in_concretizeMovePerfCnt64RL, ModReg, RDX, 4)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 5] = 32; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 6] = (rexRxb(self_in_concretizeMovePerfCnt64RL, RDX, 0, RAX)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 7] = 11; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 8] = (modRMRO(self_in_concretizeMovePerfCnt64RL, ModReg, RAX, RDX)); + offset += 9; + if (reg != RAX) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[11] = (rexRxb(self_in_concretizeMovePerfCnt64RL, reg, 0, RAX)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[12] = 137; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[13] = (modRMRO(self_in_concretizeMovePerfCnt64RL, ModReg, RAX, reg)); + offset += 3; + } + if (((liveRegisters & ((1U << RDX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 90; + offset += 1; + } + if (((liveRegisters & ((1U << RAX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 88; + offset += 1; + } + return offset; +} + /* CogX64Compiler>>#concretizeMoveRX32rR */ static sqInt NoDbgRegParms concretizeMoveRX32rR(AbstractInstruction * self_in_concretizeMoveRX32rR) @@ -24602,6 +24691,9 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) ((self_in_dispatchConcretize->machineCode))[skip28 + 1] = (modRMRO(self_in_dispatchConcretize, ModReg, srcReg28, destReg29)); return skip28 + 2; + case MovePerfCnt64RL: + return concretizeMovePerfCnt64RL(self_in_dispatchConcretize); + default: error("Case not found and no otherwise clause"); } @@ -25230,8 +25322,8 @@ genPushRegisterArgsForNumArgsscratchReg(AbstractInstruction * self_in_genPushReg /* This is a no-op on x64 SysV since the ABI passes up to 6 args in registers and trampolines currently observe a limit of 4. - But the WIN64 ABI allways reserve shadow space for saving up to 4 - parameter registers (even if less than 4 args). + But the WIN64 ABI always reserve shadow space for saving up to 4 parameter + registers (even if less than 4 args). */ /* CogX64Compiler>>#genRemoveNArgsFromStack: */ @@ -25253,7 +25345,7 @@ genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask) assert(!((((regMask & (registerMaskForand(RSP, RBP))) != 0)))); for (reg = RAX; reg <= R15; reg += 1) { - if (((regMask & (1ULL << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0)) { /* begin PopR: */ genoperand(PopR, reg); } @@ -25275,7 +25367,7 @@ genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask) assert(((R15 - RAX) + 1) == 16); assert(!((((regMask & (registerMaskForand(RSP, RBP))) != 0)))); for (reg = R15; reg >= RAX; reg += -1) { - if (((regMask & (1ULL << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0)) { /* begin PushR: */ genoperand(PushR, reg); } @@ -26096,53 +26188,42 @@ compileInterpreterPrimitive(void) static sqInt NoDbgRegParms compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) { - sqInt address2; + AbstractInstruction *anInstruction; + AbstractInstruction *anInstruction1; AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction12; + AbstractInstruction *anInstruction11; AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction15; + AbstractInstruction *anInstruction14; + AbstractInstruction *anInstruction16; + AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction18; AbstractInstruction *anInstruction19; AbstractInstruction *anInstruction2; + AbstractInstruction *anInstruction20; AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction24; - AbstractInstruction *anInstruction25; + AbstractInstruction *anInstruction22; AbstractInstruction *anInstruction26; AbstractInstruction *anInstruction27; + AbstractInstruction *anInstruction28; AbstractInstruction *anInstruction29; AbstractInstruction *anInstruction3; + AbstractInstruction *anInstruction30; AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction33; - AbstractInstruction *anInstruction34; - AbstractInstruction *anInstruction35; - AbstractInstruction *anInstruction36; - AbstractInstruction *anInstruction37; - AbstractInstruction *anInstruction38; - AbstractInstruction *anInstruction39; AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction40; AbstractInstruction *anInstruction41; - AbstractInstruction *anInstruction5; AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; AbstractInstruction *anInstruction8; - AbstractInstruction * continuePostSampleNonPrim; - AbstractInstruction * continuePostSamplePrim; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; - AbstractInstruction * jmpSampleNonPrim; - AbstractInstruction * jmpSamplePrim; + AbstractInstruction * jumpToTakeSample; + sqInt liveRegisters; sqInt offset; sqInt offset1; sqInt offset2; - sqInt operand1; - sqInt operand3; sqInt reg; sqInt retpc; - continuePostSampleNonPrim = ((AbstractInstruction *) 0); - continuePostSamplePrim = ((AbstractInstruction *) 0); - jmpSampleNonPrim = ((AbstractInstruction *) 0); - jmpSamplePrim = ((AbstractInstruction *) 0); + jumpToTakeSample = ((AbstractInstruction *) 0); assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); genExternalizePointersForPrimitiveCall(); /* begin genLoadCStackPointersForPrimCall */ @@ -26152,41 +26233,28 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) else { genLoadCStackPointer(backEnd); } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick if so */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction2 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpSampleNonPrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSampleNonPrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } if (recordPrimTraceForMethod(methodObj)) { genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction37 = genoperandoperand(MoveCqR, 0, TempReg); + anInstruction18 = genoperandoperand(MoveCqR, 0, TempReg); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction38 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); + anInstruction19 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); + anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); } /* begin checkLiteral:forInstruction: */ argumentCountAddress(); - anInstruction39 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); + anInstruction20 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { /* begin checkLiteral:forInstruction: */ ((sqInt)primitiveRoutine); - anInstruction5 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); + anInstruction1 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); /* begin checkLiteral:forInstruction: */ primitiveFunctionPointerAddress(); - anInstruction6 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); + anInstruction2 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); } if (((flags & (PrimCallNeedsNewMethod + PrimCallMayEndureCodeCompaction)) != 0)) { @@ -26198,26 +26266,25 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) /* begin MoveMw:r:R: */ offset = offsetof(CogMethod, methodObject); /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); + anInstruction3 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); /* begin checkLiteral:forInstruction: */ newMethodAddress(); - anInstruction8 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); + anInstruction4 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); } /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction40 = genoperand(PrefetchAw, primFailCodeAddress()); + anInstruction22 = genoperand(PrefetchAw, primFailCodeAddress()); if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - /* Sideways call the C primitive routine so that we return through cePrimReturnEnterCogCode. */ /* On Spur ceActivateFailingPrimitiveMethod: would like to retry if forwarders are found. So insist on PrimCallNeedsPrimitiveFunction being set too. */ assert(((flags & PrimCallNeedsPrimitiveFunction) != 0)); /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l32; + goto l20; assert(0 <= 4); if (null < NoReg) { /* begin MoveCq:R: */ - anInstruction12 = genoperandoperand(MoveCqR, -2 - null, CArg0Reg); + anInstruction11 = genoperandoperand(MoveCqR, -2 - null, CArg0Reg); } else { if (null != CArg0Reg) { @@ -26255,109 +26322,88 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) genoperandoperand(MoveRR, null, CArg3Reg); } } - l32: /* end genMarshallNArgs:arg:arg:arg:arg: */; + l20: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin genSubstituteReturnAddress: */ retpc = (((flags & PrimCallCollectsProfileSamples) != 0) ? cePrimReturnEnterCogCodeProfiling : cePrimReturnEnterCogCode); /* begin checkLiteral:forInstruction: */ - anInstruction13 = genoperand(PushCw, retpc); + anInstruction8 = genoperand(PushCw, retpc); /* begin gen:literal: */ - anInstruction10 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); - jmp = (jmpSamplePrim = (continuePostSamplePrim = null)); + anInstruction6 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); + return 0; } - else { - - /* Call the C primitive routine. */ - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l49; - assert(0 <= 4); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg0Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg1Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg2Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg3Reg); - l49: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin gen:literal: */ - anInstruction15 = genoperand(CallFull, ((sqInt)primitiveRoutine)); - /* begin genRemoveNArgsFromStack: */ - assert(0 <= 4); - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction18 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpSamplePrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSamplePrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - maybeCompileRetryOnPrimitiveFail(primitiveIndex); - /* begin MoveAw:R: */ - address2 = instructionPointerAddress(); - reg = ClassReg; - /* begin checkLiteral:forInstruction: */ - anInstruction24 = genoperandoperand(MoveAwR, address2, reg); - genLoadStackPointers(backEnd); + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + goto l43; + assert(0 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg0Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg1Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg2Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg3Reg); + l43: /* end genMarshallNArgs:arg:arg:arg:arg: */; + /* begin gen:literal: */ + anInstruction10 = genoperand(CallFull, ((sqInt)primitiveRoutine)); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 4); + maybeCompileRetryOnPrimitiveFail(primitiveIndex); + genLoadStackPointersForPrimCall(backEnd, ClassReg); + /* begin checkLiteral:forInstruction: */ + instructionPointerAddress(); + anInstruction13 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); + /* begin checkQuickConstant:forInstruction: */ + anInstruction14 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + /* begin checkLiteral:forInstruction: */ + primFailCodeAddress(); + anInstruction26 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + flag("ask concrete code gen if move sets condition codes?"); + /* begin checkQuickConstant:forInstruction: */ + anInstruction27 = genoperandoperand(CmpCqR, 0, TempReg); + /* begin JumpNonZero: */ + jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + /* begin preferredRegisterForMovePerfCnt64RL */ + reg = RAX; + gMovePerfCnt64RL(reg, liveRegisters); /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction25 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - /* begin PushR: */ - genoperand(PushR, ClassReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction26 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset1 = BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction27 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, BytesPerWord); + nextProfileTickAddress(); + anInstruction30 = genoperandoperand(MoveAwR, nextProfileTickAddress(), Arg1Reg); + /* begin CmpR:R: */ + assert(!((reg == SPReg))); + genoperandoperand(CmpRR, reg, Arg1Reg); + /* begin JumpGreaterOrEqual: */ + jumpToTakeSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l57; + l57: /* end genCheckForProfileTimerTick: */; } + /* begin MoveMw:r:R: */ + offset1 = BytesPerWord; + /* begin checkQuickConstant:forInstruction: */ + anInstruction28 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); + continueAfterProfileSample = anInstruction28; + /* begin RetN: */ + genoperand(RetN, BytesPerWord); if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* The sample is collected by cePrimReturnEnterCogCode for external calls */ - if (!(jmpSamplePrim == null)) { - - /* Call ceCheckProfileTick: to record sample and then continue. */ - jmpTarget(jmpSamplePrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin gen:literal: */ - operand1 = ((usqIntptr_t)ceCheckProfileTick); - /* begin checkLiteral:forInstruction: */ - anInstruction29 = genoperand(CallFull, operand1); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSamplePrim)); - } - jmpTarget(jmpSampleNonPrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction34 = genoperandoperand(MoveCqR, 0, TempReg); - /* begin checkLiteral:forInstruction: */ - newMethodAddress(); - anInstruction35 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); - /* begin gen:literal: */ - operand3 = ((usqIntptr_t)ceCheckProfileTick); + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); /* begin checkLiteral:forInstruction: */ - anInstruction33 = genoperand(CallFull, operand3); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSampleNonPrim)); - } - if (!(jmp == null)) { - - /* Jump to restore of receiver reg and proceed to frame build for failure. */ - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin MoveMw:r:R: */ - offset2 = BytesPerWord * (methodOrBlockNumArgs + (1)); + instructionPointerAddress(); + anInstruction16 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction36 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); + anInstruction17 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + /* begin Jump: */ + genoperand(Jump, ((sqInt)continueAfterProfileSample)); } + jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + /* begin MoveMw:r:R: */ + offset2 = BytesPerWord * (methodOrBlockNumArgs + (1)); + /* begin checkQuickConstant:forInstruction: */ + anInstruction29 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); return 0; } @@ -26387,7 +26433,7 @@ compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)) if ((methodOrBlockNumArgs > 2 /* numRegArgs */) || (methodOrBlockNumArgs == 0)) { /* begin registerMaskFor: */ - liveRegsMask = 1U << ReceiverResultReg; + liveRegsMask = (1U << ReceiverResultReg); } else { if (methodOrBlockNumArgs > 1) { @@ -26473,51 +26519,57 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags AbstractInstruction *anInstruction11; AbstractInstruction *anInstruction12; AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; AbstractInstruction *anInstruction16; AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction18; AbstractInstruction *anInstruction19; AbstractInstruction *anInstruction2; AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; AbstractInstruction *anInstruction22; AbstractInstruction *anInstruction23; + AbstractInstruction *anInstruction27; + AbstractInstruction *anInstruction28; + AbstractInstruction *anInstruction29; + AbstractInstruction *anInstruction30; AbstractInstruction *anInstruction4; AbstractInstruction *anInstruction5; AbstractInstruction *anInstruction6; AbstractInstruction *anInstruction8; AbstractInstruction *anInstruction9; sqInt calleeSavedRegisterMask; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; + AbstractInstruction * jumpToTakeSample; + sqInt liveRegisters; sqInt offset; sqInt offset1; sqInt operand1; + sqInt reg; sqInt retpcOffset; AbstractInstruction * retry; AbstractInstruction * skip; sqInt spRegSaveRegister; + jumpToTakeSample = ((AbstractInstruction *) 0); assert(((flags & PrimCallOnSmalltalkStack) != 0)); assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); if (recordFastCCallPrimTraceForMethod(methodObj)) { genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction18 = genoperandoperand(MoveCqR, 0, TempReg); + anInstruction20 = genoperandoperand(MoveCqR, 0, TempReg); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction19 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); + anInstruction22 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); } /* begin checkLiteral:forInstruction: */ argumentCountAddress(); - anInstruction20 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); + anInstruction23 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); genExternalizeStackPointerForFastPrimitiveCall(); - calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | (1U << ClassReg)) - (1U << ClassReg)); + calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | ((1U << ClassReg))) - ((1U << ClassReg))); spRegSaveRegister = NoReg; /* begin Label */ retry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); @@ -26526,22 +26578,54 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags } else { } + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + goto l53; + assert(0 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg0Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg1Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg2Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg3Reg); + l53: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin gen:literal: */ - anInstruction2 = genoperand(CallFull, primitiveRoutine); + anInstruction2 = genoperand(CallFull, ((sqInt)primitiveRoutine)); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 4); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction21 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + anInstruction27 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); if (spRegSaveRegister != NoReg) { /* begin MoveR:R: */ genoperandoperand(MoveRR, spRegSaveRegister, SPReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperand(CmpCqR, 0, TempReg); + anInstruction28 = genoperandoperand(CmpCqR, 0, TempReg); /* begin JumpNonZero: */ jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + /* begin preferredRegisterForMovePerfCnt64RL */ + reg = RAX; + gMovePerfCnt64RL(reg, liveRegisters); + /* begin checkLiteral:forInstruction: */ + nextProfileTickAddress(); + anInstruction30 = genoperandoperand(MoveAwR, nextProfileTickAddress(), Arg1Reg); + /* begin CmpR:R: */ + assert(!((reg == SPReg))); + genoperandoperand(CmpRR, reg, Arg1Reg); + /* begin JumpGreaterOrEqual: */ + jumpToTakeSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l66; + l66: /* end genCheckForProfileTimerTick: */; + } /* begin checkLiteral:forInstruction: */ stackPointerAddress(); - anInstruction23 = genoperandoperand(MoveAwR, stackPointerAddress(), TempReg); + anInstruction29 = genoperandoperand(MoveAwR, stackPointerAddress(), TempReg); + continueAfterProfileSample = anInstruction29; /* The original retpc is (argumentCount + 1) words below stackPointer. */ retpcOffset = -((methodOrBlockNumArgs + 1) * BytesPerWord); @@ -26555,6 +26639,12 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags anInstruction6 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, TempReg); /* begin RetN: */ genoperand(RetN, 0); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); + /* begin Jump: */ + genoperand(Jump, ((sqInt)continueAfterProfileSample)); + } jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); if ((accessorDepthForExternalPrimitiveMethod(methodObj)) >= 0) { @@ -26585,20 +26675,32 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags else { genLoadCStackPointer(backEnd); } + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + goto l36; + assert(0 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg0Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg1Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg2Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg3Reg); + l36: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin gen:literal: */ operand1 = ((usqIntptr_t)checkForAndFollowForwardedPrimitiveState); /* begin checkLiteral:forInstruction: */ anInstruction8 = genoperand(CallFull, operand1); - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(CmpCqR, 0, ABIResultReg); + anInstruction16 = genoperandoperand(CmpCqR, 0, ABIResultReg); /* begin JumpZero: */ skip = genConditionalBranchoperand(JumpZero, ((sqInt)0)); /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperand(MoveCqR, 0, TempReg); + anInstruction17 = genoperandoperand(MoveCqR, 0, TempReg); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction16 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); + anInstruction18 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); /* begin Jump: */ genoperand(Jump, ((sqInt)retry)); jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); @@ -26607,14 +26709,14 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags /* must reload SPReg to undo any alignment change, */ if (((flags & PrimCallOnSmalltalkStackAlign2x) != 0)) { - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); } } - if (((ABICallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((ABICallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* begin MoveMw:r:R: */ offset1 = (methodOrBlockNumArgs + (1)) * BytesPerWord; /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); + anInstruction19 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); } return 0; } @@ -27617,23 +27719,24 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) { sqInt address1; AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction10; + AbstractInstruction *anInstruction11; AbstractInstruction *anInstruction12; AbstractInstruction *anInstruction13; AbstractInstruction *anInstruction14; AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction18; + AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; + AbstractInstruction *anInstruction7; AbstractInstruction *anInstruction8; AbstractInstruction *anInstruction9; sqInt callTarget; AbstractInstruction *continuePostSample; AbstractInstruction *jmpFail; AbstractInstruction *jmpSample; + sqInt liveRegisters; sqInt quickConstant; sqInt reg; + sqInt reg1; continuePostSample = ((AbstractInstruction *) 0); jmpSample = ((AbstractInstruction *) 0); @@ -27642,56 +27745,63 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) quickConstant = varBaseAddress(); /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - if (profiling) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick: if so. - N.B. nextProfileTick is 64-bits so 32-bit systems need to test both halves. */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction3 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpSample = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction13 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + anInstruction12 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); flag("ask concrete code gen if move sets condition codes?"); /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(CmpCqR, 0, TempReg); + anInstruction13 = genoperandoperand(CmpCqR, 0, TempReg); /* begin JumpNonZero: */ jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (profiling + && (1)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + /* begin preferredRegisterForMovePerfCnt64RL */ + reg = RAX; + gMovePerfCnt64RL(reg, liveRegisters); + /* begin checkLiteral:forInstruction: */ + nextProfileTickAddress(); + anInstruction3 = genoperandoperand(MoveAwR, nextProfileTickAddress(), Arg1Reg); + /* begin CmpR:R: */ + assert(!((reg == SPReg))); + genoperandoperand(CmpRR, reg, Arg1Reg); + /* begin JumpGreaterOrEqual: */ + jmpSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l18; + l18: /* end genCheckForProfileTimerTick: */; + /* begin Label */ + continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); + } /* begin checkLiteral:forInstruction: */ instructionPointerAddress(); - anInstruction8 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); + anInstruction7 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); + anInstruction8 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + anInstruction9 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jmpFail, checkLiteralforInstruction(newMethodAddress(), genoperandoperand(MoveAwR, newMethodAddress(), SendNumArgsReg))); /* begin checkLiteral:forInstruction: */ cStackPointerAddress(); - anInstruction15 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); + anInstruction14 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); compileCallFornumArgsargargargargresultRegregsToSave(ceActivateFailingPrimitiveMethod, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); /* begin MoveAw:R: */ address1 = instructionPointerAddress(); - reg = ClassReg; + reg1 = ClassReg; /* begin checkLiteral:forInstruction: */ - anInstruction16 = genoperandoperand(MoveAwR, address1, reg); + anInstruction15 = genoperandoperand(MoveAwR, address1, reg1); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveMwrR, BytesPerWord, SPReg, ReceiverResultReg); + anInstruction11 = genoperandoperandoperand(MoveMwrR, BytesPerWord, SPReg, ReceiverResultReg); /* begin PushR: */ genoperand(PushR, ClassReg); /* begin RetN: */ genoperand(RetN, BytesPerWord); - if (profiling) { + if (profiling + && (1)) { /* Call ceCheckProfileTick: to record sample and then continue. newMethod should be up-to-date. Need to save and restore the link reg around this call. */ @@ -27700,7 +27810,7 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) /* begin CallFullRT: */ callTarget = (usqIntptr_t)ceCheckProfileTick; /* begin checkLiteral:forInstruction: */ - anInstruction18 = genoperand(CallFull, callTarget); + anInstruction17 = genoperand(CallFull, callTarget); /* begin Jump: */ genoperand(Jump, ((sqInt)continuePostSample)); } @@ -28055,6 +28165,61 @@ genStoreRemoteTempLongBytecode(void) && (shouldAnnotateObjectReference(((ssTop())->constant))))); } + /* SimpleStackBasedCogit>>#genTakeProfileSample */ +static void +genTakeProfileSample(void) +{ + AbstractInstruction *anInstruction1; + AbstractInstruction *anInstruction2; + AbstractInstruction *anInstruction3; + AbstractInstruction *anInstruction4; + sqInt operand1; + + addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + assert(1 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, ClassReg, CArg0Reg); + goto l12; + if (null < NoReg) { + /* begin MoveCq:R: */ + anInstruction2 = genoperandoperand(MoveCqR, -2 - null, CArg1Reg); + } + else { + if (null != CArg1Reg) { + /* begin MoveR:R: */ + genoperandoperand(MoveRR, null, CArg1Reg); + } + } + if (null < NoReg) { + /* begin MoveCq:R: */ + anInstruction3 = genoperandoperand(MoveCqR, -2 - null, CArg2Reg); + } + else { + if (null != CArg2Reg) { + /* begin MoveR:R: */ + genoperandoperand(MoveRR, null, CArg2Reg); + } + } + if (null < NoReg) { + /* begin MoveCq:R: */ + anInstruction4 = genoperandoperand(MoveCqR, -2 - null, CArg3Reg); + } + else { + if (null != CArg3Reg) { + /* begin MoveR:R: */ + genoperandoperand(MoveRR, null, CArg3Reg); + } + } + l12: /* end genMarshallNArgs:arg:arg:arg:arg: */; + /* begin gen:literal: */ + operand1 = ((usqIntptr_t)ceTakeProfileSample); + /* begin checkLiteral:forInstruction: */ + anInstruction1 = genoperand(CallFull, operand1); + /* begin genRemoveNArgsFromStack: */ + assert(1 <= 4); + } + /* Collect the branch and send data for cogMethod, storing it into arrayObj. */ @@ -28424,7 +28589,7 @@ primitiveGeneratorOrNil(void) static sqInt NoDbgRegParms registerisInMask(sqInt reg, sqInt mask) { - return ((mask & (1ULL << reg)) != 0); + return ((mask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0); } /* SimpleStackBasedCogit>>#v3:Block:Code:Size: */ @@ -29085,7 +29250,7 @@ genBinaryAtConstInlinePrimitive(sqInt primIndex) val = ((ssTop())->constant); if (primIndex == 65) { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); rr = ReceiverResultReg; } @@ -29101,10 +29266,10 @@ genBinaryAtConstInlinePrimitive(sqInt primIndex) break; case 65: /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << SendNumArgsReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << SendNumArgsReg), simStackPtr, simNativeStackPtr); /* begin genPushMaybeContextSlotIndex: */ assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ voidReceiverResultRegContainsSelf(); @@ -29185,13 +29350,13 @@ genBinaryAtInlinePrimitive(sqInt primIndex) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -29347,7 +29512,7 @@ genBinaryCompInlinePrimitive(sqInt primIndex) } otherReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); popToReg(ssTop(), otherReg); - resultReg = allocateRegForStackEntryAtnotConflictingWith(1, 1ULL << otherReg); + resultReg = allocateRegForStackEntryAtnotConflictingWith(1, ((otherReg < 0) ? (((usqInt)(1)) >> (-otherReg)) : (1ULL << otherReg))); popToReg(ssValue(1), resultReg); /* begin CmpR:R: */ assert(!((otherReg == SPReg))); @@ -29755,7 +29920,7 @@ genBinarySmiBitShiftLeftInlinePrimitive(void) genoperandoperand(LogicalShiftLeftCqR, quickConstant, rr); } else { - ra = allocateRegForStackEntryAtnotConflictingWith(0, 1ULL << rr); + ra = allocateRegForStackEntryAtnotConflictingWith(0, ((rr < 0) ? (((usqInt)(1)) >> (-rr)) : (1ULL << rr))); popToReg(ssTop(), ra); genConvertSmallIntegerToIntegerInReg(ra); /* begin LogicalShiftLeftR:R: */ @@ -29788,7 +29953,7 @@ genBinarySmiBitShiftRightInlinePrimitive(void) genoperandoperand(ArithmeticShiftRightCqR, quickConstant, rr); } else { - ra = allocateRegForStackEntryAtnotConflictingWith(0, 1ULL << rr); + ra = allocateRegForStackEntryAtnotConflictingWith(0, ((rr < 0) ? (((usqInt)(1)) >> (-rr)) : (1ULL << rr))); popToReg(ssTop(), ra); genConvertSmallIntegerToIntegerInReg(ra); /* begin ArithmeticShiftRightR:R: */ @@ -29879,13 +30044,13 @@ genBinaryVarOpVarSmiInlinePrimitive(sqInt primIndex) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -29956,7 +30121,7 @@ genByteAtPut(void) && (1)) { /* begin registerMaskFor: */ reg = (rTop1 = registerOrNone(ssTop())); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (((registerOrNone(ssValue(1))) != NoReg) && (1)) { @@ -29968,11 +30133,11 @@ genByteAtPut(void) } if (rThird1 == NoReg) { rThird1 = allocateRegNotConflictingWith(topRegistersMask); - topRegistersMask = topRegistersMask | (1ULL << rThird1); + topRegistersMask = topRegistersMask | (((rThird1 < 0) ? (((usqInt)(1)) >> (-rThird1)) : (1ULL << rThird1))); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); - topRegistersMask = topRegistersMask | (1ULL << rTop1); + topRegistersMask = topRegistersMask | (((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } if (rNext1 == NoReg) { rNext1 = allocateRegNotConflictingWith(topRegistersMask); @@ -30319,7 +30484,7 @@ genByteEqualsInlinePrimitive(sqInt prim) if (needLoop) { assert(!(((ssTop())->spilled))); str1Reg = allocateRegForStackEntryAtnotConflictingWith(1, 0 /* emptyRegisterMask */); - str2Reg = allocateRegForStackEntryAtnotConflictingWith(2, 1ULL << str1Reg); + str2Reg = allocateRegForStackEntryAtnotConflictingWith(2, ((str1Reg < 0) ? (((usqInt)(1)) >> (-str1Reg)) : (1ULL << str1Reg))); lenReg = allocateRegForStackEntryAtnotConflictingWith(0, (1ULL << str1Reg) | (1ULL << str2Reg)); popToReg(ssValue(1), str1Reg); popToReg(ssValue(2), str2Reg); @@ -30331,12 +30496,12 @@ genByteEqualsInlinePrimitive(sqInt prim) if (!((((ssValue(1))->type)) == SSConstant)) { str1Reg = allocateRegForStackEntryAtnotConflictingWith(1, mask); popToReg(ssValue(1), str1Reg); - mask = mask | (1ULL << str1Reg); + mask = mask | (((str1Reg < 0) ? (((usqInt)(1)) >> (-str1Reg)) : (1ULL << str1Reg))); } if (!((((ssValue(2))->type)) == SSConstant)) { str2Reg = allocateRegForStackEntryAtnotConflictingWith(2, mask); popToReg(ssValue(2), str2Reg); - mask = mask | (1ULL << str2Reg); + mask = mask | (((str2Reg < 0) ? (((usqInt)(1)) >> (-str2Reg)) : (1ULL << str2Reg))); } extraReg = allocateRegNotConflictingWith(mask); } @@ -30529,7 +30694,7 @@ genCounterTripOnlyJumpIfto(sqInt boolean, sqInt targetBytecodePC) /* We need SendNumArgsReg because of the mustBeBooleanTrampoline */ counterIndex += 1; /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << SendNumArgsReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << SendNumArgsReg), simStackPtr, simNativeStackPtr); /* begin checkQuickConstant:forInstruction: */ anInstruction1 = genoperandoperand(MoveCqR, 1, SendNumArgsReg); mustBeBooleanTrampoline = genCallMustBeBooleanFor(boolean); @@ -30645,13 +30810,13 @@ genDivInlinePrimitive(sqInt primIndex) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -30964,13 +31129,13 @@ genForwardersInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -31155,13 +31320,13 @@ genForwardersInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg1 = (rNext11 = registerOrNone(ssValue(1))); - topRegistersMask1 = 1ULL << reg1; + topRegistersMask1 = ((reg1 < 0) ? (((usqInt)(1)) >> (-reg1)) : (1ULL << reg1)); } if (rTop11 == NoReg) { rTop11 = allocateRegNotConflictingWith(topRegistersMask1); } if (rNext11 == NoReg) { - rNext11 = allocateRegNotConflictingWith(1ULL << rTop11); + rNext11 = allocateRegNotConflictingWith(((rTop11 < 0) ? (((usqInt)(1)) >> (-rTop11)) : (1ULL << rTop11))); } assert(!(((rTop11 == NoReg) || (rNext11 == NoReg)))); @@ -31212,12 +31377,12 @@ genForwardersInlinedIdenticalOrNotIf(sqInt orNot) } if (argReg == NoReg) { /* begin registerMaskFor: */ - regMask = 1ULL << rcvrReg; + regMask = ((rcvrReg < 0) ? (((usqInt)(1)) >> (-rcvrReg)) : (1ULL << rcvrReg)); } else { if (rcvrReg == NoReg) { /* begin registerMaskFor: */ - regMask = 1ULL << argReg; + regMask = ((argReg < 0) ? (((usqInt)(1)) >> (-argReg)) : (1ULL << argReg)); } else { /* begin registerMaskFor:and: */ @@ -31839,7 +32004,7 @@ genJumpIfto(sqInt boolean, sqInt targetBytecodePC) popToReg(desc, TempReg); ssPop(1); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << SendNumArgsReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << SendNumArgsReg), simStackPtr, simNativeStackPtr); /* begin Label */ retry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); /* begin genExecutionCountLogicInto:counterReg: */ @@ -32266,13 +32431,13 @@ genPointerAtPutConstantMaybeContextstoreCheckimmutabilityCheck(sqInt maybeContex rcvrReg = ReceiverResultReg; } else { - rcvrReg = allocateRegForStackEntryAtnotConflictingWith(2, 1ULL << valReg); + rcvrReg = allocateRegForStackEntryAtnotConflictingWith(2, ((valReg < 0) ? (((usqInt)(1)) >> (-valReg)) : (1ULL << valReg))); } } /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1ULL << valReg, simStackPtr - 2, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((valReg < 0) ? (((usqInt)(1)) >> (-valReg)) : (1ULL << valReg)), simStackPtr - 2, simNativeStackPtr); /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1ULL << rcvrReg, simStackPtr - 3, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((rcvrReg < 0) ? (((usqInt)(1)) >> (-rcvrReg)) : (1ULL << rcvrReg)), simStackPtr - 3, simNativeStackPtr); popToReg(ssTop(), valReg); ssPop(1); if (((ssTop())->spilled)) { @@ -32313,7 +32478,7 @@ genPointerAtPutConstantMaybeContextstoreCheckimmutabilityCheck(sqInt maybeContex # endif // IMMUTABILITY ssPop(1); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ClassReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ssPush(1); genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); ssStoreAndReplacePoptoReg(0, ClassReg); @@ -32343,7 +32508,7 @@ genPointerAtPutConstantMaybeContextstoreCheckimmutabilityCheck(sqInt maybeContex # if IMMUTABILITY if (needsImmCheck) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(0, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -32357,7 +32522,7 @@ genPointerAtPutConstantMaybeContextstoreCheckimmutabilityCheck(sqInt maybeContex return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, indexCst, rcvrReg, TempReg, needsStoreCheck, 0); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1ULL << rcvrReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, ((rcvrReg < 0) ? (((usqInt)(1)) >> (-rcvrReg)) : (1ULL << rcvrReg))); ssStorePoptoReg(0, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, indexCst, rcvrReg, TempReg, needsFrame, needsStoreCheck); } @@ -32614,7 +32779,7 @@ genPointerAtPutStoreCheck(sqInt needsStoreCheck) || ((registerOrNone(ssTop())) != ReceiverResultReg))) { /* begin registerMaskFor: */ reg = (rTop1 = registerOrNone(ssTop())); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (((registerOrNone(ssValue(1))) != NoReg) && ((!needsStoreCheck) @@ -32632,17 +32797,17 @@ genPointerAtPutStoreCheck(sqInt needsStoreCheck) /* Free ReceiverResultReg if it was not free */ rThird1 = ReceiverResultReg; /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); } else { rThird1 = allocateRegNotConflictingWith(topRegistersMask); } - topRegistersMask = topRegistersMask | (1ULL << rThird1); + topRegistersMask = topRegistersMask | (((rThird1 < 0) ? (((usqInt)(1)) >> (-rThird1)) : (1ULL << rThird1))); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); - topRegistersMask = topRegistersMask | (1ULL << rTop1); + topRegistersMask = topRegistersMask | (((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } if (rNext1 == NoReg) { rNext1 = allocateRegNotConflictingWith(topRegistersMask); @@ -33164,7 +33329,7 @@ genUnaryClassPrimitive(void) sqInt topReg; topReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - destReg = allocateRegNotConflictingWith(1ULL << topReg); + destReg = allocateRegNotConflictingWith(((topReg < 0) ? (((usqInt)(1)) >> (-topReg)) : (1ULL << topReg))); popToReg(ssTop(), topReg); /* begin MoveR:R: */ genoperandoperand(MoveRR, topReg, TempReg); @@ -33230,7 +33395,7 @@ genUnaryHashInlinePrimitive(sqInt primIndex) switch (primIndex) { case 20: rcvrReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - resultReg = allocateRegNotConflictingWith(1ULL << rcvrReg); + resultReg = allocateRegNotConflictingWith(((rcvrReg < 0) ? (((usqInt)(1)) >> (-rcvrReg)) : (1ULL << rcvrReg))); popToReg(ssTop(), rcvrReg); genGetIdentityHashresultReg(rcvrReg, resultReg); break; @@ -33420,7 +33585,7 @@ genUnarySizeInlinePrimitive(sqInt primIndex) assert(((primIndex >= 1) && (primIndex <= 6))); rcvrReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - resultReg = allocateRegNotConflictingWith(1ULL << rcvrReg); + resultReg = allocateRegNotConflictingWith(((rcvrReg < 0) ? (((usqInt)(1)) >> (-rcvrReg)) : (1ULL << rcvrReg))); popToReg(ssTop(), rcvrReg); ssPop(1); ssPushRegister(resultReg); @@ -34603,7 +34768,7 @@ anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n) sqInt regMask; /* begin registerMaskFor: */ - regMask = 1ULL << reg; + regMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { if ((((registerMask(simStackAt(i))) & regMask) != 0)) { return 1; @@ -35293,7 +35458,7 @@ ensureReceiverResultRegContainsSelf(void) if (needsFrame) { if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin putSelfInReceiverResultReg */ storeToReg(simSelf(), ReceiverResultReg); ((simSelf())->liveRegister = ReceiverResultReg); @@ -35425,7 +35590,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) && (index < simStackPtr)) { desc = simStackAt(index); if (((desc->type)) == SSRegister) { - if (!(((regMask & (1ULL << ((desc->registerr)))) != 0))) { + if (!(((regMask & (((((desc->registerr)) < 0) ? (((usqInt)(1)) >> (-((desc->registerr)))) : (1ULL << ((desc->registerr)))))) != 0))) { reg = (desc->registerr); } } @@ -35433,7 +35598,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) } assert(!((reg == NoReg))); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1ULL << reg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)), simStackPtr, simNativeStackPtr); return reg; } @@ -36533,11 +36698,11 @@ genPushMaybeContextReceiverVariable(sqInt slotIndex) AbstractInstruction *jmpSingle; /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ensureReceiverResultRegContainsSelf(); /* begin genPushMaybeContextSlotIndex: */ assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ voidReceiverResultRegContainsSelf(); @@ -36590,7 +36755,7 @@ genPushNewArrayBytecode(void) } else { /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << SendNumArgsReg)) | ((1U << ReceiverResultReg))), simStackPtr, simNativeStackPtr); } size = byte1 & 0x7F; if (!popValues) { @@ -36663,7 +36828,7 @@ genPushRemoteTempLongBytecode(void) /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperandoperand(MoveMwrR, offset, FPReg, tempVectReg); /* begin availableRegOrNoneNotConflictingWith: */ - regMask = 1ULL << tempVectReg; + regMask = ((tempVectReg < 0) ? (((usqInt)(1)) >> (-tempVectReg)) : (1ULL << tempVectReg)); remoteTempReg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); if (remoteTempReg == NoReg) { remoteTempReg = tempVectReg; @@ -37013,11 +37178,11 @@ genSpecialSelectorClass(void) || (topReg == ClassReg)) { /* begin ssAllocateRequiredReg:and: */ requiredReg1 = (topReg = SendNumArgsReg); - ssAllocateRequiredRegMaskupThroughupThroughNative((1ULL << requiredReg1) | (1U << ClassReg), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((((requiredReg1 < 0) ? (((usqInt)(1)) >> (-requiredReg1)) : (1ULL << requiredReg1))) | ((1U << ClassReg)), simStackPtr, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr, simNativeStackPtr); } ssPush(1); popToReg(ssTop(), topReg); @@ -37089,7 +37254,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean association = getLiteral(litVarIndex); voidReceiverResultRegContainsSelf(); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin genMoveConstant:R: */ if (shouldAnnotateObjectReference(association)) { annotateobjRef(checkLiteralforInstruction(association, genoperandoperand(MoveCwR, association, ReceiverResultReg)), association); @@ -37102,7 +37267,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean # if IMMUTABILITY if (needsImmCheck) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -37116,7 +37281,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -37177,7 +37342,7 @@ genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqI # endif // IMMUTABILITY ssPop(1); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ClassReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ssPush(1); genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); @@ -37222,7 +37387,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea # if IMMUTABILITY if (needsImmCheck1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -37236,7 +37401,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck1, 1); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck1); } @@ -37260,7 +37425,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt assert(needsFrame); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); /* begin MoveMw:r:R: */ offset = frameOffsetOfTemporary(remoteTempIndex); @@ -37270,7 +37435,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt # if IMMUTABILITY # endif - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -37456,13 +37621,13 @@ genVanillaInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -37716,12 +37881,12 @@ liveRegisters(void) } else { /* begin registerMaskFor: */ - regsSet = 1U << ReceiverResultReg; + regsSet = (1U << ReceiverResultReg); if ((methodOrBlockNumArgs <= 2 /* numRegArgs */) && (methodOrBlockNumArgs > 0)) { - regsSet = regsSet | (1U << Arg0Reg); + regsSet = regsSet | ((1U << Arg0Reg)); if (methodOrBlockNumArgs > 1) { - regsSet = regsSet | (1U << Arg1Reg); + regsSet = regsSet | ((1U << Arg1Reg)); } } } @@ -37824,13 +37989,13 @@ marshallSendArguments(sqInt numArgs) if (numArgs > 0) { if (numArgs > 1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 2, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 2, simNativeStackPtr); /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg1Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg1Reg), simStackPtr - 1, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 1, simNativeStackPtr); } } if (numArgs > 1) { diff --git a/spursista64src/vm/cogitX64WIN64.c b/spursista64src/vm/cogitX64WIN64.c index 15a35a085c..bd34bcb940 100644 --- a/spursista64src/vm/cogitX64WIN64.c +++ b/spursista64src/vm/cogitX64WIN64.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + CCodeGenerator VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - SistaCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + SistaCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "SistaCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 " __DATE__ ; +static char __buildInfo[] = "SistaCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__cogitBuildInfo = __buildInfo; @@ -54,7 +54,7 @@ char *__cogitBuildInfo = __buildInfo; #define ArithmeticShiftRightRR 92 #define BadRegisterSet 1 #define BlockCreationBytecodeSize 4 -#define BSR 167 +#define BSR 169 #define BytecodeSetHasDirectedSuperSend 1 #define CArg0Reg 1 #define CArg1Reg 2 @@ -64,11 +64,11 @@ char *__cogitBuildInfo = __buildInfo; #define CallerSavedRegisterMask 0x706 #define CallFull 7 #define CallR 8 -#define CDQ 159 +#define CDQ 161 #if !defined(CheckRememberedInTrampoline) /* Allow this to be overridden on the compiler command line */ # define CheckRememberedInTrampoline 0 #endif -#define CLD 163 +#define CLD 165 #define ClassArray 7 #define ClassArrayCompactIndex 51 #define ClassBlockClosureCompactIndex 37 @@ -91,7 +91,7 @@ char *__cogitBuildInfo = __buildInfo; #define CMMaxUsageCount 7 #define CMMethod 2 #define CMOpenPIC 5 -#define CMPXCHGRMr 172 +#define CMPXCHGRMr 174 #define CmpC32R 113 #define CmpCqR 105 #define CmpCwR 112 @@ -107,7 +107,7 @@ char *__cogitBuildInfo = __buildInfo; #define ConvertRsR 149 #define ConvertRsRd 147 #define CounterBytes 4 -#define CPUID 158 +#define CPUID 160 #define Debug DEBUGVM #define DisplacementMask 0x1F #define DisplacementX2N 0 @@ -151,11 +151,11 @@ char *__cogitBuildInfo = __buildInfo; #define HashMultiplyConstant 1664525 #define HashMultiplyMask 0xFFFFFFF #define HeaderIndex 0 -#define IDIVR 160 +#define IDIVR 162 #if !defined(IMMUTABILITY) /* Allow this to be overridden on the compiler command line */ # define IMMUTABILITY 1 #endif -#define IMULRR 161 +#define IMULRR 163 #define InFullBlock 2 #define InstanceSpecificationIndex 2 #define InstructionPointerIndex 1 @@ -206,11 +206,11 @@ char *__cogitBuildInfo = __buildInfo; #define Label 1 #define LargeContextSlots 62 #define LastJump 42 -#define LFENCE 168 +#define LFENCE 170 #undef LinkReg #define Literal 2 #define LiteralStart 1 -#define LOCK 171 +#define LOCK 173 #define LoadEffectiveAddressMwrR 88 #define LogicalShiftLeftCqR 95 #define LogicalShiftLeftCqRR 129 @@ -234,11 +234,11 @@ char *__cogitBuildInfo = __buildInfo; #define MethodCacheSelector 1 #define MethodIndex 3 #define MethodTooBig -4 -#define MFENCE 169 +#define MFENCE 171 #define MFMethodFlagHasContextFlag 1 #define MFMethodFlagIsBlockFlag 2 -#define MOVSB 165 -#define MOVSQ 166 +#define MOVSB 167 +#define MOVSQ 168 #define ModReg 3 #define ModRegInd 0 #define ModRegRegDisp32 2 @@ -257,10 +257,12 @@ char *__cogitBuildInfo = __buildInfo; #define MoveMbrR 65 #define MoveMs8rR 55 #define MoveMwrR 50 +#define MovePerfCnt64RL 159 +#define MovePerfCnt64RRL 158 #define MoveRA32 47 #define MoveRAb 49 #define MoveRAw 46 -#define MoveRAwNoVBR 174 +#define MoveRAwNoVBR 176 #define MoveRdM64r 76 #define MoveRdR 73 #define MoveRdRd 74 @@ -330,7 +332,7 @@ char *__cogitBuildInfo = __buildInfo; #define RCX 1 #define RDI 7 #define RDX 2 -#define REP 164 +#define REP 166 #define ReceiverIndex 5 #define ReceiverResultReg 9 #define RetN 9 @@ -339,12 +341,12 @@ char *__cogitBuildInfo = __buildInfo; #define RotateRightCqR 98 #define RSI 6 #define RSP 4 -#define SETE 173 +#define SETE 175 #define SelectorCannotInterpret 34 #define SelectorDoesNotUnderstand 20 #define SenderIndex 0 #define SendNumArgsReg 10 -#define SFENCE 170 +#define SFENCE 172 #define ShouldNotJIT -8 #define SIB1 0 #define SIB4 2 @@ -383,7 +385,7 @@ char *__cogitBuildInfo = __buildInfo; #define UnimplementedPrimitive -7 #define ValueIndex 1 #define VarBaseReg 3 -#define XCHGRR 162 +#define XCHGRR 164 #define XMM0L 0 #define XorCwR 118 #define XorRdRd 137 @@ -515,7 +517,7 @@ static sqInt NoDbgRegParms concretizeAt(AbstractInstruction * self_in_concretize static sqInt NoDbgRegParms genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer); static sqInt NoDbgRegParms genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers); static sqInt NoDbgRegParms genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers); -static sqInt NoDbgRegParms genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg); +static sqInt NoDbgRegParms genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg); static sqInt NoDbgRegParms genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers); static void NoDbgRegParms genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister); static void NoDbgRegParms initializeSharableLiteral(AbstractInstruction * self_in_initializeSharableLiteral, sqInt literal); @@ -691,6 +693,8 @@ extern void linkSendAtintooffsetreceiver(sqInt callSiteReturnAddress, CogMethod static BytecodeDescriptor * loadBytesAndGetDescriptor(void); static void NoDbgRegParms loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc); static AbstractInstruction * NoDbgRegParms gMoveCwR(sqInt wordConstant, sqInt reg); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters); static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg); static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC); @@ -1035,6 +1039,7 @@ static sqInt NoDbgRegParms computeShiftRRSize(AbstractInstruction * self_in_comp static sqInt NoDbgRegParms computeSizeOfPushCw(AbstractInstruction * self_in_computeSizeOfPushCw); static sqInt NoDbgRegParms concretizeArithCqRWithROraxOpcode(AbstractInstruction * self_in_concretizeArithCqRWithROraxOpcode, sqInt regOpcode, sqInt raxOpcode); static sqInt NoDbgRegParms concretizeFill32(AbstractInstruction * self_in_concretizeFill32); +static sqInt NoDbgRegParms concretizeMovePerfCnt64RL(AbstractInstruction * self_in_concretizeMovePerfCnt64RL); static sqInt NoDbgRegParms concretizeMoveRX32rR(AbstractInstruction * self_in_concretizeMoveRX32rR); static sqInt NoDbgRegParms concretizeMoveX32rRR(AbstractInstruction * self_in_concretizeMoveX32rRR); static sqInt NoDbgRegParms concretizeOpRR(AbstractInstruction * self_in_concretizeOpRR, sqInt x64opcode); @@ -1179,6 +1184,7 @@ static sqInt genStoreAndPopReceiverVariableBytecode(void); static sqInt genStoreAndPopRemoteTempLongBytecode(void); static sqInt genStoreAndPopTemporaryVariableBytecode(void); static sqInt genStoreRemoteTempLongBytecode(void); +static void genTakeProfileSample(void); extern sqInt mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj); static sqInt numSpecialSelectors(void); static usqInt NoDbgRegParms pcDataForBlockEntryMethod(sqInt blockEntryMcpc, sqInt cogMethod); @@ -2797,28 +2803,28 @@ addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *an static sqInt NoDbgRegParms availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << DPFPReg0)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg0))) != 0))) { return DPFPReg0; } - if (!(((liveRegsMask & (1U << DPFPReg1)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg1))) != 0))) { return DPFPReg1; } - if (!(((liveRegsMask & (1U << DPFPReg2)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg2))) != 0))) { return DPFPReg2; } - if (!(((liveRegsMask & (1U << DPFPReg3)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg3))) != 0))) { return DPFPReg3; } - if (!(((liveRegsMask & (1U << DPFPReg4)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg4))) != 0))) { return DPFPReg4; } - if (!(((liveRegsMask & (1U << DPFPReg5)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg5))) != 0))) { return DPFPReg5; } - if (!(((liveRegsMask & (1U << DPFPReg6)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg6))) != 0))) { return DPFPReg6; } - if (!(((liveRegsMask & (1U << DPFPReg7)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg7))) != 0))) { return DPFPReg7; } return NoReg; @@ -2933,9 +2939,9 @@ genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers) used immediately afterwards. */ - /* CogAbstractInstruction>>#genLoadStackPointersForFastPrimCall: */ + /* CogAbstractInstruction>>#genLoadStackPointersForPrimCall: */ static sqInt NoDbgRegParms -genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg) +genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg) { AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; @@ -5825,7 +5831,7 @@ compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numAr regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1ULL << resultRegOrNone)) - (1ULL << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ regMaskCopy = ((usqInt)regsToSave); @@ -7438,7 +7444,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) startAddress = methodZoneBase; callerSavedReg = 0; pushedVarBaseReg = 0; - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { /* VarBaseReg is not caller-saved; must save and restore it, either by using an available caller-saved reg or push/pop. */ @@ -7471,7 +7477,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) /* begin checkLiteral:forInstruction: */ cStackPointerAddress(); anInstruction3 = genoperandoperand(MoveRAw, TempReg, cStackPointerAddress()); - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { if (pushedVarBaseReg) { gNativePopR(VarBaseReg); } @@ -8765,6 +8771,22 @@ gMoveCwR(sqInt wordConstant, sqInt reg) return anInstruction; } + /* Cogit>>#MovePerfCnt64R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters) +{ + assert(BytesPerWord == 8); + return genoperandoperand(MovePerfCnt64RL, destReg, liveRegisters); +} + + /* Cogit>>#MovePerfCnt64R:R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters) +{ + assert(BytesPerWord == 4); + return genoperandoperandoperand(MovePerfCnt64RRL, destRegLo, destRegHi, liveRegisters); +} + /* Answer the address of the null byte at the end of the method map. */ @@ -10349,11 +10371,14 @@ recordRunTimeObjectReferences(void) } } + +/* N.B. (self registerMaskFor: NoReg) = 0 */ + /* Cogit>>#registerMaskFor: */ static sqInt NoDbgRegParms registerMaskFor(sqInt reg) { - return 1ULL << reg; + return ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } /* Cogit>>#registerMaskFor:and: */ @@ -17453,7 +17478,7 @@ generateObjectRepresentationTrampolines(void) } # endif // IMMUTABILITY ceNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceNewHash", 1, ReceiverResultReg, null, null, null, /* begin emptyRegisterMask */ 0, 1, ReceiverResultReg, 0); - ceInlineNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceInlineNewHash", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, ReceiverResultReg, 0); + ceInlineNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceInlineNewHash", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))), 1, ReceiverResultReg, 0); /* begin genStoreCheckTrampoline */ if (CheckRememberedInTrampoline) { zeroOpcodeIndex(); @@ -17464,7 +17489,7 @@ generateObjectRepresentationTrampolines(void) genoperand(RetN, 0); jmpTarget(jumpSC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); } - ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))), 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), CheckRememberedInTrampoline); ceStoreCheckContextReceiverTrampoline = genStoreCheckContextReceiverTrampoline(); @@ -19437,7 +19462,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jumpRC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg)); jmpTarget(jumpImmutable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); @@ -19453,7 +19478,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* Store check */ jumpImmutable1 = genJumpImmutablescratchReg(ReceiverResultReg, SendNumArgsReg); - compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), 0 /* emptyRegisterMask */); genLoadStackPointers(backEnd()); @@ -19522,7 +19547,7 @@ genStoreValueinstancenumSlots(sqInt value, sqInt destReg, sqInt numSlots) } return 0; } - constReg = allocateRegNotConflictingWith(1ULL << destReg); + constReg = allocateRegNotConflictingWith(((destReg < 0) ? (((usqInt)(1)) >> (-destReg)) : (1ULL << destReg))); if (shouldAnnotateObjectReference(value)) { annotateobjRef(gMoveCwR(value, constReg), value); } @@ -20423,7 +20448,7 @@ registerMask(SimStackEntry * self_in_registerMask) || (((self_in_registerMask->type)) == SSRegister) ? (/* begin registerMaskFor: */ (reg = (self_in_registerMask->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : 0); } @@ -20436,7 +20461,7 @@ registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone) return (((self_in_registerMaskOrNone->type)) == SSRegister ? (/* begin registerMaskFor: */ (reg = (self_in_registerMaskOrNone->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : 0); } @@ -20511,37 +20536,37 @@ isMergeFixup(BytecodeFixup * self_in_isMergeFixup) static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << Extra5Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra5Reg))) != 0))) { return Extra5Reg; } - if (!(((liveRegsMask & (1U << Extra4Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra4Reg))) != 0))) { return Extra4Reg; } - if (!(((liveRegsMask & (1U << Extra3Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra3Reg))) != 0))) { return Extra3Reg; } - if (!(((liveRegsMask & (1U << Extra2Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra2Reg))) != 0))) { return Extra2Reg; } - if (!(((liveRegsMask & (1U << Extra1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra1Reg))) != 0))) { return Extra1Reg; } - if (!(((liveRegsMask & (1U << Extra0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra0Reg))) != 0))) { return Extra0Reg; } - if (!(((liveRegsMask & (1U << Arg1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg1Reg))) != 0))) { return Arg1Reg; } - if (!(((liveRegsMask & (1U << Arg0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg0Reg))) != 0))) { return Arg0Reg; } - if (!(((liveRegsMask & (1U << SendNumArgsReg)) != 0))) { + if (!(((liveRegsMask & ((1U << SendNumArgsReg))) != 0))) { return SendNumArgsReg; } - if (!(((liveRegsMask & (1U << ClassReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ClassReg))) != 0))) { return ClassReg; } - if (!(((liveRegsMask & (1U << ReceiverResultReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ReceiverResultReg))) != 0))) { return ReceiverResultReg; } return NoReg; @@ -21127,6 +21152,11 @@ computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize) ? 1 : 0)); + case MovePerfCnt64RL: + + /* it is easier to calculate the right value by concretizing. We concretize twice, but so what? */ + return concretizeMovePerfCnt64RL(self_in_computeMaximumSize); + default: error("Case not found and no otherwise clause"); } @@ -21218,6 +21248,65 @@ concretizeFill32(AbstractInstruction * self_in_concretizeFill32) return 4; } + +/* Generate code for + 0x0: 50 pushq %rax + 0x1: 52 pushq %rdx + 0x2: 0f 31 rdtsc + 0x4: 48 c1 e2 20 shlq $0x20, %rdx + 0x8: 48 09 d0 orq %rdx, %rax + 0xb: 48 89 f8 movq %rdi, %rax + 0xe: 5a popq %rdx + 0xf: 58 popq %rax + et al */ + + /* CogX64Compiler>>#concretizeMovePerfCnt64RL */ +static sqInt NoDbgRegParms +concretizeMovePerfCnt64RL(AbstractInstruction * self_in_concretizeMovePerfCnt64RL) +{ + usqInt liveRegisters; + sqInt offset; + usqInt reg; + + reg = ((self_in_concretizeMovePerfCnt64RL->operands))[0]; + liveRegisters = ((self_in_concretizeMovePerfCnt64RL->operands))[1]; + offset = 0; + if (((liveRegisters & ((1U << RAX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[0] = 80; + offset += 1; + } + if (((liveRegisters & ((1U << RDX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 82; + offset += 1; + } + assert(!((reg == RDX))); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 15; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 1] = 49; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 2] = (rexRxb(self_in_concretizeMovePerfCnt64RL, 0, 0, RDX)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 3] = 193; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 4] = (modRMRO(self_in_concretizeMovePerfCnt64RL, ModReg, RDX, 4)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 5] = 32; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 6] = (rexRxb(self_in_concretizeMovePerfCnt64RL, RDX, 0, RAX)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 7] = 11; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 8] = (modRMRO(self_in_concretizeMovePerfCnt64RL, ModReg, RAX, RDX)); + offset += 9; + if (reg != RAX) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[11] = (rexRxb(self_in_concretizeMovePerfCnt64RL, reg, 0, RAX)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[12] = 137; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[13] = (modRMRO(self_in_concretizeMovePerfCnt64RL, ModReg, RAX, reg)); + offset += 3; + } + if (((liveRegisters & ((1U << RDX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 90; + offset += 1; + } + if (((liveRegisters & ((1U << RAX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 88; + offset += 1; + } + return offset; +} + /* CogX64Compiler>>#concretizeMoveRX32rR */ static sqInt NoDbgRegParms concretizeMoveRX32rR(AbstractInstruction * self_in_concretizeMoveRX32rR) @@ -24620,6 +24709,9 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) ((self_in_dispatchConcretize->machineCode))[skip28 + 1] = (modRMRO(self_in_dispatchConcretize, ModReg, srcReg28, destReg29)); return skip28 + 2; + case MovePerfCnt64RL: + return concretizeMovePerfCnt64RL(self_in_dispatchConcretize); + default: error("Case not found and no otherwise clause"); } @@ -25248,8 +25340,8 @@ genPushRegisterArgsForNumArgsscratchReg(AbstractInstruction * self_in_genPushReg /* This is a no-op on x64 SysV since the ABI passes up to 6 args in registers and trampolines currently observe a limit of 4. - But the WIN64 ABI allways reserve shadow space for saving up to 4 - parameter registers (even if less than 4 args). + But the WIN64 ABI always reserve shadow space for saving up to 4 parameter + registers (even if less than 4 args). */ /* CogX64Compiler>>#genRemoveNArgsFromStack: */ @@ -25275,7 +25367,7 @@ genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask) assert(!((((regMask & (registerMaskForand(RSP, RBP))) != 0)))); for (reg = RAX; reg <= R15; reg += 1) { - if (((regMask & (1ULL << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0)) { /* begin PopR: */ genoperand(PopR, reg); } @@ -25297,7 +25389,7 @@ genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask) assert(((R15 - RAX) + 1) == 16); assert(!((((regMask & (registerMaskForand(RSP, RBP))) != 0)))); for (reg = R15; reg >= RAX; reg += -1) { - if (((regMask & (1ULL << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0)) { /* begin PushR: */ genoperand(PushR, reg); } @@ -26118,56 +26210,45 @@ compileInterpreterPrimitive(void) static sqInt NoDbgRegParms compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) { - sqInt address2; + AbstractInstruction *anInstruction; + AbstractInstruction *anInstruction1; AbstractInstruction *anInstruction10; AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction15; + AbstractInstruction *anInstruction14; + AbstractInstruction *anInstruction16; + AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction18; AbstractInstruction *anInstruction19; AbstractInstruction *anInstruction2; AbstractInstruction *anInstruction20; AbstractInstruction *anInstruction21; + AbstractInstruction *anInstruction22; AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction24; AbstractInstruction *anInstruction25; AbstractInstruction *anInstruction26; AbstractInstruction *anInstruction27; + AbstractInstruction *anInstruction28; AbstractInstruction *anInstruction29; AbstractInstruction *anInstruction3; + AbstractInstruction *anInstruction30; AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction33; - AbstractInstruction *anInstruction34; - AbstractInstruction *anInstruction35; - AbstractInstruction *anInstruction36; - AbstractInstruction *anInstruction37; - AbstractInstruction *anInstruction38; - AbstractInstruction *anInstruction39; AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction40; AbstractInstruction *anInstruction41; - AbstractInstruction *anInstruction5; AbstractInstruction *anInstruction6; AbstractInstruction *anInstruction7; AbstractInstruction *anInstruction8; - AbstractInstruction * continuePostSampleNonPrim; - AbstractInstruction * continuePostSamplePrim; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; - AbstractInstruction * jmpSampleNonPrim; - AbstractInstruction * jmpSamplePrim; + AbstractInstruction * jumpToTakeSample; + sqInt liveRegisters; sqInt offset; sqInt offset1; sqInt offset2; - sqInt operand1; - sqInt operand3; sqInt reg; sqInt retpc; - continuePostSampleNonPrim = ((AbstractInstruction *) 0); - continuePostSamplePrim = ((AbstractInstruction *) 0); - jmpSampleNonPrim = ((AbstractInstruction *) 0); - jmpSamplePrim = ((AbstractInstruction *) 0); + jumpToTakeSample = ((AbstractInstruction *) 0); assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); genExternalizePointersForPrimitiveCall(); /* begin genLoadCStackPointersForPrimCall */ @@ -26177,41 +26258,28 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) else { genLoadCStackPointer(backEnd); } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick if so */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction2 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpSampleNonPrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSampleNonPrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } if (recordPrimTraceForMethod(methodObj)) { genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction37 = genoperandoperand(MoveCqR, 0, TempReg); + anInstruction18 = genoperandoperand(MoveCqR, 0, TempReg); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction38 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); + anInstruction19 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); + anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); } /* begin checkLiteral:forInstruction: */ argumentCountAddress(); - anInstruction39 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); + anInstruction20 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { /* begin checkLiteral:forInstruction: */ ((sqInt)primitiveRoutine); - anInstruction5 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); + anInstruction1 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); /* begin checkLiteral:forInstruction: */ primitiveFunctionPointerAddress(); - anInstruction6 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); + anInstruction2 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); } if (((flags & (PrimCallNeedsNewMethod + PrimCallMayEndureCodeCompaction)) != 0)) { @@ -26223,17 +26291,16 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) /* begin MoveMw:r:R: */ offset = offsetof(CogMethod, methodObject); /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); + anInstruction3 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); /* begin checkLiteral:forInstruction: */ newMethodAddress(); - anInstruction8 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); + anInstruction4 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); } /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction40 = genoperand(PrefetchAw, primFailCodeAddress()); + anInstruction22 = genoperand(PrefetchAw, primFailCodeAddress()); if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - /* Sideways call the C primitive routine so that we return through cePrimReturnEnterCogCode. */ /* On Spur ceActivateFailingPrimitiveMethod: would like to retry if forwarders are found. So insist on PrimCallNeedsPrimitiveFunction being set too. */ assert(((flags & PrimCallNeedsPrimitiveFunction) != 0)); @@ -26241,12 +26308,12 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) /* WIN64 ABI allways reserve shadow space on the stack for callee to save up to 4 register parameters */ /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperand(SubCqR, 32, RSP); - goto l32; + anInstruction7 = genoperandoperand(SubCqR, 32, RSP); + goto l20; assert(0 <= 4); if (null < NoReg) { /* begin MoveCq:R: */ - anInstruction12 = genoperandoperand(MoveCqR, -2 - null, CArg0Reg); + anInstruction11 = genoperandoperand(MoveCqR, -2 - null, CArg0Reg); } else { if (null != CArg0Reg) { @@ -26284,115 +26351,94 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) genoperandoperand(MoveRR, null, CArg3Reg); } } - l32: /* end genMarshallNArgs:arg:arg:arg:arg: */; + l20: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin genSubstituteReturnAddress: */ retpc = (((flags & PrimCallCollectsProfileSamples) != 0) ? cePrimReturnEnterCogCodeProfiling : cePrimReturnEnterCogCode); /* begin checkLiteral:forInstruction: */ - anInstruction13 = genoperand(PushCw, retpc); + anInstruction8 = genoperand(PushCw, retpc); /* begin gen:literal: */ - anInstruction10 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); - jmp = (jmpSamplePrim = (continuePostSamplePrim = null)); + anInstruction6 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); + return 0; } - else { - - /* Call the C primitive routine. */ - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - - /* WIN64 ABI allways reserve shadow space on the stack for callee to save up to 4 register parameters */ - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperand(SubCqR, 32, RSP); - goto l49; - assert(0 <= 4); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg0Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg1Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg2Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg3Reg); - l49: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin gen:literal: */ - anInstruction15 = genoperand(CallFull, ((sqInt)primitiveRoutine)); - /* begin genRemoveNArgsFromStack: */ - assert(0 <= 4); - /* begin checkQuickConstant:forInstruction: */ - anInstruction23 = genoperandoperand(AddCqR, 32, RSP); - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction18 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpSamplePrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSamplePrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - maybeCompileRetryOnPrimitiveFail(primitiveIndex); - /* begin MoveAw:R: */ - address2 = instructionPointerAddress(); - reg = ClassReg; - /* begin checkLiteral:forInstruction: */ - anInstruction24 = genoperandoperand(MoveAwR, address2, reg); - genLoadStackPointers(backEnd); + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + + /* WIN64 ABI allways reserve shadow space on the stack for callee to save up to 4 register parameters */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction23 = genoperandoperand(SubCqR, 32, RSP); + goto l43; + assert(0 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg0Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg1Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg2Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg3Reg); + l43: /* end genMarshallNArgs:arg:arg:arg:arg: */; + /* begin gen:literal: */ + anInstruction10 = genoperand(CallFull, ((sqInt)primitiveRoutine)); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 4); + /* begin checkQuickConstant:forInstruction: */ + anInstruction25 = genoperandoperand(AddCqR, 32, RSP); + maybeCompileRetryOnPrimitiveFail(primitiveIndex); + genLoadStackPointersForPrimCall(backEnd, ClassReg); + /* begin checkLiteral:forInstruction: */ + instructionPointerAddress(); + anInstruction13 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); + /* begin checkQuickConstant:forInstruction: */ + anInstruction14 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + /* begin checkLiteral:forInstruction: */ + primFailCodeAddress(); + anInstruction26 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + flag("ask concrete code gen if move sets condition codes?"); + /* begin checkQuickConstant:forInstruction: */ + anInstruction27 = genoperandoperand(CmpCqR, 0, TempReg); + /* begin JumpNonZero: */ + jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + /* begin preferredRegisterForMovePerfCnt64RL */ + reg = RAX; + gMovePerfCnt64RL(reg, liveRegisters); /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction25 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - /* begin PushR: */ - genoperand(PushR, ClassReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction26 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset1 = BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction27 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, BytesPerWord); + nextProfileTickAddress(); + anInstruction30 = genoperandoperand(MoveAwR, nextProfileTickAddress(), Arg1Reg); + /* begin CmpR:R: */ + assert(!((reg == SPReg))); + genoperandoperand(CmpRR, reg, Arg1Reg); + /* begin JumpGreaterOrEqual: */ + jumpToTakeSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l57; + l57: /* end genCheckForProfileTimerTick: */; } + /* begin MoveMw:r:R: */ + offset1 = BytesPerWord; + /* begin checkQuickConstant:forInstruction: */ + anInstruction28 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); + continueAfterProfileSample = anInstruction28; + /* begin RetN: */ + genoperand(RetN, BytesPerWord); if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* The sample is collected by cePrimReturnEnterCogCode for external calls */ - if (!(jmpSamplePrim == null)) { - - /* Call ceCheckProfileTick: to record sample and then continue. */ - jmpTarget(jmpSamplePrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin gen:literal: */ - operand1 = ((usqIntptr_t)ceCheckProfileTick); - /* begin checkLiteral:forInstruction: */ - anInstruction29 = genoperand(CallFull, operand1); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSamplePrim)); - } - jmpTarget(jmpSampleNonPrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction34 = genoperandoperand(MoveCqR, 0, TempReg); - /* begin checkLiteral:forInstruction: */ - newMethodAddress(); - anInstruction35 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); - /* begin gen:literal: */ - operand3 = ((usqIntptr_t)ceCheckProfileTick); + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); /* begin checkLiteral:forInstruction: */ - anInstruction33 = genoperand(CallFull, operand3); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSampleNonPrim)); - } - if (!(jmp == null)) { - - /* Jump to restore of receiver reg and proceed to frame build for failure. */ - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin MoveMw:r:R: */ - offset2 = BytesPerWord * (methodOrBlockNumArgs + (1)); + instructionPointerAddress(); + anInstruction16 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction36 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); + anInstruction17 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + /* begin Jump: */ + genoperand(Jump, ((sqInt)continueAfterProfileSample)); } + jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + /* begin MoveMw:r:R: */ + offset2 = BytesPerWord * (methodOrBlockNumArgs + (1)); + /* begin checkQuickConstant:forInstruction: */ + anInstruction29 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); return 0; } @@ -26424,7 +26470,7 @@ compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)) if ((methodOrBlockNumArgs > 2 /* numRegArgs */) || (methodOrBlockNumArgs == 0)) { /* begin registerMaskFor: */ - liveRegsMask = 1U << ReceiverResultReg; + liveRegsMask = (1U << ReceiverResultReg); } else { if (methodOrBlockNumArgs > 1) { @@ -26517,50 +26563,59 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags AbstractInstruction *anInstruction12; AbstractInstruction *anInstruction13; AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; AbstractInstruction *anInstruction16; AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction18; AbstractInstruction *anInstruction19; AbstractInstruction *anInstruction2; AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; AbstractInstruction *anInstruction22; AbstractInstruction *anInstruction23; + AbstractInstruction *anInstruction24; + AbstractInstruction *anInstruction26; + AbstractInstruction *anInstruction27; + AbstractInstruction *anInstruction28; + AbstractInstruction *anInstruction29; + AbstractInstruction *anInstruction30; AbstractInstruction *anInstruction4; AbstractInstruction *anInstruction5; AbstractInstruction *anInstruction6; AbstractInstruction *anInstruction8; AbstractInstruction *anInstruction9; sqInt calleeSavedRegisterMask; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; + AbstractInstruction * jumpToTakeSample; + sqInt liveRegisters; sqInt offset; sqInt offset1; sqInt operand1; + sqInt reg; sqInt retpcOffset; AbstractInstruction * retry; AbstractInstruction * skip; sqInt spRegSaveRegister; + jumpToTakeSample = ((AbstractInstruction *) 0); assert(((flags & PrimCallOnSmalltalkStack) != 0)); assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); if (recordFastCCallPrimTraceForMethod(methodObj)) { genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction18 = genoperandoperand(MoveCqR, 0, TempReg); + anInstruction20 = genoperandoperand(MoveCqR, 0, TempReg); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction19 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); + anInstruction22 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); } /* begin checkLiteral:forInstruction: */ argumentCountAddress(); - anInstruction20 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); + anInstruction23 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); genExternalizeStackPointerForFastPrimitiveCall(); - calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | (1U << ClassReg)) - (1U << ClassReg)); + calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | ((1U << ClassReg))) - ((1U << ClassReg))); spRegSaveRegister = NoReg; /* begin Label */ retry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); @@ -26569,22 +26624,60 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags } else { } + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + + /* WIN64 ABI allways reserve shadow space on the stack for callee to save up to 4 register parameters */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction24 = genoperandoperand(SubCqR, 32, RSP); + goto l53; + assert(0 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg0Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg1Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg2Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg3Reg); + l53: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin gen:literal: */ - anInstruction2 = genoperand(CallFull, primitiveRoutine); + anInstruction2 = genoperand(CallFull, ((sqInt)primitiveRoutine)); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 4); + /* begin checkQuickConstant:forInstruction: */ + anInstruction26 = genoperandoperand(AddCqR, 32, RSP); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction21 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + anInstruction27 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); if (spRegSaveRegister != NoReg) { /* begin MoveR:R: */ genoperandoperand(MoveRR, spRegSaveRegister, SPReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperand(CmpCqR, 0, TempReg); + anInstruction28 = genoperandoperand(CmpCqR, 0, TempReg); /* begin JumpNonZero: */ jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + /* begin preferredRegisterForMovePerfCnt64RL */ + reg = RAX; + gMovePerfCnt64RL(reg, liveRegisters); + /* begin checkLiteral:forInstruction: */ + nextProfileTickAddress(); + anInstruction30 = genoperandoperand(MoveAwR, nextProfileTickAddress(), Arg1Reg); + /* begin CmpR:R: */ + assert(!((reg == SPReg))); + genoperandoperand(CmpRR, reg, Arg1Reg); + /* begin JumpGreaterOrEqual: */ + jumpToTakeSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l66; + l66: /* end genCheckForProfileTimerTick: */; + } /* begin checkLiteral:forInstruction: */ stackPointerAddress(); - anInstruction23 = genoperandoperand(MoveAwR, stackPointerAddress(), TempReg); + anInstruction29 = genoperandoperand(MoveAwR, stackPointerAddress(), TempReg); + continueAfterProfileSample = anInstruction29; /* The original retpc is (argumentCount + 1) words below stackPointer. */ retpcOffset = -((methodOrBlockNumArgs + 1) * BytesPerWord); @@ -26598,6 +26691,12 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags anInstruction6 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, TempReg); /* begin RetN: */ genoperand(RetN, 0); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); + /* begin Jump: */ + genoperand(Jump, ((sqInt)continueAfterProfileSample)); + } jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); if ((accessorDepthForExternalPrimitiveMethod(methodObj)) >= 0) { @@ -26628,20 +26727,36 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags else { genLoadCStackPointer(backEnd); } + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + + /* WIN64 ABI allways reserve shadow space on the stack for callee to save up to 4 register parameters */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction14 = genoperandoperand(SubCqR, 32, RSP); + goto l36; + assert(0 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg0Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg1Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg2Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg3Reg); + l36: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin gen:literal: */ operand1 = ((usqIntptr_t)checkForAndFollowForwardedPrimitiveState); /* begin checkLiteral:forInstruction: */ anInstruction8 = genoperand(CallFull, operand1); - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(CmpCqR, 0, ABIResultReg); + anInstruction16 = genoperandoperand(CmpCqR, 0, ABIResultReg); /* begin JumpZero: */ skip = genConditionalBranchoperand(JumpZero, ((sqInt)0)); /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperand(MoveCqR, 0, TempReg); + anInstruction17 = genoperandoperand(MoveCqR, 0, TempReg); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction16 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); + anInstruction18 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); /* begin Jump: */ genoperand(Jump, ((sqInt)retry)); jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); @@ -26650,14 +26765,14 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags /* must reload SPReg to undo any alignment change, */ if (((flags & PrimCallOnSmalltalkStackAlign2x) != 0)) { - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); } } - if (((ABICallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((ABICallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* begin MoveMw:r:R: */ offset1 = (methodOrBlockNumArgs + (1)) * BytesPerWord; /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); + anInstruction19 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); } return 0; } @@ -27660,23 +27775,24 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) { sqInt address1; AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction10; + AbstractInstruction *anInstruction11; AbstractInstruction *anInstruction12; AbstractInstruction *anInstruction13; AbstractInstruction *anInstruction14; AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction18; + AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; + AbstractInstruction *anInstruction7; AbstractInstruction *anInstruction8; AbstractInstruction *anInstruction9; sqInt callTarget; AbstractInstruction *continuePostSample; AbstractInstruction *jmpFail; AbstractInstruction *jmpSample; + sqInt liveRegisters; sqInt quickConstant; sqInt reg; + sqInt reg1; continuePostSample = ((AbstractInstruction *) 0); jmpSample = ((AbstractInstruction *) 0); @@ -27685,56 +27801,63 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) quickConstant = varBaseAddress(); /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - if (profiling) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick: if so. - N.B. nextProfileTick is 64-bits so 32-bit systems need to test both halves. */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction3 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpSample = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction13 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + anInstruction12 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); flag("ask concrete code gen if move sets condition codes?"); /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(CmpCqR, 0, TempReg); + anInstruction13 = genoperandoperand(CmpCqR, 0, TempReg); /* begin JumpNonZero: */ jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (profiling + && (1)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + /* begin preferredRegisterForMovePerfCnt64RL */ + reg = RAX; + gMovePerfCnt64RL(reg, liveRegisters); + /* begin checkLiteral:forInstruction: */ + nextProfileTickAddress(); + anInstruction3 = genoperandoperand(MoveAwR, nextProfileTickAddress(), Arg1Reg); + /* begin CmpR:R: */ + assert(!((reg == SPReg))); + genoperandoperand(CmpRR, reg, Arg1Reg); + /* begin JumpGreaterOrEqual: */ + jmpSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l18; + l18: /* end genCheckForProfileTimerTick: */; + /* begin Label */ + continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); + } /* begin checkLiteral:forInstruction: */ instructionPointerAddress(); - anInstruction8 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); + anInstruction7 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); + anInstruction8 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + anInstruction9 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jmpFail, checkLiteralforInstruction(newMethodAddress(), genoperandoperand(MoveAwR, newMethodAddress(), SendNumArgsReg))); /* begin checkLiteral:forInstruction: */ cStackPointerAddress(); - anInstruction15 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); + anInstruction14 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); compileCallFornumArgsargargargargresultRegregsToSave(ceActivateFailingPrimitiveMethod, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); /* begin MoveAw:R: */ address1 = instructionPointerAddress(); - reg = ClassReg; + reg1 = ClassReg; /* begin checkLiteral:forInstruction: */ - anInstruction16 = genoperandoperand(MoveAwR, address1, reg); + anInstruction15 = genoperandoperand(MoveAwR, address1, reg1); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveMwrR, BytesPerWord, SPReg, ReceiverResultReg); + anInstruction11 = genoperandoperandoperand(MoveMwrR, BytesPerWord, SPReg, ReceiverResultReg); /* begin PushR: */ genoperand(PushR, ClassReg); /* begin RetN: */ genoperand(RetN, BytesPerWord); - if (profiling) { + if (profiling + && (1)) { /* Call ceCheckProfileTick: to record sample and then continue. newMethod should be up-to-date. Need to save and restore the link reg around this call. */ @@ -27743,7 +27866,7 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) /* begin CallFullRT: */ callTarget = (usqIntptr_t)ceCheckProfileTick; /* begin checkLiteral:forInstruction: */ - anInstruction18 = genoperand(CallFull, callTarget); + anInstruction17 = genoperand(CallFull, callTarget); /* begin Jump: */ genoperand(Jump, ((sqInt)continuePostSample)); } @@ -28098,6 +28221,69 @@ genStoreRemoteTempLongBytecode(void) && (shouldAnnotateObjectReference(((ssTop())->constant))))); } + /* SimpleStackBasedCogit>>#genTakeProfileSample */ +static void +genTakeProfileSample(void) +{ + AbstractInstruction *anInstruction1; + AbstractInstruction *anInstruction2; + AbstractInstruction *anInstruction3; + AbstractInstruction *anInstruction4; + AbstractInstruction *anInstruction5; + AbstractInstruction *anInstruction6; + sqInt operand1; + + addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + + /* WIN64 ABI allways reserve shadow space on the stack for callee to save up to 4 register parameters */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction5 = genoperandoperand(SubCqR, 32, RSP); + assert(1 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, ClassReg, CArg0Reg); + goto l12; + if (null < NoReg) { + /* begin MoveCq:R: */ + anInstruction2 = genoperandoperand(MoveCqR, -2 - null, CArg1Reg); + } + else { + if (null != CArg1Reg) { + /* begin MoveR:R: */ + genoperandoperand(MoveRR, null, CArg1Reg); + } + } + if (null < NoReg) { + /* begin MoveCq:R: */ + anInstruction3 = genoperandoperand(MoveCqR, -2 - null, CArg2Reg); + } + else { + if (null != CArg2Reg) { + /* begin MoveR:R: */ + genoperandoperand(MoveRR, null, CArg2Reg); + } + } + if (null < NoReg) { + /* begin MoveCq:R: */ + anInstruction4 = genoperandoperand(MoveCqR, -2 - null, CArg3Reg); + } + else { + if (null != CArg3Reg) { + /* begin MoveR:R: */ + genoperandoperand(MoveRR, null, CArg3Reg); + } + } + l12: /* end genMarshallNArgs:arg:arg:arg:arg: */; + /* begin gen:literal: */ + operand1 = ((usqIntptr_t)ceTakeProfileSample); + /* begin checkLiteral:forInstruction: */ + anInstruction1 = genoperand(CallFull, operand1); + /* begin genRemoveNArgsFromStack: */ + assert(1 <= 4); + /* begin checkQuickConstant:forInstruction: */ + anInstruction6 = genoperandoperand(AddCqR, 32, RSP); + } + /* Collect the branch and send data for cogMethod, storing it into arrayObj. */ @@ -28467,7 +28653,7 @@ primitiveGeneratorOrNil(void) static sqInt NoDbgRegParms registerisInMask(sqInt reg, sqInt mask) { - return ((mask & (1ULL << reg)) != 0); + return ((mask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0); } /* SimpleStackBasedCogit>>#v3:Block:Code:Size: */ @@ -29128,7 +29314,7 @@ genBinaryAtConstInlinePrimitive(sqInt primIndex) val = ((ssTop())->constant); if (primIndex == 65) { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); rr = ReceiverResultReg; } @@ -29144,10 +29330,10 @@ genBinaryAtConstInlinePrimitive(sqInt primIndex) break; case 65: /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << SendNumArgsReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << SendNumArgsReg), simStackPtr, simNativeStackPtr); /* begin genPushMaybeContextSlotIndex: */ assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ voidReceiverResultRegContainsSelf(); @@ -29228,13 +29414,13 @@ genBinaryAtInlinePrimitive(sqInt primIndex) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -29390,7 +29576,7 @@ genBinaryCompInlinePrimitive(sqInt primIndex) } otherReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); popToReg(ssTop(), otherReg); - resultReg = allocateRegForStackEntryAtnotConflictingWith(1, 1ULL << otherReg); + resultReg = allocateRegForStackEntryAtnotConflictingWith(1, ((otherReg < 0) ? (((usqInt)(1)) >> (-otherReg)) : (1ULL << otherReg))); popToReg(ssValue(1), resultReg); /* begin CmpR:R: */ assert(!((otherReg == SPReg))); @@ -29798,7 +29984,7 @@ genBinarySmiBitShiftLeftInlinePrimitive(void) genoperandoperand(LogicalShiftLeftCqR, quickConstant, rr); } else { - ra = allocateRegForStackEntryAtnotConflictingWith(0, 1ULL << rr); + ra = allocateRegForStackEntryAtnotConflictingWith(0, ((rr < 0) ? (((usqInt)(1)) >> (-rr)) : (1ULL << rr))); popToReg(ssTop(), ra); genConvertSmallIntegerToIntegerInReg(ra); /* begin LogicalShiftLeftR:R: */ @@ -29831,7 +30017,7 @@ genBinarySmiBitShiftRightInlinePrimitive(void) genoperandoperand(ArithmeticShiftRightCqR, quickConstant, rr); } else { - ra = allocateRegForStackEntryAtnotConflictingWith(0, 1ULL << rr); + ra = allocateRegForStackEntryAtnotConflictingWith(0, ((rr < 0) ? (((usqInt)(1)) >> (-rr)) : (1ULL << rr))); popToReg(ssTop(), ra); genConvertSmallIntegerToIntegerInReg(ra); /* begin ArithmeticShiftRightR:R: */ @@ -29922,13 +30108,13 @@ genBinaryVarOpVarSmiInlinePrimitive(sqInt primIndex) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -29999,7 +30185,7 @@ genByteAtPut(void) && (1)) { /* begin registerMaskFor: */ reg = (rTop1 = registerOrNone(ssTop())); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (((registerOrNone(ssValue(1))) != NoReg) && (1)) { @@ -30011,11 +30197,11 @@ genByteAtPut(void) } if (rThird1 == NoReg) { rThird1 = allocateRegNotConflictingWith(topRegistersMask); - topRegistersMask = topRegistersMask | (1ULL << rThird1); + topRegistersMask = topRegistersMask | (((rThird1 < 0) ? (((usqInt)(1)) >> (-rThird1)) : (1ULL << rThird1))); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); - topRegistersMask = topRegistersMask | (1ULL << rTop1); + topRegistersMask = topRegistersMask | (((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } if (rNext1 == NoReg) { rNext1 = allocateRegNotConflictingWith(topRegistersMask); @@ -30362,7 +30548,7 @@ genByteEqualsInlinePrimitive(sqInt prim) if (needLoop) { assert(!(((ssTop())->spilled))); str1Reg = allocateRegForStackEntryAtnotConflictingWith(1, 0 /* emptyRegisterMask */); - str2Reg = allocateRegForStackEntryAtnotConflictingWith(2, 1ULL << str1Reg); + str2Reg = allocateRegForStackEntryAtnotConflictingWith(2, ((str1Reg < 0) ? (((usqInt)(1)) >> (-str1Reg)) : (1ULL << str1Reg))); lenReg = allocateRegForStackEntryAtnotConflictingWith(0, (1ULL << str1Reg) | (1ULL << str2Reg)); popToReg(ssValue(1), str1Reg); popToReg(ssValue(2), str2Reg); @@ -30374,12 +30560,12 @@ genByteEqualsInlinePrimitive(sqInt prim) if (!((((ssValue(1))->type)) == SSConstant)) { str1Reg = allocateRegForStackEntryAtnotConflictingWith(1, mask); popToReg(ssValue(1), str1Reg); - mask = mask | (1ULL << str1Reg); + mask = mask | (((str1Reg < 0) ? (((usqInt)(1)) >> (-str1Reg)) : (1ULL << str1Reg))); } if (!((((ssValue(2))->type)) == SSConstant)) { str2Reg = allocateRegForStackEntryAtnotConflictingWith(2, mask); popToReg(ssValue(2), str2Reg); - mask = mask | (1ULL << str2Reg); + mask = mask | (((str2Reg < 0) ? (((usqInt)(1)) >> (-str2Reg)) : (1ULL << str2Reg))); } extraReg = allocateRegNotConflictingWith(mask); } @@ -30572,7 +30758,7 @@ genCounterTripOnlyJumpIfto(sqInt boolean, sqInt targetBytecodePC) /* We need SendNumArgsReg because of the mustBeBooleanTrampoline */ counterIndex += 1; /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << SendNumArgsReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << SendNumArgsReg), simStackPtr, simNativeStackPtr); /* begin checkQuickConstant:forInstruction: */ anInstruction1 = genoperandoperand(MoveCqR, 1, SendNumArgsReg); mustBeBooleanTrampoline = genCallMustBeBooleanFor(boolean); @@ -30688,13 +30874,13 @@ genDivInlinePrimitive(sqInt primIndex) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -31007,13 +31193,13 @@ genForwardersInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -31198,13 +31384,13 @@ genForwardersInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg1 = (rNext11 = registerOrNone(ssValue(1))); - topRegistersMask1 = 1ULL << reg1; + topRegistersMask1 = ((reg1 < 0) ? (((usqInt)(1)) >> (-reg1)) : (1ULL << reg1)); } if (rTop11 == NoReg) { rTop11 = allocateRegNotConflictingWith(topRegistersMask1); } if (rNext11 == NoReg) { - rNext11 = allocateRegNotConflictingWith(1ULL << rTop11); + rNext11 = allocateRegNotConflictingWith(((rTop11 < 0) ? (((usqInt)(1)) >> (-rTop11)) : (1ULL << rTop11))); } assert(!(((rTop11 == NoReg) || (rNext11 == NoReg)))); @@ -31255,12 +31441,12 @@ genForwardersInlinedIdenticalOrNotIf(sqInt orNot) } if (argReg == NoReg) { /* begin registerMaskFor: */ - regMask = 1ULL << rcvrReg; + regMask = ((rcvrReg < 0) ? (((usqInt)(1)) >> (-rcvrReg)) : (1ULL << rcvrReg)); } else { if (rcvrReg == NoReg) { /* begin registerMaskFor: */ - regMask = 1ULL << argReg; + regMask = ((argReg < 0) ? (((usqInt)(1)) >> (-argReg)) : (1ULL << argReg)); } else { /* begin registerMaskFor:and: */ @@ -31882,7 +32068,7 @@ genJumpIfto(sqInt boolean, sqInt targetBytecodePC) popToReg(desc, TempReg); ssPop(1); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << SendNumArgsReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << SendNumArgsReg), simStackPtr, simNativeStackPtr); /* begin Label */ retry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); /* begin genExecutionCountLogicInto:counterReg: */ @@ -32309,13 +32495,13 @@ genPointerAtPutConstantMaybeContextstoreCheckimmutabilityCheck(sqInt maybeContex rcvrReg = ReceiverResultReg; } else { - rcvrReg = allocateRegForStackEntryAtnotConflictingWith(2, 1ULL << valReg); + rcvrReg = allocateRegForStackEntryAtnotConflictingWith(2, ((valReg < 0) ? (((usqInt)(1)) >> (-valReg)) : (1ULL << valReg))); } } /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1ULL << valReg, simStackPtr - 2, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((valReg < 0) ? (((usqInt)(1)) >> (-valReg)) : (1ULL << valReg)), simStackPtr - 2, simNativeStackPtr); /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1ULL << rcvrReg, simStackPtr - 3, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((rcvrReg < 0) ? (((usqInt)(1)) >> (-rcvrReg)) : (1ULL << rcvrReg)), simStackPtr - 3, simNativeStackPtr); popToReg(ssTop(), valReg); ssPop(1); if (((ssTop())->spilled)) { @@ -32356,7 +32542,7 @@ genPointerAtPutConstantMaybeContextstoreCheckimmutabilityCheck(sqInt maybeContex # endif // IMMUTABILITY ssPop(1); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ClassReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ssPush(1); genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); ssStoreAndReplacePoptoReg(0, ClassReg); @@ -32386,7 +32572,7 @@ genPointerAtPutConstantMaybeContextstoreCheckimmutabilityCheck(sqInt maybeContex # if IMMUTABILITY if (needsImmCheck) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(0, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -32400,7 +32586,7 @@ genPointerAtPutConstantMaybeContextstoreCheckimmutabilityCheck(sqInt maybeContex return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, indexCst, rcvrReg, TempReg, needsStoreCheck, 0); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1ULL << rcvrReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, ((rcvrReg < 0) ? (((usqInt)(1)) >> (-rcvrReg)) : (1ULL << rcvrReg))); ssStorePoptoReg(0, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, indexCst, rcvrReg, TempReg, needsFrame, needsStoreCheck); } @@ -32657,7 +32843,7 @@ genPointerAtPutStoreCheck(sqInt needsStoreCheck) || ((registerOrNone(ssTop())) != ReceiverResultReg))) { /* begin registerMaskFor: */ reg = (rTop1 = registerOrNone(ssTop())); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (((registerOrNone(ssValue(1))) != NoReg) && ((!needsStoreCheck) @@ -32675,17 +32861,17 @@ genPointerAtPutStoreCheck(sqInt needsStoreCheck) /* Free ReceiverResultReg if it was not free */ rThird1 = ReceiverResultReg; /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); } else { rThird1 = allocateRegNotConflictingWith(topRegistersMask); } - topRegistersMask = topRegistersMask | (1ULL << rThird1); + topRegistersMask = topRegistersMask | (((rThird1 < 0) ? (((usqInt)(1)) >> (-rThird1)) : (1ULL << rThird1))); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); - topRegistersMask = topRegistersMask | (1ULL << rTop1); + topRegistersMask = topRegistersMask | (((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } if (rNext1 == NoReg) { rNext1 = allocateRegNotConflictingWith(topRegistersMask); @@ -33207,7 +33393,7 @@ genUnaryClassPrimitive(void) sqInt topReg; topReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - destReg = allocateRegNotConflictingWith(1ULL << topReg); + destReg = allocateRegNotConflictingWith(((topReg < 0) ? (((usqInt)(1)) >> (-topReg)) : (1ULL << topReg))); popToReg(ssTop(), topReg); /* begin MoveR:R: */ genoperandoperand(MoveRR, topReg, TempReg); @@ -33273,7 +33459,7 @@ genUnaryHashInlinePrimitive(sqInt primIndex) switch (primIndex) { case 20: rcvrReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - resultReg = allocateRegNotConflictingWith(1ULL << rcvrReg); + resultReg = allocateRegNotConflictingWith(((rcvrReg < 0) ? (((usqInt)(1)) >> (-rcvrReg)) : (1ULL << rcvrReg))); popToReg(ssTop(), rcvrReg); genGetIdentityHashresultReg(rcvrReg, resultReg); break; @@ -33463,7 +33649,7 @@ genUnarySizeInlinePrimitive(sqInt primIndex) assert(((primIndex >= 1) && (primIndex <= 6))); rcvrReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - resultReg = allocateRegNotConflictingWith(1ULL << rcvrReg); + resultReg = allocateRegNotConflictingWith(((rcvrReg < 0) ? (((usqInt)(1)) >> (-rcvrReg)) : (1ULL << rcvrReg))); popToReg(ssTop(), rcvrReg); ssPop(1); ssPushRegister(resultReg); @@ -34646,7 +34832,7 @@ anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n) sqInt regMask; /* begin registerMaskFor: */ - regMask = 1ULL << reg; + regMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { if ((((registerMask(simStackAt(i))) & regMask) != 0)) { return 1; @@ -35336,7 +35522,7 @@ ensureReceiverResultRegContainsSelf(void) if (needsFrame) { if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin putSelfInReceiverResultReg */ storeToReg(simSelf(), ReceiverResultReg); ((simSelf())->liveRegister = ReceiverResultReg); @@ -35468,7 +35654,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) && (index < simStackPtr)) { desc = simStackAt(index); if (((desc->type)) == SSRegister) { - if (!(((regMask & (1ULL << ((desc->registerr)))) != 0))) { + if (!(((regMask & (((((desc->registerr)) < 0) ? (((usqInt)(1)) >> (-((desc->registerr)))) : (1ULL << ((desc->registerr)))))) != 0))) { reg = (desc->registerr); } } @@ -35476,7 +35662,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) } assert(!((reg == NoReg))); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1ULL << reg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)), simStackPtr, simNativeStackPtr); return reg; } @@ -36576,11 +36762,11 @@ genPushMaybeContextReceiverVariable(sqInt slotIndex) AbstractInstruction *jmpSingle; /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ensureReceiverResultRegContainsSelf(); /* begin genPushMaybeContextSlotIndex: */ assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ voidReceiverResultRegContainsSelf(); @@ -36633,7 +36819,7 @@ genPushNewArrayBytecode(void) } else { /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << SendNumArgsReg)) | ((1U << ReceiverResultReg))), simStackPtr, simNativeStackPtr); } size = byte1 & 0x7F; if (!popValues) { @@ -36706,7 +36892,7 @@ genPushRemoteTempLongBytecode(void) /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperandoperand(MoveMwrR, offset, FPReg, tempVectReg); /* begin availableRegOrNoneNotConflictingWith: */ - regMask = 1ULL << tempVectReg; + regMask = ((tempVectReg < 0) ? (((usqInt)(1)) >> (-tempVectReg)) : (1ULL << tempVectReg)); remoteTempReg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); if (remoteTempReg == NoReg) { remoteTempReg = tempVectReg; @@ -37056,11 +37242,11 @@ genSpecialSelectorClass(void) || (topReg == ClassReg)) { /* begin ssAllocateRequiredReg:and: */ requiredReg1 = (topReg = SendNumArgsReg); - ssAllocateRequiredRegMaskupThroughupThroughNative((1ULL << requiredReg1) | (1U << ClassReg), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((((requiredReg1 < 0) ? (((usqInt)(1)) >> (-requiredReg1)) : (1ULL << requiredReg1))) | ((1U << ClassReg)), simStackPtr, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr, simNativeStackPtr); } ssPush(1); popToReg(ssTop(), topReg); @@ -37132,7 +37318,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean association = getLiteral(litVarIndex); voidReceiverResultRegContainsSelf(); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin genMoveConstant:R: */ if (shouldAnnotateObjectReference(association)) { annotateobjRef(checkLiteralforInstruction(association, genoperandoperand(MoveCwR, association, ReceiverResultReg)), association); @@ -37145,7 +37331,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean # if IMMUTABILITY if (needsImmCheck) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -37159,7 +37345,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -37220,7 +37406,7 @@ genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqI # endif // IMMUTABILITY ssPop(1); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ClassReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ssPush(1); genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); @@ -37265,7 +37451,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea # if IMMUTABILITY if (needsImmCheck1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -37279,7 +37465,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck1, 1); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck1); } @@ -37303,7 +37489,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt assert(needsFrame); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); /* begin MoveMw:r:R: */ offset = frameOffsetOfTemporary(remoteTempIndex); @@ -37313,7 +37499,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt # if IMMUTABILITY # endif - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -37499,13 +37685,13 @@ genVanillaInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -37759,12 +37945,12 @@ liveRegisters(void) } else { /* begin registerMaskFor: */ - regsSet = 1U << ReceiverResultReg; + regsSet = (1U << ReceiverResultReg); if ((methodOrBlockNumArgs <= 2 /* numRegArgs */) && (methodOrBlockNumArgs > 0)) { - regsSet = regsSet | (1U << Arg0Reg); + regsSet = regsSet | ((1U << Arg0Reg)); if (methodOrBlockNumArgs > 1) { - regsSet = regsSet | (1U << Arg1Reg); + regsSet = regsSet | ((1U << Arg1Reg)); } } } @@ -37867,13 +38053,13 @@ marshallSendArguments(sqInt numArgs) if (numArgs > 0) { if (numArgs > 1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 2, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 2, simNativeStackPtr); /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg1Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg1Reg), simStackPtr - 1, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 1, simNativeStackPtr); } } if (numArgs > 1) { diff --git a/spursista64src/vm/cointerp.c b/spursista64src/vm/cointerp.c index dd9c2d7379..64766086e6 100644 --- a/spursista64src/vm/cointerp.c +++ b/spursista64src/vm/cointerp.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - CoInterpreter VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CoInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 " __DATE__ ; +static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -491,6 +491,7 @@ extern sqInt ceSendabovetonumArgs(sqInt selector, sqInt methodClass, sqInt rcvr, extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern sqInt ceSistaTrap(void); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethod); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); @@ -667,7 +668,6 @@ static void primitiveExitCriticalSection(void); static void primitiveFlushCacheByMethod(void); static void primitiveFlushCacheBySelector(void); extern usqInt primitiveFunctionPointerAddress(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); EXPORT(sqInt) primitiveMethodPCData(void); static void primitiveMethodXray(void); EXPORT(void) primitiveMinimumUnusedHeadroom(void); @@ -1215,7 +1215,6 @@ static sqInt NoDbgRegParms isPureBitsFormat(sqInt format); extern sqInt isReallyYoung(sqInt oop); static sqInt NoDbgRegParms isRemembered(sqInt objOop); static sqInt NoDbgRegParms isSegmentBridge(sqInt objOop); -static sqInt NoDbgRegParms isSemaphoreOop(sqInt anOop); extern sqInt isShorts(sqInt oop); extern sqInt isUnambiguouslyForwarder(sqInt objOop); extern sqInt isUnmarked(sqInt objOop); @@ -1282,7 +1281,7 @@ static sqInt NoDbgRegParms num64BitUnitsOf(sqInt objOop); static sqInt NoDbgRegParms numBytesOfBitsformat(sqInt objOop, sqInt format); static sqInt NoDbgRegParms numBytesOfBytes(sqInt objOop); extern sqInt numBytesOf(sqInt objOop); -extern sqInt numPointerSlotsOf(sqInt objOop); +extern usqInt numPointerSlotsOf(sqInt objOop); static usqInt NoDbgRegParms numSlotsOfAny(sqInt objOop); extern usqInt numSlotsOf(sqInt objOop); static sqInt NoDbgRegParms numStrongSlotsOfInephemeral(sqInt objOop); @@ -1445,7 +1444,6 @@ EXPORT(sqInt) callbackLeave(sqInt cbID); extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHeader); extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkForEventsMayContextSwitch(sqInt mayContextSwitch); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); @@ -1727,7 +1725,6 @@ static sqInt NoDbgRegParms updateDisplayLeftTopRightBottom(sqInt l, sqInt t, sqI static sqInt NoDbgRegParms validBCPCinMethod(sqInt thePC, usqInt aMethod); static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, char *fp); static sqInt validStackPageBaseFrames(void); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt wakeHighestPriority(void); static sqInt NeverInline writeImageFileIO(void); static usqInt NoDbgRegParms cloneContext(sqInt aContext); @@ -1750,7 +1747,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1825,15 +1821,14 @@ _iss usqInt lastMobileObject; _iss sqInt tempOop; _iss sqInt numClassTablePages; _iss sqInt lkupClass; -_iss sqInt futureSurvivorStart; _iss sqInt profileProcess; -_iss sqInt profileSemaphore; +_iss sqInt futureSurvivorStart; _iss sqInt mournQueue; _iss sqInt numRememberedEphemerons; +_iss sqInt profileMethod; _iss sqInt jmpDepth; _iss sqInt mobileStart; -_iss sqInt profileMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; +_iss sqInt profileSemaphore; _iss sqInt growHeadroom; _iss sqInt tenureThreshold; _iss sqInt lastCoggableInterpretedBlockMethod; @@ -1841,7 +1836,6 @@ _iss sqInt lastUncoggableInterpretedBlockMethod; _iss char * objStackInvalidBecause; _iss sqInt sweepIndex; _iss sqInt ephemeronList; -_iss sqInt longRunningPrimitiveCheckMethod; _iss sqInt tenureCriterion; _iss usqInt totalHeapSizeIncludingBridges; _iss sqInt becomeEffectsFlags; @@ -1865,19 +1859,15 @@ _iss sqInt gcMode; _iss sqInt highestRunnableProcessPriority; _iss sqInt metaclassNumSlots; _iss usqLong nextWakeupUsecs; -_iss usqLong statGCEndUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; _iss sqInt shrinkThreshold; -_iss usqLong statCheckForEvents; _iss sqInt statTenures; _iss sqInt weakList; _iss usqInt cogCodeSize; -_iss usqLong gcStartUsecs; _iss sqInt marking; _iss sqLong oldSpaceUsePriorToScavenge; _iss sqInt preemptionYields; _iss sqInt rememberedSetLimit; +_iss usqLong statGCEndUsecs; _iss sqInt statSurvivorCount; _iss sqInt thisClassIndex; _iss sqInt externalPrimitiveTableFirstFreeIndex; @@ -1892,6 +1882,7 @@ _iss sqInt statShrinkMemory; _iss sqInt biasForGC; _iss sqInt edenBytes; _iss sqInt fullScreenFlag; +_iss usqLong gcStartUsecs; _iss usqInt lastHash; _iss sqInt lastMethodCacheProbeWrite; _iss sqInt newFinalization; @@ -1906,10 +1897,10 @@ _iss sqInt freeSpaceCheckOopToIgnore; _iss usqInt heapSizeAtPreviousGC; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss sqInt methodDictLinearSearchLimit; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statCompactionUsecs; _iss usqLong statForceInterruptCheck; _iss usqLong statFullGCUsecs; @@ -1930,7 +1921,6 @@ _iss sqInt extraFramesToMoveOnOverflow; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; _iss sqInt inFFIFlags; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss sqInt refCountToShrinkRT; _iss sqInt signalLowSpace; @@ -1944,7 +1934,6 @@ _iss sqInt classByteArrayCompactIndex; _iss usqInt exceptionPC; _iss sqInt gcSemaphoreIndex; _iss usqLong gcSweepEndUsecs; -_iss usqLong longRunningPrimitiveGCUsecs; _iss sqInt overflowLimit; _iss StackPage * overflowedPage; _iss sqInt statCompactPassCount; @@ -1962,6 +1951,9 @@ _iss usqInt suspendedCallbacks[MaxJumpBuf + 1 /* 33 */]; _iss usqInt suspendedMethods[MaxJumpBuf + 1 /* 33 */]; _iss jmp_buf jmpBuf[MaxJumpBuf + 1 /* 33 */]; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; _iss sqInt preferredPinningSegment; _iss sqInt statCoalesces; _iss usqLong statFGCDeltaUsecs; @@ -2638,7 +2630,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Open Smalltalk Cog[Spur] VM [CoInterpreterPrimitives VMMaker.oscog-eem.3024]"; +const char *interpreterVersion = "Open Smalltalk Cog[Spur] VM [CoInterpreterPrimitives VMMaker.oscog-eem.3031]"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */; int displayWidth; int displayDepth; @@ -18274,6 +18266,27 @@ ceStackOverflow(sqInt contextSwitchIfNotNil) error("should not be reached"); } + +/* A primitive has succeeded and the nextProfileTick has been reached (all + done in machine code). + Now take a sample. c.f. checkProfileTick: */ + + /* CoInterpreter>>#ceTakeProfileSample: */ +void +ceTakeProfileSample(CogMethod *aCogMethod) +{ DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt objOop; + sqInt objOop1; + + /* begin fetchPointer:ofObject: */ + objOop1 = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(SchedulerAssociation) << (shiftForWord()))))); + objOop = longAt((objOop1 + BaseHeaderSize) + (((sqInt)((usqInt)(ValueIndex) << (shiftForWord()))))); + GIV(profileProcess) = longAt((objOop + BaseHeaderSize) + (((sqInt)((usqInt)(ActiveProcessIndex) << (shiftForWord()))))); + GIV(profileMethod) = (aCogMethod->methodObject); + forceInterruptCheck(); + GIV(nextProfileTick) = 0; +} + /* CoInterpreter>>#ceTraceBlockActivation */ void ceTraceBlockActivation(void) @@ -20270,24 +20283,6 @@ void forceInterruptCheckFromHeartbeat(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; sqLowLevelMFence(); if (GIV(deferSmash)) { GIV(deferredSmash) = 1; @@ -23196,7 +23191,7 @@ printFrameWithSP(char *theFP, char *theSP) usqInt index; sqInt methodField; usqInt numArgs; - sqInt numTemps; + usqInt numTemps; char *rcvrAddress; sqInt rcvrOrClosure; CogBlockMethod * self_in_cmHomeMethod; @@ -26566,56 +26561,6 @@ primitiveFunctionPointerAddress(void) return ((usqInt)((&primitiveFunctionPointer))); } - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* CoInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; - int flushState; - sqInt sema; - char *sp; - - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (sema == GIV(nilObj)) { - flushState = GIV(longRunningPrimitiveCheckSemaphore) != null; - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - flushState = GIV(longRunningPrimitiveCheckSemaphore) == null; - if (!(((!(sema & (tagMask())))) - && (((longAt(sema)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(ClassSemaphore) << (shiftForWord())))))))))) { - return (GIV(primFailCode) = PrimErrBadArgument); - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(longRunningPrimitiveCheckSemaphore) == null)) - || (((stackValue(0)) == GIV(longRunningPrimitiveCheckSemaphore)) - && (isSemaphoreOop(sema)))); - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - if (flushState) { - ceInvokeInterpret(); - } - return 0; -} - /* CoInterpreterPrimitives>>#primitiveMethodPCData */ EXPORT(sqInt) primitiveMethodPCData(void) @@ -26928,14 +26873,9 @@ primitiveObjectAtPut(void) EXPORT(sqInt) primitiveProfileSemaphore(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; int flushState; sqInt sema; - char *sp; - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); if (sema == GIV(nilObj)) { flushState = GIV(profileSemaphore) != GIV(nilObj); @@ -26947,28 +26887,21 @@ primitiveProfileSemaphore(void) return (GIV(primFailCode) = PrimErrBadArgument); } } + GIV(profileSemaphore) = sema; /* If we've switched profiling on or off we must void machine code (and machine code pcs in contexts) since we will start or stop testing the profile clock in machine code primitive invocations, and so generate slightly different code from here on in. */ - GIV(profileSemaphore) = sema; - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(profileSemaphore) == (nilObject()))) - || (((stackValue(0)) == GIV(profileSemaphore)) - && (isSemaphoreOop(sema)))); - } GIV(profileProcess) = (GIV(profileMethod) = GIV(nilObj)); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; if (flushState) { - ceInvokeInterpret(); + flushExternalPrimitives(); + } + else { + /* begin methodReturnReceiver */ + assert(!((failed()))); + /* begin pop: */ + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; } return 0; } @@ -35441,26 +35374,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -38101,15 +38036,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -38127,15 +38057,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -38159,39 +38084,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((((integerPointer) & 7) == 1)) { - deltaTicks = (integerPointer >> 3); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((((deltaTicks) & 7) == 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 3)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -42671,7 +42575,7 @@ followForwardedObjectFieldstoDepth(sqInt objOop, sqInt depth) sqInt header1; sqInt i; sqInt numLiterals; - sqInt numSlots; + usqInt numSlots; usqInt numSlots1; sqInt oop; sqInt referent; @@ -50128,7 +50032,7 @@ copyObjtoAddrstopAtsavedFirstFieldsindex(sqInt objOop, sqInt segAddr, sqInt endS sqInt iLimiT; sqInt methodHeader; sqInt numLiterals; - sqInt numMediatedSlots; + usqInt numMediatedSlots; usqInt numSlots; usqInt numSlots1; sqInt oop; @@ -53567,14 +53471,6 @@ isSegmentBridge(sqInt objOop) return ((longAt(objOop)) & (classIndexMask())) == (segmentBridgePun()); } - /* SpurMemoryManager>>#isSemaphoreOop: */ -static sqInt NoDbgRegParms -isSemaphoreOop(sqInt anOop) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - return ((!(anOop & (tagMask())))) - && (((longAt(anOop)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(ClassSemaphore) << (shiftForWord())))))))); -} - /* Answer if the argument contains only indexable 16-bit half words (no oops). See comment in formatOf: @@ -55854,8 +55750,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) sqInt referent; sqInt referent1; sqInt referent2; - sqInt referent3; - sqInt referent4; sqInt sizeOfUnusedEden; StackPage *thePage; @@ -55994,38 +55888,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - if ((!((longAt(GIV(longRunningPrimitiveCheckMethod))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckMethod))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((GIV(longRunningPrimitiveCheckMethod) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent3 & (tagMask())))) - && ((!((longAt(referent3)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((referent3 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckMethod) = referent3; - } - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - if ((!((longAt(GIV(longRunningPrimitiveCheckSemaphore))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckSemaphore))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((GIV(longRunningPrimitiveCheckSemaphore) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent4 & (tagMask())))) - && ((!((longAt(referent4)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((referent4 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckSemaphore) = referent4; - } - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -56714,7 +56576,7 @@ numBytesOf(sqInt objOop) Works with CompiledMethods, as well as ordinary objects. */ /* SpurMemoryManager>>#numPointerSlotsOf: */ -sqInt +usqInt numPointerSlotsOf(sqInt objOop) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt contextSize; @@ -57549,8 +57411,8 @@ outOfPlaceBecomeandcopyHashFlag(sqInt obj1, sqInt obj2, sqInt copyHashFlag) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt classIndex; sqInt classIndex1; - usqInt clone1; - usqInt clone2; + sqInt clone1; + sqInt clone2; sqInt format; sqInt format1; sqInt hash; @@ -59724,7 +59586,7 @@ printReferencesTo(sqInt anOop) assert((ReceiverIndex + ((sp >> 3))) < (lengthOf(obj1))); contextSize = (sp >> 3); l9: /* end fetchStackPointerOf: */; - i = CtxtTempFrameStart + contextSize; + i = ((usqInt) (CtxtTempFrameStart + contextSize)); goto l10; } /* begin numSlotsOf: */ @@ -59757,7 +59619,7 @@ printReferencesTo(sqInt anOop) /* begin literalCountOfMethodHeader: */ assert((((header) & 7) == 1)); numLiterals = ((header >> 3)) & AlternateHeaderNumLiteralsMask; - i = numLiterals + LiteralStart; + i = ((usqInt) (numLiterals + LiteralStart)); l10: /* end numPointerSlotsOf: */; while (((i -= 1)) >= 0) { if (anOop == (longAt((obj1 + BaseHeaderSize) + (((sqInt)((usqInt)(i) << (shiftForWord()))))))) { @@ -62957,10 +62819,10 @@ updatePointers(void) sqInt numLiterals1; sqInt numLiterals2; sqInt numLiterals3; - sqInt numPointerSlots; - sqInt numPointerSlots1; - sqInt numPointerSlots2; - sqInt numPointerSlots3; + usqInt numPointerSlots; + usqInt numPointerSlots1; + usqInt numPointerSlots2; + usqInt numPointerSlots3; usqInt numSlots; usqInt numSlots1; usqInt numSlots11; @@ -63538,7 +63400,7 @@ updatePointersInsavedFirstFieldPointer(sqInt obj, sqInt firstFieldPtr) assert((ReceiverIndex + ((sp >> 3))) < (lengthOf(obj))); contextSize = (sp >> 3); l6: /* end fetchStackPointerOf: */; - numPointerSlots = CtxtTempFrameStart + contextSize; + numPointerSlots = ((usqInt) (CtxtTempFrameStart + contextSize)); goto l10; } /* begin numSlotsOf: */ @@ -63568,7 +63430,7 @@ updatePointersInsavedFirstFieldPointer(sqInt obj, sqInt firstFieldPtr) /* begin literalCountOfMethodHeader: */ assert((((header) & 7) == 1)); numLiterals = ((header >> 3)) & AlternateHeaderNumLiteralsMask; - numPointerSlots = numLiterals + LiteralStart; + numPointerSlots = ((usqInt) (numLiterals + LiteralStart)); l10: /* end numPointerSlotsWhileCompactingOf:withFormat:savedFirstFieldPointer: */; if ((fmt <= 5 /* lastPointerFormat */) && (numPointerSlots > 0)) { @@ -64119,7 +63981,7 @@ prepareForSnapshot(void) sqInt limit; sqInt newEndOfMemory; sqInt next; - usqInt node; + sqInt node; SpurSegmentInfo *seg; sqInt smallChild; sqInt treeNode; @@ -64950,33 +64812,6 @@ checkAllAccessibleObjectsOkay(void) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -65067,9 +64902,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { /* begin signalLowSpace: */ GIV(signalLowSpace) = 0; @@ -70087,23 +69919,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i = 1; i <= GIV(jmpDepth); i += 1) { oop = GIV(suspendedCallbacks)[i]; @@ -74192,8 +74007,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -74222,18 +74037,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -77384,22 +77201,6 @@ validStackPageBaseFrames(void) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Return the highest priority process that is ready to run. To save time looking at many empty lists before finding a runnable process the VM maintains a variable holding the @@ -79910,74 +79711,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((addressCouldBeObj(lrpcm)) - && ((!(((longAt(lrpcm)) & (classIndexMask())) == (isFreeObjectClassIndexPun()))) - && (((((usqInt)((longAt(lrpcm)))) >> (formatShift())) & (formatMask())) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - assert(!(isForwarded(result))); - if ((assert(isNonImmediate(result)), - oopisGreaterThanOrEqualTo(result, GIV(oldSpaceStart)))) { - - /* most stores into young objects */ - if (((!(lrpcm & (tagMask())))) - && (oopisLessThan(lrpcm, GIV(newSpaceLimit)))) { - /* begin possibleRootStoreInto: */ - if (!(((((usqInt)((longAt(result)))) >> (rememberedBitShift())) & 1) != 0)) { - remember(result); - } - } - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 3) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 3) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -82451,15 +82184,13 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveGreaterOrEqualLargeIntegers\000\377\000", (void*)primitiveGreaterOrEqualLargeIntegers}, {(void*)_m, "primitiveGreaterThanLargeIntegers\000\377\000", (void*)primitiveGreaterThanLargeIntegers}, {(void*)_m, "primitiveHeartbeatFrequency\000\377\000", (void*)primitiveHeartbeatFrequency}, - {(void*)_m, "primitiveHighResClock\000\377\000", (void*)primitiveHighResClock}, + {(void*)_m, "primitiveHighResClock\000\377\001", (void*)primitiveHighResClock}, {(void*)_m, "primitiveImageFormatVersion\000\377\000", (void*)primitiveImageFormatVersion}, {(void*)_m, "primitiveInterruptChecksPerMSec\000\377\000", (void*)primitiveInterruptChecksPerMSec}, {(void*)_m, "primitiveIsBigEnder\000\377\000", (void*)primitiveIsBigEnder}, {(void*)_m, "primitiveIsWindowObscured\000\377\000", (void*)primitiveIsWindowObscured}, {(void*)_m, "primitiveLessOrEqualLargeIntegers\000\377\000", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers\000\377\000", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive\000\377\000", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore\000\000\000", (void*)primitiveLongRunningPrimitiveSemaphore}, {(void*)_m, "primitiveMethodPCData\000\000\000", (void*)primitiveMethodPCData}, {(void*)_m, "primitiveMillisecondClockMask\000\377\000", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveMinimumUnusedHeadroom\000\377\000", (void*)primitiveMinimumUnusedHeadroom}, @@ -82467,10 +82198,10 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveMultiplyLargeIntegers\000\000\000", (void*)primitiveMultiplyLargeIntegers}, {(void*)_m, "primitiveNotEqualLargeIntegers\000\377\000", (void*)primitiveNotEqualLargeIntegers}, {(void*)_m, "primitivePathToUsing\000\000\000", (void*)primitivePathToUsing}, - {(void*)_m, "primitiveProfilePrimitive\000\377\000", (void*)primitiveProfilePrimitive}, - {(void*)_m, "primitiveProfileSample\000\377\000", (void*)primitiveProfileSample}, + {(void*)_m, "primitiveProfilePrimitive\000\377\001", (void*)primitiveProfilePrimitive}, + {(void*)_m, "primitiveProfileSample\000\377\001", (void*)primitiveProfileSample}, {(void*)_m, "primitiveProfileSemaphore\000\000\000", (void*)primitiveProfileSemaphore}, - {(void*)_m, "primitiveProfileStart\000\000\000", (void*)primitiveProfileStart}, + {(void*)_m, "primitiveProfileStart\000\000\001", (void*)primitiveProfileStart}, {(void*)_m, "primitiveQuoLargeIntegers\000\000\000", (void*)primitiveQuoLargeIntegers}, {(void*)_m, "primitiveRemLargeIntegers\000\000\000", (void*)primitiveRemLargeIntegers}, {(void*)_m, "primitiveResetCountersInMethod\000\000\000", (void*)primitiveResetCountersInMethod}, diff --git a/spursista64src/vm/cointerp.h b/spursista64src/vm/cointerp.h index 0c5ac23f47..720c59b0af 100644 --- a/spursista64src/vm/cointerp.h +++ b/spursista64src/vm/cointerp.h @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ @@ -51,6 +51,7 @@ extern sqInt ceSendabovetonumArgs(sqInt selector, sqInt methodClass, sqInt rcvr, extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern sqInt ceSistaTrap(void); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethod); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); @@ -250,7 +251,7 @@ extern sqInt minSlotsForShortening(void); extern sqInt nilObject(void); extern sqInt nonIndexablePointerFormat(void); extern sqInt numBytesOf(sqInt objOop); -extern sqInt numPointerSlotsOf(sqInt objOop); +extern usqInt numPointerSlotsOf(sqInt objOop); extern usqInt numSlotsOf(sqInt objOop); extern sqInt numStrongSlotsOfWeakling(sqInt objOop); extern sqInt objectAfter(sqInt objOop); diff --git a/spursista64src/vm/gcc3x-cointerp.c b/spursista64src/vm/gcc3x-cointerp.c index 0a021d8a8b..1e1e1755f4 100644 --- a/spursista64src/vm/gcc3x-cointerp.c +++ b/spursista64src/vm/gcc3x-cointerp.c @@ -2,11 +2,11 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - CoInterpreter VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CoInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 " __DATE__ ; +static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -494,6 +494,7 @@ extern sqInt ceSendabovetonumArgs(sqInt selector, sqInt methodClass, sqInt rcvr, extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern sqInt ceSistaTrap(void); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethod); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); @@ -670,7 +671,6 @@ static void primitiveExitCriticalSection(void); static void primitiveFlushCacheByMethod(void); static void primitiveFlushCacheBySelector(void); extern usqInt primitiveFunctionPointerAddress(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); EXPORT(sqInt) primitiveMethodPCData(void); static void primitiveMethodXray(void); EXPORT(void) primitiveMinimumUnusedHeadroom(void); @@ -1218,7 +1218,6 @@ static sqInt NoDbgRegParms isPureBitsFormat(sqInt format); extern sqInt isReallyYoung(sqInt oop); static sqInt NoDbgRegParms isRemembered(sqInt objOop); static sqInt NoDbgRegParms isSegmentBridge(sqInt objOop); -static sqInt NoDbgRegParms isSemaphoreOop(sqInt anOop); extern sqInt isShorts(sqInt oop); extern sqInt isUnambiguouslyForwarder(sqInt objOop); extern sqInt isUnmarked(sqInt objOop); @@ -1285,7 +1284,7 @@ static sqInt NoDbgRegParms num64BitUnitsOf(sqInt objOop); static sqInt NoDbgRegParms numBytesOfBitsformat(sqInt objOop, sqInt format); static sqInt NoDbgRegParms numBytesOfBytes(sqInt objOop); extern sqInt numBytesOf(sqInt objOop); -extern sqInt numPointerSlotsOf(sqInt objOop); +extern usqInt numPointerSlotsOf(sqInt objOop); static usqInt NoDbgRegParms numSlotsOfAny(sqInt objOop); extern usqInt numSlotsOf(sqInt objOop); static sqInt NoDbgRegParms numStrongSlotsOfInephemeral(sqInt objOop); @@ -1448,7 +1447,6 @@ EXPORT(sqInt) callbackLeave(sqInt cbID); extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHeader); extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkForEventsMayContextSwitch(sqInt mayContextSwitch); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); @@ -1730,7 +1728,6 @@ static sqInt NoDbgRegParms updateDisplayLeftTopRightBottom(sqInt l, sqInt t, sqI static sqInt NoDbgRegParms validBCPCinMethod(sqInt thePC, usqInt aMethod); static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, char *fp); static sqInt validStackPageBaseFrames(void); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt wakeHighestPriority(void); static sqInt NeverInline writeImageFileIO(void); static usqInt NoDbgRegParms cloneContext(sqInt aContext); @@ -1753,7 +1750,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1828,15 +1824,14 @@ _iss usqInt lastMobileObject; _iss sqInt tempOop; _iss sqInt numClassTablePages; _iss sqInt lkupClass; -_iss sqInt futureSurvivorStart; _iss sqInt profileProcess; -_iss sqInt profileSemaphore; +_iss sqInt futureSurvivorStart; _iss sqInt mournQueue; _iss sqInt numRememberedEphemerons; +_iss sqInt profileMethod; _iss sqInt jmpDepth; _iss sqInt mobileStart; -_iss sqInt profileMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; +_iss sqInt profileSemaphore; _iss sqInt growHeadroom; _iss sqInt tenureThreshold; _iss sqInt lastCoggableInterpretedBlockMethod; @@ -1844,7 +1839,6 @@ _iss sqInt lastUncoggableInterpretedBlockMethod; _iss char * objStackInvalidBecause; _iss sqInt sweepIndex; _iss sqInt ephemeronList; -_iss sqInt longRunningPrimitiveCheckMethod; _iss sqInt tenureCriterion; _iss usqInt totalHeapSizeIncludingBridges; _iss sqInt becomeEffectsFlags; @@ -1868,19 +1862,15 @@ _iss sqInt gcMode; _iss sqInt highestRunnableProcessPriority; _iss sqInt metaclassNumSlots; _iss usqLong nextWakeupUsecs; -_iss usqLong statGCEndUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; _iss sqInt shrinkThreshold; -_iss usqLong statCheckForEvents; _iss sqInt statTenures; _iss sqInt weakList; _iss usqInt cogCodeSize; -_iss usqLong gcStartUsecs; _iss sqInt marking; _iss sqLong oldSpaceUsePriorToScavenge; _iss sqInt preemptionYields; _iss sqInt rememberedSetLimit; +_iss usqLong statGCEndUsecs; _iss sqInt statSurvivorCount; _iss sqInt thisClassIndex; _iss sqInt externalPrimitiveTableFirstFreeIndex; @@ -1895,6 +1885,7 @@ _iss sqInt statShrinkMemory; _iss sqInt biasForGC; _iss sqInt edenBytes; _iss sqInt fullScreenFlag; +_iss usqLong gcStartUsecs; _iss usqInt lastHash; _iss sqInt lastMethodCacheProbeWrite; _iss sqInt newFinalization; @@ -1909,10 +1900,10 @@ _iss sqInt freeSpaceCheckOopToIgnore; _iss usqInt heapSizeAtPreviousGC; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss sqInt methodDictLinearSearchLimit; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statCompactionUsecs; _iss usqLong statForceInterruptCheck; _iss usqLong statFullGCUsecs; @@ -1933,7 +1924,6 @@ _iss sqInt extraFramesToMoveOnOverflow; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; _iss sqInt inFFIFlags; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss sqInt refCountToShrinkRT; _iss sqInt signalLowSpace; @@ -1947,7 +1937,6 @@ _iss sqInt classByteArrayCompactIndex; _iss usqInt exceptionPC; _iss sqInt gcSemaphoreIndex; _iss usqLong gcSweepEndUsecs; -_iss usqLong longRunningPrimitiveGCUsecs; _iss sqInt overflowLimit; _iss StackPage * overflowedPage; _iss sqInt statCompactPassCount; @@ -1965,6 +1954,9 @@ _iss usqInt suspendedCallbacks[MaxJumpBuf + 1 /* 33 */]; _iss usqInt suspendedMethods[MaxJumpBuf + 1 /* 33 */]; _iss jmp_buf jmpBuf[MaxJumpBuf + 1 /* 33 */]; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; _iss sqInt preferredPinningSegment; _iss sqInt statCoalesces; _iss usqLong statFGCDeltaUsecs; @@ -2641,7 +2633,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Open Smalltalk Cog[Spur] VM [CoInterpreterPrimitives VMMaker.oscog-eem.3024]"; +const char *interpreterVersion = "Open Smalltalk Cog[Spur] VM [CoInterpreterPrimitives VMMaker.oscog-eem.3031]"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */; int displayWidth; int displayDepth; @@ -18283,6 +18275,27 @@ ceStackOverflow(sqInt contextSwitchIfNotNil) error("should not be reached"); } + +/* A primitive has succeeded and the nextProfileTick has been reached (all + done in machine code). + Now take a sample. c.f. checkProfileTick: */ + + /* CoInterpreter>>#ceTakeProfileSample: */ +void +ceTakeProfileSample(CogMethod *aCogMethod) +{ DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt objOop; + sqInt objOop1; + + /* begin fetchPointer:ofObject: */ + objOop1 = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(SchedulerAssociation) << (shiftForWord()))))); + objOop = longAt((objOop1 + BaseHeaderSize) + (((sqInt)((usqInt)(ValueIndex) << (shiftForWord()))))); + GIV(profileProcess) = longAt((objOop + BaseHeaderSize) + (((sqInt)((usqInt)(ActiveProcessIndex) << (shiftForWord()))))); + GIV(profileMethod) = (aCogMethod->methodObject); + forceInterruptCheck(); + GIV(nextProfileTick) = 0; +} + /* CoInterpreter>>#ceTraceBlockActivation */ void ceTraceBlockActivation(void) @@ -20279,24 +20292,6 @@ void forceInterruptCheckFromHeartbeat(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; sqLowLevelMFence(); if (GIV(deferSmash)) { GIV(deferredSmash) = 1; @@ -23205,7 +23200,7 @@ printFrameWithSP(char *theFP, char *theSP) usqInt index; sqInt methodField; usqInt numArgs; - sqInt numTemps; + usqInt numTemps; char *rcvrAddress; sqInt rcvrOrClosure; CogBlockMethod * self_in_cmHomeMethod; @@ -26575,56 +26570,6 @@ primitiveFunctionPointerAddress(void) return ((usqInt)((&primitiveFunctionPointer))); } - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* CoInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; - int flushState; - sqInt sema; - char *sp; - - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (sema == GIV(nilObj)) { - flushState = GIV(longRunningPrimitiveCheckSemaphore) != null; - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - flushState = GIV(longRunningPrimitiveCheckSemaphore) == null; - if (!(((!(sema & (tagMask())))) - && (((longAt(sema)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(ClassSemaphore) << (shiftForWord())))))))))) { - return (GIV(primFailCode) = PrimErrBadArgument); - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(longRunningPrimitiveCheckSemaphore) == null)) - || (((stackValue(0)) == GIV(longRunningPrimitiveCheckSemaphore)) - && (isSemaphoreOop(sema)))); - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - if (flushState) { - ceInvokeInterpret(); - } - return 0; -} - /* CoInterpreterPrimitives>>#primitiveMethodPCData */ EXPORT(sqInt) primitiveMethodPCData(void) @@ -26937,14 +26882,9 @@ primitiveObjectAtPut(void) EXPORT(sqInt) primitiveProfileSemaphore(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; int flushState; sqInt sema; - char *sp; - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); if (sema == GIV(nilObj)) { flushState = GIV(profileSemaphore) != GIV(nilObj); @@ -26956,28 +26896,21 @@ primitiveProfileSemaphore(void) return (GIV(primFailCode) = PrimErrBadArgument); } } + GIV(profileSemaphore) = sema; /* If we've switched profiling on or off we must void machine code (and machine code pcs in contexts) since we will start or stop testing the profile clock in machine code primitive invocations, and so generate slightly different code from here on in. */ - GIV(profileSemaphore) = sema; - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(profileSemaphore) == (nilObject()))) - || (((stackValue(0)) == GIV(profileSemaphore)) - && (isSemaphoreOop(sema)))); - } GIV(profileProcess) = (GIV(profileMethod) = GIV(nilObj)); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; if (flushState) { - ceInvokeInterpret(); + flushExternalPrimitives(); + } + else { + /* begin methodReturnReceiver */ + assert(!((failed()))); + /* begin pop: */ + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; } return 0; } @@ -35450,26 +35383,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -38110,15 +38045,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -38136,15 +38066,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -38168,39 +38093,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((((integerPointer) & 7) == 1)) { - deltaTicks = (integerPointer >> 3); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((((deltaTicks) & 7) == 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 3)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -42680,7 +42584,7 @@ followForwardedObjectFieldstoDepth(sqInt objOop, sqInt depth) sqInt header1; sqInt i; sqInt numLiterals; - sqInt numSlots; + usqInt numSlots; usqInt numSlots1; sqInt oop; sqInt referent; @@ -50137,7 +50041,7 @@ copyObjtoAddrstopAtsavedFirstFieldsindex(sqInt objOop, sqInt segAddr, sqInt endS sqInt iLimiT; sqInt methodHeader; sqInt numLiterals; - sqInt numMediatedSlots; + usqInt numMediatedSlots; usqInt numSlots; usqInt numSlots1; sqInt oop; @@ -53576,14 +53480,6 @@ isSegmentBridge(sqInt objOop) return ((longAt(objOop)) & (classIndexMask())) == (segmentBridgePun()); } - /* SpurMemoryManager>>#isSemaphoreOop: */ -static sqInt NoDbgRegParms -isSemaphoreOop(sqInt anOop) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - return ((!(anOop & (tagMask())))) - && (((longAt(anOop)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(ClassSemaphore) << (shiftForWord())))))))); -} - /* Answer if the argument contains only indexable 16-bit half words (no oops). See comment in formatOf: @@ -55863,8 +55759,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) sqInt referent; sqInt referent1; sqInt referent2; - sqInt referent3; - sqInt referent4; sqInt sizeOfUnusedEden; StackPage *thePage; @@ -56003,38 +55897,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - if ((!((longAt(GIV(longRunningPrimitiveCheckMethod))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckMethod))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((GIV(longRunningPrimitiveCheckMethod) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent3 & (tagMask())))) - && ((!((longAt(referent3)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((referent3 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckMethod) = referent3; - } - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - if ((!((longAt(GIV(longRunningPrimitiveCheckSemaphore))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckSemaphore))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((GIV(longRunningPrimitiveCheckSemaphore) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent4 & (tagMask())))) - && ((!((longAt(referent4)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((referent4 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckSemaphore) = referent4; - } - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -56723,7 +56585,7 @@ numBytesOf(sqInt objOop) Works with CompiledMethods, as well as ordinary objects. */ /* SpurMemoryManager>>#numPointerSlotsOf: */ -sqInt +usqInt numPointerSlotsOf(sqInt objOop) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt contextSize; @@ -57558,8 +57420,8 @@ outOfPlaceBecomeandcopyHashFlag(sqInt obj1, sqInt obj2, sqInt copyHashFlag) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt classIndex; sqInt classIndex1; - usqInt clone1; - usqInt clone2; + sqInt clone1; + sqInt clone2; sqInt format; sqInt format1; sqInt hash; @@ -59733,7 +59595,7 @@ printReferencesTo(sqInt anOop) assert((ReceiverIndex + ((sp >> 3))) < (lengthOf(obj1))); contextSize = (sp >> 3); l9: /* end fetchStackPointerOf: */; - i = CtxtTempFrameStart + contextSize; + i = ((usqInt) (CtxtTempFrameStart + contextSize)); goto l10; } /* begin numSlotsOf: */ @@ -59766,7 +59628,7 @@ printReferencesTo(sqInt anOop) /* begin literalCountOfMethodHeader: */ assert((((header) & 7) == 1)); numLiterals = ((header >> 3)) & AlternateHeaderNumLiteralsMask; - i = numLiterals + LiteralStart; + i = ((usqInt) (numLiterals + LiteralStart)); l10: /* end numPointerSlotsOf: */; while (((i -= 1)) >= 0) { if (anOop == (longAt((obj1 + BaseHeaderSize) + (((sqInt)((usqInt)(i) << (shiftForWord()))))))) { @@ -62966,10 +62828,10 @@ updatePointers(void) sqInt numLiterals1; sqInt numLiterals2; sqInt numLiterals3; - sqInt numPointerSlots; - sqInt numPointerSlots1; - sqInt numPointerSlots2; - sqInt numPointerSlots3; + usqInt numPointerSlots; + usqInt numPointerSlots1; + usqInt numPointerSlots2; + usqInt numPointerSlots3; usqInt numSlots; usqInt numSlots1; usqInt numSlots11; @@ -63547,7 +63409,7 @@ updatePointersInsavedFirstFieldPointer(sqInt obj, sqInt firstFieldPtr) assert((ReceiverIndex + ((sp >> 3))) < (lengthOf(obj))); contextSize = (sp >> 3); l6: /* end fetchStackPointerOf: */; - numPointerSlots = CtxtTempFrameStart + contextSize; + numPointerSlots = ((usqInt) (CtxtTempFrameStart + contextSize)); goto l10; } /* begin numSlotsOf: */ @@ -63577,7 +63439,7 @@ updatePointersInsavedFirstFieldPointer(sqInt obj, sqInt firstFieldPtr) /* begin literalCountOfMethodHeader: */ assert((((header) & 7) == 1)); numLiterals = ((header >> 3)) & AlternateHeaderNumLiteralsMask; - numPointerSlots = numLiterals + LiteralStart; + numPointerSlots = ((usqInt) (numLiterals + LiteralStart)); l10: /* end numPointerSlotsWhileCompactingOf:withFormat:savedFirstFieldPointer: */; if ((fmt <= 5 /* lastPointerFormat */) && (numPointerSlots > 0)) { @@ -64128,7 +63990,7 @@ prepareForSnapshot(void) sqInt limit; sqInt newEndOfMemory; sqInt next; - usqInt node; + sqInt node; SpurSegmentInfo *seg; sqInt smallChild; sqInt treeNode; @@ -64959,33 +64821,6 @@ checkAllAccessibleObjectsOkay(void) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -65076,9 +64911,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { /* begin signalLowSpace: */ GIV(signalLowSpace) = 0; @@ -70096,23 +69928,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i = 1; i <= GIV(jmpDepth); i += 1) { oop = GIV(suspendedCallbacks)[i]; @@ -74201,8 +74016,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -74231,18 +74046,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -77393,22 +77210,6 @@ validStackPageBaseFrames(void) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Return the highest priority process that is ready to run. To save time looking at many empty lists before finding a runnable process the VM maintains a variable holding the @@ -79919,74 +79720,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((addressCouldBeObj(lrpcm)) - && ((!(((longAt(lrpcm)) & (classIndexMask())) == (isFreeObjectClassIndexPun()))) - && (((((usqInt)((longAt(lrpcm)))) >> (formatShift())) & (formatMask())) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - assert(!(isForwarded(result))); - if ((assert(isNonImmediate(result)), - oopisGreaterThanOrEqualTo(result, GIV(oldSpaceStart)))) { - - /* most stores into young objects */ - if (((!(lrpcm & (tagMask())))) - && (oopisLessThan(lrpcm, GIV(newSpaceLimit)))) { - /* begin possibleRootStoreInto: */ - if (!(((((usqInt)((longAt(result)))) >> (rememberedBitShift())) & 1) != 0)) { - remember(result); - } - } - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 3) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 3) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -82460,15 +82193,13 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveGreaterOrEqualLargeIntegers\000\377\000", (void*)primitiveGreaterOrEqualLargeIntegers}, {(void*)_m, "primitiveGreaterThanLargeIntegers\000\377\000", (void*)primitiveGreaterThanLargeIntegers}, {(void*)_m, "primitiveHeartbeatFrequency\000\377\000", (void*)primitiveHeartbeatFrequency}, - {(void*)_m, "primitiveHighResClock\000\377\000", (void*)primitiveHighResClock}, + {(void*)_m, "primitiveHighResClock\000\377\001", (void*)primitiveHighResClock}, {(void*)_m, "primitiveImageFormatVersion\000\377\000", (void*)primitiveImageFormatVersion}, {(void*)_m, "primitiveInterruptChecksPerMSec\000\377\000", (void*)primitiveInterruptChecksPerMSec}, {(void*)_m, "primitiveIsBigEnder\000\377\000", (void*)primitiveIsBigEnder}, {(void*)_m, "primitiveIsWindowObscured\000\377\000", (void*)primitiveIsWindowObscured}, {(void*)_m, "primitiveLessOrEqualLargeIntegers\000\377\000", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers\000\377\000", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive\000\377\000", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore\000\000\000", (void*)primitiveLongRunningPrimitiveSemaphore}, {(void*)_m, "primitiveMethodPCData\000\000\000", (void*)primitiveMethodPCData}, {(void*)_m, "primitiveMillisecondClockMask\000\377\000", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveMinimumUnusedHeadroom\000\377\000", (void*)primitiveMinimumUnusedHeadroom}, @@ -82476,10 +82207,10 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveMultiplyLargeIntegers\000\000\000", (void*)primitiveMultiplyLargeIntegers}, {(void*)_m, "primitiveNotEqualLargeIntegers\000\377\000", (void*)primitiveNotEqualLargeIntegers}, {(void*)_m, "primitivePathToUsing\000\000\000", (void*)primitivePathToUsing}, - {(void*)_m, "primitiveProfilePrimitive\000\377\000", (void*)primitiveProfilePrimitive}, - {(void*)_m, "primitiveProfileSample\000\377\000", (void*)primitiveProfileSample}, + {(void*)_m, "primitiveProfilePrimitive\000\377\001", (void*)primitiveProfilePrimitive}, + {(void*)_m, "primitiveProfileSample\000\377\001", (void*)primitiveProfileSample}, {(void*)_m, "primitiveProfileSemaphore\000\000\000", (void*)primitiveProfileSemaphore}, - {(void*)_m, "primitiveProfileStart\000\000\000", (void*)primitiveProfileStart}, + {(void*)_m, "primitiveProfileStart\000\000\001", (void*)primitiveProfileStart}, {(void*)_m, "primitiveQuoLargeIntegers\000\000\000", (void*)primitiveQuoLargeIntegers}, {(void*)_m, "primitiveRemLargeIntegers\000\000\000", (void*)primitiveRemLargeIntegers}, {(void*)_m, "primitiveResetCountersInMethod\000\000\000", (void*)primitiveResetCountersInMethod}, diff --git a/spursistasrc/vm/cogit.c b/spursistasrc/vm/cogit.c index 6b394d06cd..8d71e53f42 100644 --- a/spursistasrc/vm/cogit.c +++ b/spursistasrc/vm/cogit.c @@ -1,5 +1,5 @@ /* Automatically generated by - Cogit VMMaker.oscog-eem.2535 uuid: e4217d2b-77f4-4947-ad0a-eabe9fa6b911 + Cogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ #if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7__) || defined(__arm__) || defined(__arm32__) || defined(ARM32) || defined(_M_ARM) @@ -10,10 +10,6 @@ # include "cogitIA32.c" -#elif defined(__MIPSEL__) - -# include "cogitMIPSEL.c" - #else # error As yet no Cogit implementation appears to exist for your platform. # error Consider implementing it, starting by adding a subclass of CogAbstractInstruction. diff --git a/spursistasrc/vm/cogit.h b/spursistasrc/vm/cogit.h index 2a7c4301df..cbc6c61475 100644 --- a/spursistasrc/vm/cogit.h +++ b/spursistasrc/vm/cogit.h @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + CCodeGenerator VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ diff --git a/spursistasrc/vm/cogitARMv5.c b/spursistasrc/vm/cogitARMv5.c index fdd5a2cb68..e8dfae5260 100644 --- a/spursistasrc/vm/cogitARMv5.c +++ b/spursistasrc/vm/cogitARMv5.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + CCodeGenerator VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - SistaCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + SistaCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "SistaCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 " __DATE__ ; +static char __buildInfo[] = "SistaCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__cogitBuildInfo = __buildInfo; @@ -89,7 +89,7 @@ char *__cogitBuildInfo = __buildInfo; #define CMMaxUsageCount 7 #define CMMethod 2 #define CMOpenPIC 5 -#define CMPSMULL 165 +#define CMPSMULL 167 #define CmpC32R 113 #define CmpCqR 105 #define CmpCwR 112 @@ -243,6 +243,8 @@ char *__cogitBuildInfo = __buildInfo; #define MoveMwrR 50 #define MoveNotOpcode 15 #define MoveOpcode 13 +#define MovePerfCnt64RL 159 +#define MovePerfCnt64RRL 158 #define MoveRA32 47 #define MoveRAb 49 #define MoveRAw 46 @@ -256,7 +258,7 @@ char *__cogitBuildInfo = __buildInfo; #define MoveRXwrR 53 #define MoveXbrRR 67 #define MoveXwrRR 52 -#define MSR 159 +#define MSR 161 #define MULTIPLEBYTECODESETS 1 #define MulRdRd 134 #define NativePopR 84 @@ -285,7 +287,7 @@ char *__cogitBuildInfo = __buildInfo; #define PC 15 #define PCReg 15 #define PL 5 -#define PopLDM 161 +#define PopLDM 163 #define PopR 80 #define PrefetchAw 87 #define PrimCallCollectsProfileSamples 8 @@ -302,7 +304,7 @@ char *__cogitBuildInfo = __buildInfo; #define PushCq 82 #define PushCw 83 #define PushR 81 -#define PushSTM 162 +#define PushSTM 164 #define ReceiverIndex 5 #define ReceiverResultReg 5 #define RetN 9 @@ -317,7 +319,7 @@ char *__cogitBuildInfo = __buildInfo; #define SignExtend8RR 151 #define SistaV1BytecodeSet 1 #define SistaVM 1 -#define SMULL 158 +#define SMULL 160 #define SmallContextSlots 22 #define SP 13 #define SPReg 13 @@ -329,6 +331,7 @@ char *__cogitBuildInfo = __buildInfo; #define SSSpill 4 #define StackPointerIndex 2 #define Stop 11 +#define SubbRR 121 #define SubCqR 107 #define SubCwR 115 #define SubOpcode 2 @@ -473,7 +476,7 @@ static void NoDbgRegParms cloneLiteralFrom(AbstractInstruction * self_in_cloneLi static sqInt NoDbgRegParms genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer); static sqInt NoDbgRegParms genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers); static sqInt NoDbgRegParms genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers); -static sqInt NoDbgRegParms genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg); +static sqInt NoDbgRegParms genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg); static sqInt NoDbgRegParms genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers); static AbstractInstruction * NoDbgRegParms genSwapRRScratch(AbstractInstruction * self_in_genSwapRRScratch, sqInt regA, sqInt regB, sqInt regTmp); static void NoDbgRegParms genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister); @@ -748,6 +751,8 @@ static BytecodeDescriptor * loadBytesAndGetDescriptor(void); static void NoDbgRegParms loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc); static AbstractInstruction * NoDbgRegParms gMoveAwR(sqInt address, sqInt reg); static AbstractInstruction * NoDbgRegParms gMoveCwR(sqInt wordConstant, sqInt reg); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters); static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg); static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC); @@ -795,6 +800,7 @@ static void NoDbgRegParms recordGeneratedRunTimeaddress(char *aString, sqInt add extern sqInt recordPrimTraceFunc(void); static void recordRunTimeObjectReferences(void); static sqInt NoDbgRegParms registerMaskFor(sqInt reg); +static sqInt NoDbgRegParms registerMaskForand(sqInt reg1, sqInt reg2); static void NoDbgRegParms relocateCallsAndSelfReferencesInMethod(CogMethod *cogMethod); static void NoDbgRegParms relocateCallsInClosedPIC(CogMethod *cPIC); static sqInt NoDbgRegParms relocateIfCallOrMethodReferencemcpcdelta(sqInt annotation, char *mcpc, CogMethod *refDeltaArg); @@ -1166,6 +1172,7 @@ static sqInt genStoreAndPopReceiverVariableBytecode(void); static sqInt genStoreAndPopRemoteTempLongBytecode(void); static sqInt genStoreAndPopTemporaryVariableBytecode(void); static sqInt genStoreRemoteTempLongBytecode(void); +static void genTakeProfileSample(void); extern sqInt mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj); static sqInt numSpecialSelectors(void); static usqInt NoDbgRegParms pcDataForBlockEntryMethod(sqInt blockEntryMcpc, sqInt cogMethod); @@ -2786,28 +2793,28 @@ addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *an static sqInt NoDbgRegParms availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << DPFPReg0)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg0))) != 0))) { return DPFPReg0; } - if (!(((liveRegsMask & (1U << DPFPReg1)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg1))) != 0))) { return DPFPReg1; } - if (!(((liveRegsMask & (1U << DPFPReg2)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg2))) != 0))) { return DPFPReg2; } - if (!(((liveRegsMask & (1U << DPFPReg3)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg3))) != 0))) { return DPFPReg3; } - if (!(((liveRegsMask & (1U << DPFPReg4)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg4))) != 0))) { return DPFPReg4; } - if (!(((liveRegsMask & (1U << DPFPReg5)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg5))) != 0))) { return DPFPReg5; } - if (!(((liveRegsMask & (1U << DPFPReg6)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg6))) != 0))) { return DPFPReg6; } - if (!(((liveRegsMask & (1U << DPFPReg7)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg7))) != 0))) { return DPFPReg7; } return NoReg; @@ -2907,11 +2914,11 @@ genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers) used immediately afterwards. */ - /* CogAbstractInstruction>>#genLoadStackPointersForFastPrimCall: */ + /* CogAbstractInstruction>>#genLoadStackPointersForPrimCall: */ static sqInt NoDbgRegParms -genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg) +genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg) { - genLoadStackPointers(self_in_genLoadStackPointersForFastPrimCall); + genLoadStackPointers(self_in_genLoadStackPointersForPrimCall); return 0; } @@ -3191,28 +3198,28 @@ andrnimmror(AbstractInstruction * self_in_andrnimmror, sqInt destReg, sqInt srcR static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << Extra0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra0Reg))) != 0))) { return Extra0Reg; } - if (!(((liveRegsMask & (1U << Extra1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra1Reg))) != 0))) { return Extra1Reg; } - if (!(((liveRegsMask & (1U << Extra2Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra2Reg))) != 0))) { return Extra2Reg; } - if (!(((liveRegsMask & (1U << Arg1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg1Reg))) != 0))) { return Arg1Reg; } - if (!(((liveRegsMask & (1U << Arg0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg0Reg))) != 0))) { return Arg0Reg; } - if (!(((liveRegsMask & (1U << SendNumArgsReg)) != 0))) { + if (!(((liveRegsMask & ((1U << SendNumArgsReg))) != 0))) { return SendNumArgsReg; } - if (!(((liveRegsMask & (1U << ClassReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ClassReg))) != 0))) { return ClassReg; } - if (!(((liveRegsMask & (1U << ReceiverResultReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ReceiverResultReg))) != 0))) { return ReceiverResultReg; } return NoReg; @@ -10423,7 +10430,7 @@ compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numAr regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1U << resultRegOrNone)) - (1U << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1U << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1U << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ regMaskCopy = ((usqInt)regsToSave); @@ -12014,7 +12021,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) startAddress = methodZoneBase; callerSavedReg = 0; pushedVarBaseReg = 0; - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { /* VarBaseReg is not caller-saved; must save and restore it, either by using an available caller-saved reg or push/pop. */ @@ -12064,7 +12071,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) operandTwo2 = cStackPointerAddress(); checkLiteralforInstruction(operandTwo2, genoperandoperand(MoveRAw, NativeSPReg, operandTwo2)); } - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { if (pushedVarBaseReg) { gNativePopR(VarBaseReg); } @@ -13346,6 +13353,22 @@ gMoveCwR(sqInt wordConstant, sqInt reg) return checkLiteralforInstruction(wordConstant, genoperandoperand(MoveCwR, wordConstant, reg)); } + /* Cogit>>#MovePerfCnt64R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters) +{ + assert(0); + return genoperandoperand(MovePerfCnt64RL, destReg, liveRegisters); +} + + /* Cogit>>#MovePerfCnt64R:R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters) +{ + assert(0); + return genoperandoperandoperand(MovePerfCnt64RRL, destRegLo, destRegHi, liveRegisters); +} + /* Answer the address of the null byte at the end of the method map. */ @@ -14942,11 +14965,21 @@ recordRunTimeObjectReferences(void) } } + +/* N.B. (self registerMaskFor: NoReg) = 0 */ + /* Cogit>>#registerMaskFor: */ static sqInt NoDbgRegParms registerMaskFor(sqInt reg) { - return 1U << reg; + return ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); +} + + /* Cogit>>#registerMaskFor:and: */ +static sqInt NoDbgRegParms +registerMaskForand(sqInt reg1, sqInt reg2) +{ + return (1U << reg1) | (1U << reg2); } /* Cogit>>#relocateCallsAndSelfReferencesInMethod: */ @@ -22164,7 +22197,7 @@ generateObjectRepresentationTrampolines(void) } # endif // IMMUTABILITY ceNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceNewHash", 1, ReceiverResultReg, null, null, null, /* begin emptyRegisterMask */ 0, 1, ReceiverResultReg, 0); - ceInlineNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceInlineNewHash", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, ReceiverResultReg, 0); + ceInlineNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceInlineNewHash", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))), 1, ReceiverResultReg, 0); /* begin genStoreCheckTrampoline */ if (CheckRememberedInTrampoline) { zeroOpcodeIndex(); @@ -22175,7 +22208,7 @@ generateObjectRepresentationTrampolines(void) genoperand(RetN, 0); jmpTarget(jumpSC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); } - ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))), 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), CheckRememberedInTrampoline); ceStoreCheckContextReceiverTrampoline = genStoreCheckContextReceiverTrampoline(); @@ -24727,7 +24760,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jumpRC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg)); jmpTarget(jumpImmutable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); @@ -24743,7 +24776,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* Store check */ jumpImmutable1 = genJumpImmutablescratchReg(ReceiverResultReg, SendNumArgsReg); - compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), 0 /* emptyRegisterMask */); genLoadStackPointers(backEnd()); @@ -24819,7 +24852,7 @@ genStoreValueinstancenumSlots(sqInt value, sqInt destReg, sqInt numSlots) } return 0; } - constReg = allocateRegNotConflictingWith(1U << destReg); + constReg = allocateRegNotConflictingWith(((destReg < 0) ? (((usqInt)(1)) >> (-destReg)) : (1U << destReg))); if (shouldAnnotateObjectReference(value)) { annotateobjRef(gMoveCwR(value, constReg), value); } @@ -26269,7 +26302,7 @@ registerMask(SimStackEntry * self_in_registerMask) || (((self_in_registerMask->type)) == SSRegister) ? (/* begin registerMaskFor: */ (reg = (self_in_registerMask->registerr)), - 1U << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg))) : 0); } @@ -26282,7 +26315,7 @@ registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone) return (((self_in_registerMaskOrNone->type)) == SSRegister ? (/* begin registerMaskFor: */ (reg = (self_in_registerMaskOrNone->registerr)), - 1U << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg))) : 0); } @@ -26674,40 +26707,24 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) { sqInt address; sqInt address1; - sqInt address10; - sqInt address11; - sqInt address12; - sqInt address13; - sqInt address3; - sqInt address4; - sqInt address5; + sqInt address2; sqInt address6; + sqInt address7; sqInt address8; sqInt address9; + AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; AbstractInstruction *anInstruction4; AbstractInstruction *anInstruction5; AbstractInstruction *anInstruction6; AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction * continuePostSampleNonPrim; - AbstractInstruction * continuePostSamplePrim; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; - AbstractInstruction * jmpSampleNonPrim; - AbstractInstruction * jmpSamplePrim; sqInt offset; sqInt offset1; sqInt offset2; - sqInt operand1; - sqInt operand3; - sqInt reg; sqInt retpc; - continuePostSampleNonPrim = ((AbstractInstruction *) 0); - continuePostSamplePrim = ((AbstractInstruction *) 0); - jmpSampleNonPrim = ((AbstractInstruction *) 0); - jmpSamplePrim = ((AbstractInstruction *) 0); assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); genExternalizePointersForPrimitiveCall(); /* begin genLoadCStackPointersForPrimCall */ @@ -26717,54 +26734,36 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) else { genLoadCStackPointer(backEnd); } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick if so */ - /* begin MoveAw:R: */ - address = nextProfileTickAddress(); - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address, genoperandoperand(MoveAwR, address, TempReg)); - /* begin MoveAw:R: */ - address1 = (nextProfileTickAddress()) + BytesPerWord; - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address1, genoperandoperand(MoveAwR, address1, ClassReg)); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSampleNonPrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSampleNonPrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } if (recordPrimTraceForMethod(methodObj)) { genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(MoveCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction8)) { - (anInstruction8->dependent = locateLiteral(0)); + anInstruction4 = genoperandoperand(MoveCqR, 0, TempReg); + if (usesOutOfLineLiteral(anInstruction4)) { + (anInstruction4->dependent = locateLiteral(0)); } /* begin MoveR:Aw: */ - address11 = primFailCodeAddress(); + address6 = primFailCodeAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address11, genoperandoperand(MoveRAw, TempReg, address11)); + checkLiteralforInstruction(address6, genoperandoperand(MoveRAw, TempReg, address6)); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); - if (usesOutOfLineLiteral(anInstruction1)) { - (anInstruction1->dependent = locateLiteral(methodOrBlockNumArgs)); + anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); + if (usesOutOfLineLiteral(anInstruction)) { + (anInstruction->dependent = locateLiteral(methodOrBlockNumArgs)); } } /* begin MoveR:Aw: */ - address12 = argumentCountAddress(); + address7 = argumentCountAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address12, genoperandoperand(MoveRAw, TempReg, address12)); + checkLiteralforInstruction(address7, genoperandoperand(MoveRAw, TempReg, address7)); if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { /* begin MoveCw:R: */ checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg)); /* begin MoveR:Aw: */ - address3 = primitiveFunctionPointerAddress(); + address = primitiveFunctionPointerAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address3, genoperandoperand(MoveRAw, TempReg, address3)); + checkLiteralforInstruction(address, genoperandoperand(MoveRAw, TempReg, address)); } if (((flags & (PrimCallNeedsNewMethod + PrimCallMayEndureCodeCompaction)) != 0)) { @@ -26776,22 +26775,21 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) /* begin MoveMw:r:R: */ offset = offsetof(CogMethod, methodObject); /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - if (usesOutOfLineLiteral(anInstruction2)) { - (anInstruction2->dependent = locateLiteral(offset)); + anInstruction1 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); + if (usesOutOfLineLiteral(anInstruction1)) { + (anInstruction1->dependent = locateLiteral(offset)); } /* begin MoveR:Aw: */ - address4 = newMethodAddress(); + address1 = newMethodAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address4, genoperandoperand(MoveRAw, TempReg, address4)); + checkLiteralforInstruction(address1, genoperandoperand(MoveRAw, TempReg, address1)); } /* begin PrefetchAw: */ - address13 = primFailCodeAddress(); + address8 = primFailCodeAddress(); /* begin gen:literal: */ - checkLiteralforInstruction(address13, genoperand(PrefetchAw, address13)); + checkLiteralforInstruction(address8, genoperand(PrefetchAw, address8)); if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - /* Sideways call the C primitive routine so that we return through cePrimReturnEnterCogCode. */ /* On Spur ceActivateFailingPrimitiveMethod: would like to retry if forwarders are found. So insist on PrimCallNeedsPrimitiveFunction being set too. */ assert(((flags & PrimCallNeedsPrimitiveFunction) != 0)); @@ -26804,103 +26802,48 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) checkLiteralforInstruction(retpc, genoperandoperand(MoveCwR, retpc, LR)); /* begin gen:literal: */ checkLiteralforInstruction(((sqInt)(((sqInt)primitiveRoutine))), genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine))))); - jmp = (jmpSamplePrim = (continuePostSamplePrim = null)); + return 0; } - else { - - /* Call the C primitive routine. */ - genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); - /* begin gen:literal: */ - checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperand(CallFull, ((sqInt)primitiveRoutine))); - /* begin genRemoveNArgsFromStack: */ - assert(0 <= 4); - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin MoveAw:R: */ - address5 = nextProfileTickAddress(); - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address5, genoperandoperand(MoveAwR, address5, TempReg)); - /* begin MoveAw:R: */ - address6 = (nextProfileTickAddress()) + BytesPerWord; - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address6, genoperandoperand(MoveAwR, address6, ClassReg)); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSamplePrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSamplePrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - maybeCompileRetryOnPrimitiveFail(primitiveIndex); - /* begin MoveAw:R: */ - address8 = instructionPointerAddress(); - reg = LinkReg; - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address8, genoperandoperand(MoveAwR, address8, reg)); - genLoadStackPointers(backEnd); - /* begin MoveAw:R: */ - address9 = primFailCodeAddress(); - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address9, genoperandoperand(MoveAwR, address9, TempReg)); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction4)) { - (anInstruction4->dependent = locateLiteral(0)); - } - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset1 = 0; - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); - if (usesOutOfLineLiteral(anInstruction5)) { - (anInstruction5->dependent = locateLiteral(offset1)); - } - /* begin RetN: */ - genoperand(RetN, BytesPerWord); + genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); + /* begin gen:literal: */ + checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperand(CallFull, ((sqInt)primitiveRoutine))); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 4); + maybeCompileRetryOnPrimitiveFail(primitiveIndex); + genLoadStackPointersForPrimCall(backEnd, ClassReg); + /* begin MoveAw:R: */ + address2 = instructionPointerAddress(); + /* begin gen:literal:operand: */ + checkLiteralforInstruction(address2, genoperandoperand(MoveAwR, address2, LinkReg)); + /* begin MoveAw:R: */ + address9 = primFailCodeAddress(); + /* begin gen:literal:operand: */ + checkLiteralforInstruction(address9, genoperandoperand(MoveAwR, address9, TempReg)); + flag("ask concrete code gen if move sets condition codes?"); + /* begin checkQuickConstant:forInstruction: */ + anInstruction5 = genoperandoperand(CmpCqR, 0, TempReg); + if (usesOutOfLineLiteral(anInstruction5)) { + (anInstruction5->dependent = locateLiteral(0)); } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* The sample is collected by cePrimReturnEnterCogCode for external calls */ - if (!(jmpSamplePrim == null)) { - - /* Call ceCheckProfileTick: to record sample and then continue. */ - jmpTarget(jmpSamplePrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin gen:literal: */ - operand1 = ((usqIntptr_t)ceCheckProfileTick); - checkLiteralforInstruction(operand1, genoperand(CallFull, operand1)); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSamplePrim)); - } - jmpTarget(jmpSampleNonPrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(MoveCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction6)) { - (anInstruction6->dependent = locateLiteral(0)); - } - /* begin MoveR:Aw: */ - address10 = newMethodAddress(); - /* begin gen:operand:literal: */ - checkLiteralforInstruction(address10, genoperandoperand(MoveRAw, TempReg, address10)); - /* begin gen:literal: */ - operand3 = ((usqIntptr_t)ceCheckProfileTick); - checkLiteralforInstruction(operand3, genoperand(CallFull, operand3)); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSampleNonPrim)); + /* begin JumpNonZero: */ + jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + /* begin MoveMw:r:R: */ + offset1 = 0; + /* begin checkQuickConstant:forInstruction: */ + anInstruction6 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); + if (usesOutOfLineLiteral(anInstruction6)) { + (anInstruction6->dependent = locateLiteral(offset1)); } - if (!(jmp == null)) { - - /* Jump to restore of receiver reg and proceed to frame build for failure. */ - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin MoveMw:r:R: */ - offset2 = BytesPerWord * (methodOrBlockNumArgs + (0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); - if (usesOutOfLineLiteral(anInstruction7)) { - (anInstruction7->dependent = locateLiteral(offset2)); - } + continueAfterProfileSample = anInstruction6; + /* begin RetN: */ + genoperand(RetN, BytesPerWord); + jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + /* begin MoveMw:r:R: */ + offset2 = BytesPerWord * (methodOrBlockNumArgs + (0)); + /* begin checkQuickConstant:forInstruction: */ + anInstruction7 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); + if (usesOutOfLineLiteral(anInstruction7)) { + (anInstruction7->dependent = locateLiteral(offset2)); } return 0; } @@ -26930,7 +26873,7 @@ compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)) if ((methodOrBlockNumArgs > 2 /* numRegArgs */) || (methodOrBlockNumArgs == 0)) { /* begin registerMaskFor: */ - liveRegsMask = 1U << ReceiverResultReg; + liveRegsMask = (1U << ReceiverResultReg); } else { if (methodOrBlockNumArgs > 1) { @@ -27022,6 +26965,7 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags AbstractInstruction *anInstruction8; AbstractInstruction *anInstruction9; sqInt calleeSavedRegisterMask; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; sqInt linkRegSaveRegister; sqInt offset; @@ -27058,12 +27002,12 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags /* begin gen:operand:literal: */ checkLiteralforInstruction(address5, genoperandoperand(MoveRAw, TempReg, address5)); genExternalizeStackPointerForFastPrimitiveCall(); - calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | (1U << ClassReg)) - (1U << ClassReg)); + calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | ((1U << ClassReg))) - ((1U << ClassReg))); linkRegSaveRegister = availableRegisterOrNoneIn(calleeSavedRegisterMask); assert(!((linkRegSaveRegister == NoReg))); /* begin MoveR:R: */ genoperandoperand(MoveRR, LinkReg, linkRegSaveRegister); - calleeSavedRegisterMask = ((calleeSavedRegisterMask | (1U << linkRegSaveRegister)) - (1U << linkRegSaveRegister)); + calleeSavedRegisterMask = ((calleeSavedRegisterMask | (((linkRegSaveRegister < 0) ? (((usqInt)(1)) >> (-linkRegSaveRegister)) : (1U << linkRegSaveRegister)))) - (((linkRegSaveRegister < 0) ? (((usqInt)(1)) >> (-linkRegSaveRegister)) : (1U << linkRegSaveRegister)))); spRegSaveRegister = NoReg; /* begin Label */ retry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); @@ -27072,8 +27016,11 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags } else { } + genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); /* begin gen:literal: */ - checkLiteralforInstruction(primitiveRoutine, genoperand(CallFull, primitiveRoutine)); + checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperand(CallFull, ((sqInt)primitiveRoutine))); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 4); /* begin MoveAw:R: */ address6 = primFailCodeAddress(); /* begin gen:literal:operand: */ @@ -27092,7 +27039,7 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags /* begin MoveAw:R: */ address7 = stackPointerAddress(); /* begin gen:literal:operand: */ - checkLiteralforInstruction(address7, genoperandoperand(MoveAwR, address7, TempReg)); + continueAfterProfileSample = checkLiteralforInstruction(address7, genoperandoperand(MoveAwR, address7, TempReg)); /* begin checkQuickConstant:forInstruction: */ anInstruction1 = genoperandoperandoperand(MoveMwrR, 0, TempReg, ReceiverResultReg); if (usesOutOfLineLiteral(anInstruction1)) { @@ -27138,10 +27085,11 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags else { genLoadCStackPointer(backEnd); } + genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); /* begin gen:literal: */ operand1 = ((usqIntptr_t)checkForAndFollowForwardedPrimitiveState); checkLiteralforInstruction(operand1, genoperand(CallFull, operand1)); - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); /* begin checkQuickConstant:forInstruction: */ anInstruction6 = genoperandoperand(CmpCqR, 0, ABIResultReg); if (usesOutOfLineLiteral(anInstruction6)) { @@ -27166,12 +27114,12 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags /* must reload SPReg to undo any alignment change, */ if (((flags & PrimCallOnSmalltalkStackAlign2x) != 0)) { - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); } } /* begin MoveR:R: */ genoperandoperand(MoveRR, linkRegSaveRegister, LinkReg); - if (((ABICallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((ABICallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* begin MoveMw:r:R: */ offset1 = (methodOrBlockNumArgs + (0)) * BytesPerWord; /* begin checkQuickConstant:forInstruction: */ @@ -28232,24 +28180,16 @@ static void NoDbgRegParms genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) { sqInt address; - sqInt address1; sqInt address3; - sqInt address6; - sqInt address7; - sqInt address8; + sqInt address4; + sqInt address5; AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction7; - sqInt callTarget; - AbstractInstruction *continuePostSample; - AbstractInstruction * inst; + AbstractInstruction *anInstruction4; + AbstractInstruction *anInstruction6; AbstractInstruction *jmpFail; - AbstractInstruction *jmpSample; sqInt quickConstant; sqInt reg; - continuePostSample = ((AbstractInstruction *) 0); - jmpSample = ((AbstractInstruction *) 0); zeroOpcodeIndex(); /* begin MoveCq:R: */ quickConstant = varBaseAddress(); @@ -28258,34 +28198,15 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) if (usesOutOfLineLiteral(anInstruction)) { (anInstruction->dependent = locateLiteral(quickConstant)); } - if (profiling) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick: if so. - N.B. nextProfileTick is 64-bits so 32-bit systems need to test both halves. */ - /* begin MoveAw:R: */ - address = nextProfileTickAddress(); - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address, genoperandoperand(MoveAwR, address, TempReg)); - /* begin MoveAw:R: */ - address1 = (nextProfileTickAddress()) + BytesPerWord; - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address1, genoperandoperand(MoveAwR, address1, ClassReg)); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSample = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } /* begin MoveAw:R: */ - address6 = primFailCodeAddress(); + address3 = primFailCodeAddress(); /* begin gen:literal:operand: */ - checkLiteralforInstruction(address6, genoperandoperand(MoveAwR, address6, TempReg)); + checkLiteralforInstruction(address3, genoperandoperand(MoveAwR, address3, TempReg)); flag("ask concrete code gen if move sets condition codes?"); /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(CmpCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction7)) { - (anInstruction7->dependent = locateLiteral(0)); + anInstruction6 = genoperandoperand(CmpCqR, 0, TempReg); + if (usesOutOfLineLiteral(anInstruction6)) { + (anInstruction6->dependent = locateLiteral(0)); } /* begin JumpNonZero: */ jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); @@ -28293,44 +28214,29 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) /* begin PopR: */ genoperand(PopR, ReceiverResultReg); /* begin MoveAw:R: */ - address3 = instructionPointerAddress(); + address = instructionPointerAddress(); /* begin gen:literal:operand: */ - checkLiteralforInstruction(address3, genoperandoperand(MoveAwR, address3, PCReg)); + checkLiteralforInstruction(address, genoperandoperand(MoveAwR, address, PCReg)); jmpTarget(jmpFail, gMoveAwR(newMethodAddress(), SendNumArgsReg)); /* begin MoveAw:R: */ - address7 = cStackPointerAddress(); + address4 = cStackPointerAddress(); /* begin gen:literal:operand: */ - checkLiteralforInstruction(address7, genoperandoperand(MoveAwR, address7, SPReg)); + checkLiteralforInstruction(address4, genoperandoperand(MoveAwR, address4, SPReg)); compileCallFornumArgsargargargargresultRegregsToSave(ceActivateFailingPrimitiveMethod, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); /* begin MoveAw:R: */ - address8 = instructionPointerAddress(); + address5 = instructionPointerAddress(); reg = LinkReg; /* begin gen:literal:operand: */ - checkLiteralforInstruction(address8, genoperandoperand(MoveAwR, address8, reg)); + checkLiteralforInstruction(address5, genoperandoperand(MoveAwR, address5, reg)); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); - if (usesOutOfLineLiteral(anInstruction5)) { - (anInstruction5->dependent = locateLiteral(0)); + anInstruction4 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); + if (usesOutOfLineLiteral(anInstruction4)) { + (anInstruction4->dependent = locateLiteral(0)); } /* begin RetN: */ genoperand(RetN, BytesPerWord); - if (profiling) { - - /* Call ceCheckProfileTick: to record sample and then continue. newMethod - should be up-to-date. Need to save and restore the link reg around this call. */ - jmpTarget(jmpSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - /* begin CallFullRT: */ - callTarget = (usqIntptr_t)ceCheckProfileTick; - /* begin gen:literal: */ - checkLiteralforInstruction(callTarget, genoperand(CallFull, callTarget)); - genoperand(PopR, LinkReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSample)); } -} /* SimpleStackBasedCogit>>#genPushConstantFalseBytecode */ static sqInt @@ -28696,6 +28602,21 @@ genStoreRemoteTempLongBytecode(void) && (shouldAnnotateObjectReference(((ssTop())->constant))))); } + /* SimpleStackBasedCogit>>#genTakeProfileSample */ +static void +genTakeProfileSample(void) +{ + sqInt operand1; + + addDependent(methodLabel, annotateAbsolutePCRef(gMoveCwR(((sqInt)methodLabel), ClassReg))); + genMarshallNArgsargargargarg(backEnd, 1, ClassReg, null, null, null); + /* begin gen:literal: */ + operand1 = ((usqIntptr_t)ceTakeProfileSample); + checkLiteralforInstruction(operand1, genoperand(CallFull, operand1)); + /* begin genRemoveNArgsFromStack: */ + assert(1 <= 4); + } + /* Collect the branch and send data for cogMethod, storing it into arrayObj. */ @@ -29064,7 +28985,7 @@ primitiveGeneratorOrNil(void) static sqInt NoDbgRegParms registerisInMask(sqInt reg, sqInt mask) { - return ((mask & (1U << reg)) != 0); + return ((mask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)))) != 0); } /* SimpleStackBasedCogit>>#v3:Block:Code:Size: */ @@ -29733,7 +29654,7 @@ genBinaryAtConstInlinePrimitive(sqInt primIndex) val = ((ssTop())->constant); if (primIndex == 65) { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); rr = ReceiverResultReg; } @@ -29749,10 +29670,10 @@ genBinaryAtConstInlinePrimitive(sqInt primIndex) break; case 65: /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << SendNumArgsReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << SendNumArgsReg), simStackPtr, simNativeStackPtr); /* begin genPushMaybeContextSlotIndex: */ assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ voidReceiverResultRegContainsSelf(); @@ -29841,13 +29762,13 @@ genBinaryAtInlinePrimitive(sqInt primIndex) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -30015,7 +29936,7 @@ genBinaryCompInlinePrimitive(sqInt primIndex) } otherReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); popToReg(ssTop(), otherReg); - resultReg = allocateRegForStackEntryAtnotConflictingWith(1, 1U << otherReg); + resultReg = allocateRegForStackEntryAtnotConflictingWith(1, ((otherReg < 0) ? (((usqInt)(1)) >> (-otherReg)) : (1U << otherReg))); popToReg(ssValue(1), resultReg); /* begin CmpR:R: */ assert(!((otherReg == SPReg))); @@ -30440,7 +30361,7 @@ genBinarySmiBitShiftLeftInlinePrimitive(void) genoperandoperand(LogicalShiftLeftCqR, quickConstant, rr); } else { - ra = allocateRegForStackEntryAtnotConflictingWith(0, 1U << rr); + ra = allocateRegForStackEntryAtnotConflictingWith(0, ((rr < 0) ? (((usqInt)(1)) >> (-rr)) : (1U << rr))); popToReg(ssTop(), ra); genConvertSmallIntegerToIntegerInReg(ra); /* begin LogicalShiftLeftR:R: */ @@ -30473,7 +30394,7 @@ genBinarySmiBitShiftRightInlinePrimitive(void) genoperandoperand(ArithmeticShiftRightCqR, quickConstant, rr); } else { - ra = allocateRegForStackEntryAtnotConflictingWith(0, 1U << rr); + ra = allocateRegForStackEntryAtnotConflictingWith(0, ((rr < 0) ? (((usqInt)(1)) >> (-rr)) : (1U << rr))); popToReg(ssTop(), ra); genConvertSmallIntegerToIntegerInReg(ra); /* begin ArithmeticShiftRightR:R: */ @@ -30578,13 +30499,13 @@ genBinaryVarOpVarSmiInlinePrimitive(sqInt primIndex) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -30655,7 +30576,7 @@ genByteAtPut(void) && (1)) { /* begin registerMaskFor: */ reg = (rTop1 = registerOrNone(ssTop())); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } if (((registerOrNone(ssValue(1))) != NoReg) && (1)) { @@ -30667,11 +30588,11 @@ genByteAtPut(void) } if (rThird1 == NoReg) { rThird1 = allocateRegNotConflictingWith(topRegistersMask); - topRegistersMask = topRegistersMask | (1U << rThird1); + topRegistersMask = topRegistersMask | (((rThird1 < 0) ? (((usqInt)(1)) >> (-rThird1)) : (1U << rThird1))); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); - topRegistersMask = topRegistersMask | (1U << rTop1); + topRegistersMask = topRegistersMask | (((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); } if (rNext1 == NoReg) { rNext1 = allocateRegNotConflictingWith(topRegistersMask); @@ -31034,7 +30955,7 @@ genByteEqualsInlinePrimitive(sqInt prim) if (needLoop) { assert(!(((ssTop())->spilled))); str1Reg = allocateRegForStackEntryAtnotConflictingWith(1, 0 /* emptyRegisterMask */); - str2Reg = allocateRegForStackEntryAtnotConflictingWith(2, 1U << str1Reg); + str2Reg = allocateRegForStackEntryAtnotConflictingWith(2, ((str1Reg < 0) ? (((usqInt)(1)) >> (-str1Reg)) : (1U << str1Reg))); lenReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << str1Reg) | (1U << str2Reg)); popToReg(ssValue(1), str1Reg); popToReg(ssValue(2), str2Reg); @@ -31046,12 +30967,12 @@ genByteEqualsInlinePrimitive(sqInt prim) if (!((((ssValue(1))->type)) == SSConstant)) { str1Reg = allocateRegForStackEntryAtnotConflictingWith(1, mask); popToReg(ssValue(1), str1Reg); - mask = mask | (1U << str1Reg); + mask = mask | (((str1Reg < 0) ? (((usqInt)(1)) >> (-str1Reg)) : (1U << str1Reg))); } if (!((((ssValue(2))->type)) == SSConstant)) { str2Reg = allocateRegForStackEntryAtnotConflictingWith(2, mask); popToReg(ssValue(2), str2Reg); - mask = mask | (1U << str2Reg); + mask = mask | (((str2Reg < 0) ? (((usqInt)(1)) >> (-str2Reg)) : (1U << str2Reg))); } extraReg = allocateRegNotConflictingWith(mask); } @@ -31285,7 +31206,7 @@ genCounterTripOnlyJumpIfto(sqInt boolean, sqInt targetBytecodePC) /* We need SendNumArgsReg because of the mustBeBooleanTrampoline */ counterIndex += 1; /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << SendNumArgsReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << SendNumArgsReg), simStackPtr, simNativeStackPtr); /* begin checkQuickConstant:forInstruction: */ anInstruction1 = genoperandoperand(MoveCqR, 1, SendNumArgsReg); if (usesOutOfLineLiteral(anInstruction1)) { @@ -31413,13 +31334,13 @@ genDivInlinePrimitive(sqInt primIndex) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -31752,13 +31673,13 @@ genForwardersInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -31952,13 +31873,13 @@ genForwardersInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg1 = (rNext11 = registerOrNone(ssValue(1))); - topRegistersMask1 = 1U << reg1; + topRegistersMask1 = ((reg1 < 0) ? (((usqInt)(1)) >> (-reg1)) : (1U << reg1)); } if (rTop11 == NoReg) { rTop11 = allocateRegNotConflictingWith(topRegistersMask1); } if (rNext11 == NoReg) { - rNext11 = allocateRegNotConflictingWith(1U << rTop11); + rNext11 = allocateRegNotConflictingWith(((rTop11 < 0) ? (((usqInt)(1)) >> (-rTop11)) : (1U << rTop11))); } assert(!(((rTop11 == NoReg) || (rNext11 == NoReg)))); @@ -32012,12 +31933,12 @@ genForwardersInlinedIdenticalOrNotIf(sqInt orNot) } if (argReg == NoReg) { /* begin registerMaskFor: */ - regMask = 1U << rcvrReg; + regMask = ((rcvrReg < 0) ? (((usqInt)(1)) >> (-rcvrReg)) : (1U << rcvrReg)); } else { if (rcvrReg == NoReg) { /* begin registerMaskFor: */ - regMask = 1U << argReg; + regMask = ((argReg < 0) ? (((usqInt)(1)) >> (-argReg)) : (1U << argReg)); } else { /* begin registerMaskFor:and: */ @@ -32678,7 +32599,7 @@ genJumpIfto(sqInt boolean, sqInt targetBytecodePC) popToReg(desc, TempReg); ssPop(1); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << SendNumArgsReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << SendNumArgsReg), simStackPtr, simNativeStackPtr); /* begin Label */ retry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); /* begin genExecutionCountLogicInto:counterReg: */ @@ -33143,13 +33064,13 @@ genPointerAtPutConstantMaybeContextstoreCheckimmutabilityCheck(sqInt maybeContex rcvrReg = ReceiverResultReg; } else { - rcvrReg = allocateRegForStackEntryAtnotConflictingWith(2, 1U << valReg); + rcvrReg = allocateRegForStackEntryAtnotConflictingWith(2, ((valReg < 0) ? (((usqInt)(1)) >> (-valReg)) : (1U << valReg))); } } /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << valReg, simStackPtr - 2, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((valReg < 0) ? (((usqInt)(1)) >> (-valReg)) : (1U << valReg)), simStackPtr - 2, simNativeStackPtr); /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << rcvrReg, simStackPtr - 3, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((rcvrReg < 0) ? (((usqInt)(1)) >> (-rcvrReg)) : (1U << rcvrReg)), simStackPtr - 3, simNativeStackPtr); popToReg(ssTop(), valReg); ssPop(1); if (((ssTop())->spilled)) { @@ -33196,7 +33117,7 @@ genPointerAtPutConstantMaybeContextstoreCheckimmutabilityCheck(sqInt maybeContex # endif // IMMUTABILITY ssPop(1); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ClassReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ssPush(1); genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); ssStoreAndReplacePoptoReg(0, ClassReg); @@ -33229,7 +33150,7 @@ genPointerAtPutConstantMaybeContextstoreCheckimmutabilityCheck(sqInt maybeContex # if IMMUTABILITY if (needsImmCheck) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(0, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -33243,7 +33164,7 @@ genPointerAtPutConstantMaybeContextstoreCheckimmutabilityCheck(sqInt maybeContex return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, indexCst, rcvrReg, TempReg, needsStoreCheck, 0); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << rcvrReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, ((rcvrReg < 0) ? (((usqInt)(1)) >> (-rcvrReg)) : (1U << rcvrReg))); ssStorePoptoReg(0, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, indexCst, rcvrReg, TempReg, needsFrame, needsStoreCheck); } @@ -33519,7 +33440,7 @@ genPointerAtPutStoreCheck(sqInt needsStoreCheck) || ((registerOrNone(ssTop())) != ReceiverResultReg))) { /* begin registerMaskFor: */ reg = (rTop1 = registerOrNone(ssTop())); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } if (((registerOrNone(ssValue(1))) != NoReg) && ((!needsStoreCheck) @@ -33537,17 +33458,17 @@ genPointerAtPutStoreCheck(sqInt needsStoreCheck) /* Free ReceiverResultReg if it was not free */ rThird1 = ReceiverResultReg; /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); } else { rThird1 = allocateRegNotConflictingWith(topRegistersMask); } - topRegistersMask = topRegistersMask | (1U << rThird1); + topRegistersMask = topRegistersMask | (((rThird1 < 0) ? (((usqInt)(1)) >> (-rThird1)) : (1U << rThird1))); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); - topRegistersMask = topRegistersMask | (1U << rTop1); + topRegistersMask = topRegistersMask | (((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); } if (rNext1 == NoReg) { rNext1 = allocateRegNotConflictingWith(topRegistersMask); @@ -34086,7 +34007,7 @@ genUnaryClassPrimitive(void) sqInt topReg; topReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - destReg = allocateRegNotConflictingWith(1U << topReg); + destReg = allocateRegNotConflictingWith(((topReg < 0) ? (((usqInt)(1)) >> (-topReg)) : (1U << topReg))); popToReg(ssTop(), topReg); /* begin MoveR:R: */ genoperandoperand(MoveRR, topReg, TempReg); @@ -34162,7 +34083,7 @@ genUnaryHashInlinePrimitive(sqInt primIndex) switch (primIndex) { case 20: rcvrReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - resultReg = allocateRegNotConflictingWith(1U << rcvrReg); + resultReg = allocateRegNotConflictingWith(((rcvrReg < 0) ? (((usqInt)(1)) >> (-rcvrReg)) : (1U << rcvrReg))); popToReg(ssTop(), rcvrReg); genGetIdentityHashresultReg(rcvrReg, resultReg); break; @@ -34353,7 +34274,7 @@ genUnarySizeInlinePrimitive(sqInt primIndex) assert(((primIndex >= 1) && (primIndex <= 6))); rcvrReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - resultReg = allocateRegNotConflictingWith(1U << rcvrReg); + resultReg = allocateRegNotConflictingWith(((rcvrReg < 0) ? (((usqInt)(1)) >> (-rcvrReg)) : (1U << rcvrReg))); popToReg(ssTop(), rcvrReg); ssPop(1); ssPushRegister(resultReg); @@ -35513,7 +35434,7 @@ anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n) sqInt regMask; /* begin registerMaskFor: */ - regMask = 1U << reg; + regMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { if ((((registerMask(simStackAt(i))) & regMask) != 0)) { return 1; @@ -36235,7 +36156,7 @@ ensureReceiverResultRegContainsSelf(void) if (needsFrame) { if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin putSelfInReceiverResultReg */ storeToReg(simSelf(), ReceiverResultReg); ((simSelf())->liveRegister = ReceiverResultReg); @@ -36367,7 +36288,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) && (index < simStackPtr)) { desc = simStackAt(index); if (((desc->type)) == SSRegister) { - if (!(((regMask & (1U << ((desc->registerr)))) != 0))) { + if (!(((regMask & (((((desc->registerr)) < 0) ? (((usqInt)(1)) >> (-((desc->registerr)))) : (1U << ((desc->registerr)))))) != 0))) { reg = (desc->registerr); } } @@ -36375,7 +36296,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) } assert(!((reg == NoReg))); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << reg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)), simStackPtr, simNativeStackPtr); return reg; } @@ -37542,11 +37463,11 @@ genPushMaybeContextReceiverVariable(sqInt slotIndex) AbstractInstruction *jmpSingle; /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ensureReceiverResultRegContainsSelf(); /* begin genPushMaybeContextSlotIndex: */ assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ voidReceiverResultRegContainsSelf(); @@ -37604,7 +37525,7 @@ genPushNewArrayBytecode(void) } else { /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << SendNumArgsReg)) | ((1U << ReceiverResultReg))), simStackPtr, simNativeStackPtr); } size = byte1 & 0x7F; if (!popValues) { @@ -37680,7 +37601,7 @@ genPushRemoteTempLongBytecode(void) (anInstruction->dependent = locateLiteral(offset)); } /* begin availableRegOrNoneNotConflictingWith: */ - regMask = 1U << tempVectReg; + regMask = ((tempVectReg < 0) ? (((usqInt)(1)) >> (-tempVectReg)) : (1U << tempVectReg)); remoteTempReg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); if (remoteTempReg == NoReg) { remoteTempReg = tempVectReg; @@ -38058,11 +37979,11 @@ genSpecialSelectorClass(void) || (topReg == ClassReg)) { /* begin ssAllocateRequiredReg:and: */ requiredReg1 = (topReg = SendNumArgsReg); - ssAllocateRequiredRegMaskupThroughupThroughNative((1U << requiredReg1) | (1U << ClassReg), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((((requiredReg1 < 0) ? (((usqInt)(1)) >> (-requiredReg1)) : (1U << requiredReg1))) | ((1U << ClassReg)), simStackPtr, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr, simNativeStackPtr); } ssPush(1); popToReg(ssTop(), topReg); @@ -38134,7 +38055,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean association = getLiteral(litVarIndex); voidReceiverResultRegContainsSelf(); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin genMoveConstant:R: */ if (shouldAnnotateObjectReference(association)) { annotateobjRef(gMoveCwR(association, ReceiverResultReg), association); @@ -38150,7 +38071,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean # if IMMUTABILITY if (needsImmCheck) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -38164,7 +38085,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -38228,7 +38149,7 @@ genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqI # endif // IMMUTABILITY ssPop(1); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ClassReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ssPush(1); genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); @@ -38276,7 +38197,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea # if IMMUTABILITY if (needsImmCheck1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -38290,7 +38211,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck1, 1); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck1); } @@ -38314,7 +38235,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt assert(needsFrame); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); /* begin MoveMw:r:R: */ offset = frameOffsetOfTemporary(remoteTempIndex); @@ -38327,7 +38248,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt # if IMMUTABILITY # endif - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -38518,13 +38439,13 @@ genVanillaInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -38787,12 +38708,12 @@ liveRegisters(void) } else { /* begin registerMaskFor: */ - regsSet = 1U << ReceiverResultReg; + regsSet = (1U << ReceiverResultReg); if ((methodOrBlockNumArgs <= 2 /* numRegArgs */) && (methodOrBlockNumArgs > 0)) { - regsSet = regsSet | (1U << Arg0Reg); + regsSet = regsSet | ((1U << Arg0Reg)); if (methodOrBlockNumArgs > 1) { - regsSet = regsSet | (1U << Arg1Reg); + regsSet = regsSet | ((1U << Arg1Reg)); } } } @@ -38895,13 +38816,13 @@ marshallSendArguments(sqInt numArgs) if (numArgs > 0) { if (numArgs > 1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 2, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 2, simNativeStackPtr); /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg1Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg1Reg), simStackPtr - 1, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 1, simNativeStackPtr); } } if (numArgs > 1) { diff --git a/spursistasrc/vm/cogitIA32.c b/spursistasrc/vm/cogitIA32.c index 64c0bbedd4..e2d26eb9c5 100644 --- a/spursistasrc/vm/cogitIA32.c +++ b/spursistasrc/vm/cogitIA32.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + CCodeGenerator VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - SistaCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + SistaCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "SistaCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 " __DATE__ ; +static char __buildInfo[] = "SistaCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__cogitBuildInfo = __buildInfo; @@ -54,17 +54,17 @@ char *__cogitBuildInfo = __buildInfo; #define ArithmeticShiftRightRR 92 #define BadRegisterSet 1 #define BlockCreationBytecodeSize 4 -#define BSR 168 +#define BSR 170 #define BytecodeSetHasDirectedSuperSend 1 #define Call 6 #define CallerSavedRegisterMask 0x6 #define CallFull 7 #define CallR 8 -#define CDQ 159 +#define CDQ 161 #if !defined(CheckRememberedInTrampoline) /* Allow this to be overridden on the compiler command line */ # define CheckRememberedInTrampoline 0 #endif -#define CLD 164 +#define CLD 166 #define ClassArray 7 #define ClassArrayCompactIndex 51 #define ClassBlockClosureCompactIndex 37 @@ -86,7 +86,7 @@ char *__cogitBuildInfo = __buildInfo; #define CMMaxUsageCount 7 #define CMMethod 2 #define CMOpenPIC 5 -#define CMPXCHGRAw 174 +#define CMPXCHGRAw 176 #define CmpC32R 113 #define CmpCqR 105 #define CmpCwR 112 @@ -102,7 +102,7 @@ char *__cogitBuildInfo = __buildInfo; #define ConvertRsR 149 #define ConvertRsRd 147 #define CounterBytes 4 -#define CPUID 158 +#define CPUID 160 #define Debug DEBUGVM #define DisplacementMask 0x1F #define DisplacementX2N 0 @@ -140,8 +140,8 @@ char *__cogitBuildInfo = __buildInfo; #define FoxSavedFP 0 #define FoxThisContext -8 #define FPReg 5 -#define FSTPD 163 -#define FSTPS 162 +#define FSTPD 165 +#define FSTPS 164 #define FullClosureCompiledBlockIndex 1 #define FullClosureFirstCopiedValueIndex 4 #define FullClosureReceiverIndex 3 @@ -152,11 +152,11 @@ char *__cogitBuildInfo = __buildInfo; #define HashMultiplyConstant 1664525 #define HashMultiplyMask 0xFFFFFFF #define HeaderIndex 0 -#define IDIVR 160 +#define IDIVR 162 #if !defined(IMMUTABILITY) /* Allow this to be overridden on the compiler command line */ # define IMMUTABILITY 1 #endif -#define IMULRR 161 +#define IMULRR 163 #define InFullBlock 2 #define InstanceSpecificationIndex 2 #define InstructionPointerIndex 1 @@ -207,10 +207,10 @@ char *__cogitBuildInfo = __buildInfo; #define Label 1 #define LargeContextSlots 62 #define LastJump 42 -#define LFENCE 170 +#define LFENCE 172 #undef LinkReg #define Literal 2 -#define LOCK 173 +#define LOCK 175 #define LoadEffectiveAddressMwrR 88 #define LogicalShiftLeftCqR 95 #define LogicalShiftLeftCqRR 129 @@ -234,11 +234,11 @@ char *__cogitBuildInfo = __buildInfo; #define MethodCacheSelector 1 #define MethodIndex 3 #define MethodTooBig -4 -#define MFENCE 171 +#define MFENCE 173 #define MFMethodFlagHasContextFlag 1 #define MFMethodFlagIsBlockFlag 2 -#define MOVSB 166 -#define MOVSD 167 +#define MOVSB 168 +#define MOVSD 169 #define ModReg 3 #define ModRegInd 0 #define ModRegRegDisp32 2 @@ -256,6 +256,8 @@ char *__cogitBuildInfo = __buildInfo; #define MoveM8rR 54 #define MoveMbrR 65 #define MoveMwrR 50 +#define MovePerfCnt64RL 159 +#define MovePerfCnt64RRL 158 #define MoveRA32 47 #define MoveRAb 49 #define MoveRAw 46 @@ -315,17 +317,17 @@ char *__cogitBuildInfo = __buildInfo; #define PushCq 82 #define PushCw 83 #define PushR 81 -#define REP 165 +#define REP 167 #define ReceiverIndex 5 #define ReceiverResultReg 2 #define RetN 9 #undef RISCTempReg -#define SETE 175 +#define SETE 177 #define SelectorCannotInterpret 34 #define SelectorDoesNotUnderstand 20 #define SenderIndex 0 #define SendNumArgsReg 3 -#define SFENCE 172 +#define SFENCE 174 #define ShouldNotJIT -8 #define SIB1 0 #define SIB4 2 @@ -359,7 +361,7 @@ char *__cogitBuildInfo = __buildInfo; #define UnimplementedPrimitive -7 #define ValueIndex 1 #undef VarBaseReg -#define XCHGRR 169 +#define XCHGRR 171 #define XorCwR 118 #define XorRdRd 137 #define XorRR 104 @@ -489,7 +491,7 @@ static sqInt NoDbgRegParms concretizeAt(AbstractInstruction * self_in_concretize static sqInt NoDbgRegParms genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer); static sqInt NoDbgRegParms genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers); static sqInt NoDbgRegParms genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers); -static sqInt NoDbgRegParms genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg); +static sqInt NoDbgRegParms genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg); static sqInt NoDbgRegParms genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers); static void NoDbgRegParms genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister); static sqInt NoDbgRegParms hasVarBaseRegister(AbstractInstruction * self_in_hasVarBaseRegister); @@ -516,6 +518,7 @@ static sqInt NoDbgRegParms cmpC32RTempByteSize(AbstractInstruction * self_in_cmp static sqInt NoDbgRegParms computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize); static sqInt NoDbgRegParms computeShiftRRSize(AbstractInstruction * self_in_computeShiftRRSize); static sqInt NoDbgRegParms concretizeFill32(AbstractInstruction * self_in_concretizeFill32); +static sqInt NoDbgRegParms concretizeMovePerfCnt64RRL(AbstractInstruction * self_in_concretizeMovePerfCnt64RRL); static sqInt NoDbgRegParms concretizeOpRR(AbstractInstruction * self_in_concretizeOpRR, sqInt x86opcode); static sqInt NoDbgRegParms concretizeReverseOpRR(AbstractInstruction * self_in_concretizeReverseOpRR, sqInt x86opcode); static sqInt NoDbgRegParms concretizeSet(AbstractInstruction * self_in_concretizeSet, sqInt conditionCode); @@ -732,6 +735,8 @@ extern void linkSendAtintooffsetreceiver(sqInt callSiteReturnAddress, CogMethod static BytecodeDescriptor * loadBytesAndGetDescriptor(void); static void NoDbgRegParms loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc); static AbstractInstruction * NoDbgRegParms gMoveCwR(sqInt wordConstant, sqInt reg); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters); static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg); static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC); @@ -1124,6 +1129,7 @@ static sqInt genStoreAndPopReceiverVariableBytecode(void); static sqInt genStoreAndPopRemoteTempLongBytecode(void); static sqInt genStoreAndPopTemporaryVariableBytecode(void); static sqInt genStoreRemoteTempLongBytecode(void); +static void genTakeProfileSample(void); extern sqInt mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj); static sqInt numSpecialSelectors(void); static usqInt NoDbgRegParms pcDataForBlockEntryMethod(sqInt blockEntryMcpc, sqInt cogMethod); @@ -2747,28 +2753,28 @@ addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *an static sqInt NoDbgRegParms availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << DPFPReg0)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg0))) != 0))) { return DPFPReg0; } - if (!(((liveRegsMask & (1U << DPFPReg1)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg1))) != 0))) { return DPFPReg1; } - if (!(((liveRegsMask & (1U << DPFPReg2)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg2))) != 0))) { return DPFPReg2; } - if (!(((liveRegsMask & (1U << DPFPReg3)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg3))) != 0))) { return DPFPReg3; } - if (!(((liveRegsMask & (1U << DPFPReg4)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg4))) != 0))) { return DPFPReg4; } - if (!(((liveRegsMask & (1U << DPFPReg5)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg5))) != 0))) { return DPFPReg5; } - if (!(((liveRegsMask & (1U << DPFPReg6)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg6))) != 0))) { return DPFPReg6; } - if (!(((liveRegsMask & (1U << DPFPReg7)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg7))) != 0))) { return DPFPReg7; } return NoReg; @@ -2783,19 +2789,19 @@ availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegi static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << Arg1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg1Reg))) != 0))) { return Arg1Reg; } - if (!(((liveRegsMask & (1U << Arg0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg0Reg))) != 0))) { return Arg0Reg; } - if (!(((liveRegsMask & (1U << SendNumArgsReg)) != 0))) { + if (!(((liveRegsMask & ((1U << SendNumArgsReg))) != 0))) { return SendNumArgsReg; } - if (!(((liveRegsMask & (1U << ClassReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ClassReg))) != 0))) { return ClassReg; } - if (!(((liveRegsMask & (1U << ReceiverResultReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ReceiverResultReg))) != 0))) { return ReceiverResultReg; } return NoReg; @@ -2910,9 +2916,9 @@ genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers) used immediately afterwards. */ - /* CogAbstractInstruction>>#genLoadStackPointersForFastPrimCall: */ + /* CogAbstractInstruction>>#genLoadStackPointersForPrimCall: */ static sqInt NoDbgRegParms -genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg) +genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg) { AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; @@ -3269,6 +3275,7 @@ computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize) case OrRR: case XorRR: case SubRR: + case SubbRR: case NegateR: case NotR: case MoveRR: @@ -3507,6 +3514,11 @@ computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize) ? 7 : 0); + case MovePerfCnt64RRL: + + /* it is easier to calculate the right value by concretizing. We concretize twice, but so what? */ + return concretizeMovePerfCnt64RRL(self_in_computeMaximumSize); + default: error("Case not found and no otherwise clause"); } @@ -3546,6 +3558,63 @@ concretizeFill32(AbstractInstruction * self_in_concretizeFill32) return 4; } + +/* Generate code for + 0x0: 50 pushl %eax + 0x1: 52 pushl %edx + 0x2: 0f 31 rdtsc + 0x4: 89 f8 movl %edi, %eax + 0x6: 89 f2 movl %esi, %edx + 0x8: 5a popl %edx + et al */ + + /* CogIA32Compiler>>#concretizeMovePerfCnt64RRL */ +static sqInt NoDbgRegParms +concretizeMovePerfCnt64RRL(AbstractInstruction * self_in_concretizeMovePerfCnt64RRL) +{ + usqInt liveRegisters; + sqInt offset; + usqInt regHi; + usqInt regLo; + + regLo = ((self_in_concretizeMovePerfCnt64RRL->operands))[0]; + regHi = ((self_in_concretizeMovePerfCnt64RRL->operands))[1]; + liveRegisters = ((self_in_concretizeMovePerfCnt64RRL->operands))[2]; + offset = 0; + if (((liveRegisters & ((1U << EAX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[0] = 80; + offset += 1; + } + if (((liveRegisters & ((1U << EDX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset] = 82; + offset += 1; + } + assert(!(((regLo == EDX) + || (regHi == EAX)))); + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset] = 15; + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset + 1] = 49; + offset += 2; + if (regHi != EDX) { + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset] = 137; + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset + 1] = (modRMRO(self_in_concretizeMovePerfCnt64RRL, ModReg, regHi, EDX)); + offset += 2; + } + if (regLo != EAX) { + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset + 4] = 137; + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset + 5] = (modRMRO(self_in_concretizeMovePerfCnt64RRL, ModReg, regLo, EAX)); + offset += 2; + } + if (((liveRegisters & ((1U << EDX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset] = 90; + offset += 1; + } + if (((liveRegisters & ((1U << EAX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset] = 88; + offset += 1; + } + return offset; +} + /* CogIA32Compiler>>#concretizeOpRR: */ static sqInt NoDbgRegParms concretizeOpRR(AbstractInstruction * self_in_concretizeOpRR, sqInt x86opcode) @@ -3889,7 +3958,6 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) usqInt regLHS10; usqInt regLHS11; usqInt regLHS12; - usqInt regLHS13; usqInt regLHS2; usqInt regLHS3; usqInt regLHS4; @@ -3903,7 +3971,6 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) usqInt regRHS10; usqInt regRHS11; usqInt regRHS12; - usqInt regRHS13; usqInt regRHS2; usqInt regRHS3; usqInt regRHS4; @@ -5054,31 +5121,26 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) return concretizeOpRR(self_in_dispatchConcretize, 43); case SubbRR: - /* begin concretizeSubbRR */ - regLHS9 = ((self_in_dispatchConcretize->operands))[0]; - regRHS9 = ((self_in_dispatchConcretize->operands))[1]; - ((self_in_dispatchConcretize->machineCode))[0] = 27; - ((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, regLHS9, regRHS9)); - return 2; + return concretizeOpRR(self_in_dispatchConcretize, 27); case SubRdRd: /* begin concretizeSEE2OpRdRd: */ - regRHS10 = ((self_in_dispatchConcretize->operands))[0]; - regLHS10 = ((self_in_dispatchConcretize->operands))[1]; + regRHS9 = ((self_in_dispatchConcretize->operands))[0]; + regLHS9 = ((self_in_dispatchConcretize->operands))[1]; ((self_in_dispatchConcretize->machineCode))[0] = 242; ((self_in_dispatchConcretize->machineCode))[1] = 15; ((self_in_dispatchConcretize->machineCode))[2] = 92; - ((self_in_dispatchConcretize->machineCode))[3] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS10, regLHS10)); + ((self_in_dispatchConcretize->machineCode))[3] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS9, regLHS9)); return 4; case SubRsRs: /* begin concretizeSEEOpRsRs: */ - regRHS11 = ((self_in_dispatchConcretize->operands))[0]; - regLHS11 = ((self_in_dispatchConcretize->operands))[1]; + regRHS10 = ((self_in_dispatchConcretize->operands))[0]; + regLHS10 = ((self_in_dispatchConcretize->operands))[1]; ((self_in_dispatchConcretize->machineCode))[0] = 243; ((self_in_dispatchConcretize->machineCode))[1] = 15; ((self_in_dispatchConcretize->machineCode))[2] = 92; - ((self_in_dispatchConcretize->machineCode))[3] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS11, regLHS11)); + ((self_in_dispatchConcretize->machineCode))[3] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS10, regLHS10)); return 4; case SqrtRd: @@ -5124,21 +5186,21 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) case XorRdRd: /* begin concretizeXorRdRd */ - regRHS12 = ((self_in_dispatchConcretize->operands))[0]; - regLHS12 = ((self_in_dispatchConcretize->operands))[1]; + regRHS11 = ((self_in_dispatchConcretize->operands))[0]; + regLHS11 = ((self_in_dispatchConcretize->operands))[1]; ((self_in_dispatchConcretize->machineCode))[0] = 102; ((self_in_dispatchConcretize->machineCode))[1] = 15; ((self_in_dispatchConcretize->machineCode))[2] = 87; - ((self_in_dispatchConcretize->machineCode))[3] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS12, regLHS12)); + ((self_in_dispatchConcretize->machineCode))[3] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS11, regLHS11)); return 4; case XorRsRs: /* begin concretizeXorRsRs */ - regRHS13 = ((self_in_dispatchConcretize->operands))[0]; - regLHS13 = ((self_in_dispatchConcretize->operands))[1]; + regRHS12 = ((self_in_dispatchConcretize->operands))[0]; + regLHS12 = ((self_in_dispatchConcretize->operands))[1]; ((self_in_dispatchConcretize->machineCode))[0] = 15; ((self_in_dispatchConcretize->machineCode))[1] = 87; - ((self_in_dispatchConcretize->machineCode))[2] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS13, regLHS13)); + ((self_in_dispatchConcretize->machineCode))[2] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS12, regLHS12)); return 3; case NegateR: @@ -6132,6 +6194,9 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) case ZeroExtend16RR: return concretizeZeroExtend16RR(self_in_dispatchConcretize); + case MovePerfCnt64RRL: + return concretizeMovePerfCnt64RRL(self_in_dispatchConcretize); + default: error("Case not found and no otherwise clause"); } @@ -6785,7 +6850,7 @@ genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask) assert(!((((regMask & (registerMaskForand(ESP, EBP))) != 0)))); for (reg = EAX; reg <= EDI; reg += 1) { - if (((regMask & (1U << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)))) != 0)) { genoperand(PopR, reg); } } @@ -6806,7 +6871,7 @@ genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask) assert(((EDI - EAX) + 1) == 8); assert(!((((regMask & (registerMaskForand(ESP, EBP))) != 0)))); for (reg = EDI; reg >= EAX; reg += -1) { - if (((regMask & (1U << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)))) != 0)) { genoperand(PushR, reg); } } @@ -9996,7 +10061,7 @@ compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numAr regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1U << resultRegOrNone)) - (1U << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1U << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1U << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ regMaskCopy = ((usqInt)regsToSave); @@ -12760,6 +12825,22 @@ gMoveCwR(sqInt wordConstant, sqInt reg) return anInstruction; } + /* Cogit>>#MovePerfCnt64R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters) +{ + assert(BytesPerWord == 8); + return genoperandoperand(MovePerfCnt64RL, destReg, liveRegisters); +} + + /* Cogit>>#MovePerfCnt64R:R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters) +{ + assert(BytesPerWord == 4); + return genoperandoperandoperand(MovePerfCnt64RRL, destRegLo, destRegHi, liveRegisters); +} + /* Answer the address of the null byte at the end of the method map. */ @@ -14345,11 +14426,14 @@ recordRunTimeObjectReferences(void) } } + +/* N.B. (self registerMaskFor: NoReg) = 0 */ + /* Cogit>>#registerMaskFor: */ static sqInt NoDbgRegParms registerMaskFor(sqInt reg) { - return 1U << reg; + return ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } /* Cogit>>#registerMaskFor:and: */ @@ -20804,7 +20888,7 @@ generateObjectRepresentationTrampolines(void) } # endif // IMMUTABILITY ceNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceNewHash", 1, ReceiverResultReg, null, null, null, /* begin emptyRegisterMask */ 0, 1, ReceiverResultReg, 0); - ceInlineNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceInlineNewHash", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, ReceiverResultReg, 0); + ceInlineNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceInlineNewHash", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))), 1, ReceiverResultReg, 0); /* begin genStoreCheckTrampoline */ if (CheckRememberedInTrampoline) { zeroOpcodeIndex(); @@ -20815,7 +20899,7 @@ generateObjectRepresentationTrampolines(void) genoperand(RetN, 0); jmpTarget(jumpSC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); } - ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))), 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), CheckRememberedInTrampoline); ceStoreCheckContextReceiverTrampoline = genStoreCheckContextReceiverTrampoline(); @@ -22828,7 +22912,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jumpRC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg)); jmpTarget(jumpImmutable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); @@ -22844,7 +22928,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* Store check */ jumpImmutable1 = genJumpImmutablescratchReg(ReceiverResultReg, SendNumArgsReg); - compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), 0 /* emptyRegisterMask */); genLoadStackPointers(backEnd()); @@ -22914,7 +22998,7 @@ genStoreValueinstancenumSlots(sqInt value, sqInt destReg, sqInt numSlots) } return 0; } - constReg = allocateRegNotConflictingWith(1U << destReg); + constReg = allocateRegNotConflictingWith(((destReg < 0) ? (((usqInt)(1)) >> (-destReg)) : (1U << destReg))); if (shouldAnnotateObjectReference(value)) { annotateobjRef(gMoveCwR(value, constReg), value); } @@ -23761,7 +23845,7 @@ registerMask(SimStackEntry * self_in_registerMask) || (((self_in_registerMask->type)) == SSRegister) ? (/* begin registerMaskFor: */ (reg = (self_in_registerMask->registerr)), - 1U << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg))) : 0); } @@ -23774,7 +23858,7 @@ registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone) return (((self_in_registerMaskOrNone->type)) == SSRegister ? (/* begin registerMaskFor: */ (reg = (self_in_registerMaskOrNone->registerr)), - 1U << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg))) : 0); } @@ -23955,54 +24039,43 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) { AbstractInstruction *abstractInstruction; AbstractInstruction *abstractInstruction1; - AbstractInstruction *abstractInstruction2; - AbstractInstruction *abstractInstruction3; sqInt address; - sqInt address1; - sqInt address2; AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; + AbstractInstruction *anInstruction10; AbstractInstruction *anInstruction11; + AbstractInstruction *anInstruction110; AbstractInstruction *anInstruction13; AbstractInstruction *anInstruction14; + AbstractInstruction *anInstruction15; + AbstractInstruction *anInstruction16; AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction18; AbstractInstruction *anInstruction19; + AbstractInstruction *anInstruction2; AbstractInstruction *anInstruction20; AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction25; + AbstractInstruction *anInstruction210; + AbstractInstruction *anInstruction22; AbstractInstruction *anInstruction26; AbstractInstruction *anInstruction27; - AbstractInstruction *anInstruction28; - AbstractInstruction *anInstruction29; - AbstractInstruction *anInstruction30; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction35; - AbstractInstruction *anInstruction36; + AbstractInstruction *anInstruction3; AbstractInstruction *anInstruction4; AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - AbstractInstruction * continuePostSampleNonPrim; - AbstractInstruction * continuePostSamplePrim; + AbstractInstruction * continueAfterProfileSample; + sqInt effectiveLiveRegisters; AbstractInstruction * jmp; - AbstractInstruction * jmpSampleNonPrim; - AbstractInstruction * jmpSamplePrim; + AbstractInstruction * jumpToTakeSample; + sqInt liveRegisters; sqInt offset; sqInt offset1; sqInt offset2; - sqInt operand; - sqInt operand2; - sqInt reg; + sqInt regHi; + sqInt regLo; sqInt retpc; - continuePostSampleNonPrim = ((AbstractInstruction *) 0); - continuePostSamplePrim = ((AbstractInstruction *) 0); - jmpSampleNonPrim = ((AbstractInstruction *) 0); - jmpSamplePrim = ((AbstractInstruction *) 0); + jumpToTakeSample = ((AbstractInstruction *) 0); assert(!((0))); genExternalizePointersForPrimitiveCall(); /* begin genLoadCStackPointersForPrimCall */ @@ -24012,45 +24085,28 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) else { genLoadCStackPointer(backEnd); } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick if so */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin MoveAw:R: */ - address = (nextProfileTickAddress()) + BytesPerWord; - /* begin checkLiteral:forInstruction: */ - anInstruction1 = genoperandoperand(MoveAwR, address, ClassReg); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSampleNonPrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSampleNonPrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } if (recordPrimTraceForMethod(methodObj)) { genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction28 = genoperandoperand(MoveCqR, 0, TempReg); + anInstruction15 = genoperandoperand(MoveCqR, 0, TempReg); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction29 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); + anInstruction16 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); + anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); } /* begin checkLiteral:forInstruction: */ argumentCountAddress(); - anInstruction30 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); + anInstruction17 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { /* begin checkLiteral:forInstruction: */ ((sqInt)primitiveRoutine); - anInstruction5 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); + anInstruction1 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); /* begin checkLiteral:forInstruction: */ primitiveFunctionPointerAddress(); - anInstruction6 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); + anInstruction2 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); } if (((flags & (PrimCallNeedsNewMethod + PrimCallMayEndureCodeCompaction)) != 0)) { @@ -24062,135 +24118,120 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) /* begin MoveMw:r:R: */ offset = offsetof(CogMethod, methodObject); /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); + anInstruction3 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); /* begin checkLiteral:forInstruction: */ newMethodAddress(); - anInstruction8 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); + anInstruction4 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); } /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction31 = genoperand(PrefetchAw, primFailCodeAddress()); + anInstruction18 = genoperand(PrefetchAw, primFailCodeAddress()); if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - /* Sideways call the C primitive routine so that we return through cePrimReturnEnterCogCode. */ /* On Spur ceActivateFailingPrimitiveMethod: would like to retry if forwarders are found. So insist on PrimCallNeedsPrimitiveFunction being set too. */ assert(((flags & PrimCallNeedsPrimitiveFunction) != 0)); /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l23; + goto l11; if (null < NoReg) { /* begin checkQuickConstant:forInstruction: */ - anInstruction35 = genoperand(PushCq, -2 - null); + anInstruction26 = genoperand(PushCq, -2 - null); } else { genoperand(PushR, null); } - l23: /* end genMarshallNArgs:arg:arg:arg:arg: */; + l11: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin genSubstituteReturnAddress: */ retpc = (((flags & PrimCallCollectsProfileSamples) != 0) ? cePrimReturnEnterCogCodeProfiling : cePrimReturnEnterCogCode); /* begin checkLiteral:forInstruction: */ - anInstruction36 = genoperand(PushCw, retpc); + anInstruction27 = genoperand(PushCw, retpc); /* begin annotateCall: */ - anInstruction9 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); - abstractInstruction = anInstruction9; + anInstruction5 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); + abstractInstruction = anInstruction5; (abstractInstruction->annotation = IsRelativeCall); - jmp = (jmpSamplePrim = (continuePostSamplePrim = null)); + return 0; } - else { - - /* Call the C primitive routine. */ - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l31; - genoperand(PushR, 0); - l31: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin annotateCall: */ - anInstruction11 = genoperand(CallFull, ((sqInt)primitiveRoutine)); - abstractInstruction1 = anInstruction11; - (abstractInstruction1->annotation = IsRelativeCall); - /* begin genRemoveNArgsFromStack: */ - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction13 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin MoveAw:R: */ - address1 = (nextProfileTickAddress()) + BytesPerWord; - /* begin checkLiteral:forInstruction: */ - anInstruction14 = genoperandoperand(MoveAwR, address1, ClassReg); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSamplePrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSamplePrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + goto l25; + genoperand(PushR, 0); + l25: /* end genMarshallNArgs:arg:arg:arg:arg: */; + /* begin annotateCall: */ + anInstruction7 = genoperand(CallFull, ((sqInt)primitiveRoutine)); + abstractInstruction1 = anInstruction7; + (abstractInstruction1->annotation = IsRelativeCall); + /* begin genRemoveNArgsFromStack: */ + maybeCompileRetryOnPrimitiveFail(primitiveIndex); + genLoadStackPointersForPrimCall(backEnd, ClassReg); + /* begin checkLiteral:forInstruction: */ + instructionPointerAddress(); + anInstruction10 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); + /* begin checkQuickConstant:forInstruction: */ + anInstruction11 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + /* begin checkLiteral:forInstruction: */ + primFailCodeAddress(); + anInstruction19 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + flag("ask concrete code gen if move sets condition codes?"); + /* begin checkQuickConstant:forInstruction: */ + anInstruction20 = genoperandoperand(CmpCqR, 0, TempReg); + /* begin JumpNonZero: */ + jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + flag("endianness"); + assert(!(((((registerMaskForand(ClassReg, SendNumArgsReg)) & liveRegisters) != 0)))); + effectiveLiveRegisters = liveRegisters | ((1U << ClassReg) | (1U << SendNumArgsReg)); + regLo = Arg0Reg; + regHi = Arg1Reg; + /* begin preferredRegisterPairForMovePerfCnt64RRLInto: */ + if (!(((liveRegisters & ((1U << EAX))) != 0))) { + regLo = EAX; + } + if (!(((liveRegisters & ((1U << EDX))) != 0))) { + regHi = EDX; } - maybeCompileRetryOnPrimitiveFail(primitiveIndex); - /* begin MoveAw:R: */ - address2 = instructionPointerAddress(); - reg = ClassReg; /* begin checkLiteral:forInstruction: */ - anInstruction17 = genoperandoperand(MoveAwR, address2, reg); - genLoadStackPointers(backEnd); + nextProfileTickAddress(); + anInstruction110 = genoperandoperand(MoveAwR, nextProfileTickAddress(), ClassReg); + /* begin MoveAw:R: */ + address = (nextProfileTickAddress()) + 4; /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction18 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - /* begin PushR: */ - genoperand(PushR, ClassReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset1 = BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, BytesPerWord); + anInstruction210 = genoperandoperand(MoveAwR, address, SendNumArgsReg); + gMovePerfCnt64RRL(regLo, regHi, liveRegisters); + /* begin SubR:R: */ + genoperandoperand(SubRR, regLo, ClassReg); + /* begin SubbR:R: */ + genoperandoperand(SubbRR, regHi, SendNumArgsReg); + /* begin JumpGreaterOrEqual: */ + jumpToTakeSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l47; + l47: /* end genCheckForProfileTimerTick: */; } + /* begin MoveMw:r:R: */ + offset1 = BytesPerWord; + /* begin checkQuickConstant:forInstruction: */ + anInstruction21 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); + continueAfterProfileSample = anInstruction21; + /* begin RetN: */ + genoperand(RetN, BytesPerWord); if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* The sample is collected by cePrimReturnEnterCogCode for external calls */ - if (!(jmpSamplePrim == null)) { - - /* Call ceCheckProfileTick: to record sample and then continue. */ - jmpTarget(jmpSamplePrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin annotateCall: */ - operand = ((usqIntptr_t)ceCheckProfileTick); - /* begin checkLiteral:forInstruction: */ - anInstruction21 = genoperand(CallFull, operand); - abstractInstruction2 = anInstruction21; - (abstractInstruction2->annotation = IsRelativeCall); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSamplePrim)); - } - jmpTarget(jmpSampleNonPrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction25 = genoperandoperand(MoveCqR, 0, TempReg); + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); /* begin checkLiteral:forInstruction: */ - newMethodAddress(); - anInstruction26 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); - /* begin annotateCall: */ - operand2 = ((usqIntptr_t)ceCheckProfileTick); - /* begin checkLiteral:forInstruction: */ - anInstruction23 = genoperand(CallFull, operand2); - abstractInstruction3 = anInstruction23; - (abstractInstruction3->annotation = IsRelativeCall); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSampleNonPrim)); - } - if (!(jmp == null)) { - - /* Jump to restore of receiver reg and proceed to frame build for failure. */ - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin MoveMw:r:R: */ - offset2 = BytesPerWord * (methodOrBlockNumArgs + (1)); + instructionPointerAddress(); + anInstruction13 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction27 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); + anInstruction14 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + /* begin Jump: */ + genoperand(Jump, ((sqInt)continueAfterProfileSample)); } + jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + /* begin MoveMw:r:R: */ + offset2 = BytesPerWord * (methodOrBlockNumArgs + (1)); + /* begin checkQuickConstant:forInstruction: */ + anInstruction22 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); return 0; } @@ -24220,7 +24261,7 @@ compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)) if ((methodOrBlockNumArgs > 2 /* numRegArgs */) || (methodOrBlockNumArgs == 0)) { /* begin registerMaskFor: */ - liveRegsMask = 1U << ReceiverResultReg; + liveRegsMask = (1U << ReceiverResultReg); } else { if (methodOrBlockNumArgs > 1) { @@ -24298,10 +24339,12 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags { AbstractInstruction *abstractInstruction; AbstractInstruction *abstractInstruction1; + sqInt address; AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; AbstractInstruction *anInstruction10; AbstractInstruction *anInstruction11; + AbstractInstruction *anInstruction110; AbstractInstruction *anInstruction12; AbstractInstruction *anInstruction13; AbstractInstruction *anInstruction14; @@ -24312,6 +24355,7 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags AbstractInstruction *anInstruction19; AbstractInstruction *anInstruction20; AbstractInstruction *anInstruction21; + AbstractInstruction *anInstruction210; AbstractInstruction *anInstruction22; AbstractInstruction *anInstruction23; AbstractInstruction *anInstruction4; @@ -24320,15 +24364,22 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags AbstractInstruction *anInstruction7; AbstractInstruction *anInstruction9; sqInt calleeSavedRegisterMask; + AbstractInstruction * continueAfterProfileSample; + sqInt effectiveLiveRegisters; AbstractInstruction * jmp; + AbstractInstruction * jumpToTakeSample; + sqInt liveRegisters; sqInt offset; sqInt offset1; sqInt operand; + sqInt regHi; + sqInt regLo; sqInt retpcOffset; AbstractInstruction * retry; AbstractInstruction * skip; sqInt spRegSaveRegister; + jumpToTakeSample = ((AbstractInstruction *) 0); assert(((flags & PrimCallOnSmalltalkStack) != 0)); assert(!((0))); if (recordFastCCallPrimTraceForMethod(methodObj)) { @@ -24347,7 +24398,7 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags argumentCountAddress(); anInstruction20 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); genExternalizeStackPointerForFastPrimitiveCall(); - calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | (1U << ClassReg)) - (1U << ClassReg)); + calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | ((1U << ClassReg))) - ((1U << ClassReg))); spRegSaveRegister = NoReg; /* begin Label */ retry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); @@ -24356,10 +24407,15 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags } else { } + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + goto l35; + genoperand(PushR, 0); + l35: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin annotateCall: */ - anInstruction1 = genoperand(CallFull, primitiveRoutine); + anInstruction1 = genoperand(CallFull, ((sqInt)primitiveRoutine)); abstractInstruction = anInstruction1; (abstractInstruction->annotation = IsRelativeCall); + /* begin genRemoveNArgsFromStack: */ /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); anInstruction21 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); @@ -24371,9 +24427,42 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags anInstruction22 = genoperandoperand(CmpCqR, 0, TempReg); /* begin JumpNonZero: */ jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + flag("endianness"); + assert(!(((((registerMaskForand(ClassReg, SendNumArgsReg)) & liveRegisters) != 0)))); + effectiveLiveRegisters = liveRegisters | ((1U << ClassReg) | (1U << SendNumArgsReg)); + regLo = Arg0Reg; + regHi = Arg1Reg; + /* begin preferredRegisterPairForMovePerfCnt64RRLInto: */ + if (!(((liveRegisters & ((1U << EAX))) != 0))) { + regLo = EAX; + } + if (!(((liveRegisters & ((1U << EDX))) != 0))) { + regHi = EDX; + } + /* begin checkLiteral:forInstruction: */ + nextProfileTickAddress(); + anInstruction110 = genoperandoperand(MoveAwR, nextProfileTickAddress(), ClassReg); + /* begin MoveAw:R: */ + address = (nextProfileTickAddress()) + 4; + /* begin checkLiteral:forInstruction: */ + anInstruction210 = genoperandoperand(MoveAwR, address, SendNumArgsReg); + gMovePerfCnt64RRL(regLo, regHi, liveRegisters); + /* begin SubR:R: */ + genoperandoperand(SubRR, regLo, ClassReg); + /* begin SubbR:R: */ + genoperandoperand(SubbRR, regHi, SendNumArgsReg); + /* begin JumpGreaterOrEqual: */ + jumpToTakeSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l51; + l51: /* end genCheckForProfileTimerTick: */; + } /* begin checkLiteral:forInstruction: */ stackPointerAddress(); anInstruction23 = genoperandoperand(MoveAwR, stackPointerAddress(), TempReg); + continueAfterProfileSample = anInstruction23; /* The original retpc is (argumentCount + 1) words below stackPointer. */ retpcOffset = -((methodOrBlockNumArgs + 1) * BytesPerWord); @@ -24387,6 +24476,12 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags anInstruction6 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, TempReg); /* begin RetN: */ genoperand(RetN, 0); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); + /* begin Jump: */ + genoperand(Jump, ((sqInt)continueAfterProfileSample)); + } jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); if ((accessorDepthForExternalPrimitiveMethod(methodObj)) >= 0) { @@ -24417,13 +24512,17 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags else { genLoadCStackPointer(backEnd); } + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + goto l27; + genoperand(PushR, 0); + l27: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin annotateCall: */ operand = ((usqIntptr_t)checkForAndFollowForwardedPrimitiveState); /* begin checkLiteral:forInstruction: */ anInstruction7 = genoperand(CallFull, operand); abstractInstruction1 = anInstruction7; (abstractInstruction1->annotation = IsRelativeCall); - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); /* begin checkQuickConstant:forInstruction: */ anInstruction14 = genoperandoperand(CmpCqR, 0, ABIResultReg); /* begin JumpZero: */ @@ -24441,10 +24540,10 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags /* must reload SPReg to undo any alignment change, */ if (((flags & PrimCallOnSmalltalkStackAlign2x) != 0)) { - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); } } - if (((ABICallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((ABICallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* begin MoveMw:r:R: */ offset1 = (methodOrBlockNumArgs + (1)) * BytesPerWord; /* begin checkQuickConstant:forInstruction: */ @@ -25430,79 +25529,101 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) sqInt address; sqInt address1; AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; + AbstractInstruction *anInstruction11; AbstractInstruction *anInstruction12; AbstractInstruction *anInstruction13; AbstractInstruction *anInstruction14; AbstractInstruction *anInstruction15; AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction2; + AbstractInstruction *anInstruction7; AbstractInstruction *anInstruction8; AbstractInstruction *anInstruction9; sqInt callTarget; AbstractInstruction *continuePostSample; + sqInt effectiveLiveRegisters; AbstractInstruction *jmpFail; AbstractInstruction *jmpSample; - sqInt reg; + sqInt liveRegisters; + sqInt reg1; + sqInt regHi; + sqInt regLo; continuePostSample = ((AbstractInstruction *) 0); jmpSample = ((AbstractInstruction *) 0); zeroOpcodeIndex(); - if (profiling) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick: if so. - N.B. nextProfileTick is 64-bits so 32-bit systems need to test both halves. */ + /* begin checkLiteral:forInstruction: */ + primFailCodeAddress(); + anInstruction12 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + flag("ask concrete code gen if move sets condition codes?"); + /* begin checkQuickConstant:forInstruction: */ + anInstruction13 = genoperandoperand(CmpCqR, 0, TempReg); + /* begin JumpNonZero: */ + jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (profiling + && (1)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + flag("endianness"); + assert(!(((((registerMaskForand(ClassReg, SendNumArgsReg)) & liveRegisters) != 0)))); + effectiveLiveRegisters = liveRegisters | ((1U << ClassReg) | (1U << SendNumArgsReg)); + regLo = Arg0Reg; + regHi = Arg1Reg; + /* begin preferredRegisterPairForMovePerfCnt64RRLInto: */ + if (!(((liveRegisters & ((1U << EAX))) != 0))) { + regLo = EAX; + } + if (!(((liveRegisters & ((1U << EDX))) != 0))) { + regHi = EDX; + } /* begin checkLiteral:forInstruction: */ nextProfileTickAddress(); - anInstruction1 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); + anInstruction1 = genoperandoperand(MoveAwR, nextProfileTickAddress(), ClassReg); /* begin MoveAw:R: */ - address = (nextProfileTickAddress()) + BytesPerWord; + address = (nextProfileTickAddress()) + 4; /* begin checkLiteral:forInstruction: */ - anInstruction2 = genoperandoperand(MoveAwR, address, ClassReg); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSample = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + anInstruction2 = genoperandoperand(MoveAwR, address, SendNumArgsReg); + gMovePerfCnt64RRL(regLo, regHi, liveRegisters); + /* begin SubR:R: */ + genoperandoperand(SubRR, regLo, ClassReg); + /* begin SubbR:R: */ + genoperandoperand(SubbRR, regHi, SendNumArgsReg); + /* begin JumpGreaterOrEqual: */ + jmpSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l17; + l17: /* end genCheckForProfileTimerTick: */; /* begin Label */ continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); } /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction13 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkLiteral:forInstruction: */ instructionPointerAddress(); - anInstruction8 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); + anInstruction7 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); + anInstruction8 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + anInstruction9 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jmpFail, checkLiteralforInstruction(newMethodAddress(), genoperandoperand(MoveAwR, newMethodAddress(), SendNumArgsReg))); /* begin checkLiteral:forInstruction: */ cStackPointerAddress(); - anInstruction15 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); + anInstruction14 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); compileCallFornumArgsargargargargresultRegregsToSave(ceActivateFailingPrimitiveMethod, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); /* begin MoveAw:R: */ address1 = instructionPointerAddress(); - reg = ClassReg; + reg1 = ClassReg; /* begin checkLiteral:forInstruction: */ - anInstruction16 = genoperandoperand(MoveAwR, address1, reg); + anInstruction15 = genoperandoperand(MoveAwR, address1, reg1); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveMwrR, BytesPerWord, SPReg, ReceiverResultReg); + anInstruction11 = genoperandoperandoperand(MoveMwrR, BytesPerWord, SPReg, ReceiverResultReg); /* begin PushR: */ genoperand(PushR, ClassReg); /* begin RetN: */ genoperand(RetN, BytesPerWord); - if (profiling) { + if (profiling + && (1)) { /* Call ceCheckProfileTick: to record sample and then continue. newMethod should be up-to-date. Need to save and restore the link reg around this call. */ @@ -25511,8 +25632,8 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) /* begin CallFullRT: */ callTarget = (usqIntptr_t)ceCheckProfileTick; /* begin annotateCall: */ - anInstruction17 = genoperand(CallFull, callTarget); - abstractInstruction = anInstruction17; + anInstruction16 = genoperand(CallFull, callTarget); + abstractInstruction = anInstruction16; (abstractInstruction->annotation = IsRelativeCall); /* begin Jump: */ genoperand(Jump, ((sqInt)continuePostSample)); @@ -25868,6 +25989,30 @@ genStoreRemoteTempLongBytecode(void) && (shouldAnnotateObjectReference(((ssTop())->constant))))); } + /* SimpleStackBasedCogit>>#genTakeProfileSample */ +static void +genTakeProfileSample(void) +{ + AbstractInstruction *abstractInstruction; + AbstractInstruction *anInstruction; + AbstractInstruction *anInstruction6; + sqInt operand; + + addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + genoperand(PushR, ClassReg); + l3: /* end genMarshallNArgs:arg:arg:arg:arg: */; + /* begin annotateCall: */ + operand = ((usqIntptr_t)ceTakeProfileSample); + /* begin checkLiteral:forInstruction: */ + anInstruction = genoperand(CallFull, operand); + abstractInstruction = anInstruction; + (abstractInstruction->annotation = IsRelativeCall); + /* begin genRemoveNArgsFromStack: */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction6 = genoperandoperand(AddCqR, 4, ESP); + } + /* Collect the branch and send data for cogMethod, storing it into arrayObj. */ @@ -26236,7 +26381,7 @@ primitiveGeneratorOrNil(void) static sqInt NoDbgRegParms registerisInMask(sqInt reg, sqInt mask) { - return ((mask & (1U << reg)) != 0); + return ((mask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)))) != 0); } /* SimpleStackBasedCogit>>#v3:Block:Code:Size: */ @@ -26897,7 +27042,7 @@ genBinaryAtConstInlinePrimitive(sqInt primIndex) val = ((ssTop())->constant); if (primIndex == 65) { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); rr = ReceiverResultReg; } @@ -26913,10 +27058,10 @@ genBinaryAtConstInlinePrimitive(sqInt primIndex) break; case 65: /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << SendNumArgsReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << SendNumArgsReg), simStackPtr, simNativeStackPtr); /* begin genPushMaybeContextSlotIndex: */ assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ voidReceiverResultRegContainsSelf(); @@ -26996,13 +27141,13 @@ genBinaryAtInlinePrimitive(sqInt primIndex) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -27158,7 +27303,7 @@ genBinaryCompInlinePrimitive(sqInt primIndex) } otherReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); popToReg(ssTop(), otherReg); - resultReg = allocateRegForStackEntryAtnotConflictingWith(1, 1U << otherReg); + resultReg = allocateRegForStackEntryAtnotConflictingWith(1, ((otherReg < 0) ? (((usqInt)(1)) >> (-otherReg)) : (1U << otherReg))); popToReg(ssValue(1), resultReg); /* begin CmpR:R: */ assert(!((otherReg == SPReg))); @@ -27566,7 +27711,7 @@ genBinarySmiBitShiftLeftInlinePrimitive(void) genoperandoperand(LogicalShiftLeftCqR, quickConstant, rr); } else { - ra = allocateRegForStackEntryAtnotConflictingWith(0, 1U << rr); + ra = allocateRegForStackEntryAtnotConflictingWith(0, ((rr < 0) ? (((usqInt)(1)) >> (-rr)) : (1U << rr))); popToReg(ssTop(), ra); genConvertSmallIntegerToIntegerInReg(ra); /* begin LogicalShiftLeftR:R: */ @@ -27599,7 +27744,7 @@ genBinarySmiBitShiftRightInlinePrimitive(void) genoperandoperand(ArithmeticShiftRightCqR, quickConstant, rr); } else { - ra = allocateRegForStackEntryAtnotConflictingWith(0, 1U << rr); + ra = allocateRegForStackEntryAtnotConflictingWith(0, ((rr < 0) ? (((usqInt)(1)) >> (-rr)) : (1U << rr))); popToReg(ssTop(), ra); genConvertSmallIntegerToIntegerInReg(ra); /* begin ArithmeticShiftRightR:R: */ @@ -27690,13 +27835,13 @@ genBinaryVarOpVarSmiInlinePrimitive(sqInt primIndex) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -27767,7 +27912,7 @@ genByteAtPut(void) && (1)) { /* begin registerMaskFor: */ reg = (rTop1 = registerOrNone(ssTop())); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } if (((registerOrNone(ssValue(1))) != NoReg) && (1)) { @@ -27779,11 +27924,11 @@ genByteAtPut(void) } if (rThird1 == NoReg) { rThird1 = allocateRegNotConflictingWith(topRegistersMask); - topRegistersMask = topRegistersMask | (1U << rThird1); + topRegistersMask = topRegistersMask | (((rThird1 < 0) ? (((usqInt)(1)) >> (-rThird1)) : (1U << rThird1))); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); - topRegistersMask = topRegistersMask | (1U << rTop1); + topRegistersMask = topRegistersMask | (((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); } if (rNext1 == NoReg) { rNext1 = allocateRegNotConflictingWith(topRegistersMask); @@ -28130,7 +28275,7 @@ genByteEqualsInlinePrimitive(sqInt prim) if (needLoop) { assert(!(((ssTop())->spilled))); str1Reg = allocateRegForStackEntryAtnotConflictingWith(1, 0 /* emptyRegisterMask */); - str2Reg = allocateRegForStackEntryAtnotConflictingWith(2, 1U << str1Reg); + str2Reg = allocateRegForStackEntryAtnotConflictingWith(2, ((str1Reg < 0) ? (((usqInt)(1)) >> (-str1Reg)) : (1U << str1Reg))); lenReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << str1Reg) | (1U << str2Reg)); popToReg(ssValue(1), str1Reg); popToReg(ssValue(2), str2Reg); @@ -28142,12 +28287,12 @@ genByteEqualsInlinePrimitive(sqInt prim) if (!((((ssValue(1))->type)) == SSConstant)) { str1Reg = allocateRegForStackEntryAtnotConflictingWith(1, mask); popToReg(ssValue(1), str1Reg); - mask = mask | (1U << str1Reg); + mask = mask | (((str1Reg < 0) ? (((usqInt)(1)) >> (-str1Reg)) : (1U << str1Reg))); } if (!((((ssValue(2))->type)) == SSConstant)) { str2Reg = allocateRegForStackEntryAtnotConflictingWith(2, mask); popToReg(ssValue(2), str2Reg); - mask = mask | (1U << str2Reg); + mask = mask | (((str2Reg < 0) ? (((usqInt)(1)) >> (-str2Reg)) : (1U << str2Reg))); } extraReg = allocateRegNotConflictingWith(mask); } @@ -28340,7 +28485,7 @@ genCounterTripOnlyJumpIfto(sqInt boolean, sqInt targetBytecodePC) /* We need SendNumArgsReg because of the mustBeBooleanTrampoline */ counterIndex += 1; /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << SendNumArgsReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << SendNumArgsReg), simStackPtr, simNativeStackPtr); /* begin checkQuickConstant:forInstruction: */ anInstruction1 = genoperandoperand(MoveCqR, 1, SendNumArgsReg); mustBeBooleanTrampoline = genCallMustBeBooleanFor(boolean); @@ -28456,13 +28601,13 @@ genDivInlinePrimitive(sqInt primIndex) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -28775,13 +28920,13 @@ genForwardersInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -28966,13 +29111,13 @@ genForwardersInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg1 = (rNext11 = registerOrNone(ssValue(1))); - topRegistersMask1 = 1U << reg1; + topRegistersMask1 = ((reg1 < 0) ? (((usqInt)(1)) >> (-reg1)) : (1U << reg1)); } if (rTop11 == NoReg) { rTop11 = allocateRegNotConflictingWith(topRegistersMask1); } if (rNext11 == NoReg) { - rNext11 = allocateRegNotConflictingWith(1U << rTop11); + rNext11 = allocateRegNotConflictingWith(((rTop11 < 0) ? (((usqInt)(1)) >> (-rTop11)) : (1U << rTop11))); } assert(!(((rTop11 == NoReg) || (rNext11 == NoReg)))); @@ -29023,12 +29168,12 @@ genForwardersInlinedIdenticalOrNotIf(sqInt orNot) } if (argReg == NoReg) { /* begin registerMaskFor: */ - regMask = 1U << rcvrReg; + regMask = ((rcvrReg < 0) ? (((usqInt)(1)) >> (-rcvrReg)) : (1U << rcvrReg)); } else { if (rcvrReg == NoReg) { /* begin registerMaskFor: */ - regMask = 1U << argReg; + regMask = ((argReg < 0) ? (((usqInt)(1)) >> (-argReg)) : (1U << argReg)); } else { /* begin registerMaskFor:and: */ @@ -29650,7 +29795,7 @@ genJumpIfto(sqInt boolean, sqInt targetBytecodePC) popToReg(desc, TempReg); ssPop(1); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << SendNumArgsReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << SendNumArgsReg), simStackPtr, simNativeStackPtr); /* begin Label */ retry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); /* begin genExecutionCountLogicInto:counterReg: */ @@ -30077,13 +30222,13 @@ genPointerAtPutConstantMaybeContextstoreCheckimmutabilityCheck(sqInt maybeContex rcvrReg = ReceiverResultReg; } else { - rcvrReg = allocateRegForStackEntryAtnotConflictingWith(2, 1U << valReg); + rcvrReg = allocateRegForStackEntryAtnotConflictingWith(2, ((valReg < 0) ? (((usqInt)(1)) >> (-valReg)) : (1U << valReg))); } } /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << valReg, simStackPtr - 2, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((valReg < 0) ? (((usqInt)(1)) >> (-valReg)) : (1U << valReg)), simStackPtr - 2, simNativeStackPtr); /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << rcvrReg, simStackPtr - 3, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((rcvrReg < 0) ? (((usqInt)(1)) >> (-rcvrReg)) : (1U << rcvrReg)), simStackPtr - 3, simNativeStackPtr); popToReg(ssTop(), valReg); ssPop(1); if (((ssTop())->spilled)) { @@ -30124,7 +30269,7 @@ genPointerAtPutConstantMaybeContextstoreCheckimmutabilityCheck(sqInt maybeContex # endif // IMMUTABILITY ssPop(1); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ClassReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ssPush(1); genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); ssStoreAndReplacePoptoReg(0, ClassReg); @@ -30154,7 +30299,7 @@ genPointerAtPutConstantMaybeContextstoreCheckimmutabilityCheck(sqInt maybeContex # if IMMUTABILITY if (needsImmCheck) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(0, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -30168,7 +30313,7 @@ genPointerAtPutConstantMaybeContextstoreCheckimmutabilityCheck(sqInt maybeContex return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, indexCst, rcvrReg, TempReg, needsStoreCheck, 0); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << rcvrReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, ((rcvrReg < 0) ? (((usqInt)(1)) >> (-rcvrReg)) : (1U << rcvrReg))); ssStorePoptoReg(0, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, indexCst, rcvrReg, TempReg, needsFrame, needsStoreCheck); } @@ -30425,7 +30570,7 @@ genPointerAtPutStoreCheck(sqInt needsStoreCheck) || ((registerOrNone(ssTop())) != ReceiverResultReg))) { /* begin registerMaskFor: */ reg = (rTop1 = registerOrNone(ssTop())); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } if (((registerOrNone(ssValue(1))) != NoReg) && ((!needsStoreCheck) @@ -30443,17 +30588,17 @@ genPointerAtPutStoreCheck(sqInt needsStoreCheck) /* Free ReceiverResultReg if it was not free */ rThird1 = ReceiverResultReg; /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); } else { rThird1 = allocateRegNotConflictingWith(topRegistersMask); } - topRegistersMask = topRegistersMask | (1U << rThird1); + topRegistersMask = topRegistersMask | (((rThird1 < 0) ? (((usqInt)(1)) >> (-rThird1)) : (1U << rThird1))); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); - topRegistersMask = topRegistersMask | (1U << rTop1); + topRegistersMask = topRegistersMask | (((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); } if (rNext1 == NoReg) { rNext1 = allocateRegNotConflictingWith(topRegistersMask); @@ -30975,7 +31120,7 @@ genUnaryClassPrimitive(void) sqInt topReg; topReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - destReg = allocateRegNotConflictingWith(1U << topReg); + destReg = allocateRegNotConflictingWith(((topReg < 0) ? (((usqInt)(1)) >> (-topReg)) : (1U << topReg))); popToReg(ssTop(), topReg); /* begin MoveR:R: */ genoperandoperand(MoveRR, topReg, TempReg); @@ -31041,7 +31186,7 @@ genUnaryHashInlinePrimitive(sqInt primIndex) switch (primIndex) { case 20: rcvrReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - resultReg = allocateRegNotConflictingWith(1U << rcvrReg); + resultReg = allocateRegNotConflictingWith(((rcvrReg < 0) ? (((usqInt)(1)) >> (-rcvrReg)) : (1U << rcvrReg))); popToReg(ssTop(), rcvrReg); genGetIdentityHashresultReg(rcvrReg, resultReg); break; @@ -31231,7 +31376,7 @@ genUnarySizeInlinePrimitive(sqInt primIndex) assert(((primIndex >= 1) && (primIndex <= 6))); rcvrReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - resultReg = allocateRegNotConflictingWith(1U << rcvrReg); + resultReg = allocateRegNotConflictingWith(((rcvrReg < 0) ? (((usqInt)(1)) >> (-rcvrReg)) : (1U << rcvrReg))); popToReg(ssTop(), rcvrReg); ssPop(1); ssPushRegister(resultReg); @@ -32404,7 +32549,7 @@ anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n) sqInt regMask; /* begin registerMaskFor: */ - regMask = 1U << reg; + regMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { if ((((registerMask(simStackAt(i))) & regMask) != 0)) { return 1; @@ -33094,7 +33239,7 @@ ensureReceiverResultRegContainsSelf(void) if (needsFrame) { if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin putSelfInReceiverResultReg */ storeToReg(simSelf(), ReceiverResultReg); ((simSelf())->liveRegister = ReceiverResultReg); @@ -33226,7 +33371,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) && (index < simStackPtr)) { desc = simStackAt(index); if (((desc->type)) == SSRegister) { - if (!(((regMask & (1U << ((desc->registerr)))) != 0))) { + if (!(((regMask & (((((desc->registerr)) < 0) ? (((usqInt)(1)) >> (-((desc->registerr)))) : (1U << ((desc->registerr)))))) != 0))) { reg = (desc->registerr); } } @@ -33234,7 +33379,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) } assert(!((reg == NoReg))); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << reg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)), simStackPtr, simNativeStackPtr); return reg; } @@ -34328,11 +34473,11 @@ genPushMaybeContextReceiverVariable(sqInt slotIndex) AbstractInstruction *jmpSingle; /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ensureReceiverResultRegContainsSelf(); /* begin genPushMaybeContextSlotIndex: */ assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ voidReceiverResultRegContainsSelf(); @@ -34384,7 +34529,7 @@ genPushNewArrayBytecode(void) } else { /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << SendNumArgsReg)) | ((1U << ReceiverResultReg))), simStackPtr, simNativeStackPtr); } size = byte1 & 0x7F; if (!popValues) { @@ -34457,7 +34602,7 @@ genPushRemoteTempLongBytecode(void) /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperandoperand(MoveMwrR, offset, FPReg, tempVectReg); /* begin availableRegOrNoneNotConflictingWith: */ - regMask = 1U << tempVectReg; + regMask = ((tempVectReg < 0) ? (((usqInt)(1)) >> (-tempVectReg)) : (1U << tempVectReg)); remoteTempReg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); if (remoteTempReg == NoReg) { remoteTempReg = tempVectReg; @@ -34807,11 +34952,11 @@ genSpecialSelectorClass(void) || (topReg == ClassReg)) { /* begin ssAllocateRequiredReg:and: */ requiredReg1 = (topReg = SendNumArgsReg); - ssAllocateRequiredRegMaskupThroughupThroughNative((1U << requiredReg1) | (1U << ClassReg), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((((requiredReg1 < 0) ? (((usqInt)(1)) >> (-requiredReg1)) : (1U << requiredReg1))) | ((1U << ClassReg)), simStackPtr, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr, simNativeStackPtr); } ssPush(1); popToReg(ssTop(), topReg); @@ -34883,7 +35028,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean association = getLiteral(litVarIndex); voidReceiverResultRegContainsSelf(); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin genMoveConstant:R: */ if (shouldAnnotateObjectReference(association)) { annotateobjRef(checkLiteralforInstruction(association, genoperandoperand(MoveCwR, association, ReceiverResultReg)), association); @@ -34896,7 +35041,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean # if IMMUTABILITY if (needsImmCheck) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -34910,7 +35055,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -34971,7 +35116,7 @@ genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqI # endif // IMMUTABILITY ssPop(1); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ClassReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ssPush(1); genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); @@ -35016,7 +35161,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea # if IMMUTABILITY if (needsImmCheck1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -35030,7 +35175,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck1, 1); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck1); } @@ -35054,7 +35199,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt assert(needsFrame); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); /* begin MoveMw:r:R: */ offset = frameOffsetOfTemporary(remoteTempIndex); @@ -35064,7 +35209,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt # if IMMUTABILITY # endif - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -35250,13 +35395,13 @@ genVanillaInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -35510,12 +35655,12 @@ liveRegisters(void) } else { /* begin registerMaskFor: */ - regsSet = 1U << ReceiverResultReg; + regsSet = (1U << ReceiverResultReg); if ((methodOrBlockNumArgs <= 2 /* numRegArgs */) && (methodOrBlockNumArgs > 0)) { - regsSet = regsSet | (1U << Arg0Reg); + regsSet = regsSet | ((1U << Arg0Reg)); if (methodOrBlockNumArgs > 1) { - regsSet = regsSet | (1U << Arg1Reg); + regsSet = regsSet | ((1U << Arg1Reg)); } } } @@ -35618,13 +35763,13 @@ marshallSendArguments(sqInt numArgs) if (numArgs > 0) { if (numArgs > 1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 2, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 2, simNativeStackPtr); /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg1Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg1Reg), simStackPtr - 1, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 1, simNativeStackPtr); } } if (numArgs > 1) { diff --git a/spursistasrc/vm/cogitMIPSEL.c b/spursistasrc/vm/cogitMIPSEL.c deleted file mode 100644 index 5d92042d96..0000000000 --- a/spursistasrc/vm/cogitMIPSEL.c +++ /dev/null @@ -1,36395 +0,0 @@ -/* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 - from - SistaCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 - */ -static char __buildInfo[] = "SistaCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 " __DATE__ ; -char *__cogitBuildInfo = __buildInfo; - - - -#include "sqConfig.h" -#include -#include -#include -#include -#include "sqPlatformSpecific.h" -#include "sqMemoryAccess.h" -#include "sqCogStackAlignment.h" -#include "dispdbg.h" -#include "cogmethod.h" -#if COGMTVM -#include "cointerpmt.h" -#else -#include "cointerp.h" -#endif -#include "cogit.h" -#include - - -/*** Constants ***/ -#define A0 4 -#define A1 5 -#define A2 6 -#define A3 7 -#define ABICalleeSavedRegisterMask 0xFF0000 -#define ABICallerSavedRegisterMask 0x300FF00 -#define ABIResultReg 2 -#define ADDIU 9 -#define ADDU 33 -#define AddCheckOverflowCqR 162 -#define AddCheckOverflowRR 163 -#define AddCqR 106 -#define AddCqRR 123 -#define AddCwR 114 -#define AddRdRd 132 -#define AddRR 100 -#define AddRRR 126 -#define AlignmentNops 3 -#define AltBlockCreationBytecodeSize 3 -#define AltFirstSpecialSelector 96 -#define AltNumSpecialSelectors 32 -#define AND 36 -#define ANDI 12 -#define AndCqR 108 -#define AndCqRR 124 -#define AndCwR 116 -#define AndRR 102 -#define AnnotationShift 5 -#define Arg0Reg 17 -#define Arg1Reg 18 -#define ArithmeticShiftRightCqR 91 -#define ArithmeticShiftRightCqRR 128 -#define ArithmeticShiftRightRR 92 -#define AT 1 -#define BadRegisterSet 1 -#define BEQ 4 -#define BGEZ 1 -#define BGTZ 7 -#define BLEZ 6 -#define BLTZ 0 -#define BlockCreationBytecodeSize 4 -#define BNE 5 -#define BREAK 13 -#define BranchTemp 11 -#define BrEqualRR 167 -#define BrLongEqualRR 177 -#define BrLongNotEqualRR 178 -#define BrNotEqualRR 168 -#define BrSignedGreaterEqualRR 176 -#define BrSignedGreaterRR 175 -#define BrSignedLessEqualRR 174 -#define BrSignedLessRR 173 -#define BrUnsignedGreaterEqualRR 172 -#define BrUnsignedGreaterRR 171 -#define BrUnsignedLessEqualRR 170 -#define BrUnsignedLessRR 169 -#define BytecodeSetHasDirectedSuperSend 1 -#define Call 6 -#define CallerSavedRegisterMask 0x0 -#define CallFull 7 -#if !defined(CheckRememberedInTrampoline) /* Allow this to be overridden on the compiler command line */ -# define CheckRememberedInTrampoline 0 -#endif -#define ClassArray 7 -#define ClassArrayCompactIndex 51 -#define ClassBlockClosureCompactIndex 37 -#define ClassFloatCompactIndex 34 -#define ClassFullBlockClosureCompactIndex 38 -#define ClassLargePositiveIntegerCompactIndex 33 -#define ClassMethodContextCompactIndex 36 -#define ClassPointCompactIndex 54 -#define ClassReg 19 -#define ClosureFirstCopiedValueIndex 3 -#define ClosureIndex 4 -#define ClosureNumArgsIndex 2 -#define ClosureOuterContextIndex 0 -#define ClosureStartPCIndex 1 -#define ClzRR 157 -#define CMBlock 3 -#define CMClosedPIC 4 -#define CMFree 1 -#define CMMaxUsageCount 7 -#define CMMethod 2 -#define CMOpenPIC 5 -#define Cmp 8 -#define CmpC32R 113 -#define CmpCqR 105 -#define CmpCwR 112 -#define CmpRdRd 131 -#define CmpRR 99 -#define CompletePrimitive 4 -#define ConcreteVarBaseReg 22 -#define ConstZero 1 -#define ConvertRRd 145 -#define CounterBytes 4 -#define Debug DEBUGVM -#define DIV 26 -#define DisplacementMask 0x1F -#define DisplacementX2N 0 -#define DivRdRd 135 -#define DivRR 159 -#undef DPFPReg0 -#undef DPFPReg1 -#undef DPFPReg2 -#undef DPFPReg3 -#undef DPFPReg4 -#undef DPFPReg5 -#undef DPFPReg6 -#undef DPFPReg7 -#define EncounteredUnknownBytecode -6 -#undef Extra0Reg -#undef Extra2Reg -#define FastCPrimitiveUseCABIFlag 4 -#define Fill32 4 -#define FirstAnnotation 64 -#define FirstJump 12 -#define FirstSpecialSelector 176 -#define FoxCallerSavedIP 4 -#define FoxIFSavedIP -16 -#define FoxMethod -4 -#define FoxMFReceiver -12 -#define FoxSavedFP 0 -#define FoxThisContext -8 -#define FP 30 -#define FPReg 30 -#define FullClosureCompiledBlockIndex 1 -#define FullClosureFirstCopiedValueIndex 4 -#define FullClosureReceiverIndex 3 -#define GCModeBecome 8 -#define GCModeFull 1 -#define GCModeNewSpace 2 -#define HasBytecodePC 5 -#define HashMultiplyConstant 1664525 -#define HashMultiplyMask 0xFFFFFFF -#define HeaderIndex 0 -#define HintLoad 0 -#define HintStore 1 -#if !defined(IMMUTABILITY) /* Allow this to be overridden on the compiler command line */ -# define IMMUTABILITY 1 -#endif -#define InFullBlock 2 -#define InstanceSpecificationIndex 2 -#define InstructionPointerIndex 1 -#define InsufficientCodeSpace -2 -#define InVanillaBlock 1 -#define IsAbsPCReference 3 -#define IsAnnotationExtension 1 -#define IsDirectedSuperBindingSend 10 -#define IsDirectedSuperSend 9 -#define IsDisplacementX2N 0 -#define IsNSDynamicSuperSend null -#define IsNSSelfSend null -#define IsNSSendCall null -#define IsObjectReference 2 -#define IsRelativeCall 4 -#define IsSendCall 7 -#define IsSuperSend 8 -#define J 2 -#define JAL 3 -#define JALR 9 -#define JR 8 -#define Jump 16 -#define JumpAbove 33 -#define JumpAboveOrEqual 32 -#define JumpBelow 31 -#define JumpBelowOrEqual 34 -#define JumpCarry 25 -#define JumpFPEqual 35 -#define JumpFPGreater 39 -#define JumpFPGreaterOrEqual 40 -#define JumpFPLess 37 -#define JumpFPLessOrEqual 38 -#define JumpFPNotEqual 36 -#define JumpFPOrdered 41 -#define JumpFPUnordered 42 -#define JumpFull 12 -#define JumpGreater 29 -#define JumpGreaterOrEqual 28 -#define JumpLess 27 -#define JumpLessOrEqual 30 -#define JumpLong 13 -#define JumpLongNonZero 15 -#define JumpLongZero 14 -#define JumpNegative 19 -#define JumpNoCarry 26 -#define JumpNonNegative 20 -#define JumpNonZero 18 -#define JumpNoOverflow 22 -#define JumpOverflow 21 -#define JumpR 10 -#define JumpZero 17 -#define Label 1 -#define LargeContextSlots 62 -#define LastJump 42 -#define LB 32 -#define LBU 36 -#define LH 33 -#define LHU 37 -#define LinkReg 31 -#define Literal 2 -#define LoadEffectiveAddressMwrR 88 -#define LogicalShiftLeftCqR 95 -#define LogicalShiftLeftCqRR 129 -#define LogicalShiftLeftRR 96 -#define LogicalShiftRightCqR 93 -#define LogicalShiftRightCqRR 130 -#define LogicalShiftRightRR 94 -#define LowcodeVM 0 -#define LUI 15 -#define LW 35 -#define MapEnd 0 -#define MaxCompiledPrimitiveIndex 575 -#define MaxCounterValue 0xFFFF -#define MaxCPICCases 6 -#define MaxMethodSize 65535 -#define MaxNegativeErrorCode -8 -#define MaxStackAllocSize 1572864 -#define MaxStackCheckOffset 0xFFF -#define MaxX2NDisplacement 992 -#define MethodCacheClass 2 -#define MethodCacheMask 0xFFC -#define MethodCacheMethod 3 -#define MethodCacheSelector 1 -#define MethodIndex 3 -#define MethodTooBig -4 -#define MFHI 16 -#define MFLO 18 -#define MFMethodFlagHasContextFlag 1 -#define MFMethodFlagIsBlockFlag 2 -#define MoveA32R 45 -#define MoveAbR 48 -#define MoveAwR 44 -#define MoveC32R 71 -#define MoveCqR 69 -#define MoveCwR 70 -#define MoveHighR 161 -#define MoveLowR 160 -#define MoveM16rR 57 -#define MoveM64rRd 75 -#define MoveMbrR 65 -#define MoveMwrR 50 -#define MoveRA32 47 -#define MoveRAb 49 -#define MoveRAw 46 -#define MoveRdM64r 76 -#define MoveRdRd 74 -#define MoveRM16r 58 -#define MoveRMbr 66 -#define MoveRMwr 51 -#define MoveRR 43 -#define MoveRXbrR 68 -#define MoveRXwrR 53 -#define MoveXbrRR 67 -#define MoveXwrRR 52 -#define MULT 24 -#define MULTIPLEBYTECODESETS 1 -#define MulCheckOverflowRR 164 -#define MulRdRd 134 -#define MulRR 158 -#define NativePopR 84 -#define NativePushR 85 -#define NativeRetN 86 -#define NativeSPReg 29 -#define NeedsMergeFixupFlag 2 -#define NeedsNonMergeFixupFlag 1 -#define NegateR 89 -#define NewspeakVM 0 -#define Nop 5 -#define NoReg -1 -#define NotFullyInitialized -1 -#define NumObjRefsInRuntime 0 -#define NumOopsPerNSC 6 -#define NumSendTrampolines 4 -#define NumSpecialSelectors 32 -#define NumStoreTrampolines 5 -#define NumTrampolines (69 + (COGMTVM ? 1 : 0) + (IMMUTABILITY ? 5 : 0)) -#define OneInstruction 4 -#define OR 37 -#define ORI 13 -#define OrCqR 109 -#define OrCqRR 125 -#define OrCwR 117 -#define OrRR 103 -#define Overflow 8 -#define OverflowTemp1 9 -#define OverflowTemp2 10 -#undef PCReg -#define PopR 80 -#define PREF 51 -#define PrefetchAw 87 -#define PrimCallCollectsProfileSamples 8 -#define PrimCallDoNotJIT 16 -#define PrimCallMayEndureCodeCompaction 4 -#define PrimCallNeedsNewMethod 1 -#define PrimCallNeedsPrimitiveFunction 2 -#define PrimCallOnSmalltalkStack 64 -#define PrimCallOnSmalltalkStackAlign2x 128 -#define PrimErrBadArgument 3 -#define PrimErrNoMemory 9 -#define PrimNumberExternalCall 117 -#define PrimNumberFFICall 120 -#define PushCq 82 -#define PushCw 83 -#define PushR 81 -#define R0 0 -#define R28 28 -#define RA 31 -#define REGIMM 1 -#define ReceiverIndex 5 -#define ReceiverResultReg 16 -#define RetN 9 -#define RISCTempReg 1 -#define SB 40 -#define SelectorCannotInterpret 34 -#define SelectorDoesNotUnderstand 20 -#define SenderIndex 0 -#define SendNumArgsReg 20 -#define SH 41 -#define ShouldNotJIT -8 -#define SignExtend16RR 152 -#define SignExtend8RR 151 -#define SistaV1BytecodeSet 1 -#define SistaVM 1 -#define SLL 0 -#define SLLV 4 -#define SLT 42 -#define SLTI 10 -#define SLTIU 11 -#define SLTU 43 -#define SmallContextSlots 22 -#define SP 29 -#define SPECIAL 0 -#define SPReg 29 -#define SPURVM 1 -#define SqrtRd 136 -#define SRA 3 -#define SRAV 7 -#define SRL 2 -#define SRLV 6 -#define SSBaseOffset 1 -#define SSConstant 2 -#define SSRegister 3 -#define SSSpill 4 -#define StackPointerIndex 2 -#define Stop 11 -#define SUBU 35 -#define SubCheckOverflowCqR 165 -#define SubCheckOverflowRR 166 -#define SubCqR 107 -#define SubCwR 115 -#define SubRdRd 133 -#define SubRR 101 -#define SubRRR 127 -#define SW 43 -#define TargetReg 25 -#define TempReg 21 -#define TempVectReadBarrier 0 -#define TstCqR 110 -#define UnfailingPrimitive 3 -#define UnimplementedOperation 2 -#define UnimplementedPrimitive -7 -#define ValueIndex 1 -#define VarBaseReg 22 -#define XOR 38 -#define XORI 14 -#define XorCqR 111 -#define XorCwR 118 -#define XorRR 104 -#define YoungSelectorInPIC -5 -#define ZR 0 - -typedef struct _AbstractInstruction { - unsigned char opcode; - unsigned char machineCodeSize; - unsigned char maxSize; - unsigned char annotation; - unsigned int machineCode[7]; - usqInt operands[3]; - usqInt address; - struct _AbstractInstruction *dependent; - } AbstractInstruction; - -#define CogMIPSELCompiler AbstractInstruction -#define CogAbstractInstruction AbstractInstruction - - -typedef struct { - AbstractInstruction *fakeHeader; - AbstractInstruction *fillInstruction; - sqInt numArgs; - sqInt numCopied; - sqInt numInitialNils; - sqInt startpc; - AbstractInstruction *entryLabel; - AbstractInstruction *stackCheckLabel; - sqInt span; - sqInt hasInstVarRef; - } BlockStart; - -#define CogBlockStart BlockStart - - -typedef struct _BytecodeDescriptor { - sqInt (*generator)(void); - sqInt NoDbgRegParms (*spanFunction)(struct _BytecodeDescriptor *,sqInt,sqInt,sqInt); - sqInt NoDbgRegParms (*needsFrameFunction)(sqInt); - signed char stackDelta; - unsigned char opcode; - unsigned char numBytes; - unsigned isBranchTrue : 1; - unsigned isBranchFalse : 1; - unsigned isReturn : 1; - unsigned isBlockCreation : 1; - unsigned isMapped : 1; - unsigned isMappedInBlock : 1; - unsigned isExtension : 1; - unsigned isInstVarRef : 1; - unsigned is1ByteInstVarStore : 1; - unsigned hasUnsafeJump : 1; - } BytecodeDescriptor; - -#define CogBytecodeDescriptor BytecodeDescriptor - - -typedef struct { - sqInt (*primitiveGenerator)(void); - sqInt primNumArgs; - } PrimitiveDescriptor; - -#define CogPrimitiveDescriptor PrimitiveDescriptor - - -typedef struct { - char type; - char spilled; - signed char liveRegister; - signed char registerr; - sqInt offset; - sqInt constant; - sqInt bcptr; - } SimStackEntry; - -#define CogSimStackEntry SimStackEntry - - -typedef struct { - AbstractInstruction *targetInstruction; - unsigned char simStackPtr; - char isTargetOfBackwardBranch; - unsigned short instructionIndex; -#if LowcodeVM - short simNativeStackPtr; - unsigned short simNativeStackSize; -#endif - } BytecodeFixup; - -#define CogSSBytecodeFixup BytecodeFixup -#define CogBytecodeFixup BytecodeFixup - - -typedef struct { - sqInt isReceiverResultRegLive; - CogSimStackEntry *ssEntry; - } CogSSOptStatus; - - - -/*** Function Prototypes ***/ - - -#if !PRODUCTION && defined(PlatformNoDbgRegParms) -# define NoDbgRegParms PlatformNoDbgRegParms -#endif - -#if !defined(NoDbgRegParms) -# define NoDbgRegParms /*empty*/ -#endif - - - -#if !defined(NeverInline) -# define NeverInline /*empty*/ -#endif - -static AbstractInstruction * NoDbgRegParms addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *anInstruction); -static sqInt NoDbgRegParms availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask); -static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask); -static void NoDbgRegParms cloneLiteralFrom(AbstractInstruction * self_in_cloneLiteralFrom, AbstractInstruction *existingLiteral); -static sqInt NoDbgRegParms genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer); -static sqInt NoDbgRegParms genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers); -static sqInt NoDbgRegParms genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers); -static sqInt NoDbgRegParms genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg); -static sqInt NoDbgRegParms genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers); -static AbstractInstruction * NoDbgRegParms genSwapRRScratch(AbstractInstruction * self_in_genSwapRRScratch, sqInt regA, sqInt regB, sqInt regTmp); -static void NoDbgRegParms genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister); -static void NoDbgRegParms initializeSharableLiteral(AbstractInstruction * self_in_initializeSharableLiteral, sqInt literal); -static void NoDbgRegParms initializeUniqueLiteral(AbstractInstruction * self_in_initializeUniqueLiteral, sqInt literal); -static sqInt NoDbgRegParms isWithinMwOffsetRange(AbstractInstruction * self_in_isWithinMwOffsetRange, sqInt anAddress); -static AbstractInstruction * NoDbgRegParms jmpTarget(AbstractInstruction * self_in_jmpTarget, AbstractInstruction *anAbstractInstruction); -static void NoDbgRegParms resolveJumpTarget(AbstractInstruction * self_in_resolveJumpTarget); -static sqInt NoDbgRegParms rewriteCallFullAttarget(AbstractInstruction * self_in_rewriteCallFullAttarget, sqInt callSiteReturnAddress, sqInt callTargetAddress); -static sqInt NoDbgRegParms rewriteJumpFullAttarget(AbstractInstruction * self_in_rewriteJumpFullAttarget, sqInt callSiteReturnAddress, sqInt callTargetAddress); -static CogMethod * NoDbgRegParms cmHomeMethod(CogBlockMethod * self_in_cmHomeMethod); -static sqInt NoDbgRegParms isBranch(BytecodeDescriptor * self_in_isBranch); -static AbstractInstruction * NoDbgRegParms gAddCqR(sqInt quickConstant, sqInt reg); -static AbstractInstruction * NoDbgRegParms gAddCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); -static AbstractInstruction * NoDbgRegParms gAndCqR(sqInt quickConstant, sqInt reg); -static AbstractInstruction * NoDbgRegParms gAndCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); -static AbstractInstruction * NoDbgRegParms gArithmeticShiftRightCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); -extern sqInt abortOffset(void); -static void addCleanBlockStarts(void); -extern void addCogMethodsToHeapMap(void); -static sqInt NoDbgRegParms addressIsInCurrentCompilation(sqInt address); -static sqInt NoDbgRegParms addressIsInFixups(BytecodeFixup *address); -static sqInt NoDbgRegParms addressOfEndOfCaseinCPIC(sqInt n, CogMethod *cPIC); -static void alignMethodZoneBase(void); -static sqInt NoDbgRegParms alignUptoRoutineBoundary(sqInt anAddress); -static sqInt allMachineCodeObjectReferencesValid(void); -static sqInt allMethodsHaveCorrectHeader(void); -static AbstractInstruction * NoDbgRegParms annotateAbsolutePCRef(AbstractInstruction *abstractInstruction); -static AbstractInstruction * NoDbgRegParms annotateBytecode(AbstractInstruction *abstractInstruction); -static AbstractInstruction * NoDbgRegParms annotateobjRef(AbstractInstruction *abstractInstruction, sqInt anOop); -static void NoDbgRegParms assertSaneJumpTarget(AbstractInstruction *jumpTarget); -static void assertValidDualZone(void); -static sqInt NoDbgRegParms availableRegisterOrNoneIn(sqInt liveRegsMask); -static sqInt NoDbgRegParms blockDispatchTargetsForperformarg(CogMethod *cogMethod, usqInt (*binaryFunction)(sqInt mcpc, sqInt arg), sqInt arg); -extern sqInt bytecodePCForstartBcpcin(sqInt mcpc, sqInt startbcpc, CogBlockMethod *cogMethod); -static AbstractInstruction * NoDbgRegParms CallRTregistersToBeSavedMask(sqInt callTarget, sqInt registersToBeSaved); -static AbstractInstruction * NoDbgRegParms gCall(sqInt callTarget); -static AbstractInstruction * NoDbgRegParms gCmpCqR(sqInt quickConstant, sqInt reg); -extern void callCogCodePopReceiver(void); -extern void callCogCodePopReceiverAndClassRegs(void); -static sqInt NoDbgRegParms ceCPICMissreceiver(CogMethod *cPIC, sqInt receiver); -extern void ceFree(void *pointer); -static void* NoDbgRegParms ceMalloc(size_t size); -static sqInt NoDbgRegParms ceSICMiss(sqInt receiver); -static sqInt NoDbgRegParms checkIfValidOopRefAndTargetpccogMethod(sqInt annotation, char *mcpc, CogMethod *cogMethod); -static sqInt NoDbgRegParms checkIfValidOopRefpccogMethod(sqInt annotation, char *mcpc, CogMethod *cogMethod); -extern sqInt checkIntegrityOfObjectReferencesInCode(sqInt gcModes); -static sqInt NoDbgRegParms checkMaybeObjRefInClosedPIC(sqInt maybeObject); -static sqInt NoDbgRegParms checkValidObjectReferencesInClosedPIC(CogMethod *cPIC); -static sqInt NoDbgRegParms NeverInline cleanUpFailingCogCodeConstituents(CogMethod *cogMethodArg); -static sqInt NoDbgRegParms closedPICRefersToUnmarkedObject(CogMethod *cPIC); -extern char * codeEntryFor(char *address); -extern char * codeEntryNameFor(char *address); -extern sqInt cogCodeBase(void); -extern sqInt cogCodeConstituents(sqInt withDetails); -static void NoDbgRegParms cogExtendPICCaseNMethodtagisMNUCase(CogMethod *cPIC, sqInt caseNMethod, sqInt caseNTag, sqInt isMNUCase); -extern CogMethod * cogFullBlockMethodnumCopied(sqInt aMethodObj, sqInt numCopied); -extern void cogitPostGCAction(sqInt gcMode); -extern sqInt cogMethodDoesntLookKosher(CogMethod *cogMethod); -extern CogMethod * cogMNUPICSelectorreceivermethodOperandnumArgs(sqInt selector, sqInt rcvr, sqInt methodOperand, sqInt numArgs); -static CogMethod * NoDbgRegParms cogOpenPICSelectornumArgs(sqInt selector, sqInt numArgs); -static CogMethod * NoDbgRegParms cogPICSelectornumArgsCase0MethodCase1MethodtagisMNUCase(sqInt selector, sqInt numArgs, CogMethod *case0CogMethod, sqInt case1MethodOrNil, sqInt case1Tag, sqInt isMNUCase); -extern CogMethod * cogselector(sqInt aMethodObj, sqInt aSelectorOop); -static sqInt NoDbgRegParms collectCogConstituentForAnnotationMcpcBcpcMethod(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *cogMethodArg); -static sqInt NoDbgRegParms collectCogMethodConstituent(CogMethod *cogMethod); -extern void compactCogCompiledCode(void); -static void compactPICsWithFreedTargets(void); -static AbstractInstruction * compileAbort(void); -static sqInt NoDbgRegParms compileBlockDispatchFromto(sqInt lowBlockStartIndex, sqInt highBlockStartIndex); -static void NoDbgRegParms compileBlockEntry(BlockStart *blockStart); -static void NoDbgRegParms compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt resultRegOrNone, sqInt regMask); -static AbstractInstruction * compileCPICEntry(void); -static sqInt NoDbgRegParms compileEntireFullBlockMethod(sqInt numCopied); -static void compileEntry(void); -static sqInt compileFullBlockEntry(void); -static sqInt compileMethodBody(void); -static sqInt NoDbgRegParms compilePICAbort(sqInt numArgs); -static AbstractInstruction * NoDbgRegParms compileStackOverflowCheck(sqInt canContextSwitch); -static void NoDbgRegParms compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone); -static void computeEntryOffsets(void); -static void computeFullBlockEntryOffsets(void); -static usqInt computeGoodVarBaseAddress(void); -static void computeMaximumSizes(void); -static sqInt NoDbgRegParms configureCPICCase0Case1MethodtagisMNUCasenumArgsdelta(CogMethod *cPIC, CogMethod *case0CogMethod, sqInt case1Method, sqInt case1Tag, sqInt isMNUCase, sqInt numArgs, sqInt addrDelta); -static sqInt NoDbgRegParms configureMNUCPICmethodOperandnumArgsdelta(CogMethod *cPIC, sqInt methodOperand, sqInt numArgs, sqInt addrDelta); -static sqInt NoDbgRegParms cPICCompactAndIsNowEmpty(CogMethod *cPIC); -static sqInt NoDbgRegParms cPICHasForwardedClass(CogMethod *cPIC); -static sqInt NoDbgRegParms cPICHasFreedTargets(CogMethod *cPIC); -static usqInt cPICPrototypeCaseOffset(void); -static sqInt NoDbgRegParms cPICHasTarget(CogMethod *cPIC, CogMethod *targetMethod); -static sqInt NoDbgRegParms createCPICData(CogMethod *cPIC); -static AbstractInstruction * NoDbgRegParms gDivRRQuoRem(sqInt rDivisor, sqInt rDividend, sqInt rQuotient, sqInt rRemainder); -static sqInt NoDbgRegParms deltaToSkipPrimAndErrorStoreInheader(sqInt aMethodObj, sqInt aMethodHeader); -static sqInt NoDbgRegParms endPCOf(sqInt aMethod); -extern void enterCogCodePopReceiver(void); -static sqInt NoDbgRegParms entryPointTagIsSelector(sqInt entryPoint); -static sqInt NoDbgRegParms expectedClosedPICPrototype(CogMethod *cPIC); -static sqInt extABytecode(void); -static sqInt extBBytecode(void); -static sqInt NoDbgRegParms fillInBlockHeadersAt(sqInt startAddress); -static sqInt NoDbgRegParms findBackwardBranchIsBackwardBranchMcpcBcpcMatchingBcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *targetBcpc); -static usqInt NoDbgRegParms findBlockMethodWithEntrystartBcpc(sqInt blockEntryMcpc, sqInt startBcpc); -static usqInt NoDbgRegParms findMapLocationForMcpcinMethod(usqInt targetMcpc, CogMethod *cogMethod); -extern CogBlockMethod * findMethodForStartBcpcinHomeMethod(sqInt startbcpc, CogMethod *cogMethod); -static sqInt NoDbgRegParms findIsBackwardBranchMcpcBcpcMatchingMcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *targetMcpc); -static sqInt NoDbgRegParms firstMappedPCFor(CogMethod *cogMethod); -static sqInt firstPrototypeMethodOop(void); -static BytecodeFixup * NoDbgRegParms fixupAt(sqInt fixupPC); -extern void followForwardedLiteralsIn(CogMethod *cogMethod); -extern void followForwardedMethods(void); -static sqInt NoDbgRegParms followMaybeObjRefInClosedPICAt(sqInt mcpc); -static sqInt NoDbgRegParms followMethodReferencesInClosedPIC(CogMethod *cPIC); -extern void followMovableLiteralsAndUpdateYoungReferrers(void); -extern void freeCogMethod(CogMethod *cogMethod); -extern void freeUnmarkedMachineCode(void); -static AbstractInstruction * NoDbgRegParms genCallMustBeBooleanFor(sqInt boolean); -static AbstractInstruction * NoDbgRegParms genConditionalBranchoperand(sqInt opcode, sqInt operandOne); -static void (*genEnilopmartForandandforCallcalled(sqInt regArg1, sqInt regArg2OrNone, sqInt regArg3OrNone, sqInt forCall, char *trampolineName))(void) ; -static void NoDbgRegParms genEnilopmartReturn(sqInt forCall); -static void NoDbgRegParms NeverInline generateCaptureCStackPointers(sqInt captureFramePointer); -static void generateClosedPICPrototype(void); -static CogMethod * generateCogFullBlock(void); -static CogMethod * NoDbgRegParms generateCogMethod(sqInt selector); -static sqInt NoDbgRegParms generateMapAtstart(usqInt addressOrNull, usqInt startAddress); -static void generateOpenPICPrototype(void); -static void generateRunTimeTrampolines(void); -static void generateStackPointerCapture(void); -static void generateTrampolines(void); -static BytecodeDescriptor * NoDbgRegParms generatorForPC(sqInt pc); -static void genGetLeafCallStackPointers(void); -static usqInt NoDbgRegParms genInnerPICAbortTrampoline(char *name); -static void (*genInvokeInterpretTrampoline(void))(void) ; -static void NoDbgRegParms genLoadInlineCacheWithSelector(sqInt selectorIndex); -static usqInt genReturnToInterpreterTrampoline(void); -static sqInt NoDbgRegParms genSmalltalkToCStackSwitch(sqInt pushLinkReg); -static usqInt NoDbgRegParms genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(void *aRoutine, char *trampolineName, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone, sqInt appendBoolean); -static void NoDbgRegParms genTrampolineReturn(sqInt lnkRegWasPushed); -static AbstractInstruction * NoDbgRegParms gen(sqInt opcode); -static AbstractInstruction * NoDbgRegParms genoperand(sqInt opcode, sqInt operand); -static AbstractInstruction * NoDbgRegParms genoperandoperand(sqInt opcode, sqInt operandOne, sqInt operandTwo); -static AbstractInstruction * NoDbgRegParms genoperandoperandoperand(sqInt opcode, sqInt operandOne, sqInt operandTwo, sqInt operandThree); -static sqInt NoDbgRegParms getLiteral(sqInt litIndex); -static sqInt NoDbgRegParms incrementUsageOfTargetIfLinkedSendmcpcignored(sqInt annotation, char *mcpc, sqInt superfluity); -static sqInt initialClosedPICUsageCount(void); -static void initializeBackend(void); -static sqInt initialMethodUsageCount(void); -static sqInt initialOpenPICUsageCount(void); -static sqInt NoDbgRegParms inverseBranchFor(sqInt opcode); -static sqInt NoDbgRegParms isPCMappedAnnotation(sqInt annotation); -extern sqInt isPCWithinMethodZone(void *address); -extern sqInt isSendReturnPC(sqInt retpc); -static AbstractInstruction * NoDbgRegParms gJumpFPEqual(void *jumpTarget); -static AbstractInstruction * NoDbgRegParms gJumpFPGreaterOrEqual(void *jumpTarget); -static AbstractInstruction * NoDbgRegParms gJumpFPGreater(void *jumpTarget); -static AbstractInstruction * NoDbgRegParms gJumpFPNotEqual(void *jumpTarget); -static AbstractInstruction * NoDbgRegParms gLogicalShiftLeftCqR(sqInt quickConstant, sqInt reg); -static AbstractInstruction * NoDbgRegParms gLogicalShiftLeftCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); -static AbstractInstruction * NoDbgRegParms gLogicalShiftRightCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); -static AbstractInstruction * lastOpcode(void); -extern void linkSendAtintooffsetreceiver(sqInt callSiteReturnAddress, CogMethod *sendingMethod, CogMethod *targetMethod, sqInt theEntryOffset, sqInt receiver); -static BytecodeDescriptor * loadBytesAndGetDescriptor(void); -static void NoDbgRegParms loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc); -static AbstractInstruction * NoDbgRegParms gMoveCwR(sqInt wordConstant, sqInt reg); -static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); -static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg); -static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC); -static void mapObjectReferencesInGeneratedRuntime(void); -static void mapObjectReferencesInMachineCodeForBecome(void); -static void mapObjectReferencesInMachineCodeForFullGC(void); -static void mapObjectReferencesInMachineCodeForYoungGC(void); -extern void mapObjectReferencesInMachineCode(sqInt gcMode); -extern void markAndTraceMachineCodeOfMarkedMethods(void); -static void markAndTraceObjectReferencesInGeneratedRuntime(void); -static sqInt NoDbgRegParms markAndTraceOrFreeCogMethodfirstVisit(CogMethod *cogMethod, sqInt firstVisit); -static sqInt NoDbgRegParms markAndTraceOrFreePICTargetin(sqInt entryPoint, CogMethod *cPIC); -static sqInt NoDbgRegParms markLiteralsAndUnlinkIfUnmarkedSendpcmethod(sqInt annotation, char *mcpc, sqInt cogMethod); -static sqInt NoDbgRegParms markLiteralspcmethod(sqInt annotation, char *mcpc, CogMethod *cogMethod); -extern void markMethodAndReferents(CogBlockMethod *aCogMethod); -extern usqInt maxCogMethodAddress(void); -static sqInt maybeAllocAndInitIRCs(void); -static sqInt NoDbgRegParms maybeFreeCogMethodDoesntLookKosher(CogMethod *cogMethod); -static sqInt mclassIsSmallInteger(void); -extern usqInt mcPCForBackwardBranchstartBcpcin(sqInt bcpc, sqInt startbcpc, CogBlockMethod *cogMethod); -static sqInt NoDbgRegParms methodhasSameCodeAscheckPenultimate(sqInt methodA, sqInt methodB, sqInt comparePenultimateLiteral); -extern sqInt mnuOffset(void); -static AbstractInstruction * NoDbgRegParms gNativePopR(sqInt reg); -static AbstractInstruction * NoDbgRegParms gNativePushR(sqInt reg); -static AbstractInstruction * NoDbgRegParms gNativeRetN(sqInt offset); -static sqInt NoDbgRegParms needsFrameIfImmutability(sqInt stackDelta); -static sqInt NoDbgRegParms needsFrameIfInBlock(sqInt stackDelta); -static sqInt NoDbgRegParms needsFrameNever(sqInt stackDelta); -static sqInt NoDbgRegParms noAssertMethodClassAssociationOf(sqInt methodPointer); -static sqInt noCogMethodsMaximallyMarked(void); -static sqInt NoDbgRegParms noTargetsFreeInClosedPIC(CogMethod *cPIC); -static AbstractInstruction * NoDbgRegParms gOrCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); -static sqInt NoDbgRegParms outputInstructionsAt(sqInt startAddress); -static sqInt NoDbgRegParms outputInstructionsForGeneratedRuntimeAt(sqInt startAddress); -static AbstractInstruction * NoDbgRegParms gPushCw(sqInt wordConstant); -extern sqInt patchToOpenPICFornumArgsreceiver(sqInt selector, sqInt numArgs, sqInt receiver); -static sqInt picAbortDiscriminatorValue(void); -static sqInt picInterpretAbortOffset(void); -static AbstractInstruction * previousInstruction(void); -extern void printCogMethodFor(void *address); -extern void printTrampolineTable(void); -static sqInt processorHasDivQuoRemAndMClassIsSmallInteger(void); -static sqInt processorHasDoublePrecisionFloatingPointSupport(void); -static sqInt processorHasMultiplyAndMClassIsSmallInteger(void); -static void NoDbgRegParms recordGeneratedRunTimeaddress(char *aString, sqInt address); -extern sqInt recordPrimTraceFunc(void); -static void recordRunTimeObjectReferences(void); -static sqInt NoDbgRegParms registerMaskFor(sqInt reg); -static sqInt NoDbgRegParms registerMaskForandand(sqInt reg1, sqInt reg2, sqInt reg3); -static void NoDbgRegParms relocateCallsAndSelfReferencesInMethod(CogMethod *cogMethod); -static void NoDbgRegParms relocateCallsInClosedPIC(CogMethod *cPIC); -static sqInt NoDbgRegParms relocateIfCallOrMethodReferencemcpcdelta(sqInt annotation, char *mcpc, CogMethod *refDeltaArg); -static sqInt NoDbgRegParms remapIfObjectRefpchasYoung(sqInt annotation, char *mcpc, CogMethod *hasYoungPtr); -static sqInt NoDbgRegParms remapMaybeObjRefInClosedPICAt(sqInt mcpc); -static void NoDbgRegParms rewriteCPICCaseAttagobjReftarget(sqInt followingAddress, sqInt newTag, sqInt newObjRef, sqInt newTarget); -static AbstractInstruction * NoDbgRegParms gSubRRR(sqInt subReg, sqInt fromReg, sqInt destReg); -static sqInt scanForCleanBlocks(void); -extern void setBreakMethod(sqInt anObj); -extern void setSelectorOfto(CogMethod *cogMethod, sqInt aSelectorOop); -static sqInt NoDbgRegParms spanForCleanBlockStartingAt(sqInt startPC); -static usqInt NoDbgRegParms stackCheckOffsetOfBlockAtisMcpc(sqInt blockEntryMcpc, sqInt mcpc); -static sqInt subsequentPrototypeMethodOop(void); -extern sqInt traceLinkedSendOffset(void); -static sqInt NoDbgRegParms trampolineArgConstant(sqInt booleanOrInteger); -static char * NoDbgRegParms trampolineNamenumArgs(char *routinePrefix, sqInt numArgs); -static char * NoDbgRegParms trampolineNamenumArgslimit(char *routinePrefix, int numArgs, sqInt argsLimit); -static char * NoDbgRegParms trampolineNamenumRegArgs(char *routinePrefix, sqInt numArgs); -static sqInt unknownBytecode(void); -extern void unlinkAllSends(void); -static sqInt NoDbgRegParms unlinkIfFreeOrLinkedSendpcof(sqInt annotation, char *mcpc, CogMethod *theSelector); -static sqInt NoDbgRegParms unlinkIfInvalidClassSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity); -static sqInt NoDbgRegParms unlinkIfLinkedSendToFreepcignored(sqInt annotation, char *mcpc, sqInt superfluity); -static sqInt NoDbgRegParms unlinkIfLinkedSendpcif(sqInt annotation, char *mcpc, CogMethod *criterionArg); -static sqInt NoDbgRegParms unlinkIfLinkedSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity); -static sqInt NoDbgRegParms unlinkIfLinkedSendpcto(sqInt annotation, char *mcpc, sqInt theCogMethod); -extern void unlinkSendsLinkedForInvalidClasses(void); -extern void unlinkSendsOfisMNUSelector(sqInt selector, sqInt isMNUSelector); -extern void unlinkSendsToFree(void); -extern void unlinkSendsToMethodsSuchThatAndFreeIf(sqInt (*criterion)(CogMethod *), sqInt freeIfTrue); -extern void unlinkSendsToandFreeIf(sqInt targetMethodObject, sqInt freeIfTrue); -extern void voidCogCompiledCode(void); -static void zeroOpcodeIndex(void); -static void zeroOpcodeIndexForNewOpcodes(void); -static void NoDbgRegParms addToOpenPICList(CogMethod *anOpenPIC); -static void NoDbgRegParms addToYoungReferrers(CogMethod *cogMethod); -static usqInt NoDbgRegParms allocate(sqInt numBytes); -extern CogMethod * cogMethodContaining(usqInt mcpc); -static void compactCompiledCode(void); -static void NoDbgRegParms ensureInYoungReferrers(CogMethod *cogMethod); -static void followForwardedLiteralsInOpenPICList(void); -static void NoDbgRegParms freeMethod(CogMethod *cogMethod); -static void freeOlderMethodsForCompaction(void); -extern sqInt kosherYoungReferrers(void); -static sqInt NoDbgRegParms mcpcisAtStackCheckOfBlockMethodIn(sqInt mcpc, CogMethod *cogMethod); -extern CogMethod * methodFor(void *address); -extern sqInt methodsCompiledToMachineCodeInto(sqInt arrayObj); -extern sqInt numMethods(void); -extern sqInt numMethodsOfType(sqInt cogMethodType); -static sqInt NoDbgRegParms occurrencesInYoungReferrers(CogMethod *cogMethod); -static CogMethod * NoDbgRegParms openPICWithSelector(sqInt aSelector); -static void planCompaction(void); -extern void printCogMethods(void); -extern void printCogMethodsOfType(sqInt cmType); -extern void printCogMethodsWithMethod(sqInt methodOop); -extern void printCogMethodsWithPrimitive(sqInt primIdx); -extern void printCogMethodsWithSelector(sqInt selectorOop); -extern void printCogYoungReferrers(void); -extern sqInt printOpenPICList(void); -extern sqInt pruneYoungReferrers(void); -static sqInt relocateAndPruneYoungReferrers(void); -static sqInt relocateMethodsPreCompaction(void); -static sqInt NoDbgRegParms removeFromOpenPICList(CogMethod *anOpenPIC); -static void NoDbgRegParms restorePICUsageCount(CogMethod *cogMethod); -static sqInt NoDbgRegParms roundUpLength(sqInt numBytes); -static void NoDbgRegParms savePICUsageCount(CogMethod *cogMethod); -static void voidOpenPICList(void); -static void voidUnpairedMethodList(void); -static void voidYoungReferrersPostTenureAll(void); -EXPORT(char *) whereIsMaybeCodeThing(sqInt anOop); -static sqInt NoDbgRegParms addiuRRC(AbstractInstruction * self_in_addiuRRC, sqInt destReg, sqInt srcReg, sqInt imm); -static sqInt NoDbgRegParms adduRRR(AbstractInstruction * self_in_adduRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms andiRRC(AbstractInstruction * self_in_andiRRC, sqInt destReg, sqInt srcReg, sqInt imm); -static sqInt NoDbgRegParms andRRR(AbstractInstruction * self_in_andRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms beqRRoffset(AbstractInstruction * self_in_beqRRoffset, sqInt leftReg, sqInt rightReg, sqInt offset); -static sqInt NoDbgRegParms bgezRoffset(AbstractInstruction * self_in_bgezRoffset, sqInt cmpReg, sqInt offset); -static sqInt NoDbgRegParms bgtzRoffset(AbstractInstruction * self_in_bgtzRoffset, sqInt cmpReg, sqInt offset); -static sqInt NoDbgRegParms blezRoffset(AbstractInstruction * self_in_blezRoffset, sqInt cmpReg, sqInt offset); -static sqInt NoDbgRegParms bltzRoffset(AbstractInstruction * self_in_bltzRoffset, sqInt cmpReg, sqInt offset); -static sqInt NoDbgRegParms bneRRoffset(AbstractInstruction * self_in_bneRRoffset, sqInt leftReg, sqInt rightReg, sqInt offset); -static sqInt NoDbgRegParms callInstructionByteSize(AbstractInstruction * self_in_callInstructionByteSize); -static usqInt NoDbgRegParms callTargetFromReturnAddress(AbstractInstruction * self_in_callTargetFromReturnAddress, sqInt callSiteReturnAddress); -static sqInt NoDbgRegParms canDivQuoRem(AbstractInstruction * self_in_canDivQuoRem); -static sqInt NoDbgRegParms clzRRR(AbstractInstruction * self_in_clzRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms cmpC32RTempByteSize(AbstractInstruction * self_in_cmpC32RTempByteSize); -static sqInt NoDbgRegParms computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize); -static sqInt NoDbgRegParms concretizeAddCheckOverflowCqR(AbstractInstruction * self_in_concretizeAddCheckOverflowCqR); -static sqInt NoDbgRegParms concretizeAddCheckOverflowRR(AbstractInstruction * self_in_concretizeAddCheckOverflowRR); -static sqInt NoDbgRegParms concretizeAddCqR(AbstractInstruction * self_in_concretizeAddCqR); -static sqInt NoDbgRegParms concretizeAddCwR(AbstractInstruction * self_in_concretizeAddCwR); -static sqInt NoDbgRegParms concretizeAddRRDest(AbstractInstruction * self_in_concretizeAddRRDest, sqInt destReg); -static usqInt NoDbgRegParms concretizeAlignmentNops(AbstractInstruction * self_in_concretizeAlignmentNops); -static sqInt NoDbgRegParms concretizeAndCqR(AbstractInstruction * self_in_concretizeAndCqR); -static sqInt NoDbgRegParms concretizeAndCqRDest(AbstractInstruction * self_in_concretizeAndCqRDest, sqInt destReg); -static sqInt NoDbgRegParms concretizeAndCwR(AbstractInstruction * self_in_concretizeAndCwR); -static sqInt NoDbgRegParms concretizeAndRR(AbstractInstruction * self_in_concretizeAndRR); -static sqInt NoDbgRegParms concretizeArithmeticShiftRightCqR(AbstractInstruction * self_in_concretizeArithmeticShiftRightCqR); -static sqInt NoDbgRegParms concretizeArithmeticShiftRightRR(AbstractInstruction * self_in_concretizeArithmeticShiftRightRR); -static sqInt NoDbgRegParms concretizeAt(AbstractInstruction * self_in_concretizeAt, sqInt actualAddress); -static sqInt NoDbgRegParms concretizeBrEqualRR(AbstractInstruction * self_in_concretizeBrEqualRR); -static sqInt NoDbgRegParms concretizeBrLongEqualRR(AbstractInstruction * self_in_concretizeBrLongEqualRR); -static sqInt NoDbgRegParms concretizeBrLongNotEqualRR(AbstractInstruction * self_in_concretizeBrLongNotEqualRR); -static sqInt NoDbgRegParms concretizeBrNotEqualRR(AbstractInstruction * self_in_concretizeBrNotEqualRR); -static sqInt NoDbgRegParms concretizeBrSignedGreaterEqualRR(AbstractInstruction * self_in_concretizeBrSignedGreaterEqualRR); -static sqInt NoDbgRegParms concretizeBrSignedGreaterRR(AbstractInstruction * self_in_concretizeBrSignedGreaterRR); -static sqInt NoDbgRegParms concretizeBrSignedLessEqualRR(AbstractInstruction * self_in_concretizeBrSignedLessEqualRR); -static sqInt NoDbgRegParms concretizeBrSignedLessRR(AbstractInstruction * self_in_concretizeBrSignedLessRR); -static sqInt NoDbgRegParms concretizeBrUnsignedGreaterEqualRR(AbstractInstruction * self_in_concretizeBrUnsignedGreaterEqualRR); -static sqInt NoDbgRegParms concretizeBrUnsignedGreaterRR(AbstractInstruction * self_in_concretizeBrUnsignedGreaterRR); -static sqInt NoDbgRegParms concretizeBrUnsignedLessEqualRR(AbstractInstruction * self_in_concretizeBrUnsignedLessEqualRR); -static sqInt NoDbgRegParms concretizeBrUnsignedLessRR(AbstractInstruction * self_in_concretizeBrUnsignedLessRR); -static sqInt NoDbgRegParms concretizeCall(AbstractInstruction * self_in_concretizeCall); -static sqInt NoDbgRegParms concretizeCallFull(AbstractInstruction * self_in_concretizeCallFull); -static sqInt NoDbgRegParms concretizeClzRR(AbstractInstruction * self_in_concretizeClzRR); -static sqInt NoDbgRegParms concretizeCmpCqR(AbstractInstruction * self_in_concretizeCmpCqR); -static sqInt NoDbgRegParms concretizeCmpCwR(AbstractInstruction * self_in_concretizeCmpCwR); -static sqInt NoDbgRegParms concretizeCmpRR(AbstractInstruction * self_in_concretizeCmpRR); -static sqInt NoDbgRegParms concretizeDivRR(AbstractInstruction * self_in_concretizeDivRR); -static sqInt NoDbgRegParms concretizeFill32(AbstractInstruction * self_in_concretizeFill32); -static sqInt NoDbgRegParms concretizeJump(AbstractInstruction * self_in_concretizeJump); -static sqInt NoDbgRegParms concretizeJumpFull(AbstractInstruction * self_in_concretizeJumpFull); -static sqInt NoDbgRegParms concretizeJumpLong(AbstractInstruction * self_in_concretizeJumpLong); -static sqInt NoDbgRegParms concretizeJumpLongNonZero(AbstractInstruction * self_in_concretizeJumpLongNonZero); -static sqInt NoDbgRegParms concretizeJumpLongZero(AbstractInstruction * self_in_concretizeJumpLongZero); -static sqInt NoDbgRegParms concretizeJumpNonZero(AbstractInstruction * self_in_concretizeJumpNonZero); -static sqInt NoDbgRegParms concretizeJumpNoOverflow(AbstractInstruction * self_in_concretizeJumpNoOverflow); -static sqInt NoDbgRegParms concretizeJumpOverflow(AbstractInstruction * self_in_concretizeJumpOverflow); -static sqInt NoDbgRegParms concretizeJumpR(AbstractInstruction * self_in_concretizeJumpR); -static sqInt NoDbgRegParms concretizeJumpSignedGreaterEqual(AbstractInstruction * self_in_concretizeJumpSignedGreaterEqual); -static sqInt NoDbgRegParms concretizeJumpSignedGreaterThan(AbstractInstruction * self_in_concretizeJumpSignedGreaterThan); -static sqInt NoDbgRegParms concretizeJumpSignedLessEqual(AbstractInstruction * self_in_concretizeJumpSignedLessEqual); -static sqInt NoDbgRegParms concretizeJumpSignedLessThan(AbstractInstruction * self_in_concretizeJumpSignedLessThan); -static sqInt NoDbgRegParms concretizeJumpUnsignedGreaterEqual(AbstractInstruction * self_in_concretizeJumpUnsignedGreaterEqual); -static sqInt NoDbgRegParms concretizeJumpUnsignedGreaterThan(AbstractInstruction * self_in_concretizeJumpUnsignedGreaterThan); -static sqInt NoDbgRegParms concretizeJumpUnsignedLessEqual(AbstractInstruction * self_in_concretizeJumpUnsignedLessEqual); -static sqInt NoDbgRegParms concretizeJumpUnsignedLessThan(AbstractInstruction * self_in_concretizeJumpUnsignedLessThan); -static sqInt NoDbgRegParms concretizeJumpZero(AbstractInstruction * self_in_concretizeJumpZero); -static sqInt NoDbgRegParms concretizeLoadEffectiveAddressMwrR(AbstractInstruction * self_in_concretizeLoadEffectiveAddressMwrR); -static sqInt NoDbgRegParms concretizeLogicalShiftLeftCqR(AbstractInstruction * self_in_concretizeLogicalShiftLeftCqR); -static sqInt NoDbgRegParms concretizeLogicalShiftLeftRR(AbstractInstruction * self_in_concretizeLogicalShiftLeftRR); -static sqInt NoDbgRegParms concretizeLogicalShiftRightCqR(AbstractInstruction * self_in_concretizeLogicalShiftRightCqR); -static sqInt NoDbgRegParms concretizeLogicalShiftRightRR(AbstractInstruction * self_in_concretizeLogicalShiftRightRR); -static sqInt NoDbgRegParms concretizeMoveAbR(AbstractInstruction * self_in_concretizeMoveAbR); -static sqInt NoDbgRegParms concretizeMoveAwR(AbstractInstruction * self_in_concretizeMoveAwR); -static sqInt NoDbgRegParms concretizeMoveCqR(AbstractInstruction * self_in_concretizeMoveCqR); -static sqInt NoDbgRegParms concretizeMoveCwR(AbstractInstruction * self_in_concretizeMoveCwR); -static sqInt NoDbgRegParms concretizeMoveHighR(AbstractInstruction * self_in_concretizeMoveHighR); -static sqInt NoDbgRegParms concretizeMoveLowR(AbstractInstruction * self_in_concretizeMoveLowR); -static sqInt NoDbgRegParms concretizeMoveM16rR(AbstractInstruction * self_in_concretizeMoveM16rR); -static sqInt NoDbgRegParms concretizeMoveMbrR(AbstractInstruction * self_in_concretizeMoveMbrR); -static sqInt NoDbgRegParms concretizeMoveMwrR(AbstractInstruction * self_in_concretizeMoveMwrR); -static sqInt NoDbgRegParms concretizeMoveRAb(AbstractInstruction * self_in_concretizeMoveRAb); -static sqInt NoDbgRegParms concretizeMoveRAw(AbstractInstruction * self_in_concretizeMoveRAw); -static sqInt NoDbgRegParms concretizeMoveRM16r(AbstractInstruction * self_in_concretizeMoveRM16r); -static sqInt NoDbgRegParms concretizeMoveRMbr(AbstractInstruction * self_in_concretizeMoveRMbr); -static sqInt NoDbgRegParms concretizeMoveRMwr(AbstractInstruction * self_in_concretizeMoveRMwr); -static sqInt NoDbgRegParms concretizeMoveRR(AbstractInstruction * self_in_concretizeMoveRR); -static sqInt NoDbgRegParms concretizeMoveRXbrR(AbstractInstruction * self_in_concretizeMoveRXbrR); -static sqInt NoDbgRegParms concretizeMoveRXwrR(AbstractInstruction * self_in_concretizeMoveRXwrR); -static sqInt NoDbgRegParms concretizeMoveXbrRR(AbstractInstruction * self_in_concretizeMoveXbrRR); -static sqInt NoDbgRegParms concretizeMoveXwrRR(AbstractInstruction * self_in_concretizeMoveXwrRR); -static sqInt NoDbgRegParms concretizeMulCheckOverflowRR(AbstractInstruction * self_in_concretizeMulCheckOverflowRR); -static sqInt NoDbgRegParms concretizeNegateR(AbstractInstruction * self_in_concretizeNegateR); -static sqInt NoDbgRegParms concretizeNop(AbstractInstruction * self_in_concretizeNop); -static sqInt NoDbgRegParms concretizeOrCqR(AbstractInstruction * self_in_concretizeOrCqR); -static sqInt NoDbgRegParms concretizeOrCqRR(AbstractInstruction * self_in_concretizeOrCqRR); -static sqInt NoDbgRegParms concretizeOrCwR(AbstractInstruction * self_in_concretizeOrCwR); -static sqInt NoDbgRegParms concretizeOrRR(AbstractInstruction * self_in_concretizeOrRR); -static sqInt NoDbgRegParms concretizePopR(AbstractInstruction * self_in_concretizePopR); -static sqInt NoDbgRegParms concretizePrefetchAw(AbstractInstruction * self_in_concretizePrefetchAw); -static sqInt NoDbgRegParms concretizePushCq(AbstractInstruction * self_in_concretizePushCq); -static sqInt NoDbgRegParms concretizePushCw(AbstractInstruction * self_in_concretizePushCw); -static sqInt NoDbgRegParms concretizePushR(AbstractInstruction * self_in_concretizePushR); -static sqInt NoDbgRegParms concretizeRetN(AbstractInstruction * self_in_concretizeRetN); -static sqInt NoDbgRegParms concretizeStop(AbstractInstruction * self_in_concretizeStop); -static sqInt NoDbgRegParms concretizeSubCheckOverflowCqR(AbstractInstruction * self_in_concretizeSubCheckOverflowCqR); -static sqInt NoDbgRegParms concretizeSubCheckOverflowRR(AbstractInstruction * self_in_concretizeSubCheckOverflowRR); -static sqInt NoDbgRegParms concretizeSubCqR(AbstractInstruction * self_in_concretizeSubCqR); -static sqInt NoDbgRegParms concretizeSubCwR(AbstractInstruction * self_in_concretizeSubCwR); -static sqInt NoDbgRegParms concretizeSubRRDest(AbstractInstruction * self_in_concretizeSubRRDest, sqInt destReg); -static sqInt NoDbgRegParms concretizeTstCqR(AbstractInstruction * self_in_concretizeTstCqR); -static sqInt NoDbgRegParms concretizeTstCwR(AbstractInstruction * self_in_concretizeTstCwR); -static sqInt NoDbgRegParms concretizeUnimplemented(AbstractInstruction * self_in_concretizeUnimplemented); -static sqInt NoDbgRegParms concretizeXorCwR(AbstractInstruction * self_in_concretizeXorCwR); -static sqInt NoDbgRegParms concretizeXorRR(AbstractInstruction * self_in_concretizeXorRR); -static sqInt NoDbgRegParms dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize); -static sqInt NoDbgRegParms divRR(AbstractInstruction * self_in_divRR, sqInt dividendReg, sqInt divisorReg); -static sqInt NoDbgRegParms fullCallsAreRelative(AbstractInstruction * self_in_fullCallsAreRelative); -static sqInt NoDbgRegParms functionAtAddress(AbstractInstruction * self_in_functionAtAddress, sqInt mcpc); -static sqInt NoDbgRegParms genDivRRQuoRem(AbstractInstruction * self_in_genDivRRQuoRem, sqInt abstractRegDivisor, sqInt abstractRegDividend, sqInt abstractRegQuotient, sqInt abstractRegRemainder); -static AbstractInstruction * NoDbgRegParms genMulRR(AbstractInstruction * self_in_genMulRR, sqInt regSource, sqInt regDest); -static void NoDbgRegParms genPushRegisterArgsForAbortMissNumArgs(AbstractInstruction * self_in_genPushRegisterArgsForAbortMissNumArgs, sqInt numArgs); -static void NoDbgRegParms genPushRegisterArgsForNumArgsscratchReg(AbstractInstruction * self_in_genPushRegisterArgsForNumArgsscratchReg, sqInt numArgs, sqInt ignored); -static sqInt NoDbgRegParms genRemoveNArgsFromStack(AbstractInstruction * self_in_genRemoveNArgsFromStack, sqInt n); -static sqInt NoDbgRegParms genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask); -static sqInt NoDbgRegParms genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask); -static AbstractInstruction * NoDbgRegParms genSubstituteReturnAddress(AbstractInstruction * self_in_genSubstituteReturnAddress, sqInt retpc); -static sqInt NoDbgRegParms hasVarBaseRegister(AbstractInstruction * self_in_hasVarBaseRegister); -static usqInt NoDbgRegParms high16BitsOf(AbstractInstruction * self_in_high16BitsOf, usqInt word); -static usqInt NoDbgRegParms inlineCacheTagAt(AbstractInstruction * self_in_inlineCacheTagAt, usqInt callSiteReturnAddress); -static sqInt NoDbgRegParms instructionSizeAt(AbstractInstruction * self_in_instructionSizeAt, sqInt pc); -static sqInt NoDbgRegParms isCallPrecedingReturnPC(AbstractInstruction * self_in_isCallPrecedingReturnPC, sqInt mcpc); -static sqInt NoDbgRegParms isJump(AbstractInstruction * self_in_isJump); -static sqInt NoDbgRegParms isJumpAt(AbstractInstruction * self_in_isJumpAt, sqInt pc); -static sqInt NoDbgRegParms isPCDependent(AbstractInstruction * self_in_isPCDependent); -static sqInt NoDbgRegParms isShortOffset(AbstractInstruction * self_in_isShortOffset, sqInt offset); -static sqInt NoDbgRegParms itypersrteitherImmediate(AbstractInstruction * self_in_itypersrteitherImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate); -static sqInt NoDbgRegParms itypersrtsignedImmediate(AbstractInstruction * self_in_itypersrtsignedImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate); -static sqInt NoDbgRegParms itypersrtunsignedImmediate(AbstractInstruction * self_in_itypersrtunsignedImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate); -static sqInt NoDbgRegParms jA(AbstractInstruction * self_in_jA, sqInt target); -static sqInt NoDbgRegParms jalA(AbstractInstruction * self_in_jalA, sqInt target); -static sqInt NoDbgRegParms jalR(AbstractInstruction * self_in_jalR, sqInt targetReg); -static sqInt NoDbgRegParms jR(AbstractInstruction * self_in_jR, sqInt targetReg); -static sqInt NoDbgRegParms jtypetarget(AbstractInstruction * self_in_jtypetarget, sqInt op, sqInt target); -static sqInt NoDbgRegParms jumpLongByteSize(AbstractInstruction * self_in_jumpLongByteSize); -static sqInt NoDbgRegParms jumpLongConditionalByteSize(AbstractInstruction * self_in_jumpLongConditionalByteSize); -static usqInt NoDbgRegParms jumpLongConditionalTargetBeforeFollowingAddress(AbstractInstruction * self_in_jumpLongConditionalTargetBeforeFollowingAddress, sqInt mcpc); -static usqInt NoDbgRegParms jumpLongTargetBeforeFollowingAddress(AbstractInstruction * self_in_jumpLongTargetBeforeFollowingAddress, sqInt mcpc); -static sqInt NoDbgRegParms jumpShortByteSize(AbstractInstruction * self_in_jumpShortByteSize); -static usqInt NoDbgRegParms jumpTargetPCAt(AbstractInstruction * self_in_jumpTargetPCAt, sqInt pc); -static sqInt NoDbgRegParms lbRbaseoffset(AbstractInstruction * self_in_lbRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset); -static sqInt NoDbgRegParms lbuRbaseoffset(AbstractInstruction * self_in_lbuRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset); -static sqInt NoDbgRegParms lhRbaseoffset(AbstractInstruction * self_in_lhRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset); -static sqInt NoDbgRegParms lhuRbaseoffset(AbstractInstruction * self_in_lhuRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset); -static usqInt NoDbgRegParms literalAtAddress(AbstractInstruction * self_in_literalAtAddress, sqInt mcpc); -static sqInt NoDbgRegParms literalAtAddressput(AbstractInstruction * self_in_literalAtAddressput, sqInt mcpc, sqInt newLiteral); -static usqInt NoDbgRegParms literalBeforeFollowingAddress(AbstractInstruction * self_in_literalBeforeFollowingAddress, sqInt followingAddress); -static sqInt NoDbgRegParms loadLiteralByteSize(AbstractInstruction * self_in_loadLiteralByteSize); -static sqInt NoDbgRegParms loadPICLiteralByteSize(AbstractInstruction * self_in_loadPICLiteralByteSize); -static usqInt NoDbgRegParms low16BitsOf(AbstractInstruction * self_in_low16BitsOf, usqInt word); -static sqInt NoDbgRegParms luiRC(AbstractInstruction * self_in_luiRC, sqInt destReg, sqInt imm); -static sqInt NoDbgRegParms lwRbaseoffset(AbstractInstruction * self_in_lwRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset); -static sqInt NoDbgRegParms machineCodeBytes(AbstractInstruction * self_in_machineCodeBytes); -static sqInt NoDbgRegParms machineCodeWords(AbstractInstruction * self_in_machineCodeWords); -static sqInt NoDbgRegParms mfhiR(AbstractInstruction * self_in_mfhiR, sqInt destReg); -static sqInt NoDbgRegParms mfloR(AbstractInstruction * self_in_mfloR, sqInt destReg); -static sqInt NoDbgRegParms mipsbreak(AbstractInstruction * self_in_mipsbreak, sqInt code); -static sqInt NoDbgRegParms multRR(AbstractInstruction * self_in_multRR, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms nop(AbstractInstruction * self_in_nop); -static AbstractInstruction * NoDbgRegParms noteFollowingConditionalBranch(AbstractInstruction * self_in_noteFollowingConditionalBranch, AbstractInstruction *branch); -static AbstractInstruction * NoDbgRegParms noteFollowingOverflowBranch(AbstractInstruction * self_in_noteFollowingOverflowBranch, AbstractInstruction *branch); -static sqInt NoDbgRegParms numIntRegArgs(AbstractInstruction * self_in_numIntRegArgs); -static sqInt NoDbgRegParms opcodeAtAddress(AbstractInstruction * self_in_opcodeAtAddress, sqInt mcpc); -static sqInt NoDbgRegParms oriRRC(AbstractInstruction * self_in_oriRRC, sqInt destReg, sqInt srcReg, sqInt imm); -static sqInt NoDbgRegParms orRRR(AbstractInstruction * self_in_orRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static void NoDbgRegParms padIfPossibleWithStopsFromto(AbstractInstruction * self_in_padIfPossibleWithStopsFromto, sqInt startAddr, sqInt endAddr); -static sqInt NoDbgRegParms prefRoffsethint(AbstractInstruction * self_in_prefRoffsethint, sqInt baseReg, sqInt offset, sqInt hint); -static sqInt NoDbgRegParms pushLinkRegisterByteSize(AbstractInstruction * self_in_pushLinkRegisterByteSize); -static AbstractInstruction * NoDbgRegParms relocateCallBeforeReturnPCby(AbstractInstruction * self_in_relocateCallBeforeReturnPCby, sqInt retpc, sqInt delta); -static AbstractInstruction * NoDbgRegParms relocateJumpLongBeforeFollowingAddressby(AbstractInstruction * self_in_relocateJumpLongBeforeFollowingAddressby, sqInt pc, sqInt delta); -static void NoDbgRegParms relocateJumpLongConditionalBeforeFollowingAddressby(AbstractInstruction * self_in_relocateJumpLongConditionalBeforeFollowingAddressby, sqInt pc, sqInt delta); -static AbstractInstruction * NoDbgRegParms relocateMethodReferenceBeforeAddressby(AbstractInstruction * self_in_relocateMethodReferenceBeforeAddressby, sqInt pc, sqInt delta); -static sqInt NoDbgRegParms rewriteCallAttarget(AbstractInstruction * self_in_rewriteCallAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress); -static void NoDbgRegParms rewriteConditionalJumpLongAttarget(AbstractInstruction * self_in_rewriteConditionalJumpLongAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress); -static void NoDbgRegParms rewriteCPICJumpAttarget(AbstractInstruction * self_in_rewriteCPICJumpAttarget, usqInt addressFollowingJump, usqInt jumpTargetAddr); -static sqInt NoDbgRegParms rewriteInlineCacheAttagtarget(AbstractInstruction * self_in_rewriteInlineCacheAttagtarget, usqInt callSiteReturnAddress, sqInt cacheTag, usqInt callTargetAddress); -static void NoDbgRegParms rewriteInlineCacheTagat(AbstractInstruction * self_in_rewriteInlineCacheTagat, sqInt cacheTag, usqInt callSiteReturnAddress); -static void NoDbgRegParms rewriteITypeBranchAtAddresstarget(AbstractInstruction * self_in_rewriteITypeBranchAtAddresstarget, sqInt mcpc, sqInt newTarget); -static void NoDbgRegParms rewriteJTypeAtAddressdelta(AbstractInstruction * self_in_rewriteJTypeAtAddressdelta, sqInt mcpc, sqInt delta); -static void NoDbgRegParms rewriteJTypeAtAddresstarget(AbstractInstruction * self_in_rewriteJTypeAtAddresstarget, sqInt mcpc, sqInt newTarget); -static sqInt NoDbgRegParms rewriteJumpLongAttarget(AbstractInstruction * self_in_rewriteJumpLongAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress); -static sqInt NoDbgRegParms rtAtAddress(AbstractInstruction * self_in_rtAtAddress, sqInt mcpc); -static sqInt NoDbgRegParms rtypersrtrdsafunct(AbstractInstruction * self_in_rtypersrtrdsafunct, sqInt op, sqInt rs, sqInt rt, sqInt rd, sqInt sa, sqInt funct); -static sqInt NoDbgRegParms sbRbaseoffset(AbstractInstruction * self_in_sbRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset); -static sqInt NoDbgRegParms setsConditionCodesFor(AbstractInstruction * self_in_setsConditionCodesFor, sqInt aConditionalJumpOpcode); -static sqInt NoDbgRegParms shRbaseoffset(AbstractInstruction * self_in_shRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset); -static usqInt NoDbgRegParms sizePCDependentInstructionAt(AbstractInstruction * self_in_sizePCDependentInstructionAt, sqInt eventualAbsoluteAddress); -static sqInt NoDbgRegParms sllRRC(AbstractInstruction * self_in_sllRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount); -static sqInt NoDbgRegParms sllvRRR(AbstractInstruction * self_in_sllvRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms sltiRRC(AbstractInstruction * self_in_sltiRRC, sqInt destReg, sqInt leftReg, sqInt imm); -static sqInt NoDbgRegParms sltiuRRC(AbstractInstruction * self_in_sltiuRRC, sqInt destReg, sqInt leftReg, sqInt imm); -static sqInt NoDbgRegParms sltRRR(AbstractInstruction * self_in_sltRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms sltuRRR(AbstractInstruction * self_in_sltuRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms sraRRC(AbstractInstruction * self_in_sraRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount); -static sqInt NoDbgRegParms sravRRR(AbstractInstruction * self_in_sravRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms srlRRC(AbstractInstruction * self_in_srlRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount); -static sqInt NoDbgRegParms srlvRRR(AbstractInstruction * self_in_srlvRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms stop(AbstractInstruction * self_in_stop); -static void NoDbgRegParms stopsFromto(AbstractInstruction * self_in_stopsFromto, sqInt startAddr, sqInt endAddr); -static sqInt NoDbgRegParms storeLiteralbeforeFollowingAddress(AbstractInstruction * self_in_storeLiteralbeforeFollowingAddress, sqInt literal, sqInt followingAddress); -static sqInt NoDbgRegParms subuRRR(AbstractInstruction * self_in_subuRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms swRbaseoffset(AbstractInstruction * self_in_swRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset); -static usqInt NoDbgRegParms targetFromITypeAtAddress(AbstractInstruction * self_in_targetFromITypeAtAddress, usqInt mcpc); -static usqInt NoDbgRegParms targetFromJTypeAtAddress(AbstractInstruction * self_in_targetFromJTypeAtAddress, usqInt mcpc); -static sqInt NoDbgRegParms xoriRRC(AbstractInstruction * self_in_xoriRRC, sqInt destReg, sqInt srcReg, sqInt imm); -static sqInt NoDbgRegParms xorRRR(AbstractInstruction * self_in_xorRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms zoneCallsAreRelative(AbstractInstruction * self_in_zoneCallsAreRelative); -static sqInt NoDbgRegParms checkValidObjectReference(sqInt anOop); -static AbstractInstruction * NoDbgRegParms genCmpClassFloatCompactIndexR(sqInt reg); -static AbstractInstruction * NoDbgRegParms genCmpClassMethodContextCompactIndexR(sqInt reg); -static sqInt NoDbgRegParms genGetMethodHeaderOfintoscratch(sqInt methodReg, sqInt headerReg, sqInt scratchReg); -static sqInt NoDbgRegParms genLoadSlotsourceRegdestReg(sqInt index, sqInt sourceReg, sqInt destReg); -static sqInt genPrimitiveAdd(void); -static sqInt genPrimitiveBitAnd(void); -static sqInt genPrimitiveBitOr(void); -static sqInt genPrimitiveBitShift(void); -static sqInt genPrimitiveBitXor(void); -static sqInt genPrimitiveClass(void); -static sqInt genPrimitiveDiv(void); -static sqInt genPrimitiveDivide(void); -static sqInt genPrimitiveEqual(void); -static sqInt genPrimitiveGreaterOrEqual(void); -static sqInt genPrimitiveGreaterThan(void); -static sqInt genPrimitiveHighBit(void); -static sqInt genPrimitiveIdentical(void); -static sqInt genPrimitiveLessOrEqual(void); -static sqInt genPrimitiveLessThan(void); -static sqInt genPrimitiveMod(void); -static sqInt genPrimitiveMultiply(void); -static sqInt genPrimitiveNewMethod(void); -static sqInt genPrimitiveNotEqual(void); -static sqInt genPrimitiveNotIdentical(void); -static sqInt genPrimitiveQuo(void); -static sqInt genPrimitiveSubtract(void); -static sqInt NoDbgRegParms genSmallIntegerComparison(sqInt jumpOpcode); -static sqInt NoDbgRegParms genSmallIntegerComparisonorDoubleComparisoninvert(sqInt jumpOpcode, AbstractInstruction * NoDbgRegParms (*jumpFPOpcodeGenerator)(void *), sqInt invertComparison); -static sqInt NoDbgRegParms isUnannotatableConstant(CogSimStackEntry *simStackEntry); -static sqInt NoDbgRegParms classForInlineCacheTag(sqInt inlineCacheTag); -static sqInt NoDbgRegParms genAddSmallIntegerTagsTo(sqInt aRegister); -static sqInt NoDbgRegParms genClearAndSetSmallIntegerTagsIn(sqInt scratchReg); -static void NoDbgRegParms genConvertCharacterToSmallIntegerInReg(sqInt reg); -static sqInt NoDbgRegParms genConvertIntegerInRegtoSmallIntegerInReg(sqInt srcReg, sqInt destReg); -static sqInt NoDbgRegParms genConvertIntegerToSmallIntegerInReg(sqInt reg); -static void NoDbgRegParms genConvertSmallIntegerToCharacterInReg(sqInt reg); -static sqInt NoDbgRegParms genConvertSmallIntegerToIntegerInReg(sqInt reg); -static sqInt NoDbgRegParms genGetHashFieldNonImmOfasSmallIntegerInto(sqInt instReg, sqInt destReg); -static sqInt NoDbgRegParms genGetHashFieldNonImmOfinto(sqInt instReg, sqInt destReg); -static AbstractInstruction * NoDbgRegParms genGetInlineCacheClassTagFromintoforEntry(sqInt sourceReg, sqInt destReg, sqInt forEntry); -static sqInt NoDbgRegParms genGetNumBytesOfinto(sqInt srcReg, sqInt destReg); -static sqInt NoDbgRegParms genGetOverflowSlotsOfinto(sqInt srcReg, sqInt destReg); -static AbstractInstruction * NoDbgRegParms genJumpIsSmallIntegerValuescratch(sqInt aRegister, sqInt scratchReg); -static AbstractInstruction * NoDbgRegParms genJumpNotSmallIntegerInScratchReg(sqInt aRegister); -static AbstractInstruction * NoDbgRegParms genJumpNotSmallIntegerValuescratch(sqInt aRegister, sqInt scratchReg); -static AbstractInstruction * NoDbgRegParms genJumpNotSmallInteger(sqInt aRegister); -static AbstractInstruction * NoDbgRegParms genJumpSmallInteger(sqInt aRegister); -static sqInt genPrimitiveAtPut(void); -static sqInt NoDbgRegParms genPrimitiveAtPutSigned(sqInt signedVersion); -static sqInt NoDbgRegParms genPrimitiveAtSigned(sqInt signedVersion); -static sqInt genPrimitiveIdentityHash(void); -static sqInt genPrimitiveImmediateAsInteger(void); -static sqInt genPrimitiveNew(void); -static sqInt genPrimitiveNewWithArg(void); -static sqInt genPrimitiveShallowCopy(void); -static sqInt genPrimitiveStringAt(void); -static sqInt genPrimitiveStringAtPut(void); -static sqInt NoDbgRegParms genRemoveSmallIntegerTagsInScratchReg(sqInt scratchReg); -static sqInt NoDbgRegParms genShiftAwaySmallIntegerTagsInScratchReg(sqInt scratchReg); -static sqInt NoDbgRegParms getLiteralCountOfplusOneinBytesintoscratch(sqInt methodReg, sqInt plusOne, sqInt inBytes, sqInt litCountReg, sqInt scratchReg); -static sqInt NoDbgRegParms inlineCacheTagForInstance(sqInt oop); -static AbstractInstruction * NoDbgRegParms jumpNotSmallIntegerUnsignedValueInRegister(sqInt reg); -static sqInt NoDbgRegParms markAndTraceCacheTagLiteralinatpc(sqInt literal, CogMethod *cogMethodOrNil, usqInt address); -static usqInt NoDbgRegParms numCountersFor(usqInt theCounters); -static sqInt numSmallIntegerBits(void); -static sqInt NoDbgRegParms validInlineCacheTag(usqInt classIndexOrTagPattern); -static sqInt NoDbgRegParms branchIfinstanceOfBehaviorstarget(sqInt reg, sqInt arrayObj, AbstractInstruction *targetFixUp); -static sqInt NoDbgRegParms branchIfnotInstanceOfBehaviorstarget(sqInt reg, sqInt arrayObj, AbstractInstruction *targetFixUp); -static void callStoreCheckTrampoline(void); -static sqInt NoDbgRegParms checkValidDerivedObjectReference(sqInt bodyAddress); -static sqInt NoDbgRegParms checkValidOopReference(sqInt anOop); -static sqInt NoDbgRegParms couldBeDerivedObject(sqInt bodyAddress); -static sqInt NoDbgRegParms couldBeObject(sqInt literal); -static usqInt NoDbgRegParms genActiveContextTrampolineLargeinBlockcalled(sqInt isLarge, sqInt isInBlock, char *aString); -static AbstractInstruction * NoDbgRegParms genAllocFloatValueintoscratchRegscratchReg(sqInt dpreg, sqInt resultReg, sqInt scratch1, sqInt scratch2); -static AbstractInstruction * NoDbgRegParms genCheckRememberedBitOfscratch(sqInt objReg, sqInt scratchReg); -static void NoDbgRegParms genCmpClassIndexR(sqInt classIndex, sqInt reg); -static sqInt NoDbgRegParms genConvertCharacterToCodeInReg(sqInt reg); -static sqInt NoDbgRegParms genConvertIntegerToCharacterInReg(sqInt reg); -static sqInt NoDbgRegParms genCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(sqInt bcpc, sqInt numArgs, sqInt numCopied, sqInt ctxtNumArgs, sqInt isLargeCtxt, sqInt isInBlock); -static sqInt NoDbgRegParms genCreateFullClosurenumArgsnumCopiedignoreContextcontextNumArgslargeinBlock(sqInt compiledBlock, sqInt numArgs, sqInt numCopied, sqInt ignoreContext, sqInt contextNumArgs, sqInt contextIsLarge, sqInt contextIsBlock); -static sqInt NoDbgRegParms genEnsureObjInRegNotForwardedscratchReg(sqInt reg, sqInt scratch); -static sqInt NoDbgRegParms genEnsureOopInRegNotForwardedscratchReg(sqInt reg, sqInt scratch); -static sqInt NoDbgRegParms genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(sqInt reg, sqInt scratch, void *fwdJumpTarget, void *nonFwdJumpTargetOrZero); -static sqInt NoDbgRegParms genEnsureOopInRegNotForwardedscratchRegupdatingSlotin(sqInt reg, sqInt scratch, sqInt index, sqInt objReg); -static void generateObjectRepresentationTrampolines(void); -static sqInt NoDbgRegParms genGetActiveContextLargeinBlock(sqInt isLarge, sqInt isInBlock); -static sqInt NoDbgRegParms genGetActiveContextNumArgslargeinBlock(sqInt numArgs, sqInt isLargeContext, sqInt isInBlock); -static sqInt NoDbgRegParms genGetBitsofFormatByteOfinto(sqInt mask, sqInt sourceReg, sqInt destReg); -static sqInt NoDbgRegParms genGetClassIndexOfNonImminto(sqInt sourceReg, sqInt destReg); -static sqInt NoDbgRegParms genGetClassObjectOfClassIndexintoscratchReg(sqInt instReg, sqInt destReg, sqInt scratchReg); -static sqInt NoDbgRegParms genGetClassObjectOfintoscratchRegmayBeAForwarder(sqInt instReg, sqInt destReg, sqInt scratchReg, sqInt mayBeForwarder); -static AbstractInstruction * NoDbgRegParms genGetClassTagOfintoscratchReg(sqInt instReg, sqInt destReg, sqInt scratchReg); -static sqInt NoDbgRegParms genGetCompactClassIndexNonImmOfinto(sqInt instReg, sqInt destReg); -static sqInt NoDbgRegParms genGetDoubleValueOfinto(sqInt srcReg, sqInt destFPReg); -static sqInt NoDbgRegParms genGetFormatOfinto(sqInt srcReg, sqInt destReg); -static sqInt NoDbgRegParms genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(sqInt sourceReg, sqInt destReg, sqInt scratchRegOrNone); -static void NoDbgRegParms genGetIdentityHashresultReg(sqInt rcvrReg, sqInt resultReg); -static sqInt NoDbgRegParms genGetInstanceOfByteClassintoinitializingIfnumBytes(sqInt classObj, sqInt destReg, sqInt initializeInstance, sqInt numBytes); -static sqInt NoDbgRegParms genGetInstanceOfPointerClassintoinitializingIfnumVariableSlots(sqInt classObj, sqInt destReg, sqInt initializeInstance, sqInt varSlots); -static sqInt NoDbgRegParms genGetNumSlotsOfinto(sqInt srcReg, sqInt destReg); -static sqInt NoDbgRegParms genGetRawSlotSizeOfNonImminto(sqInt sourceReg, sqInt destReg); -static sqInt NoDbgRegParms genGetUninitializedInstanceWithClassIndexnumSlotsformatinto(sqInt classIndex, sqInt numSlots, sqInt format, sqInt destReg); -static AbstractInstruction * NoDbgRegParms genIfRequiredCheckRememberedBitOfscratch(sqInt rr, sqInt scratchReg); -static AbstractInstruction * NoDbgRegParms genJumpCharacterInScratchReg(sqInt reg); -static AbstractInstruction * NoDbgRegParms genJumpImmediate(sqInt aRegister); -#if IMMUTABILITY -static AbstractInstruction * NoDbgRegParms genJumpImmutablescratchReg(sqInt sourceReg, sqInt scratchReg); -#endif /* IMMUTABILITY */ -#if IMMUTABILITY -static AbstractInstruction * NoDbgRegParms genJumpMutablescratchReg(sqInt sourceReg, sqInt scratchReg); -#endif /* IMMUTABILITY */ -static AbstractInstruction * NoDbgRegParms genJumpNotCharacterInScratchReg(sqInt reg); -static AbstractInstruction * NoDbgRegParms genJumpNotImmediate(sqInt aRegister); -static sqInt NoDbgRegParms genNewArrayOfSizeinitialized(sqInt size, sqInt initialize); -static sqInt NoDbgRegParms genNoPopCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(sqInt bcpc, sqInt numArgs, sqInt numCopied, sqInt ctxtNumArgs, sqInt isLargeCtxt, sqInt isInBlock); -static sqInt genPrimitiveAsCharacter(void); -static sqInt genPrimitiveAt(void); -static sqInt NoDbgRegParms genPrimitiveIdenticalOrNotIf(sqInt orNot); -static sqInt genPrimitiveIntegerAt(void); -static sqInt genPrimitiveIntegerAtPut(void); -static sqInt genPrimitiveMakePoint(void); -static sqInt genPrimitiveObjectAt(void); -static sqInt genPrimitiveSize(void); -static sqInt genPrimitiveStringCompareWith(void); -static sqInt genPrimitiveStringReplace(void); -static sqInt NoDbgRegParms genSetSmallIntegerTagsIn(sqInt scratchReg); -static usqInt genStoreCheckContextReceiverTrampoline(void); -static sqInt NoDbgRegParms genStoreCheckReceiverRegvalueRegscratchReginFrame(sqInt destReg, sqInt valueReg, sqInt scratchReg, sqInt inFrame); -static sqInt NoDbgRegParms genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt inFrame, sqInt needsStoreCheck); -static sqInt NoDbgRegParms genStoreSourceRegslotIndexintoNewObjectInDestReg(sqInt sourceReg, sqInt index, sqInt destReg); -#if IMMUTABILITY -static usqInt NoDbgRegParms genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex); -#endif /* IMMUTABILITY */ -static sqInt NoDbgRegParms genStoreValueinstancenumSlots(sqInt value, sqInt destReg, sqInt numSlots); -#if IMMUTABILITY -static sqInt NoDbgRegParms genStoreWithImmutabilityAndStoreCheckSourceRegslotIndexdestRegscratchRegneedRestoreRcvr(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt needRestoreRcvr); -#endif /* IMMUTABILITY */ -#if IMMUTABILITY -static sqInt NoDbgRegParms genStoreWithImmutabilityButNoStoreCheckSourceRegslotIndexdestRegscratchRegneedRestoreRcvr(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt needRestoreRcvr); -#endif /* IMMUTABILITY */ -#if IMMUTABILITY -static sqInt NoDbgRegParms genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt needsStoreCheck, sqInt needRestoreRcvr); -#endif /* IMMUTABILITY */ -static void genVarIndexCallStoreTrampoline(void); -static sqInt getActiveContextAllocatesInMachineCode(void); -static sqInt NoDbgRegParms inlineCacheTagIsYoung(sqInt cacheTag); -static AbstractInstruction * NoDbgRegParms jumpNotCharacterUnsignedValueInRegister(sqInt reg); -static sqInt NoDbgRegParms markAndTraceLiteralinatpc(sqInt literal, CogMethod *cogMethodOrNil, usqInt address); -static void NoDbgRegParms markAndTraceLiteralinat(sqInt literal, CogMethod *cogMethod, sqInt *address); -static void NoDbgRegParms markAndTraceUpdatedLiteralin(sqInt objOop, CogMethod *cogMethodOrNil); -static sqInt NoDbgRegParms maybeCompileRetryOnPrimitiveFail(sqInt primIndex); -static sqInt NoDbgRegParms maybeShiftClassTagRegisterForMethodCacheProbe(sqInt classTagReg); -static sqInt NoDbgRegParms mixedbranchIfinstanceOfBehaviorstarget(sqInt numNonImmediates, sqInt reg, sqInt arrayObj, AbstractInstruction *targetFixUp); -static sqInt NoDbgRegParms mixedbranchIfnotInstanceOfBehaviorstarget(sqInt numNonImmediates, sqInt reg, sqInt arrayObj, AbstractInstruction *targetFixUp); -static sqInt NoDbgRegParms noneImmediateBranchIfinstanceOfBehaviorstarget(sqInt reg, sqInt arrayObj, AbstractInstruction *targetFixUp); -static sqInt NoDbgRegParms noneImmediateBranchIfnotInstanceOfBehaviorstarget(sqInt reg, sqInt arrayObj, AbstractInstruction *targetFixUp); -static sqInt numCharacterBits(void); -extern sqInt numRegArgs(void); -static sqInt NoDbgRegParms remapObject(sqInt objOop); -static sqInt NoDbgRegParms remapOop(sqInt objOop); -extern void resetCountersIn(CogMethod *cogMethod); -static sqInt NoDbgRegParms shouldAnnotateObjectReference(sqInt anOop); -static sqInt NoDbgRegParms slotOffsetOfInstVarIndex(sqInt index); -static sqInt NoDbgRegParms valueOfAssociation(sqInt associationOop); -static SimStackEntry * NoDbgRegParms ensureSpilledAtfrom(SimStackEntry * self_in_ensureSpilledAtfrom, sqInt baseOffset, sqInt baseRegister); -static sqInt NoDbgRegParms isSameEntryAs(SimStackEntry * self_in_isSameEntryAs, CogSimStackEntry *ssEntry); -static sqInt NoDbgRegParms mayBeAForwarder(SimStackEntry * self_in_mayBeAForwarder); -static void NoDbgRegParms popToReg(SimStackEntry * self_in_popToReg, sqInt reg); -static sqInt NoDbgRegParms registerMask(SimStackEntry * self_in_registerMask); -static sqInt NoDbgRegParms registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone); -static sqInt NoDbgRegParms registerOrNone(SimStackEntry * self_in_registerOrNone); -static void NoDbgRegParms storeToReg(SimStackEntry * self_in_storeToReg, sqInt reg); -static sqInt NoDbgRegParms isMergeFixup(BytecodeFixup * self_in_isMergeFixup); -static AbstractInstruction * NoDbgRegParms checkLiteralforInstruction(sqInt literal, AbstractInstruction *anInstruction); -static AbstractInstruction * NoDbgRegParms checkQuickConstantforInstruction(sqInt literal, AbstractInstruction *anInstruction); -extern sqInt cogMethodHasExternalPrim(CogMethod *aCogMethod); -extern sqInt cogMethodHasMachineCodePrim(CogMethod *aCogMethod); -static sqInt compileBlockDispatch(void); -static void compileGetErrorCode(void); -static sqInt compileInterpreterPrimitive(void); -static sqInt NoDbgRegParms compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags); -static sqInt NoDbgRegParms compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)); -static sqInt NoDbgRegParms compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags); -static AbstractInstruction * NoDbgRegParms compileOpenPICMethodCacheProbeForwithShiftbaseRegOrNone(sqInt selector, sqInt shift, sqInt baseRegOrNone); -static void NoDbgRegParms compileOpenPICnumArgs(sqInt selector, sqInt numArgs); -static AbstractInstruction * NoDbgRegParms compilePerformMethodCacheProbeForwithShiftbaseRegOrNone(sqInt selectorReg, sqInt shift, sqInt baseRegOrNone); -static sqInt compilePrimitive(void); -static sqInt extendedPushBytecode(void); -static sqInt extendedStoreAndPopBytecode(void); -static sqInt extendedStoreBytecode(void); -static sqInt NoDbgRegParms frameOffsetOfTemporary(sqInt index); -static sqInt genExtendedSendBytecode(void); -static sqInt genExtendedSuperBytecode(void); -static sqInt genExtJumpIfFalse(void); -static sqInt genExtJumpIfTrue(void); -static sqInt genExtNopBytecode(void); -static sqInt genExtPushCharacterBytecode(void); -static sqInt genExtPushIntegerBytecode(void); -static sqInt genExtPushLiteralBytecode(void); -static sqInt genExtPushLiteralVariableBytecode(void); -static sqInt genExtPushPseudoVariable(void); -static sqInt genExtPushReceiverVariableBytecode(void); -static sqInt genExtSendBytecode(void); -static sqInt genExtSendSuperBytecode(void); -static sqInt genExtStoreAndPopLiteralVariableBytecode(void); -static sqInt genExtStoreAndPopReceiverVariableBytecode(void); -static sqInt genExtStoreLiteralVariableBytecode(void); -static sqInt genExtStoreReceiverVariableBytecode(void); -static sqInt genExtUnconditionalJump(void); -static sqInt genFastPrimFail(void); -static void NoDbgRegParms genFastPrimTraceUsingand(sqInt r1, sqInt r2); -static sqInt genLongJumpIfFalse(void); -static sqInt genLongJumpIfTrue(void); -static sqInt genLongPushTemporaryVariableBytecode(void); -static sqInt genLongStoreAndPopTemporaryVariableBytecode(void); -static sqInt genLongStoreTemporaryVariableBytecode(void); -static sqInt genLongUnconditionalBackwardJump(void); -static sqInt genLongUnconditionalForwardJump(void); -static sqInt NoDbgRegParms genLookupForPerformNumArgs(sqInt numArgs); -static AbstractInstruction * NoDbgRegParms genMoveFalseR(sqInt reg); -static AbstractInstruction * NoDbgRegParms genMoveTrueR(sqInt reg); -static sqInt genPrimitiveHashMultiply(void); -static void NoDbgRegParms genPrimReturnEnterCogCodeEnilopmart(sqInt profiling); -static sqInt genPushConstantFalseBytecode(void); -static sqInt genPushConstantNilBytecode(void); -static sqInt genPushConstantOneBytecode(void); -static sqInt genPushConstantTrueBytecode(void); -static sqInt genPushConstantZeroBytecode(void); -static sqInt genPushLiteralConstantBytecode(void); -static sqInt genPushLiteralVariable16CasesBytecode(void); -static sqInt genPushLiteralVariableBytecode(void); -static sqInt genPushQuickIntegerConstantBytecode(void); -static sqInt genPushReceiverVariableBytecode(void); -static sqInt genPushTemporaryVariableBytecode(void); -extern sqInt genQuickReturnConst(void); -extern sqInt genQuickReturnInstVar(void); -extern sqInt genQuickReturnSelf(void); -static sqInt genReturnFalse(void); -static sqInt genReturnNil(void); -static sqInt genReturnNilFromBlock(void); -static sqInt genReturnTrue(void); -static sqInt genSecondExtendedSendBytecode(void); -static sqInt genSendLiteralSelector0ArgsBytecode(void); -static sqInt genSendLiteralSelector1ArgBytecode(void); -static sqInt genSendLiteralSelector2ArgsBytecode(void); -static sqInt genShortJumpIfFalse(void); -static sqInt genShortJumpIfTrue(void); -static sqInt genShortUnconditionalJump(void); -static sqInt genSpecialSelectorEqualsEquals(void); -static sqInt genSpecialSelectorNotEqualsEquals(void); -static sqInt genSpecialSelectorSend(void); -static sqInt genStoreAndPopReceiverVariableBytecode(void); -static sqInt genStoreAndPopRemoteTempLongBytecode(void); -static sqInt genStoreAndPopTemporaryVariableBytecode(void); -static sqInt genStoreRemoteTempLongBytecode(void); -extern sqInt mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj); -static sqInt numSpecialSelectors(void); -static usqInt NoDbgRegParms pcDataForBlockEntryMethod(sqInt blockEntryMcpc, sqInt cogMethod); -static sqInt NoDbgRegParms pcDataForAnnotationMcpcBcpcMethod(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *cogMethodArg); -static PrimitiveDescriptor * primitiveGeneratorOrNil(void); -static sqInt NoDbgRegParms registerisInMask(sqInt reg, sqInt mask); -static sqInt NoDbgRegParms v3BlockCodeSize(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt NoDbgRegParms v3LongForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt NoDbgRegParms v3LongBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt NoDbgRegParms v3ShortForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt NoDbgRegParms v4BlockCodeSize(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt NoDbgRegParms v4LongForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt NoDbgRegParms v4LongBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static CogMethod * NoDbgRegParms compileCogFullBlockMethod(sqInt numCopied); -static CogMethod * NoDbgRegParms compileCogMethod(sqInt selector); -static void compileFrameBuild(void); -static void NoDbgRegParms compileFullBlockMethodFrameBuild(sqInt numCopied); -extern sqInt defaultCogCodeSize(void); -static void NoDbgRegParms fillInCountersatStartAddress(sqInt nCounters, sqInt startAddress); -static void NoDbgRegParms fillInMethodHeadersizeselector(CogMethod *method, sqInt size, sqInt selector); -static sqInt NoDbgRegParms genAtPutInlinePrimitive(sqInt prim); -static sqInt NoDbgRegParms genBinaryAtConstInlinePrimitive(sqInt primIndex); -static sqInt NoDbgRegParms genBinaryAtInlinePrimitive(sqInt primIndex); -static sqInt NoDbgRegParms genBinaryCompInlinePrimitive(sqInt primIndex); -static sqInt NoDbgRegParms genBinaryConstOpVarSmiInlinePrimitive(sqInt primIndex); -static sqInt NoDbgRegParms genBinaryInlineComparisonopFalsedestReg(sqInt opTrue, sqInt opFalse, sqInt destReg); -static sqInt NoDbgRegParms genBinaryInlinePrimitive(sqInt primIndex); -static sqInt NoDbgRegParms genBinaryNewInlinePrimitive(sqInt primIndex); -static sqInt genBinarySmiBitShiftLeftInlinePrimitive(void); -static sqInt genBinarySmiBitShiftRightInlinePrimitive(void); -static sqInt NoDbgRegParms genBinaryVarOpConstSmiInlinePrimitive(sqInt primIndex); -static sqInt NoDbgRegParms genBinaryVarOpVarSmiInlinePrimitive(sqInt primIndex); -static sqInt genByteAtPut(void); -static sqInt genByteAtPutImmutabilityCheck(void); -static sqInt NoDbgRegParms genByteEqualsInlinePrimitiveResultreturnReg(sqInt jmp, sqInt reg); -static sqInt NoDbgRegParms genByteEqualsInlinePrimitive(sqInt prim); -static sqInt genCallMappedInlinedPrimitive(void); -static sqInt genCallPrimitiveBytecode(void); -static sqInt NoDbgRegParms genCounterTripOnlyJumpIfto(sqInt boolean, sqInt targetBytecodePC); -static sqInt genDirectCall(void); -static sqInt NoDbgRegParms genDivInlinePrimitive(sqInt primIndex); -static sqInt genEnsureEnoughSlots(void); -static void generateSistaRuntime(void); -static sqInt NoDbgRegParms genForwardersInlinedIdenticalOrNotIf(sqInt orNot); -static sqInt NoDbgRegParms genJumpBinaryInlinePrimitive(sqInt primIndex); -static sqInt NoDbgRegParms genJumpIfto(sqInt boolean, sqInt targetBytecodePC); -static sqInt NoDbgRegParms genJumpTrinaryInlinePrimitive(sqInt primIndex); -static sqInt NoDbgRegParms genJumpUnaryInlinePrimitive(sqInt primIndex); -static sqInt NoDbgRegParms genMappedInlinePrimitive(sqInt primIndex); -static usqInt NoDbgRegParms genMustBeBooleanTrampolineForcalled(sqInt boolean, char *trampolineName); -static sqInt NoDbgRegParms genPointerAtPutConstantMaybeContextstoreCheckimmutabilityCheck(sqInt maybeContext, sqInt needsStoreCheck, sqInt needsImmCheck); -static sqInt genPointerAtPutImmCheckAndStoreCheck(void); -static sqInt genPointerAtPutImmCheckButNoStoreCheck(void); -static sqInt NoDbgRegParms genPointerAtPutMaybeContextstoreCheckimmutabilityCheck(sqInt maybeContext, sqInt needsStoreCheck, sqInt needsImmCheck); -static sqInt NoDbgRegParms genPointerAtPutStoreCheck(sqInt needsStoreCheck); -static sqInt NoDbgRegParms genSistaInlinePrimitive(sqInt prim); -static sqInt genSpecialSelectorComparison(void); -static sqInt genSpecialSelectorComparisonWithoutCounters(void); -static sqInt NoDbgRegParms genTrinaryInlinePrimitive(sqInt prim); -static sqInt genUnaryClassPrimitive(void); -static sqInt NoDbgRegParms genUnaryConvertInlinePrimitive(sqInt primIndex); -static sqInt NoDbgRegParms genUnaryHashInlinePrimitive(sqInt primIndex); -static sqInt NoDbgRegParms genUnaryInlinePrimitive(sqInt primIndex); -static sqInt NoDbgRegParms genUnaryNewInlinePrimitive(sqInt primIndex); -static sqInt genUnaryPossibleRootInlinePrimitive(void); -static sqInt NoDbgRegParms genUnarySizeInlinePrimitive(sqInt primIndex); -static sqInt genUnaryUnforwardInlinePrimitive(void); -static sqInt genUnaryUnforwardNonImmediateInlinePrimitive(void); -static sqInt genUnconditionalTrapBytecode(void); -extern usqInt getJumpTargetPCAt(sqInt pc); -extern void initializeCodeZoneFromupTo(sqInt startAddress, sqInt endAddress); -static sqInt maybeAllocAndInitCounters(void); -static sqInt NoDbgRegParms maybeDealWithUnsafeJumpForDescriptorpclatestContinuation(BytecodeDescriptor *descriptor, sqInt pc, sqInt latestContinuation); -static usqInt NoDbgRegParms picDataForBlockEntryMethod(sqInt blockEntryMcpc, sqInt cogMethod); -static sqInt NoDbgRegParms picDataForCounterat(unsigned int counter, sqInt bcpc); -static sqInt NoDbgRegParms picDataForSendTomethodClassIfSuperatbcpc(CogMethod *cogMethod, sqInt methodClassOrNil, char *sendMcpc, sqInt sendBcpc); -static sqInt NoDbgRegParms picDataForAnnotationMcpcBcpcMethod(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *cogMethodArg); -extern sqInt picDataForinto(CogMethod *cogMethod, sqInt arrayObj); -static void NoDbgRegParms populatewithPICInfoForfirstCacheTag(sqInt tuple, CogMethod *cPIC, sqInt firstCacheTag); -extern double getCogCodeZoneThreshold(void); -extern sqInt setCogCodeZoneThreshold(double ratio); -static BlockStart * NoDbgRegParms addBlockStartAtnumArgsnumCopiedspan(sqInt bytecodepc, sqInt numArgs, sqInt numCopied, sqInt span); -static void NoDbgRegParms adjustArgumentsForPerform(sqInt numArgs); -static sqInt NoDbgRegParms allocateRegForStackEntryAtnotConflictingWith(sqInt index, sqInt regMask); -static sqInt NoDbgRegParms allocateRegNotConflictingWith(sqInt regMask); -static sqInt NoDbgRegParms anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n); -extern void callCogCodePopReceiverArg0Regs(void); -extern void callCogCodePopReceiverArg1Arg0Regs(void); -static sqInt NoDbgRegParms compileAbstractInstructionsFromthrough(sqInt start, sqInt end); -static sqInt compileBlockBodies(void); -static void NoDbgRegParms compileBlockFrameBuild(BlockStart *blockStart); -static void NoDbgRegParms compileBlockFramelessEntry(BlockStart *blockStart); -static sqInt compileEntireMethod(void); -static void NoDbgRegParms compileFullBlockFramelessEntry(sqInt numCopied); -#if IMMUTABILITY -static void compileTwoPathFrameBuild(void); -#endif /* IMMUTABILITY */ -static void compileTwoPathFramelessInit(void); -static sqInt NoDbgRegParms cPICMissTrampolineFor(sqInt numArgs); -static sqInt doubleExtendedDoAnythingBytecode(void); -static sqInt duplicateTopBytecode(void); -static BytecodeFixup * NoDbgRegParms ensureFixupAt(sqInt targetPC); -static BytecodeFixup * NoDbgRegParms ensureNonMergeFixupAt(sqInt targetPC); -static void ensureReceiverResultRegContainsSelf(void); -static void NoDbgRegParms evaluateat(BytecodeDescriptor *descriptor, sqInt pc); -static sqInt NoDbgRegParms eventualTargetOf(sqInt targetBytecodePC); -static sqInt NoDbgRegParms freeAnyRegNotConflictingWith(sqInt regMask); -static sqInt genBlockReturn(void); -static void (*genCallPICEnilopmartNumArgs(sqInt numArgs))(void) ; -static sqInt genExternalizePointersForPrimitiveCall(void); -static AbstractInstruction * genExternalizeStackPointerForFastPrimitiveCall(void); -static sqInt genExtPushClosureBytecode(void); -static sqInt genExtPushFullClosureBytecode(void); -static void generateEnilopmarts(void); -static sqInt NoDbgRegParms generateInstructionsAt(sqInt eventualAbsoluteAddress); -static void generateMissAbortTrampolines(void); -static void generateSendTrampolines(void); -static void generateTracingTrampolines(void); -static sqInt NoDbgRegParms genIdenticalNoBranchArgIsConstantrcvrIsConstantargRegrcvrRegorNotIf(sqInt argIsConstant, sqInt rcvrIsConstant, sqInt argReg, sqInt rcvrRegOrNone, sqInt orNot); -static sqInt NoDbgRegParms genInlinedIdenticalOrNotIf(sqInt orNot); -static sqInt NoDbgRegParms genJumpBackTo(sqInt targetBytecodePC); -static sqInt NoDbgRegParms genJumpTo(sqInt targetBytecodePC); -static sqInt NoDbgRegParms genMarshalledSendnumArgssendTable(sqInt selectorIndex, sqInt numArgs, sqInt *sendTable); -static usqInt NoDbgRegParms genMethodAbortTrampolineFor(sqInt numArgs); -static usqInt NoDbgRegParms genPICAbortTrampolineFor(sqInt numArgs); -static usqInt NoDbgRegParms genPICMissTrampolineFor(sqInt numArgs); -static sqInt genPopStackBytecode(void); -static sqInt genPrimitiveClosureValue(void); -static sqInt genPrimitiveFullClosureValue(void); -static sqInt genPrimitivePerform(void); -static sqInt genPushActiveContextBytecode(void); -static sqInt genPushClosureCopyCopiedValuesBytecode(void); -static sqInt NoDbgRegParms genPushLiteralIndex(sqInt literalIndex); -static sqInt NoDbgRegParms genPushLiteralVariable(sqInt literalIndex); -static sqInt NoDbgRegParms genPushLiteral(sqInt literal); -static sqInt NoDbgRegParms genPushMaybeContextReceiverVariable(sqInt slotIndex); -static sqInt genPushNewArrayBytecode(void); -static sqInt genPushReceiverBytecode(void); -static sqInt NoDbgRegParms genPushReceiverVariable(sqInt index); -static void genPushRegisterArgs(void); -static sqInt genPushRemoteTempLongBytecode(void); -static sqInt NoDbgRegParms genPushTemporaryVariable(sqInt index); -static sqInt genReturnReceiver(void); -static sqInt genReturnTopFromBlock(void); -static sqInt genReturnTopFromMethod(void); -static sqInt NoDbgRegParms genSendDirectedSupernumArgs(sqInt selectorIndex, sqInt numArgs); -static sqInt NoDbgRegParms genSendSupernumArgs(sqInt selectorIndex, sqInt numArgs); -static usqInt NoDbgRegParms genSendTrampolineFornumArgscalledargargargarg(void *aRoutine, sqInt numArgs, char *aString, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3); -static sqInt NoDbgRegParms genSendnumArgs(sqInt selectorIndex, sqInt numArgs); -static sqInt genSpecialSelectorArithmetic(void); -static sqInt genSpecialSelectorClass(void); -static sqInt genStaticallyResolvedSpecialSelectorComparison(void); -static sqInt NoDbgRegParms genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt litVarIndex, sqInt needsStoreCheck, sqInt needsImmCheck); -static sqInt NoDbgRegParms genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt slotIndex, sqInt needsStoreCheck, sqInt needsImmCheck); -static sqInt NoDbgRegParms genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt slotIndex, sqInt needsStoreCheck, sqInt needsImmCheck); -static sqInt NoDbgRegParms genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt remoteTempIndex, sqInt needsStoreCheck); -static sqInt NoDbgRegParms genStorePopTemporaryVariable(sqInt popBoolean, sqInt tempIndex); -static sqInt genUpArrowReturn(void); -static sqInt NoDbgRegParms genVanillaInlinedIdenticalOrNotIf(sqInt orNot); -static void NoDbgRegParms initSimStackForFramefulMethod(sqInt startpc); -static void NoDbgRegParms initSimStackForFramelessBlock(sqInt startpc); -static void NoDbgRegParms initSimStackForFramelessMethod(sqInt startpc); -static sqInt NoDbgRegParms isNonForwarderReceiver(sqInt reg); -static sqInt liveRegisters(void); -static sqInt NoDbgRegParms mapDeadDescriptorIfNeeded(BytecodeDescriptor *descriptor); -static void NoDbgRegParms marshallSendArguments(sqInt numArgs); -static sqInt maybeCompilingFirstPassOfBlockWithInitialPushNil(void); -static sqInt NoDbgRegParms mergeWithFixupIfRequired(BytecodeFixup *fixup); -static sqInt NoDbgRegParms methodAbortTrampolineFor(sqInt numArgs); -static sqInt methodFoundInvalidPostScan(void); -static sqInt NoDbgRegParms needsFrameIfMod16GENumArgs(sqInt stackDelta); -static sqInt NoDbgRegParms needsFrameIfStackGreaterThanOne(sqInt stackDelta); -static sqInt NoDbgRegParms numberOfSpillsInTopNItems(sqInt n); -static sqInt NoDbgRegParms picAbortTrampolineFor(sqInt numArgs); -static sqInt prevInstIsPCAnnotated(void); -static sqInt receiverIsInReceiverResultReg(void); -static void NoDbgRegParms reinitializeFixupsFromthrough(sqInt start, sqInt end); -static sqInt NoDbgRegParms scanBlock(BlockStart *blockStart); -static sqInt scanMethod(void); -static sqInt NoDbgRegParms squeakV3orSistaV1PushNilSizenumInitialNils(sqInt aMethodObj, sqInt numInitialNils); -static sqInt NoDbgRegParms squeakV3orSistaV1NumPushNils(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static void NoDbgRegParms ssAllocateRequiredRegMaskupThroughupThroughNative(sqInt requiredRegsMask, sqInt stackPtr, sqInt nativeStackPtr); -static void NoDbgRegParms ssFlushUpThroughReceiverVariable(sqInt slotIndex); -static void NoDbgRegParms ssFlushUpThroughTemporaryVariable(sqInt tempIndex); -static void NoDbgRegParms ssPop(sqInt n); -static sqInt NoDbgRegParms ssPushAnnotatedConstant(sqInt literal); -static sqInt NoDbgRegParms ssPushBaseoffset(sqInt reg, sqInt offset); -static sqInt NoDbgRegParms ssPushConstant(sqInt literal); -static sqInt NoDbgRegParms ssPushDesc(SimStackEntry simStackEntry); -static sqInt NoDbgRegParms ssPushRegister(sqInt reg); -static void NoDbgRegParms ssPush(sqInt n); -static SimStackEntry ssSelfDescriptor(void); -static void NoDbgRegParms ssStoreAndReplacePoptoReg(sqInt popBoolean, sqInt reg); -static sqInt NoDbgRegParms ssStorePoptoPreferredReg(sqInt popBoolean, sqInt preferredReg); -static void NoDbgRegParms ssStorePoptoReg(sqInt popBoolean, sqInt reg); -static CogSimStackEntry * ssTop(void); -static CogSimStackEntry * NoDbgRegParms ssValue(sqInt n); -static sqInt NoDbgRegParms stackEntryIsBoolean(CogSimStackEntry *simStackEntry); -static sqInt tempsValidAndVolatileEntriesSpilled(void); -static sqInt NoDbgRegParms tryCollapseTempVectorInitializationOfSize(sqInt slots); -static sqInt violatesEnsureSpilledSpillAssert(void); -static void voidReceiverResultRegContainsSelf(void); - - -/*** Variables ***/ -static AbstractInstruction * abstractOpcodes; -static usqInt allocationThreshold; -static usqInt baseAddress; -static sqInt blockCount; -static AbstractInstruction * blockEntryLabel; -static AbstractInstruction * blockEntryNoContextSwitch; -static BlockStart * blockStarts; -static sqInt branchReachedOnlyForCounterTrip; -static sqInt breakBlock; -static sqInt breakMethod; -static sqInt byte0; -static sqInt byte1; -static sqInt byte2; -static sqInt byte3; -static sqInt bytecodePC; -static sqInt bytecodeSetOffset; -static sqInt ceByteSizeOfTrampoline; -static sqInt ceCPICMissTrampoline; -static sqInt ceFetchContextInstVarTrampoline; -static sqInt ceFFICalloutTrampoline; -static sqInt ceFloatObjectOfTrampoline; -static sqInt ceFloatValueOfTrampoline; -static sqInt ceFlushICache; -static sqInt ceFreeTrampoline; -static sqInt ceInlineNewHashTrampoline; -static sqInt ceInstantiateClassIndexableSizeTrampoline; -static sqInt ceInstantiateClassTrampoline; -static sqInt ceLargeActiveContextInBlockTrampoline; -static sqInt ceLargeActiveContextInFullBlockTrampoline; -static sqInt ceLargeActiveContextInMethodTrampoline; -static sqInt ceMallocTrampoline; -static sqInt ceMethodAbortTrampoline; -static sqInt ceNewHashTrampoline; -static sqInt ceNonLocalReturnTrampoline; -static sqInt cePICAbortTrampoline; -static sqInt cePositive32BitIntegerTrampoline; -static sqInt cePositive32BitValueOfTrampoline; -static sqInt cePositive64BitIntegerTrampoline; -static sqInt cePositive64BitValueOfTrampoline; -static sqInt cePrimReturnEnterCogCode; -static sqInt cePrimReturnEnterCogCodeProfiling; -static sqInt ceReapAndResetErrorCodeTrampoline; -static sqInt ceScheduleScavengeTrampoline; -static sqInt ceSendMustBeBooleanAddFalseTrampoline; -static sqInt ceSendMustBeBooleanAddTrueTrampoline; -static sqInt ceSigned32BitIntegerTrampoline; -static sqInt ceSigned32BitValueOfTrampoline; -static sqInt ceSigned64BitIntegerTrampoline; -static sqInt ceSigned64BitValueOfTrampoline; -static sqInt ceSmallActiveContextInBlockTrampoline; -static sqInt ceSmallActiveContextInFullBlockTrampoline; -static sqInt ceSmallActiveContextInMethodTrampoline; -static sqInt ceStoreCheckContextReceiverTrampoline; -static sqInt ceStoreCheckTrampoline; -static sqInt ceStoreContextInstVarTrampoline; -static sqInt ceTraceBlockActivationTrampoline; -static sqInt ceTraceLinkedSendTrampoline; -static sqInt ceTraceStoreTrampoline; -static sqInt ceTrapTrampoline; -static sqInt checkedEntryAlignment; -static sqInt closedPICSize; -static sqInt codeBase; -static sqInt codeModified; -static sqInt cogConstituentIndex; -static sqInt compactionInProgress; -static sqInt compilationPass; -static sqInt compilationTrace; -static sqInt counterIndex; -static usqInt counters; -static sqInt cPICCaseSize; -static sqInt cPICEndOfCodeOffset; -static sqInt cPICEndSize; -static CogMethod * cPICPrototype; -static sqInt currentCallCleanUpSize; -static sqInt deadCode; -static sqInt debugBytecodePointers; -static sqInt debugFixupBreaks; -static sqInt debugOpcodeIndices; -static sqInt debugStackPointers; -static sqInt directedSendUsesBinding; -static sqInt directedSuperBindingSendTrampolines[NumSendTrampolines]; -static sqInt directedSuperSendTrampolines[NumSendTrampolines]; -static sqInt disassemblingMethod; -static AbstractInstruction * endCPICCase0; -static sqInt endPC; -static AbstractInstruction * entry; -static sqInt entryPointMask; -static CogMethod * enumeratingCogMethod; -static sqInt expectedFPAlignment; -static sqInt expectedSPAlignment; -static sqInt extA; -static sqInt extB; -static sqInt firstCPICCaseOffset; -static sqInt firstSend; -static BytecodeFixup * fixups; -static AbstractInstruction * fullBlockEntry; -static AbstractInstruction * fullBlockNoContextSwitchEntry; -static BytecodeDescriptor generatorTable[512] = { - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushReceiverBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantTrueBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantFalseBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantNilBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushQuickIntegerConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushQuickIntegerConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushQuickIntegerConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushQuickIntegerConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genReturnReceiver, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnTrue, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnFalse, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnNil, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnTopFromMethod, 0, needsFrameIfInBlock, -1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnTopFromBlock, 0, needsFrameNever, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { extendedPushBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { extendedStoreBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 0, 0 }, - { extendedStoreAndPopBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 0, 0 }, - { genExtendedSendBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { doubleExtendedDoAnythingBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genExtendedSuperBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0 }, - { genSecondExtendedSendBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genPopStackBytecode, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { duplicateTopBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushActiveContextBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushNewArrayBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genCallPrimitiveBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushClosureCopyCopiedValuesBytecode, v3BlockCodeSize, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongUnconditionalBackwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongUnconditionalBackwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongUnconditionalBackwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongUnconditionalBackwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongUnconditionalForwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genLongUnconditionalForwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genLongUnconditionalForwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genLongUnconditionalForwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genLongJumpIfTrue, v3LongForwardBranchDistance, 0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongJumpIfTrue, v3LongForwardBranchDistance, 0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongJumpIfTrue, v3LongForwardBranchDistance, 0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongJumpIfTrue, v3LongForwardBranchDistance, 0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongJumpIfFalse, v3LongForwardBranchDistance, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongJumpIfFalse, v3LongForwardBranchDistance, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongJumpIfFalse, v3LongForwardBranchDistance, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongJumpIfFalse, v3LongForwardBranchDistance, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, AddRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, SubRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpLess, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpGreater, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpLessOrEqual, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpGreaterOrEqual, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpZero, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpNonZero, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, AndRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, OrRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorEqualsEquals, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorClass, 0, needsFrameIfStackGreaterThanOne, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorNotEqualsEquals, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushReceiverBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantTrueBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantFalseBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantNilBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantZeroBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantOneBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtPushPseudoVariable, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { duplicateTopBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genReturnReceiver, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnTrue, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnFalse, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnNil, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnTopFromMethod, 0, needsFrameIfInBlock, -1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnNilFromBlock, 0, needsFrameNever, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, - { genReturnTopFromBlock, 0, needsFrameNever, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, - { genExtNopBytecode, 0, needsFrameNever, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, AddRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, SubRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpLess, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpGreater, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpLessOrEqual, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpGreaterOrEqual, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpZero, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpNonZero, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, AndRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, OrRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorEqualsEquals, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorClass, 0, needsFrameIfStackGreaterThanOne, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorNotEqualsEquals, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPopStackBytecode, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genUnconditionalTrapBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { extABytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { extBBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genExtPushReceiverVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genExtPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtPushLiteralBytecode, 0, needsFrameNever, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genLongPushTemporaryVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushNewArrayBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtPushIntegerBytecode, 0, needsFrameNever, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtPushCharacterBytecode, 0, needsFrameNever, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtSendBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genExtSendSuperBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genCallMappedInlinedPrimitive, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 }, - { genExtUnconditionalJump, v4LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genExtJumpIfTrue, v4LongBranchDistance, 0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genExtJumpIfFalse, v4LongBranchDistance, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genExtStoreAndPopReceiverVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 0, 0 }, - { genExtStoreAndPopLiteralVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 0, 0, 0 }, - { genLongStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtStoreReceiverVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 0, 0 }, - { genExtStoreLiteralVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 0, 0, 0 }, - { genLongStoreTemporaryVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genCallPrimitiveBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, - { genExtPushFullClosureBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtPushClosureBytecode, v4BlockCodeSize, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genPushRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 } -}; -static sqInt guardPageSize; -static sqInt hasMovableLiteral; -static sqInt hasYoungReferent; -static sqInt inBlock; -static sqInt initialCounterValue; -static sqInt initialPC; -static sqInt introspectionData; -static sqInt introspectionDataIndex; -static int labelCounter; -static sqInt lastSend; -static usqInt limitAddress; -static sqInt maxLitIndex; -static sqInt methodAbortTrampolines[4]; -static sqInt methodBytesFreedSinceLastCompaction; -static sqInt methodCount; -static sqInt methodHeader; -static sqInt methodObj; -static sqInt methodOrBlockNumArgs; -static sqInt methodOrBlockNumTemps; -static usqIntptr_t minValidCallAddress; -static usqInt mzFreeStart; -static sqInt needsFrame; -static AbstractInstruction * noCheckEntry; -static sqInt numAbstractOpcodes; -static sqInt numCounters; -static sqInt numExtB; -static usqInt objectReferencesInRuntime[NumObjRefsInRuntime+1]; -static sqInt opcodeIndex; -static CogMethod *openPICList = 0; -static sqInt openPICSize; -static sqInt ordinarySendTrampolines[NumSendTrampolines]; -static sqInt picAbortTrampolines[4]; -static AbstractInstruction * picInterpretAbort; -static sqInt picMissTrampolines[4]; -static AbstractInstruction * picMNUAbort; -static BytecodeDescriptor * prevBCDescriptor; -static PrimitiveDescriptor primitiveGeneratorTable[MaxCompiledPrimitiveIndex+1] = { - { 0, -1 }, - { genPrimitiveAdd, 1 }, - { genPrimitiveSubtract, 1 }, - { genPrimitiveLessThan, 1 }, - { genPrimitiveGreaterThan, 1 }, - { genPrimitiveLessOrEqual, 1 }, - { genPrimitiveGreaterOrEqual, 1 }, - { genPrimitiveEqual, 1 }, - { genPrimitiveNotEqual, 1 }, - { genPrimitiveMultiply, 1 }, - { genPrimitiveDivide, 1 }, - { genPrimitiveMod, 1 }, - { genPrimitiveDiv, 1 }, - { genPrimitiveQuo, 1 }, - { genPrimitiveBitAnd, 1 }, - { genPrimitiveBitOr, 1 }, - { genPrimitiveBitXor, 1 }, - { genPrimitiveBitShift, 1 }, - { genPrimitiveMakePoint, 1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveAt, 1 }, - { genPrimitiveAtPut, 2 }, - { genPrimitiveSize, 0 }, - { genPrimitiveStringAt, 1 }, - { genPrimitiveStringAtPut, 2 }, - { genFastPrimFail, -1 }, - { genFastPrimFail, -1 }, - { genFastPrimFail, -1 }, - { genPrimitiveObjectAt, 1 }, - { 0, -1 }, - { genPrimitiveNew, 0 }, - { genPrimitiveNewWithArg, 1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveIdentityHash, 0 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveNewMethod, 2 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitivePerform, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveStringReplace, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveIdentical, 1 }, - { genPrimitiveClass, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveShallowCopy, 0 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveStringCompareWith, 1 }, - { genPrimitiveHashMultiply, 0 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveIntegerAt, 1 }, - { genPrimitiveIntegerAtPut, 2 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveNotIdentical, 1 }, - { genPrimitiveAsCharacter, -1 }, - { genPrimitiveImmediateAsInteger, 0 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveIdentityHash, 0 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genFastPrimFail, -1 }, - { genFastPrimFail, -1 }, - { 0, -1 }, - { genPrimitiveClosureValue, 0 }, - { genPrimitiveClosureValue, 1 }, - { genPrimitiveClosureValue, 2 }, - { genPrimitiveClosureValue, 3 }, - { genPrimitiveClosureValue, 4 }, - { 0, -1 }, - { genPrimitiveFullClosureValue, -1 }, - { 0, -1 }, - { genPrimitiveFullClosureValue, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveClosureValue, 0 }, - { genPrimitiveClosureValue, 1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveHighBit, 0 } -}; -static sqInt primitiveIndex; -static sqInt processorLock; -static sqInt receiverTags; -static sqInt regArgsHaveBeenPushed; -static sqInt runtimeObjectRefIndex; -static AbstractInstruction * sendMiss; -static sqInt simNativeStackPtr; -static sqInt simSpillBase; -static SimStackEntry simStack[70]; -static sqInt simStackPtr; -static AbstractInstruction * stackCheckLabel; -static AbstractInstruction * stackOverflowCall; -static sqInt superSendTrampolines[NumSendTrampolines]; -static sqInt tempOop; -static char *trampolineAddresses[NumTrampolines*2]; -static sqInt trampolineTableIndex; -static sqInt uncheckedEntryAlignment; -static usqInt unpairedMethodList; -static sqInt useTwoPaths; -static sqInt varBaseAddress; -static usqInt youngReferrers; -static AbstractInstruction aMethodLabel; -static AbstractInstruction * const backEnd = &aMethodLabel; -#if DUAL_MAPPED_CODE_ZONE -static void (*ceFlushDCache)(usqIntptr_t from, usqIntptr_t to); -#endif -#if IMMUTABILITY -static sqInt ceStoreTrampolines[5];; -#endif -#if DUAL_MAPPED_CODE_ZONE -static sqInt codeToDataDelta; -#else -# define codeToDataDelta 0 -#endif -static AbstractInstruction * const methodLabel = &aMethodLabel; -static float thresholdRatio = 0.5f; -sqInt blockNoContextSwitchOffset; -sqInt breakPC; -sqInt cbEntryOffset; -sqInt cbNoSwitchEntryOffset; -sqInt ceBaseFrameReturnTrampoline; -sqInt ceCannotResumeTrampoline; -sqInt ceCheckForInterruptTrampoline; -sqInt ceReturnToInterpreterTrampoline; -sqInt cFramePointerInUse; -sqInt cmEntryOffset; -sqInt cmNoCheckEntryOffset; -usqInt methodZoneBase; -sqInt missOffset; -int traceFlags = 8 /* prim trace log on by default */; -sqInt traceStores; -void (*ceCall0ArgsPIC)(void); -void (*ceCall1ArgsPIC)(void); -void (*ceCall2ArgsPIC)(void); -void (*ceCallCogCodePopReceiverAndClassRegs)(void); -void (*ceCallCogCodePopReceiverArg0Regs)(void); -void (*ceCallCogCodePopReceiverArg1Arg0Regs)(void); -void (*ceCallCogCodePopReceiverReg)(void); -void (*ceCaptureCStackPointers)(void); -void (*ceEnterCogCodePopReceiverReg)(void); -usqIntptr_t (*ceGetFP)(void); -usqIntptr_t (*ceGetSP)(void); -void (*ceInvokeInterpret)(void); -#if COGMTVM -usqIntptr_t (*ceTryLockVMOwner)(usqIntptr_t); -#endif -void (*realCECallCogCodePopReceiverAndClassRegs)(void); -void (*realCECallCogCodePopReceiverArg0Regs)(void); -void (*realCECallCogCodePopReceiverArg1Arg0Regs)(void); -void (*realCECallCogCodePopReceiverReg)(void); -void (*realCEEnterCogCodePopReceiverReg)(void); - - -/*** Macros ***/ -#define inlineCacheValueForSelectorin(backEnd,selector,aCogMethod) (selector) -#define roundUpToMethodAlignment(ignored,numBytes) ((numBytes) + 7 & -8) -#define cPICNumCases stackCheckOffset -#define cPICNumCasesHack hack hack hack i.e. the getter macro does all the work -#define abstractInstructionAt(index) (&abstractOpcodes[index]) -#define addressIsInInstructions(address) (!((usqInt)(address) & (BytesPerWord-1)) \ - && (address) >= &abstractOpcodes[0] \ - && (address) < &abstractOpcodes[opcodeIndex]) -#define allocateBlockStarts(numBlocks) do { \ - blockStarts = (numBlocks) ? alloca(sizeof(BlockStart) * (numBlocks)) : 0; \ -} while (0) -#define assertValidDualZoneReadAddress(address) 0 -#define assertValidDualZoneWriteAddress(address) 0 -#define backEnd() backEnd -#define blockAlignment() 8 -#define blockStartAt(index) (&blockStarts[index]) -#define breakOnImplicitReceiver() (traceFlags & 64) -#define ceBaseFrameReturnPC() ceBaseFrameReturnTrampoline -#define ceCannotResumePC() ((usqInt)ceCannotResumeTrampoline) -#define ceCheckForInterruptTrampoline() ceCheckForInterruptTrampoline -#define ceReturnToInterpreterPC() ((usqInt)ceReturnToInterpreterTrampoline) -#define codeByteAtput(address,value) byteAtput((address) + codeToDataDelta, value) -#define codeLong32Atput(address,value) long32Atput((address) + codeToDataDelta, value) -#define codeLong64Atput(address,value) long64Atput((address) + codeToDataDelta, value) -#define codeLongAtput(address,value) longAtput((address) + codeToDataDelta, value) -#define codeMemcpy(dest,src,bytes) memcpy(dest,src,bytes) -#define codeMemmove(dest,src,bytes) memmove((char *)(dest)+codeToDataDelta,src,bytes) -#define cr() putchar('\n') -#define entryOffset() cmEntryOffset -#define generatorAt(index) (&generatorTable[index]) -#define getCodeToDataDelta() codeToDataDelta -#define getIsObjectReference() 2 -#define halt() warning("halt") -#define haltmsg(msg) warning("halt: " msg) -#define interpretOffset() missOffset -#define maxCogCodeSize() (16*1024*1024) -#define maybeBreakGeneratingFromto(address,end) 0 -#define maybeBreakGeneratingInstructionWithIndex(i) 0 -#define maybeHaltIfDebugPC() 0 -#define methodLabel() methodLabel -#define methodZoneBase() methodZoneBase -#define minCallAddress() minValidCallAddress -#define minCogMethodAddress() methodZoneBase -#define noCheckEntryOffset() cmNoCheckEntryOffset -#define noContextSwitchBlockEntryOffset() blockNoContextSwitchOffset -#define notYetImplemented() warning("not yet implemented") -#define null 0 -#define printNum(n) printf("%" PRIdSQINT, (sqInt) (n)) -#define printOnTrace() (traceFlags & 1) -#define print(aString) printf("%s", aString) -#define recordBlockTrace() (traceFlags & 4) -#define recordEventTrace() (traceFlags & 16) -#define recordFastCCallPrimTrace() (traceFlags & 512) -#define recordOverflowTrace() (traceFlags & 32) -#define recordPrimTrace() (traceFlags & 8) -#define recordSendTrace() (traceFlags & 2) -#define reportError(n) warning("compilation error") -#define setHasMovableLiteral(b) (hasMovableLiteral = (b)) -#define setHasYoungReferent(b) (hasYoungReferent = (b)) -#define tryLockVMOwnerTo(value) ceTryLockVMOwner(value) -#define varBaseAddress() varBaseAddress -#define nextOpenPIC methodObject -#define nextOpenPICHack hack hack hack i.e. the getter macro does all the work -#define freeStart() mzFreeStart -#define limitZony() ((CogMethod *)mzFreeStart) -#define methodBytesFreedSinceLastCompaction() methodBytesFreedSinceLastCompaction -#define youngReferrers() youngReferrers -#define flushDCacheFromto(me,startAddress,endAddress) 0 -#define flushICacheFromto(me,startAddress,endAddress) cacheflush((char*) startAddress, endAddress - startAddress, ICACHE) -#define maybeConstant(sse) ((sse)->constant) -#define fullBlockEntryOffset() cbEntryOffset -#define fullBlockNoContextSwitchEntryOffset() cbNoSwitchEntryOffset -#define fixupAtIndex(index) (&fixups[index]) -#define simNativeStackAt(index) (simNativeStack + (index)) -#define simSelf() simStack -#define simStackAt(index) (simStack + (index)) -#define traceDescriptor(ign) 0 -#define traceFixupmerge(igu,ana) 0 -#define traceMerge(ign) 0 -#define traceSimStack() 0 -#define traceSpill(ign) 0 -#define allocatype(numElements, elementType) alloca((numElements)*sizeof(elementType)) -#define numElementsIn(anArray) (sizeof(anArray)/sizeof(anArray[0])) -#define oopisGreaterThanOrEqualTo(anOop,otherOop) ((usqInt)(anOop) >= (usqInt)(otherOop)) -#define oopisGreaterThanOrEqualToandLessThanOrEqualTo(anOop,baseOop,limitOop) ((usqInt)(anOop) >= (usqInt)(baseOop) && (usqInt)(anOop) <= (usqInt)(limitOop)) -#define oopisGreaterThanOrEqualToandLessThan(anOop,baseOop,limitOop) ((usqInt)(anOop) >= (usqInt)(baseOop) && (usqInt)(anOop) < (usqInt)(limitOop)) -#define oopisGreaterThan(anOop,otherOop) ((usqInt)(anOop) > (usqInt)(otherOop)) -#define oopisGreaterThanandLessThan(anOop,baseOop,limitOop) ((usqInt)(anOop) > (usqInt)(baseOop) && (usqInt)(anOop) < (usqInt)(limitOop)) -#define oopisLessThanOrEqualTo(anOop,otherOop) ((usqInt)(anOop) <= (usqInt)(otherOop)) -#define oopisLessThan(anOop,otherOop) ((usqInt)(anOop) < (usqInt)(otherOop)) - - - /* CogAbstractInstruction>>#addDependent: */ -static AbstractInstruction * NoDbgRegParms -addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *anInstruction) -{ - if (!(((self_in_addDependent->dependent)) == null)) { - (anInstruction->dependent = (self_in_addDependent->dependent)); - } - return ((self_in_addDependent->dependent) = anInstruction); -} - - -/* Answer an unused abstract register in the liveRegMask. - Subclasses with more registers can override to answer them. */ - - /* CogAbstractInstruction>>#availableFloatRegisterOrNoneFor: */ -static sqInt NoDbgRegParms -availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask) -{ - if (!(((liveRegsMask & (1U << DPFPReg0)) != 0))) { - return DPFPReg0; - } - if (!(((liveRegsMask & (1U << DPFPReg1)) != 0))) { - return DPFPReg1; - } - if (!(((liveRegsMask & (1U << DPFPReg2)) != 0))) { - return DPFPReg2; - } - if (!(((liveRegsMask & (1U << DPFPReg3)) != 0))) { - return DPFPReg3; - } - if (!(((liveRegsMask & (1U << DPFPReg4)) != 0))) { - return DPFPReg4; - } - if (!(((liveRegsMask & (1U << DPFPReg5)) != 0))) { - return DPFPReg5; - } - if (!(((liveRegsMask & (1U << DPFPReg6)) != 0))) { - return DPFPReg6; - } - if (!(((liveRegsMask & (1U << DPFPReg7)) != 0))) { - return DPFPReg7; - } - return NoReg; -} - - -/* Answer an unused abstract register in the liveRegMask. - Subclasses with more registers can override to answer them. - N.B. Do /not/ allocate TempReg. */ - - /* CogAbstractInstruction>>#availableRegisterOrNoneFor: */ -static sqInt NoDbgRegParms -availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask) -{ - if (!(((liveRegsMask & (1U << Arg1Reg)) != 0))) { - return Arg1Reg; - } - if (!(((liveRegsMask & (1U << Arg0Reg)) != 0))) { - return Arg0Reg; - } - if (!(((liveRegsMask & (1U << SendNumArgsReg)) != 0))) { - return SendNumArgsReg; - } - if (!(((liveRegsMask & (1U << ClassReg)) != 0))) { - return ClassReg; - } - if (!(((liveRegsMask & (1U << ReceiverResultReg)) != 0))) { - return ReceiverResultReg; - } - return NoReg; -} - - -/* For out-of-line literal support, clone a literal from a literal. */ - - /* CogAbstractInstruction>>#cloneLiteralFrom: */ -static void NoDbgRegParms -cloneLiteralFrom(AbstractInstruction * self_in_cloneLiteralFrom, AbstractInstruction *existingLiteral) -{ - assert((((existingLiteral->opcode)) == Literal) - && ((((self_in_cloneLiteralFrom->dependent)) == null) - && (((self_in_cloneLiteralFrom->address)) == null))); - (self_in_cloneLiteralFrom->opcode) = Literal; - (self_in_cloneLiteralFrom->annotation) = (existingLiteral->annotation); - ((self_in_cloneLiteralFrom->operands))[0] = (((existingLiteral->operands))[0]); - ((self_in_cloneLiteralFrom->operands))[1] = (((existingLiteral->operands))[1]); - ((self_in_cloneLiteralFrom->operands))[2] = (((existingLiteral->operands))[2]); -} - - -/* Load the stack pointer register with that of the C stack, effecting - a switch to the C stack. Used when machine code calls into the - CoInterpreter run-time (e.g. to invoke interpreter primitives). */ - - /* CogAbstractInstruction>>#genLoadCStackPointer */ -static sqInt NoDbgRegParms -genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer) -{ - AbstractInstruction *anInstruction; - - /* begin checkLiteral:forInstruction: */ - cStackPointerAddress(); - anInstruction = genoperandoperand(MoveAwR, cStackPointerAddress(), NativeSPReg); - return 0; -} - - -/* Load the frame and stack pointer registers with those of the C stack, - effecting a switch to the C stack. Used when machine code calls into - the CoInterpreter run-time (e.g. to invoke interpreter primitives). - N.B. CoInterpreter stack layout dictates that the stack pointer should be - loaded first. - The stack zone is allocated on the C stack before the interpreter runs and - hence before CStackPointer and CFramePointer are captured. So when running - in machine - code the native stack pointer and frame pointer appear to be on a colder - part of the - stack to CStackPointer and CFramePointer. When CStackPointerhas been set - and the frame pointer is still in machine code the current frame looks - like it has lots of - stack. If the frame pointer was set to CFramePointer before hand then it - would be beyond the stack pointer for that one instruction. */ - - /* CogAbstractInstruction>>#genLoadCStackPointers */ -static sqInt NoDbgRegParms -genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkLiteral:forInstruction: */ - cStackPointerAddress(); - anInstruction = genoperandoperand(MoveAwR, cStackPointerAddress(), NativeSPReg); - /* begin checkLiteral:forInstruction: */ - cFramePointerAddress(); - anInstruction1 = genoperandoperand(MoveAwR, cFramePointerAddress(), FPReg); - return 0; -} - - -/* Switch back to the Smalltalk stack. Assign SPReg first - because typically it is used immediately afterwards. */ - - /* CogAbstractInstruction>>#genLoadStackPointers */ -static sqInt NoDbgRegParms -genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkLiteral:forInstruction: */ - stackPointerAddress(); - anInstruction = genoperandoperand(MoveAwR, stackPointerAddress(), SPReg); - /* begin checkLiteral:forInstruction: */ - framePointerAddress(); - anInstruction1 = genoperandoperand(MoveAwR, framePointerAddress(), FPReg); - return 0; -} - - -/* Switch back to the Smalltalk stack where there may be a C return address - on top of stack below - the last primitive argument. Assign SPReg first because typically it is - used immediately afterwards. - */ - - /* CogAbstractInstruction>>#genLoadStackPointersForFastPrimCall: */ -static sqInt NoDbgRegParms -genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg) -{ - genLoadStackPointers(self_in_genLoadStackPointersForFastPrimCall); - return 0; -} - - -/* Save the frame and stack pointer registers to the framePointer - and stackPointer variables. Used to save the machine code frame - for use by the run-time when calling into the CoInterpreter run-time. */ - - /* CogAbstractInstruction>>#genSaveStackPointers */ -static sqInt NoDbgRegParms -genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkLiteral:forInstruction: */ - framePointerAddress(); - anInstruction = genoperandoperand(MoveRAw, FPReg, framePointerAddress()); - /* begin checkLiteral:forInstruction: */ - stackPointerAddress(); - anInstruction1 = genoperandoperand(MoveRAw, SPReg, stackPointerAddress()); - return 0; -} - - -/* Generic register swap code. Subclasses for processors that have a true - exchange operation will override to use it. */ - - /* CogAbstractInstruction>>#genSwapR:R:Scratch: */ -static AbstractInstruction * NoDbgRegParms -genSwapRRScratch(AbstractInstruction * self_in_genSwapRRScratch, sqInt regA, sqInt regB, sqInt regTmp) -{ - AbstractInstruction *first; - - first = genoperandoperand(MoveRR, regA, regTmp); - genoperandoperand(MoveRR, regB, regA); - genoperandoperand(MoveRR, TempReg, regB); - return first; -} - - /* CogAbstractInstruction>>#genWriteCResultIntoReg: */ -static void NoDbgRegParms -genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister) -{ - if ((abstractRegister != NoReg) - && (abstractRegister != ABIResultReg)) { - genoperandoperand(MoveRR, ABIResultReg, abstractRegister); - } -} - - -/* For out-of-line literal support, initialize a sharable literal. */ - - /* CogAbstractInstruction>>#initializeSharableLiteral: */ -static void NoDbgRegParms -initializeSharableLiteral(AbstractInstruction * self_in_initializeSharableLiteral, sqInt literal) -{ - (self_in_initializeSharableLiteral->opcode) = Literal; - - /* separate := nil for Slang */ - (self_in_initializeSharableLiteral->annotation) = null; - (self_in_initializeSharableLiteral->address) = null; - (self_in_initializeSharableLiteral->dependent) = null; - ((self_in_initializeSharableLiteral->operands))[0] = literal; - ((self_in_initializeSharableLiteral->operands))[1] = (1 + (((sqInt)((usqInt)(BytesPerOop) << 1)))); - ((self_in_initializeSharableLiteral->operands))[2] = -1; -} - - -/* For out-of-line literal support, initialize an unsharable literal. */ - - /* CogAbstractInstruction>>#initializeUniqueLiteral: */ -static void NoDbgRegParms -initializeUniqueLiteral(AbstractInstruction * self_in_initializeUniqueLiteral, sqInt literal) -{ - (self_in_initializeUniqueLiteral->opcode) = Literal; - - /* separate := nil for Slang */ - (self_in_initializeUniqueLiteral->annotation) = null; - (self_in_initializeUniqueLiteral->address) = null; - (self_in_initializeUniqueLiteral->dependent) = null; - ((self_in_initializeUniqueLiteral->operands))[0] = literal; - ((self_in_initializeUniqueLiteral->operands))[1] = (0 + (((sqInt)((usqInt)(BytesPerOop) << 1)))); - ((self_in_initializeUniqueLiteral->operands))[2] = -1; -} - - -/* Answer if an address can be accessed using the offset in a MoveMw:r:R: or - similar instruction. - We assume this is true for 32-bit processors and expect 64-bit processors - to answer false - for values in the interpreter or the object memory. */ - - /* CogAbstractInstruction>>#isWithinMwOffsetRange: */ -static sqInt NoDbgRegParms -isWithinMwOffsetRange(AbstractInstruction * self_in_isWithinMwOffsetRange, sqInt anAddress) -{ - return 1; -} - - -/* Set the target of a jump instruction. These all have the target in the - first operand. */ - - /* CogAbstractInstruction>>#jmpTarget: */ -static AbstractInstruction * NoDbgRegParms -jmpTarget(AbstractInstruction * self_in_jmpTarget, AbstractInstruction *anAbstractInstruction) -{ - ((self_in_jmpTarget->operands))[0] = (((usqInt)anAbstractInstruction)); - return anAbstractInstruction; -} - - /* CogAbstractInstruction>>#resolveJumpTarget */ -static void NoDbgRegParms -resolveJumpTarget(AbstractInstruction * self_in_resolveJumpTarget) -{ - BytecodeFixup *fixup; - - assert(isJump(self_in_resolveJumpTarget)); - fixup = ((BytecodeFixup *) (((self_in_resolveJumpTarget->operands))[0])); - if (addressIsInFixups(fixup)) { - assert(addressIsInInstructions((fixup->targetInstruction))); - jmpTarget(self_in_resolveJumpTarget, (fixup->targetInstruction)); - } -} - - -/* Rewrite a CallFull instruction to call a different target. This variant is - used to rewrite cached primitive calls. - Answer the extent of the code change which is used to compute the range of - the icache to flush. - This defaults to rewriteCallAt:target:; processors that differentiate - between Call and CallFull will override. */ - - /* CogAbstractInstruction>>#rewriteCallFullAt:target: */ -static sqInt NoDbgRegParms -rewriteCallFullAttarget(AbstractInstruction * self_in_rewriteCallFullAttarget, sqInt callSiteReturnAddress, sqInt callTargetAddress) -{ - return rewriteCallAttarget(self_in_rewriteCallFullAttarget, callSiteReturnAddress, callTargetAddress); -} - - -/* Rewrite a JumpFull instruction to jump to a different target. This variant - is used to rewrite cached primitive calls. - Answer the extent of the code change which is used to compute the range of - the icache to flush. - This defaults to rewriteJumpLongAt:target:; processors that differentiate - between Jump and JumpFull will override. */ - - /* CogAbstractInstruction>>#rewriteJumpFullAt:target: */ -static sqInt NoDbgRegParms -rewriteJumpFullAttarget(AbstractInstruction * self_in_rewriteJumpFullAttarget, sqInt callSiteReturnAddress, sqInt callTargetAddress) -{ - return rewriteJumpLongAttarget(self_in_rewriteJumpFullAttarget, callSiteReturnAddress, callTargetAddress); -} - - /* CogBlockMethod>>#cmHomeMethod */ -static CogMethod * NoDbgRegParms -cmHomeMethod(CogBlockMethod * self_in_cmHomeMethod) -{ - return ((self_in_cmHomeMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? ((CogMethod *) self_in_cmHomeMethod) - : ((CogMethod *) ((((usqInt)self_in_cmHomeMethod)) - ((self_in_cmHomeMethod->homeOffset))))); -} - - /* CogBytecodeDescriptor>>#isBranch */ -static sqInt NoDbgRegParms -isBranch(BytecodeDescriptor * self_in_isBranch) -{ - return (((self_in_isBranch->spanFunction)) != null) - && (!((self_in_isBranch->isBlockCreation))); -} - - /* Cogit>>#AddCq:R: */ -static AbstractInstruction * NoDbgRegParms -gAddCqR(sqInt quickConstant, sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, quickConstant, reg); - return anInstruction; -} - - -/* N.B. if the condition codes don't require setting and three address - arithmetic is unavailable, then LoadEffectiveAddressMw:r:R: can be used - instead. - */ - - /* Cogit>>#AddCq:R:R: */ -static AbstractInstruction * NoDbgRegParms -gAddCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction * first; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(AddCqRR, quickConstant, srcReg, destReg); - return anInstruction2; - if (srcReg == destReg) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, quickConstant, destReg); - return anInstruction; - } - first = genoperandoperand(MoveRR, srcReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AddCqR, quickConstant, destReg); - return first; -} - - /* Cogit>>#AndCq:R: */ -static AbstractInstruction * NoDbgRegParms -gAndCqR(sqInt quickConstant, sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, quickConstant, reg); - return anInstruction; -} - - /* Cogit>>#AndCq:R:R: */ -static AbstractInstruction * NoDbgRegParms -gAndCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction * first; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(AndCqRR, quickConstant, srcReg, destReg); - return anInstruction2; - if (srcReg == destReg) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, quickConstant, destReg); - return anInstruction; - } - first = genoperandoperand(MoveRR, srcReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, quickConstant, destReg); - return first; -} - - -/* destReg := (signed)srcReg >> quickConstant */ - - /* Cogit>>#ArithmeticShiftRightCq:R:R: */ -static AbstractInstruction * NoDbgRegParms -gArithmeticShiftRightCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) -{ - AbstractInstruction * first; - - return genoperandoperandoperand(ArithmeticShiftRightCqRR, quickConstant, srcReg, destReg); - first = genoperandoperand(MoveRR, srcReg, destReg); - genoperandoperand(ArithmeticShiftRightCqR, quickConstant, destReg); - return first; -} - - /* Cogit>>#abortOffset */ -sqInt -abortOffset(void) -{ - return missOffset; -} - - /* Cogit>>#addCleanBlockStarts */ -static void -addCleanBlockStarts(void) -{ - sqInt i; - sqInt iLimiT; - sqInt lit; - sqInt startPCOrNil; - - for (i = 1, iLimiT = (literalCountOf(methodObj)); i <= iLimiT; i += 1) { - lit = fetchPointerofObject(i, methodObj); - startPCOrNil = startPCOrNilOfLiteralin(lit, methodObj); - if (!(startPCOrNil == null)) { - maxLitIndex = ((maxLitIndex < i) ? i : maxLitIndex); - addBlockStartAtnumArgsnumCopiedspan(startPCOrNil - 1, argumentCountOfClosure(lit), copiedValueCountOfClosure(lit), spanForCleanBlockStartingAt(startPCOrNil - 1)); - } - } -} - - -/* Perform an integrity/leak check using the heapMap. - Set a bit at each cog method's header. */ - - /* Cogit>>#addCogMethodsToHeapMap */ -void -addCogMethodsToHeapMap(void) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - heapMapAtWordPut(cogMethod, 1); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* Cogit>>#addressIsInCurrentCompilation: */ -static sqInt NoDbgRegParms -addressIsInCurrentCompilation(sqInt address) -{ - return ((((usqInt)address)) >= ((methodLabel->address))) - && ((((usqInt)address)) < ((((youngReferrers()) < (((methodLabel->address)) + MaxMethodSize)) ? (youngReferrers()) : (((methodLabel->address)) + MaxMethodSize)))); -} - - /* Cogit>>#addressIsInFixups: */ -static sqInt NoDbgRegParms -addressIsInFixups(BytecodeFixup *address) -{ - return (BytecodeFixup *)address >= fixups && (BytecodeFixup *)address < (fixups + numAbstractOpcodes); -} - - -/* calculate the end of the n'th case statement - which is complicated - because we have case 1 right at the top of our CPIC and then build up from - the last one. Yes I know this sounds strange, but trust me - I'm an - Engineer, we do things backwards all the emit - */ - - /* Cogit>>#addressOfEndOfCase:inCPIC: */ -static sqInt NoDbgRegParms -addressOfEndOfCaseinCPIC(sqInt n, CogMethod *cPIC) -{ - assert((n >= 1) - && (n <= MaxCPICCases)); - return (n == 1 - ? (((sqInt)cPIC)) + firstCPICCaseOffset - : ((((sqInt)cPIC)) + firstCPICCaseOffset) + (((MaxCPICCases + 1) - n) * cPICCaseSize)); -} - - -/* Align methodZoneBase to that for the start of a method. */ - - /* Cogit>>#alignMethodZoneBase */ -static void -alignMethodZoneBase(void) -{ - usqInt oldBase; - - oldBase = methodZoneBase; - methodZoneBase = roundUpToMethodAlignment(backEnd(), methodZoneBase); - stopsFromto(backEnd, oldBase, methodZoneBase - 1); -} - - /* Cogit>>#alignUptoRoutineBoundary: */ -static sqInt NoDbgRegParms -alignUptoRoutineBoundary(sqInt anAddress) -{ - return (((anAddress + 7) | 7) - 7); -} - - -/* Check that all methods have valid selectors, and that all linked sends are - to valid targets and have valid cache tags - */ - - /* Cogit>>#allMachineCodeObjectReferencesValid */ -static sqInt -allMachineCodeObjectReferencesValid(void) -{ - CogMethod *cogMethod; - sqInt ok; - - ok = 1; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - if (!(asserta(checkValidOopReference((cogMethod->selector))))) { - ok = 0; - } - if (!(asserta((cogMethodDoesntLookKosher(cogMethod)) == 0))) { - ok = 0; - } - } - if ((((cogMethod->cmType)) == CMMethod) - || (((cogMethod->cmType)) == CMOpenPIC)) { - if (!(asserta((mapForperformUntilarg(cogMethod, checkIfValidOopRefAndTargetpccogMethod, cogMethod)) == 0))) { - ok = 0; - } - } - if ((((cogMethod->cmType)) == CMMethod) - && (1)) { - if (((cogMethod->counters)) != 0) { - if (!(asserta(checkValidDerivedObjectReference((cogMethod->counters))))) { - ok = 0; - } - } - } - if (((cogMethod->cmType)) == CMClosedPIC) { - if (!(asserta(noTargetsFreeInClosedPIC(cogMethod)))) { - ok = 0; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return ok; -} - - /* Cogit>>#allMethodsHaveCorrectHeader */ -static sqInt -allMethodsHaveCorrectHeader(void) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - if (!(((cogMethod->objectHeader)) == (nullHeaderForMachineCodeMethod()))) { - return 0; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return 1; -} - - /* Cogit>>#annotateAbsolutePCRef: */ -static AbstractInstruction * NoDbgRegParms -annotateAbsolutePCRef(AbstractInstruction *abstractInstruction) -{ - (abstractInstruction->annotation = IsAbsPCReference); - return abstractInstruction; -} - - /* Cogit>>#annotateBytecode: */ -static AbstractInstruction * NoDbgRegParms -annotateBytecode(AbstractInstruction *abstractInstruction) -{ - (abstractInstruction->annotation = HasBytecodePC); - return abstractInstruction; -} - - /* Cogit>>#annotate:objRef: */ -static AbstractInstruction * NoDbgRegParms -annotateobjRef(AbstractInstruction *abstractInstruction, sqInt anOop) -{ - if (shouldAnnotateObjectReference(anOop)) { - setHasMovableLiteral(1); - if (isYoungObject(anOop)) { - setHasYoungReferent(1); - } - (abstractInstruction->annotation = IsObjectReference); - } - return abstractInstruction; -} - - /* Cogit>>#assertSaneJumpTarget: */ -static void NoDbgRegParms -assertSaneJumpTarget(AbstractInstruction *jumpTarget) -{ - assert((closedPICSize == null) - || ((openPICSize == null) - || ((addressIsInInstructions(jumpTarget)) - || ((((((usqInt)jumpTarget)) >= codeBase) && ((((usqInt)jumpTarget)) <= ((((sqInt)(limitZony()))) + (((closedPICSize < openPICSize) ? openPICSize : closedPICSize))))))))); -} - - -/* {self firstInvalidDualZoneAddress. self firstInvalidDualZoneAddress + - codeToDataDelta } - */ -/* {self firstInvalidDualZoneAddress hex. (self firstInvalidDualZoneAddress + - codeToDataDelta) hex } - */ -/* {(objectMemory longAt: self firstInvalidDualZoneAddress) hex. - (objectMemory longAt: self firstInvalidDualZoneAddress + codeToDataDelta) - hex } - */ -/* self armDisassembleDualZoneAnomalies */ -/* self armPrintDualZoneAnomalies */ - - /* Cogit>>#assertValidDualZone */ -static void -assertValidDualZone(void) -{ -} - - -/* Answer an unused abstract register in the registerMask, or NoReg if none. */ - - /* Cogit>>#availableRegisterOrNoneIn: */ -static sqInt NoDbgRegParms -availableRegisterOrNoneIn(sqInt liveRegsMask) -{ - sqInt reg; - - if (liveRegsMask != 0) { - for (reg = 0; reg <= 0x1F; reg += 1) { - if (((liveRegsMask & (1U << reg)) != 0)) { - return reg; - } - } - } - return NoReg; -} - - -/* Evaluate binaryFunction with the block start mcpc and supplied arg for - each entry in the block dispatch. If the function answers non-zero answer - the value - it answered. Used to update back-references to the home method in - compaction. */ - - /* Cogit>>#blockDispatchTargetsFor:perform:arg: */ -static sqInt NoDbgRegParms -blockDispatchTargetsForperformarg(CogMethod *cogMethod, usqInt (*binaryFunction)(sqInt mcpc, sqInt arg), sqInt arg) -{ - sqInt blockEntry; - usqInt end; - sqInt pc; - sqInt result; - usqInt targetpc; - - if (((cogMethod->blockEntryOffset)) == 0) { - return null; - } - blockEntry = ((cogMethod->blockEntryOffset)) + (((sqInt)cogMethod)); - pc = blockEntry; - end = (mapEndFor(cogMethod)) - 1; - while (pc < end) { - if (isJumpAt(backEnd, pc)) { - targetpc = jumpTargetPCAt(backEnd, pc); - if (targetpc < blockEntry) { - result = binaryFunction(targetpc, arg); - if (result != 0) { - return result; - } - } - } - pc += 4 /* instructionSizeAt: */; - } - return 0; -} - - -/* Answer the zero-relative bytecode pc matching the machine code pc argument - in cogMethod, given the start of the bytecodes for cogMethod's block or - method object. */ - - /* Cogit>>#bytecodePCFor:startBcpc:in: */ -sqInt -bytecodePCForstartBcpcin(sqInt mcpc, sqInt startbcpc, CogBlockMethod *cogMethod) -{ - sqInt aMethodHeader; - sqInt aMethodHeader1; - sqInt aMethodObj; - sqInt annotation; - sqInt bcpc; - sqInt bsOffset; - sqInt byte; - sqInt byte01; - sqInt byte02; - BytecodeDescriptor *descriptor; - sqInt distance; - sqInt distance1; - sqInt distance2; - sqInt endbcpc; - CogMethod *homeMethod; - sqInt isBackwardBranch; - sqInt isInBlock; - sqInt latestContinuation; - usqInt map; - sqInt mapByte; - usqInt mcpc1; - sqInt nExts; - sqInt newContinuation; - sqInt nextBcpc; - sqInt prim; - sqInt result; - sqInt targetPC; - sqInt targetPC1; - sqInt upperByte; - - latestContinuation = 0; - /* begin mapFor:bcpc:performUntil:arg: */ - assert(((cogMethod->stackCheckOffset)) > 0); - - /* The stack check maps to the start of the first bytecode, - the first bytecode being effectively after frame build. */ - mcpc1 = (((usqInt)cogMethod)) + ((cogMethod->stackCheckOffset)); - result = findIsBackwardBranchMcpcBcpcMatchingMcpc(null, (0 + (((int)((usqInt)(HasBytecodePC) << 1)))), (((char *) mcpc1)), startbcpc, (((void *)mcpc))); - if (result != 0) { - return result; - } - - /* In both CMMethod and CMBlock cases find the start of the map and - skip forward to the bytecode pc map entry for the stack check. */ - bcpc = startbcpc; - if (((cogMethod->cmType)) == CMMethod) { - /* begin cmIsFullBlock */ - isInBlock = (cogMethod->cpicHasMNUCaseOrCMIsFullBlock); - homeMethod = ((CogMethod *) cogMethod); - assert(startbcpc == (startPCOfMethodHeader((homeMethod->methodHeader)))); - map = ((((usqInt)homeMethod)) + ((homeMethod->blockSize))) - 1; - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert((annotation == IsAbsPCReference) - || ((annotation == IsObjectReference) - || ((annotation == IsRelativeCall) - || (annotation == IsDisplacementX2N)))); - latestContinuation = startbcpc; - aMethodObj = (homeMethod->methodObject); - endbcpc = (numBytesOf(aMethodObj)) - 1; - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader) - ? 0x100 - : 0) -# else - 0 -# endif - ; - bcpc += deltaToSkipPrimAndErrorStoreInheader(aMethodObj, (homeMethod->methodHeader)); - } - else { - isInBlock = 1; - assert(bcpc == ((cogMethod->startpc))); - homeMethod = cmHomeMethod(cogMethod); - map = findMapLocationForMcpcinMethod((((usqInt)cogMethod)) + (sizeof(CogBlockMethod)), homeMethod); - assert(map != 0); - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert(((((usqInt)(annotation)) >> AnnotationShift) == HasBytecodePC) - || ((((usqInt)(annotation)) >> AnnotationShift) == IsDisplacementX2N)); - while (((annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift)) != HasBytecodePC) { - map -= 1; - } - - /* skip fiducial; i.e. the map entry for the pc immediately following the method header. */ - map -= 1; - aMethodObj = (homeMethod->methodObject); - bcpc = startbcpc - ( -#if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet((homeMethod->methodHeader)) - ? AltBlockCreationBytecodeSize - : BlockCreationBytecodeSize) -#else // MULTIPLEBYTECODESETS - BlockCreationBytecodeSize -#endif - ); - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader1 = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader1) - ? 0x100 - : 0) -# else - 0 -# endif - ; - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - endbcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, -1, aMethodObj)) - : 0)); - bcpc = startbcpc; - } - nExts = 0; - while ((((usqInt)((byteAt(map)))) >> AnnotationShift) != HasBytecodePC) { - map -= 1; - } - map -= 1; - while (((mapByte = byteAt(map))) != MapEnd) { - - /* defensive; we exit on bcpc */ - if (mapByte >= FirstAnnotation) { - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - mcpc1 += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if (annotation >= HasBytecodePC) { - if ((annotation == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - while (1) { - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - if (isInBlock) { - if (bcpc >= endbcpc) { - return 0; - } - } - else { - if (((descriptor->isReturn)) - && (bcpc >= latestContinuation)) { - return 0; - } - if ((isBranch(descriptor)) - || ((descriptor->isBlockCreation))) { - /* begin latestContinuationPCFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj); - targetPC = (bcpc + ((descriptor->numBytes))) + (((distance < 0) ? 0 : distance)); - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - /* begin maybeUnsafeJumpContinuation:at:for:in: */ - newContinuation = latestContinuation; - if ((descriptor->hasUnsafeJump)) { - byte01 = fetchByteofObject(bcpc + 1, aMethodObj); - - /* pushIntegerLong */ - byte02 = fetchByteofObject(bcpc + 2, aMethodObj); - /* begin decodePushIntegerLongBefore:in: */ - distance1 = fetchByteofObject(bcpc - 1, methodObj); - upperByte = fetchByteofObject(bcpc - 3, methodObj); - if (upperByte > 0x7F) { - upperByte -= 0x100; - } - distance2 = (((sqInt)((usqInt)(upperByte) << 8))) + distance1; - targetPC1 = (bcpc + ((descriptor->numBytes))) + distance2; - if (!((descriptor->isMapped))) { - if ((((usqInt)(byte02)) >> 5) == 4) { - - /* inlined sista primitive */ - prim = (((sqInt)((usqInt)((byte02 & 0x1F)) << 8))) + byte01; - if (prim >= 7000) { - - /* branch forward */ - newContinuation = ((latestContinuation < targetPC1) ? targetPC1 : latestContinuation); - } - } - } - } - latestContinuation = newContinuation; - } - nextBcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) - : 0)); - if (((descriptor->isMapped)) - || (isInBlock - && ((descriptor->isMappedInBlock)))) break; - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - isBackwardBranch = (isBranch(descriptor)) - && ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) < 0)); - result = findIsBackwardBranchMcpcBcpcMatchingMcpc(descriptor, ((isBackwardBranch - ? (((sqInt)((usqInt)(annotation) << 1))) + 1 - : ((sqInt)((usqInt)(annotation) << 1)))), (((char *) mcpc1)), ((isBackwardBranch - ? bcpc - (2 * nExts) - : bcpc)), (((void *)mcpc))); - if (result != 0) { - return result; - } - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - } - else { - assert(((((usqInt)(mapByte)) >> AnnotationShift) == IsDisplacementX2N) - || ((((usqInt)(mapByte)) >> AnnotationShift) == IsAnnotationExtension)); - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc1 += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - return 0; -} - - /* Cogit>>#CallRT:registersToBeSavedMask: */ -static AbstractInstruction * NoDbgRegParms -CallRTregistersToBeSavedMask(sqInt callTarget, sqInt registersToBeSaved) -{ - AbstractInstruction *abstractInstruction; - sqInt callerSavedRegsToBeSaved; - AbstractInstruction *lastInst; - sqInt reg; - sqInt registersToBePushed; - - reg = 0; - callerSavedRegsToBeSaved = CallerSavedRegisterMask & registersToBeSaved; - registersToBePushed = callerSavedRegsToBeSaved; - reg = 0; - while (registersToBePushed != 0) { - if (((registersToBePushed & 1) != 0)) { - genoperand(PushR, reg); - } - reg += 1; - registersToBePushed = (registersToBePushed) >> 1; - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, callTarget); - (abstractInstruction->annotation = IsRelativeCall); - lastInst = abstractInstruction; - while (reg > 0) { - reg -= 1; - if (((callerSavedRegsToBeSaved & (1U << reg)) != 0)) { - lastInst = genoperand(PopR, reg); - } - } - return lastInst; -} - - /* Cogit>>#Call: */ -static AbstractInstruction * NoDbgRegParms -gCall(sqInt callTarget) -{ - return genoperand(Call, callTarget); -} - - /* Cogit>>#CmpCq:R: */ -static AbstractInstruction * NoDbgRegParms -gCmpCqR(sqInt quickConstant, sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, quickConstant, reg); - return anInstruction; -} - - -/* This is a static version of ceCallCogCodePopReceiverReg - for break-pointing when debugging in C. */ -/* This exists only for break-pointing. */ - - /* Cogit>>#callCogCodePopReceiver */ -void -callCogCodePopReceiver(void) -{ - realCECallCogCodePopReceiverReg(); - error("what??"); -} - - -/* This is a static version of ceCallCogCodePopReceiverAndClassRegs - for break-pointing when debugging in C. */ -/* This exists only for break-pointing. */ - - /* Cogit>>#callCogCodePopReceiverAndClassRegs */ -void -callCogCodePopReceiverAndClassRegs(void) -{ - realCECallCogCodePopReceiverAndClassRegs(); -} - - -/* Code entry closed PIC miss. A send has fallen - through a closed (finite) polymorphic inline cache. - Either extend it or patch the send site to an open PIC. - The stack looks like: - receiver - args - sp=> sender return address */ - - /* Cogit>>#ceCPICMiss:receiver: */ -static sqInt NoDbgRegParms -ceCPICMissreceiver(CogMethod *cPIC, sqInt receiver) -{ - sqInt cacheTag; - sqInt errorSelectorOrNil; - sqInt methodOrSelectorIndex; - sqInt newTargetMethodOrNil; - sqInt outerReturn; - sqInt result; - sqInt selector; - - if (isOopForwarded(receiver)) { - return ceSendFromInLineCacheMiss(cPIC); - } - outerReturn = stackTop(); - assert(!(((inlineCacheTagAt(backEnd, outerReturn)) == (picAbortDiscriminatorValue())))); - if (((cPIC->cPICNumCases)) < MaxCPICCases) { - /* begin lookup:for:methodAndErrorSelectorInto: */ - selector = (cPIC->selector); - methodOrSelectorIndex = lookupOrdinaryreceiver(selector, receiver); - if ((((usqInt)methodOrSelectorIndex)) > (maxLookupNoMNUErrorCode())) { - if (!(isOopCompiledMethod(methodOrSelectorIndex))) { - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = SelectorCannotInterpret; - goto l1; - } - if ((!(methodHasCogMethod(methodOrSelectorIndex))) - && (methodShouldBeCogged(methodOrSelectorIndex))) { - - /* We assume cog:selector: will *not* reclaim the method zone */ - cogselector(methodOrSelectorIndex, selector); - } - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = null; - goto l1; - } - if (methodOrSelectorIndex == SelectorDoesNotUnderstand) { - methodOrSelectorIndex = lookupMNUreceiver(splObj(SelectorDoesNotUnderstand), receiver); - if ((((usqInt)methodOrSelectorIndex)) > (maxLookupNoMNUErrorCode())) { - assert(isOopCompiledMethod(methodOrSelectorIndex)); - if ((!(methodHasCogMethod(methodOrSelectorIndex))) - && (methodShouldBeCogged(methodOrSelectorIndex))) { - - /* We assume cog:selector: will *not* reclaim the method zone */ - cogselector(methodOrSelectorIndex, splObj(SelectorDoesNotUnderstand)); - } - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = SelectorDoesNotUnderstand; - goto l1; - } - newTargetMethodOrNil = null; - errorSelectorOrNil = SelectorDoesNotUnderstand; - goto l1; - } - newTargetMethodOrNil = null; - errorSelectorOrNil = methodOrSelectorIndex; - l1: /* end lookup:for:methodAndErrorSelectorInto: */; - } - else { - newTargetMethodOrNil = (errorSelectorOrNil = null); - } - assert(outerReturn == (stackTop())); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - cacheTag = inlineCacheTagForInstance(receiver); - if ((((cPIC->cPICNumCases)) >= MaxCPICCases) - || (((errorSelectorOrNil != null) - && (errorSelectorOrNil != SelectorDoesNotUnderstand)) - || ((newTargetMethodOrNil == null) - || (isYoung(newTargetMethodOrNil))))) { - result = patchToOpenPICFornumArgsreceiver((cPIC->selector), (cPIC->cmNumArgs), receiver); - assert(!result); - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - return ceSendFromInLineCacheMiss(cPIC); - } - cogExtendPICCaseNMethodtagisMNUCase(cPIC, newTargetMethodOrNil, cacheTag, errorSelectorOrNil == SelectorDoesNotUnderstand); - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - executeCogPICfromLinkedSendWithReceiverandCacheTag(cPIC, receiver, inlineCacheTagAt(backEnd, outerReturn)); - return null; -} - - /* Cogit>>#ceFree: */ -void -ceFree(void *pointer) -{ - free(pointer); -} - - /* Cogit>>#ceMalloc: */ -static void* NoDbgRegParms -ceMalloc(size_t size) -{ - return malloc(size); -} - - -/* An in-line cache check in a method has failed. The failing entry check has - jumped to the ceMethodAbort abort call at the start of the method which - has called this routine. - If possible allocate a closed PIC for the current and existing classes. - The stack looks like: - receiver - args - sender return address - sp=> ceMethodAbort call return address - So we can find the method that did the failing entry check at - ceMethodAbort call return address - missOffset - and we can find the send site from the outer return address. */ - - /* Cogit>>#ceSICMiss: */ -static sqInt NoDbgRegParms -ceSICMiss(sqInt receiver) -{ - sqInt cacheTag; - usqInt entryPoint; - sqInt errorSelectorOrNil; - sqInt extent; - usqInt innerReturn; - sqInt methodOrSelectorIndex; - sqInt newTargetMethodOrNil; - usqInt outerReturn; - CogMethod *pic; - sqInt result; - sqInt selector; - CogMethod *targetMethod; - - - /* Whether we can relink to a PIC or not we need to pop off the inner return and identify the target method. */ - innerReturn = ((usqInt)(popStack())); - targetMethod = ((CogMethod *) (innerReturn - missOffset)); - if (isOopForwarded(receiver)) { - return ceSendFromInLineCacheMiss(targetMethod); - } - outerReturn = ((usqInt)(stackTop())); - assert(((outerReturn >= methodZoneBase) && (outerReturn <= (freeStart())))); - entryPoint = callTargetFromReturnAddress(backEnd, outerReturn); - assert(((targetMethod->selector)) != (nilObject())); - assert(((((sqInt)targetMethod)) + cmEntryOffset) == entryPoint); - /* begin lookup:for:methodAndErrorSelectorInto: */ - selector = (targetMethod->selector); - methodOrSelectorIndex = lookupOrdinaryreceiver(selector, receiver); - if ((((usqInt)methodOrSelectorIndex)) > (maxLookupNoMNUErrorCode())) { - if (!(isOopCompiledMethod(methodOrSelectorIndex))) { - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = SelectorCannotInterpret; - goto l1; - } - if ((!(methodHasCogMethod(methodOrSelectorIndex))) - && (methodShouldBeCogged(methodOrSelectorIndex))) { - - /* We assume cog:selector: will *not* reclaim the method zone */ - cogselector(methodOrSelectorIndex, selector); - } - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = null; - goto l1; - } - if (methodOrSelectorIndex == SelectorDoesNotUnderstand) { - methodOrSelectorIndex = lookupMNUreceiver(splObj(SelectorDoesNotUnderstand), receiver); - if ((((usqInt)methodOrSelectorIndex)) > (maxLookupNoMNUErrorCode())) { - assert(isOopCompiledMethod(methodOrSelectorIndex)); - if ((!(methodHasCogMethod(methodOrSelectorIndex))) - && (methodShouldBeCogged(methodOrSelectorIndex))) { - - /* We assume cog:selector: will *not* reclaim the method zone */ - cogselector(methodOrSelectorIndex, splObj(SelectorDoesNotUnderstand)); - } - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = SelectorDoesNotUnderstand; - goto l1; - } - newTargetMethodOrNil = null; - errorSelectorOrNil = SelectorDoesNotUnderstand; - goto l1; - } - newTargetMethodOrNil = null; - errorSelectorOrNil = methodOrSelectorIndex; - l1: /* end lookup:for:methodAndErrorSelectorInto: */; - assert(outerReturn == (stackTop())); - cacheTag = inlineCacheTagForInstance(receiver); - if (((errorSelectorOrNil != null) - && (errorSelectorOrNil != SelectorDoesNotUnderstand)) - || (((inlineCacheTagAt(backEnd, outerReturn)) == 0 /* picAbortDiscriminatorValue */) - || ((newTargetMethodOrNil == null) - || (isYoung(newTargetMethodOrNil))))) { - result = patchToOpenPICFornumArgsreceiver((targetMethod->selector), (targetMethod->cmNumArgs), receiver); - assert(!result); - return ceSendFromInLineCacheMiss(targetMethod); - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - pic = openPICWithSelector((targetMethod->selector)); - - /* otherwise attempt to create a closed PIC for the two cases. */ - pic = cogPICSelectornumArgsCase0MethodCase1MethodtagisMNUCase((targetMethod->selector), (targetMethod->cmNumArgs), targetMethod, newTargetMethodOrNil, cacheTag, errorSelectorOrNil == SelectorDoesNotUnderstand); - if ((((((sqInt)pic)) >= MaxNegativeErrorCode) && ((((sqInt)pic)) <= -1))) { - - /* For some reason the PIC couldn't be generated, most likely a lack of code memory. - Continue as if this is an unlinked send. */ - if ((((sqInt)pic)) == InsufficientCodeSpace) { - callForCogCompiledCodeCompaction(); - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - return ceSendFromInLineCacheMiss(targetMethod); - } - extent = (((pic->cmType)) == CMOpenPIC - ? rewriteInlineCacheAttagtarget(backEnd, outerReturn, inlineCacheValueForSelectorin(backEnd, (targetMethod->selector), mframeHomeMethodExport()), (((sqInt)pic)) + cmEntryOffset) - : rewriteCallAttarget(backEnd, outerReturn, (((sqInt)pic)) + cmEntryOffset)); - /* begin assertValidDualZoneFrom:to: */ - (((usqInt)pic)) + closedPICSize; -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, (((usqInt)pic)) + cmNoCheckEntryOffset, codeToDataDelta); -# endif - flushICacheFromto(backEnd, ((usqInt)pic), (((usqInt)pic)) + closedPICSize); - flushICacheFromto(backEnd, (((usqInt)outerReturn)) - extent, ((usqInt)outerReturn)); - executeCogPICfromLinkedSendWithReceiverandCacheTag(pic, receiver, inlineCacheTagAt(backEnd, outerReturn)); - return null; -} - - -/* Check for a valid object reference, if any, at a map entry. Answer a code - unique to each error for debugging. */ - - /* Cogit>>#checkIfValidOopRefAndTarget:pc:cogMethod: */ -static sqInt NoDbgRegParms -checkIfValidOopRefAndTargetpccogMethod(sqInt annotation, char *mcpc, CogMethod *cogMethod) -{ - usqInt cacheTag1; - sqInt entryPoint; - usqInt entryPoint1; - usqInt literal; - sqInt offset1; - sqInt *sendTable1; - sqInt tagCouldBeObj; - CogMethod *targetMethod1; - - if (annotation == IsObjectReference) { - literal = literalBeforeFollowingAddress(backEnd, ((usqInt)mcpc)); - if (!(asserta(checkValidOopReference(literal)))) { - return 1; - } - if ((couldBeObject(literal)) - && (isReallyYoungObject(literal))) { - if (!(asserta(((((CogMethod *) cogMethod))->cmRefersToYoung)))) { - return 2; - } - } - } - if (annotation >= IsSendCall) { - if (!(asserta((((((CogMethod *) cogMethod))->cmType)) == CMMethod))) { - return 3; - } - /* begin entryCacheTagAndCouldBeObjectAt:annotation:into: */ - cacheTag1 = inlineCacheTagAt(backEnd, ((sqInt)mcpc)); - - /* in-line cache tags are the selectors of sends if sends are unlinked, - the selectors of super sends (entry offset = cmNoCheckEntryOffset), - the selectors of open PIC sends (entry offset = cmEntryOffset, target is an Open PIC) - or in-line cache tags (classes, class indices, immediate bit patterns, etc). - Note that selectors can be immediate so there is no guarantee that they - are markable/remappable objects. */ - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - tagCouldBeObj = entryPointTagIsSelector(entryPoint1); - entryPoint = entryPoint1; - if (tagCouldBeObj) { - if (couldBeObject(cacheTag1)) { - if (!(asserta(checkValidOopReference(cacheTag1)))) { - return 4; - } - } - else { - if (!(asserta(validInlineCacheTag(cacheTag1)))) { - return 5; - } - } - if ((couldBeObject(cacheTag1)) - && (isReallyYoungObject(cacheTag1))) { - if (!(asserta(((((CogMethod *) cogMethod))->cmRefersToYoung)))) { - return 6; - } - } - } - else { - if (!(asserta(validInlineCacheTag(cacheTag1)))) { - return 9; - } - } - if (entryPoint > methodZoneBase) { - - /* It's a linked send; find which kind. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (!(asserta((((targetMethod1->cmType)) == CMMethod) - || ((((targetMethod1->cmType)) == CMClosedPIC) - || (((targetMethod1->cmType)) == CMOpenPIC))))) { - return 10; - } - } - } - return 0; -} - - -/* Check for a valid object reference, if any, at a map entry. Answer a code - unique to each error for debugging. */ - - /* Cogit>>#checkIfValidOopRef:pc:cogMethod: */ -static sqInt NoDbgRegParms -checkIfValidOopRefpccogMethod(sqInt annotation, char *mcpc, CogMethod *cogMethod) -{ - usqInt entryPoint; - usqInt literal; - usqInt offset; - sqInt offset1; - usqInt selectorOrCacheTag; - sqInt *sendTable; - - if (annotation == IsObjectReference) { - literal = literalBeforeFollowingAddress(backEnd, ((usqInt)mcpc)); - if (!(checkValidOopReference(literal))) { - print("object ref leak in CM "); - printHex(((sqInt)cogMethod)); - print(" @ "); - printHex(((sqInt)mcpc)); - cr(); - return 1; - } - } - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint <= methodZoneBase) { - offset = entryPoint; - } - else { - /* begin offsetAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable = superSendTrampolines; - } - } - } - offset = offset1; - } - selectorOrCacheTag = inlineCacheTagAt(backEnd, ((sqInt)mcpc)); - if ((entryPoint > methodZoneBase) - && ((offset != cmNoCheckEntryOffset) - && ((((((CogMethod *) (entryPoint - offset)))->cmType)) != CMOpenPIC))) { - - /* linked non-super send, cacheTag is a cacheTag */ - if (!(validInlineCacheTag(selectorOrCacheTag))) { - print("cache tag leak in CM "); - printHex(((sqInt)cogMethod)); - print(" @ "); - printHex(((sqInt)mcpc)); - cr(); - return 1; - } - } - else { - - /* unlinked send or super send; cacheTag is a selector unless 64-bit, in which case it is an index. */ - if (!(checkValidOopReference(selectorOrCacheTag))) { - print("selector leak in CM "); - printHex(((sqInt)cogMethod)); - print(" @ "); - printHex(((sqInt)mcpc)); - cr(); - return 1; - } - } - } - return 0; -} - - -/* Answer if all references to objects in machine-code are valid. */ - - /* Cogit>>#checkIntegrityOfObjectReferencesInCode: */ -sqInt -checkIntegrityOfObjectReferencesInCode(sqInt gcModes) -{ - CogMethod *cogMethod; - sqInt count; - sqInt ok; - - cogMethod = ((CogMethod *) methodZoneBase); - ok = 1; - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - if ((cogMethod->cmRefersToYoung)) { - if (((count = occurrencesInYoungReferrers(cogMethod))) != 1) { - print("young referrer CM "); - printHex(((sqInt)cogMethod)); - if (count == 0) { - print(" is not in youngReferrers"); - cr(); - } - else { - print(" is in youngReferrers "); - printNum(count); - print(" times!"); - cr(); - } - ok = 0; - } - } - if (!(checkValidOopReference((cogMethod->selector)))) { - print("object leak in CM "); - printHex(((sqInt)cogMethod)); - print(" selector"); - cr(); - ok = 0; - } - if (((cogMethod->cmType)) == CMMethod) { - assert(((cogMethod->objectHeader)) == (nullHeaderForMachineCodeMethod())); - if (!(checkValidObjectReference((cogMethod->methodObject)))) { - print("object leak in CM "); - printHex(((sqInt)cogMethod)); - print(" methodObject"); - cr(); - ok = 0; - } - if (!(isOopCompiledMethod((cogMethod->methodObject)))) { - print("non-method in CM "); - printHex(((sqInt)cogMethod)); - print(" methodObject"); - cr(); - ok = 0; - } - if ((mapForperformUntilarg(cogMethod, checkIfValidOopRefpccogMethod, cogMethod)) != 0) { - ok = 0; - } - if (((isYoungObject((cogMethod->methodObject))) - || (isYoung((cogMethod->selector)))) - && (!((cogMethod->cmRefersToYoung)))) { - print("CM "); - printHex(((sqInt)cogMethod)); - print(" refers to young but not marked as such"); - cr(); - ok = 0; - } - } - else { - if (((cogMethod->cmType)) == CMClosedPIC) { - if (!(checkValidObjectReferencesInClosedPIC(cogMethod))) { - ok = 0; - } - } - else { - if (((cogMethod->cmType)) == CMOpenPIC) { - if ((mapForperformUntilarg(cogMethod, checkIfValidOopRefpccogMethod, cogMethod)) != 0) { - ok = 0; - } - } - } - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return ok; -} - - /* Cogit>>#checkMaybeObjRefInClosedPIC: */ -static sqInt NoDbgRegParms -checkMaybeObjRefInClosedPIC(sqInt maybeObject) -{ - if (maybeObject == 0) { - return 1; - } - if (!(couldBeObject(maybeObject))) { - return 1; - } - return checkValidObjectReference(maybeObject); -} - - /* Cogit>>#checkValidObjectReferencesInClosedPIC: */ -static sqInt NoDbgRegParms -checkValidObjectReferencesInClosedPIC(CogMethod *cPIC) -{ - sqInt i; - sqInt ok; - sqInt pc; - - ok = 1; - - /* first we check the obj ref at the beginning of the CPIC */ - pc = (((sqInt)cPIC)) + firstCPICCaseOffset; - if (!(checkMaybeObjRefInClosedPIC(literalBeforeFollowingAddress(backEnd, pc - (jumpLongByteSize(backEnd)))))) { - print("object leak in CPIC "); - printHex(((sqInt)cPIC)); - print(" @ "); - printHex(pc - (jumpLongByteSize(backEnd))); - cr(); - ok = 0; - } - - /* For each case we check any object reference at the end address - sizeof(conditional instruction) and then increment the end address by case size */ - pc = addressOfEndOfCaseinCPIC((cPIC->cPICNumCases), cPIC); - for (i = 2; i <= ((cPIC->cPICNumCases)); i += 1) { - if (!(checkMaybeObjRefInClosedPIC(literalBeforeFollowingAddress(backEnd, (pc - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */)))) { - print("object leak in CPIC "); - printHex(((sqInt)cPIC)); - print(" @ "); - printHex(pc - 16 /* jumpLongConditionalByteSize */); - cr(); - ok = 0; - } - pc += cPICCaseSize; - } - return ok; -} - - -/* i.e. this should never be called, so keep it out of the main path. */ - - /* Cogit>>#cleanUpFailingCogCodeConstituents: */ -static sqInt NoDbgRegParms NeverInline -cleanUpFailingCogCodeConstituents(CogMethod *cogMethodArg) -{ - CogMethod *cogMethod; - - cogMethod = cogMethodArg; - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMClosedPIC) { - (cogMethod->methodObject = 0); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - popRemappableOop(); - return null; -} - - -/* Answer if the ClosedPIC refers to any unmarked objects or freed/freeable - target methods, - applying markAndTraceOrFreeCogMethod:firstVisit: to those targets to - determine if freed/freeable. - */ - - /* Cogit>>#closedPICRefersToUnmarkedObject: */ -static sqInt NoDbgRegParms -closedPICRefersToUnmarkedObject(CogMethod *cPIC) -{ - sqInt i; - usqInt object; - sqInt pc; - - if (!((isImmediate((cPIC->selector))) - || (isMarked((cPIC->selector))))) { - return 1; - } - pc = addressOfEndOfCaseinCPIC(1, cPIC); - if (couldBeObject((object = literalBeforeFollowingAddress(backEnd, pc - (jumpLongByteSize(backEnd)))))) { - if (!(isMarked(object))) { - return 1; - } - } - if (markAndTraceOrFreePICTargetin(jumpLongTargetBeforeFollowingAddress(backEnd, pc), cPIC)) { - return 1; - } - for (i = 2; i <= ((cPIC->cPICNumCases)); i += 1) { - pc = addressOfEndOfCaseinCPIC(i, cPIC); - if (couldBeObject((object = literalBeforeFollowingAddress(backEnd, (pc - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */)))) { - if (!(isMarked(object))) { - return 1; - } - } - if (markAndTraceOrFreePICTargetin(jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc), cPIC)) { - return 1; - } - } - return 0; -} - - /* Cogit>>#codeEntryFor: */ -char * -codeEntryFor(char *address) -{ - sqInt i; - - for (i = 0; i <= (trampolineTableIndex - 3); i += 2) { - if (((address >= (trampolineAddresses[i + 1])) && (address <= ((trampolineAddresses[i + 3]) - 1)))) { - return trampolineAddresses[i + 1]; - } - } - return null; -} - - /* Cogit>>#codeEntryNameFor: */ -char * -codeEntryNameFor(char *address) -{ - sqInt i; - - for (i = 0; i <= (trampolineTableIndex - 3); i += 2) { - if (((address >= (trampolineAddresses[i + 1])) && (address <= ((trampolineAddresses[i + 3]) - 1)))) { - return trampolineAddresses[i]; - } - } - return null; -} - - /* Cogit>>#cogCodeBase */ -sqInt -cogCodeBase(void) -{ - return codeBase; -} - - -/* Answer the contents of the code zone as an array of pair-wise element, - address in ascending address order. - Answer a string for a runtime routine or abstract label (beginning, end, - etc), a CompiledMethod for a CMMethod, - or a selector (presumably a Symbol) for a PIC. - If withDetails is true - - answer machine-code to bytecode pc mapping information for methods - - answer class, target pair information for closed PIC - N.B. Since the class tag for the first case of a closed PIC is stored at - the send site, it must be collected - by scanning methods (see - collectCogConstituentFor:Annotation:Mcpc:Bcpc:Method:). Since closed PICs - are never shared they always come after the method that references them, - so we don't need an extra pass - to collect the first case class tags, which are (temporarily) assigned to - each closed PIC's methodObject field. - But we do need to reset the methodObject fields to zero. This is done in - createPICData:, unless memory - runs out, in which case it is done by cleanUpFailingCogCodeConstituents:. */ - - /* Cogit>>#cogCodeConstituents: */ -sqInt -cogCodeConstituents(sqInt withDetails) -{ - CogMethod *cogMethod; - sqInt constituents; - sqInt count; - sqInt i; - sqInt label; - sqInt profileData; - sqInt value; - - - /* + 3 for start, freeStart and end */ - count = (trampolineTableIndex / 2) + 3; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - count += 1; - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - constituents = instantiateClassindexableSize(classArray(), count * 2); - if (!constituents) { - return constituents; - } - pushRemappableOop(constituents); - if ((((label = stringForCString("CogCode"))) == null) - || (((value = positive32BitIntegerFor(codeBase))) == null)) { - popRemappableOop(); - return null; - } - storePointerUncheckedofObjectwithValue(0, constituents, label); - storePointerUncheckedofObjectwithValue(1, constituents, value); - for (i = 0; i < trampolineTableIndex; i += 2) { - if ((((label = stringForCString(trampolineAddresses[i]))) == null) - || (((value = positive32BitIntegerFor(((usqInt)(trampolineAddresses[i + 1]))))) == null)) { - popRemappableOop(); - return null; - } - storePointerUncheckedofObjectwithValue(2 + i, constituents, label); - storePointerUncheckedofObjectwithValue(3 + i, constituents, value); - } - count = trampolineTableIndex + 2; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - profileData = (((cogMethod->cmType)) == CMMethod - ? (cogMethod->methodObject) - : (withDetails - && (((cogMethod->cmType)) == CMClosedPIC) - ? createCPICData(cogMethod) - : (cogMethod->selector))); - if (!profileData) { - return cleanUpFailingCogCodeConstituents(cogMethod); - } - storePointerUncheckedofObjectwithValue(count, constituents, profileData); - if (withDetails) { - value = collectCogMethodConstituent(cogMethod); - } - else { - value = positive32BitIntegerFor(((usqInt)cogMethod)); - } - if (!value) { - return cleanUpFailingCogCodeConstituents(cogMethod); - } - storePointerUncheckedofObjectwithValue(count + 1, constituents, value); - count += 2; - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if ((((label = stringForCString("CCFree"))) == null) - || (((value = positive32BitIntegerFor(mzFreeStart))) == null)) { - popRemappableOop(); - return null; - } - storePointerUncheckedofObjectwithValue(count, constituents, label); - storePointerUncheckedofObjectwithValue(count + 1, constituents, value); - if ((((label = stringForCString("CCEnd"))) == null) - || (((value = positive32BitIntegerFor(limitAddress))) == null)) { - popRemappableOop(); - return null; - } - storePointerUncheckedofObjectwithValue(count + 2, constituents, label); - storePointerUncheckedofObjectwithValue(count + 3, constituents, value); - constituents = popRemappableOop(); - beRootIfOld(constituents); - return constituents; -} - - -/* Extend the cPIC with the supplied case. If caseNMethod is cogged dispatch - direct to - its unchecked entry-point. If caseNMethod is not cogged, jump to the fast - interpreter dispatch, and if isMNUCase then dispatch to fast MNU - invocation and mark the cPIC as - having the MNU case for cache flushing. */ - - /* Cogit>>#cogExtendPIC:CaseNMethod:tag:isMNUCase: */ -static void NoDbgRegParms -cogExtendPICCaseNMethodtagisMNUCase(CogMethod *cPIC, sqInt caseNMethod, sqInt caseNTag, sqInt isMNUCase) -{ - sqInt address; - sqInt operand; - CogBlockMethod * self_in_cpicHasMNUCase; - sqInt target; - - compilationBreakpointclassTagisMNUCase((cPIC->selector), caseNTag, isMNUCase); - assert(!(inlineCacheTagIsYoung(caseNTag))); - assert((caseNMethod != null) - && (!(isYoung(caseNMethod)))); - if ((!isMNUCase) - && (methodHasCogMethod(caseNMethod))) { - - /* this isn't an MNU and we have an already cogged method to jump to */ - operand = 0; - target = (((sqInt)(cogMethodOf(caseNMethod)))) + cmNoCheckEntryOffset; - } - else { - operand = caseNMethod; - if (isMNUCase) { - - /* this is an MNU so tag the CPIC header and setup a jump to the MNUAbort */ - /* begin cpicHasMNUCase: */ - self_in_cpicHasMNUCase = ((CogBlockMethod *) (((CogMethod *) ((((usqInt)cPIC)) + codeToDataDelta)))); - (self_in_cpicHasMNUCase->cpicHasMNUCaseOrCMIsFullBlock) = 1; - target = (((sqInt)cPIC)) + (sizeof(CogMethod)); - } - else { - - /* setup a jump to the interpretAborth so we can cog the target method */ - target = (((sqInt)cPIC)) + (picInterpretAbortOffset()); - } - } - address = addressOfEndOfCaseinCPIC(((cPIC->cPICNumCases)) + 1, cPIC); - rewriteCPICCaseAttagobjReftarget(address, caseNTag, operand, target); - /* begin rewriteCPIC:caseJumpTo: */ - rewriteCPICJumpAttarget(backEnd, (((((sqInt)cPIC)) + firstCPICCaseOffset) - (jumpLongByteSize(backEnd))) - 8 /* loadLiteralByteSize */, address - cPICCaseSize); - ((((CogMethod *) ((((usqInt)cPIC)) + codeToDataDelta)))->cPICNumCases = ((cPIC->cPICNumCases)) + 1); - flushICacheFromto(backEnd, ((usqInt)cPIC), (((usqInt)cPIC)) + closedPICSize); - /* begin assertValidDualZoneFrom:to: */ - (((usqInt)cPIC)) + closedPICSize; -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, (((usqInt)cPIC)) + cmNoCheckEntryOffset, codeToDataDelta); -# endif -} - - -/* Attempt to produce a machine code method for the bytecode method - object aMethodObj. N.B. If there is no code memory available do *NOT* - attempt to reclaim the method zone. Certain clients (e.g. ceSICMiss:) - depend on the zone remaining constant across method generation. */ - - /* Cogit>>#cogFullBlockMethod:numCopied: */ -CogMethod * -cogFullBlockMethodnumCopied(sqInt aMethodObj, sqInt numCopied) -{ - CogMethod *cogMethod; - - - /* inline exclude: */ - assert(!((methodHasCogMethod(aMethodObj)))); - assert(isOopCompiledMethod(ultimateLiteralOf(aMethodObj))); - if (aMethodObj == breakMethod) { - haltmsg("Compilation of breakMethod"); - } - if (methodUsesAlternateBytecodeSet(aMethodObj)) { - if ((numElementsIn(generatorTable)) <= 0x100) { - return null; - } - bytecodeSetOffset = 0x100; - } - else { - bytecodeSetOffset = 0; - } - ensureNoForwardedLiteralsIn(aMethodObj); - methodObj = aMethodObj; - methodHeader = methodHeaderOf(aMethodObj); - receiverTags = receiverTagBitsForMethod(methodObj); - cogMethod = compileCogFullBlockMethod(numCopied); - if ((((((sqInt)cogMethod)) >= MaxNegativeErrorCode) && ((((sqInt)cogMethod)) <= -1))) { - if ((((sqInt)cogMethod)) == InsufficientCodeSpace) { - callForCogCompiledCodeCompaction(); - } - /* begin maybeFreeCounters */ - if (counters != 0) { - /* begin freeCounters: */ - if (counters != 0) { - freeObject(counters - BaseHeaderSize); - } - } - return null; - } - return cogMethod; -} - - /* Cogit>>#cogitPostGCAction: */ -void -cogitPostGCAction(sqInt gcMode) -{ - -# if SPURVM - if (gcMode == GCModeBecome) { - followForwardedLiteralsInOpenPICList(); - } -# endif - assert(allMethodsHaveCorrectHeader()); - assert(((!(gcMode & (GCModeFull + GCModeNewSpace)))) - || (kosherYoungReferrers())); - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - -/* Check that the header fields onf a non-free method are consistent with - the type. Answer 0 if it is ok, otherwise answer a code for the error. */ - - /* Cogit>>#cogMethodDoesntLookKosher: */ -sqInt -cogMethodDoesntLookKosher(CogMethod *cogMethod) -{ - if (((((cogMethod->blockSize)) & (BytesPerWord - 1)) != 0) - || ((((cogMethod->blockSize)) < (sizeof(CogMethod))) - || (((cogMethod->blockSize)) >= 0x8000))) { - return 1; - } - if (((cogMethod->cmType)) == CMFree) { - return 2; - } - if (((cogMethod->cmType)) == CMMethod) { - if (!((((cogMethod->methodHeader)) & 1))) { - return 11; - } - if (!(couldBeObject((cogMethod->methodObject)))) { - return 12; - } - if ((((cogMethod->stackCheckOffset)) > 0) - && (((cogMethod->stackCheckOffset)) < cmNoCheckEntryOffset)) { - return 13; - } - if (((cogMethod->counters)) != 0) { - if (!(couldBeDerivedObject((cogMethod->counters)))) { - return 14; - } - } - return 0; - } - if (((cogMethod->cmType)) == CMOpenPIC) { - if (((cogMethod->blockSize)) != openPICSize) { - return 21; - } - if (((cogMethod->methodHeader)) != 0) { - return 22; - } - if (((cogMethod->objectHeader)) >= 0) { - if (!((((cogMethod->methodObject)) == 0) - || (compactionInProgress - || (((cogMethod->methodObject)) == (((usqInt)(methodFor(((void *)((cogMethod->methodObject))))))))))) { - return 23; - } - } - if (((cogMethod->stackCheckOffset)) != 0) { - return 24; - } - return 0; - } - if (((cogMethod->cmType)) == CMClosedPIC) { - if (((cogMethod->blockSize)) != closedPICSize) { - return 0x1F; - } - if (!(((((cogMethod->cPICNumCases)) >= 1) && (((cogMethod->cPICNumCases)) <= MaxCPICCases)))) { - return 32; - } - if (((cogMethod->methodHeader)) != 0) { - return 33; - } - if (((cogMethod->methodObject)) != 0) { - return 34; - } - return 0; - } - return 9; -} - - -/* Attempt to create a one-case PIC for an MNU. - The tag for the case is at the send site and so doesn't need to be - generated. - */ - - /* Cogit>>#cogMNUPICSelector:receiver:methodOperand:numArgs: */ -CogMethod * -cogMNUPICSelectorreceivermethodOperandnumArgs(sqInt selector, sqInt rcvr, sqInt methodOperand, sqInt numArgs) -{ - CogMethod * actualPIC; - usqInt startAddress; - CogMethod * writablePIC; - - if ((isYoung(selector)) - || ((inlineCacheTagForInstance(rcvr)) == 0 /* picAbortDiscriminatorValue */)) { - return 0; - } - compilationBreakpointclassTagisMNUCase(selector, fetchClassTagOf(rcvr), 1); - assert(endCPICCase0 != null); - startAddress = allocate(closedPICSize); - if (startAddress == 0) { - callForCogCompiledCodeCompaction(); - return 0; - } - maybeBreakGeneratingFromto(startAddress, startAddress + closedPICSize); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - - /* memcpy the prototype across to our allocated space; because anything else would be silly */ - writablePIC = ((CogMethod *) ((((usqInt)startAddress)) + codeToDataDelta)); - codeMemcpy(writablePIC, cPICPrototype, closedPICSize); - /* begin fillInCPICHeader:numArgs:numCases:hasMNUCase:selector: */ - (writablePIC->counters = 0); - assert(!(isYoung(selector))); - (writablePIC->cmType = CMClosedPIC); - (writablePIC->objectHeader = 0); - (writablePIC->blockSize = closedPICSize); - (writablePIC->methodObject = 0); - (writablePIC->methodHeader = 0); - (writablePIC->selector = selector); - (writablePIC->cmNumArgs = numArgs); - (writablePIC->cmHasMovableLiteral = 0); - (writablePIC->cmRefersToYoung = 0); - (writablePIC->cmUsageCount = initialClosedPICUsageCount()); - /* begin cpicHasMNUCase: */ - ((((CogBlockMethod *) writablePIC))->cpicHasMNUCaseOrCMIsFullBlock) = 1; - (writablePIC->cPICNumCases = 1); - (writablePIC->blockEntryOffset = 0); - assert(((writablePIC->cmType)) == CMClosedPIC); - assert(((writablePIC->selector)) == selector); - assert(((writablePIC->cmNumArgs)) == numArgs); - assert(((writablePIC->cPICNumCases)) == 1); - assert(closedPICSize == (roundUpLength(closedPICSize))); - /* begin maybeEnableSingleStep */ - configureMNUCPICmethodOperandnumArgsdelta((actualPIC = ((CogMethod *) startAddress)), methodOperand, numArgs, startAddress - (((usqInt)cPICPrototype))); - flushICacheFromto(backEnd, startAddress, startAddress + closedPICSize); - assert((callTargetFromReturnAddress(backEnd, startAddress + missOffset)) == (picAbortTrampolineFor(numArgs))); - /* begin assertValidDualZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, startAddress + cmNoCheckEntryOffset, codeToDataDelta); -# endif - return actualPIC; -} - - -/* Create an Open PIC. Temporarily create a direct call of - ceSendFromOpenPIC:. Should become a probe of the first-level method lookup - cache followed by a - call of ceSendFromOpenPIC: if the probe fails. */ - - /* Cogit>>#cogOpenPICSelector:numArgs: */ -static CogMethod * NoDbgRegParms -cogOpenPICSelectornumArgs(sqInt selector, sqInt numArgs) -{ - sqInt codeSize; - sqInt end; - sqInt fixupSize; - sqInt mapSize; - sqInt opcodeSize; - CogMethod *pic; - usqInt startAddress; - - compilationBreakpointisMNUCase(selector, 0); - startAddress = allocate(openPICSize); - if (startAddress == 0) { - return ((CogMethod *) InsufficientCodeSpace); - } - (methodLabel->address = startAddress); - (methodLabel->dependent = null); - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 100; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - compileOpenPICnumArgs(selector, numArgs); - computeMaximumSizes(); - concretizeAt(methodLabel, startAddress); - codeSize = generateInstructionsAt(startAddress + (sizeof(CogMethod))); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - mapSize = generateMapAtstart((startAddress + openPICSize) - 1, startAddress + cmNoCheckEntryOffset); - assert((((entry->address)) - startAddress) == cmEntryOffset); - assert(((roundUpLength((sizeof(CogMethod)) + codeSize)) + (roundUpLength(mapSize))) <= openPICSize); - end = outputInstructionsAt(startAddress + (sizeof(CogMethod))); - /* begin fillInOPICHeader:numArgs:selector: */ - pic = ((CogMethod *) ((((usqInt)startAddress)) + codeToDataDelta)); - (pic->counters = 0); - (pic->cmType = CMOpenPIC); - (pic->objectHeader = 0); - (pic->blockSize = openPICSize); - addToOpenPICList(pic); - (pic->methodHeader = 0); - (pic->selector = selector); - (pic->cmNumArgs = numArgs); - (pic->cmHasMovableLiteral = isNonImmediate(selector)); - if ((pic->cmRefersToYoung = isYoung(selector))) { - addToYoungReferrers(pic); - } - (pic->cmUsageCount = initialOpenPICUsageCount()); - /* begin cpicHasMNUCase: */ - ((((CogBlockMethod *) pic))->cpicHasMNUCaseOrCMIsFullBlock) = 0; - (pic->cPICNumCases = 0); - (pic->blockEntryOffset = 0); - flushICacheFromto(backEnd, (((usqInt)pic)) - codeToDataDelta, ((((usqInt)pic)) - codeToDataDelta) + openPICSize); - assert(((pic->cmType)) == CMOpenPIC); - assert(((pic->selector)) == selector); - assert(((pic->cmNumArgs)) == numArgs); - assert((callTargetFromReturnAddress(backEnd, ((((sqInt)pic)) - codeToDataDelta) + missOffset)) == (picAbortTrampolineFor(numArgs))); - assert(openPICSize == (roundUpLength(openPICSize))); - /* begin assertValidDualZoneFrom:to: */ - ((((usqInt)pic)) - codeToDataDelta) + openPICSize; -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, ((((usqInt)pic)) - codeToDataDelta) + cmNoCheckEntryOffset, codeToDataDelta); -# endif - /* begin maybeEnableSingleStep */ - return ((CogMethod *) startAddress); -} - - -/* Attempt to create a two-case PIC for case0CogMethod and - case1Method,case1Tag. The tag for case0CogMethod is at the send site and - so doesn't need to be generated. - case1Method may be any of - - a Cog method; link to its unchecked entry-point - - a CompiledMethod; link to ceInterpretMethodFromPIC: - - a CompiledMethod; link to ceMNUFromPICMNUMethod:receiver: */ - - /* Cogit>>#cogPICSelector:numArgs:Case0Method:Case1Method:tag:isMNUCase: */ -static CogMethod * NoDbgRegParms -cogPICSelectornumArgsCase0MethodCase1MethodtagisMNUCase(sqInt selector, sqInt numArgs, CogMethod *case0CogMethod, sqInt case1MethodOrNil, sqInt case1Tag, sqInt isMNUCase) -{ - CogMethod * actualPIC; - usqInt startAddress; - CogMethod * writablePIC; - - if (isYoung(selector)) { - return ((CogMethod *) YoungSelectorInPIC); - } - compilationBreakpointclassTagisMNUCase(selector, case1Tag, isMNUCase); - startAddress = allocate(closedPICSize); - if (startAddress == 0) { - return ((CogMethod *) InsufficientCodeSpace); - } - maybeBreakGeneratingFromto(startAddress, startAddress + closedPICSize); - - /* memcpy the prototype across to our allocated space; because anything else would be silly */ - writablePIC = ((CogMethod *) ((((usqInt)startAddress)) + codeToDataDelta)); - codeMemcpy(writablePIC, cPICPrototype, closedPICSize); - /* begin fillInCPICHeader:numArgs:numCases:hasMNUCase:selector: */ - (writablePIC->counters = 0); - assert(!(isYoung(selector))); - (writablePIC->cmType = CMClosedPIC); - (writablePIC->objectHeader = 0); - (writablePIC->blockSize = closedPICSize); - (writablePIC->methodObject = 0); - (writablePIC->methodHeader = 0); - (writablePIC->selector = selector); - (writablePIC->cmNumArgs = numArgs); - (writablePIC->cmHasMovableLiteral = 0); - (writablePIC->cmRefersToYoung = 0); - (writablePIC->cmUsageCount = initialClosedPICUsageCount()); - /* begin cpicHasMNUCase: */ - ((((CogBlockMethod *) writablePIC))->cpicHasMNUCaseOrCMIsFullBlock) = isMNUCase; - (writablePIC->cPICNumCases = 2); - (writablePIC->blockEntryOffset = 0); - assert(((writablePIC->cmType)) == CMClosedPIC); - assert(((writablePIC->selector)) == selector); - assert(((writablePIC->cmNumArgs)) == numArgs); - assert(((writablePIC->cPICNumCases)) == 2); - assert(closedPICSize == (roundUpLength(closedPICSize))); - /* begin maybeEnableSingleStep */ - configureCPICCase0Case1MethodtagisMNUCasenumArgsdelta((actualPIC = ((CogMethod *) startAddress)), case0CogMethod, case1MethodOrNil, case1Tag, isMNUCase, numArgs, startAddress - (((usqInt)cPICPrototype))); - assert((callTargetFromReturnAddress(backEnd, startAddress + missOffset)) == (picAbortTrampolineFor(numArgs))); - return actualPIC; -} - - -/* Attempt to produce a machine code method for the bytecode method - object aMethodObj. N.B. If there is no code memory available do *NOT* - attempt to reclaim the method zone. Certain clients (e.g. ceSICMiss:) - depend on the zone remaining constant across method generation. */ - - /* Cogit>>#cog:selector: */ -CogMethod * -cogselector(sqInt aMethodObj, sqInt aSelectorOop) -{ - CogMethod *cogMethod; - sqInt selector; - - - /* inline exclude:selector: */ - assert(!((methodHasCogMethod(aMethodObj)))); - assert(!((isOopCompiledMethod(ultimateLiteralOf(aMethodObj))))); - - /* coInterpreter stringOf: selector */ - selector = (aSelectorOop == (nilObject()) - ? maybeSelectorOfMethod(aMethodObj) - : aSelectorOop); - if (!(selector == null)) { - compilationBreakpointisMNUCase(selector, 0); - } - if (aMethodObj == breakMethod) { - haltmsg("Compilation of breakMethod"); - } - if (methodUsesAlternateBytecodeSet(aMethodObj)) { - if ((numElementsIn(generatorTable)) <= 0x100) { - return null; - } - bytecodeSetOffset = 0x100; - } - else { - bytecodeSetOffset = 0; - } - ensureNoForwardedLiteralsIn(aMethodObj); - methodObj = aMethodObj; - methodHeader = methodHeaderOf(aMethodObj); - receiverTags = receiverTagBitsForMethod(methodObj); - cogMethod = compileCogMethod(aSelectorOop); - if ((((((sqInt)cogMethod)) >= MaxNegativeErrorCode) && ((((sqInt)cogMethod)) <= -1))) { - if ((((sqInt)cogMethod)) == InsufficientCodeSpace) { - callForCogCompiledCodeCompaction(); - } - /* begin maybeFreeCounters */ - if (counters != 0) { - /* begin freeCounters: */ - if (counters != 0) { - freeObject(counters - BaseHeaderSize); - } - } - return null; - } - return cogMethod; -} - - /* Cogit>>#collectCogConstituentFor:Annotation:Mcpc:Bcpc:Method: */ -static sqInt NoDbgRegParms -collectCogConstituentForAnnotationMcpcBcpcMethod(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *cogMethodArg) -{ - sqInt address; - sqInt annotation; - usqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - - if (!descriptor) { - return 0; - } - if (!((descriptor->isMapped))) { - return 0; - } - address = positive32BitIntegerFor(((usqInt)mcpc)); - if (!address) { - return PrimErrNoMemory; - } - storePointerUncheckedofObjectwithValue(cogConstituentIndex, topRemappableOop(), address); - storePointerUncheckedofObjectwithValue(cogConstituentIndex + 1, topRemappableOop(), (((usqInt)bcpc << 1) | 1)); - - /* Collect any first case classTags for closed PICs. */ - cogConstituentIndex += 2; - if (((!(isBackwardBranchAndAnnotation & 1))) - && (((((usqInt)(isBackwardBranchAndAnnotation)) >> 1) >= IsSendCall) - || (0))) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* send is linked */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - annotation = ((usqInt)(isBackwardBranchAndAnnotation)) >> 1; - /* begin offsetAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (((targetMethod1->cmType)) == CMClosedPIC) { - (targetMethod1->methodObject = classForInlineCacheTag(inlineCacheTagAt(backEnd, mcpc))); - } - } - } - return 0; -} - - -/* Answer a description of the mapping between machine code pointers and - bytecode pointers for the Cog Method. - First value is the address of the cog method. - Following values are pairs of machine code pc and bytecode pc */ - - /* Cogit>>#collectCogMethodConstituent: */ -static sqInt NoDbgRegParms -collectCogMethodConstituent(CogMethod *cogMethod) -{ - sqInt address; - sqInt aMethodHeader; - sqInt aMethodHeader1; - sqInt aMethodObj; - sqInt annotation; - sqInt bcpc; - sqInt bsOffset; - sqInt byte; - sqInt byte01; - sqInt byte02; - sqInt cm; - CogBlockMethod *cogBlockMethod; - sqInt data; - BytecodeDescriptor *descriptor; - sqInt distance; - sqInt distance1; - sqInt distance2; - sqInt endbcpc; - sqInt errCode; - CogMethod *homeMethod; - sqInt isBackwardBranch; - sqInt isInBlock; - sqInt latestContinuation; - usqInt map; - sqInt mapByte; - usqInt mcpc; - sqInt nExts; - sqInt newContinuation; - sqInt nextBcpc; - sqInt nSlots; - sqInt prim; - sqInt result; - sqInt startbcpc; - sqInt targetPC; - sqInt targetPC1; - sqInt upperByte; - - latestContinuation = 0; - if (!(((cogMethod->cmType)) == CMMethod)) { - return positive32BitIntegerFor(((usqInt)cogMethod)); - } - cogBlockMethod = ((CogBlockMethod *) cogMethod); - if (((cogBlockMethod->stackCheckOffset)) == 0) { - - /* isFrameless ? */ - return positive32BitIntegerFor(((usqInt)cogMethod)); - } - cm = (cogMethod->methodObject); - - /* +1 for first address */ - nSlots = ((((byteSizeOf(cm)) - (startPCOfMethod(cm))) * 2) + (minSlotsForShortening())) + 1; - data = instantiateClassindexableSize(splObj(ClassArray), nSlots); - if (!data) { - return null; - } - pushRemappableOop(data); - address = positive32BitIntegerFor(((usqInt)cogMethod)); - if (!address) { - popRemappableOop(); - return null; - } - storePointerUncheckedofObjectwithValue(0, topRemappableOop(), address); - cogConstituentIndex = 1; - /* begin mapFor:bcpc:performUntil:arg: */ - startbcpc = startPCOfMethod((cogMethod->methodObject)); - assert(((cogBlockMethod->stackCheckOffset)) > 0); - - /* The stack check maps to the start of the first bytecode, - the first bytecode being effectively after frame build. */ - mcpc = (((usqInt)cogBlockMethod)) + ((cogBlockMethod->stackCheckOffset)); - result = collectCogConstituentForAnnotationMcpcBcpcMethod(null, (0 + (((int)((usqInt)(HasBytecodePC) << 1)))), (((char *) mcpc)), startbcpc, (((void *)cogMethod))); - if (result != 0) { - errCode = result; - goto l9; - } - - /* In both CMMethod and CMBlock cases find the start of the map and - skip forward to the bytecode pc map entry for the stack check. */ - bcpc = startbcpc; - if (((cogBlockMethod->cmType)) == CMMethod) { - /* begin cmIsFullBlock */ - isInBlock = (cogBlockMethod->cpicHasMNUCaseOrCMIsFullBlock); - homeMethod = ((CogMethod *) cogBlockMethod); - assert(startbcpc == (startPCOfMethodHeader((homeMethod->methodHeader)))); - map = ((((usqInt)homeMethod)) + ((homeMethod->blockSize))) - 1; - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert((annotation == IsAbsPCReference) - || ((annotation == IsObjectReference) - || ((annotation == IsRelativeCall) - || (annotation == IsDisplacementX2N)))); - latestContinuation = startbcpc; - aMethodObj = (homeMethod->methodObject); - endbcpc = (numBytesOf(aMethodObj)) - 1; - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader) - ? 0x100 - : 0) -# else - 0 -# endif - ; - bcpc += deltaToSkipPrimAndErrorStoreInheader(aMethodObj, (homeMethod->methodHeader)); - } - else { - isInBlock = 1; - assert(bcpc == ((cogBlockMethod->startpc))); - homeMethod = cmHomeMethod(cogBlockMethod); - map = findMapLocationForMcpcinMethod((((usqInt)cogBlockMethod)) + (sizeof(CogBlockMethod)), homeMethod); - assert(map != 0); - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert(((((usqInt)(annotation)) >> AnnotationShift) == HasBytecodePC) - || ((((usqInt)(annotation)) >> AnnotationShift) == IsDisplacementX2N)); - while (((annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift)) != HasBytecodePC) { - map -= 1; - } - - /* skip fiducial; i.e. the map entry for the pc immediately following the method header. */ - map -= 1; - aMethodObj = (homeMethod->methodObject); - bcpc = startbcpc - ( -#if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet((homeMethod->methodHeader)) - ? AltBlockCreationBytecodeSize - : BlockCreationBytecodeSize) -#else // MULTIPLEBYTECODESETS - BlockCreationBytecodeSize -#endif - ); - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader1 = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader1) - ? 0x100 - : 0) -# else - 0 -# endif - ; - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - endbcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, -1, aMethodObj)) - : 0)); - bcpc = startbcpc; - } - nExts = 0; - while ((((usqInt)((byteAt(map)))) >> AnnotationShift) != HasBytecodePC) { - map -= 1; - } - map -= 1; - while (((mapByte = byteAt(map))) != MapEnd) { - - /* defensive; we exit on bcpc */ - if (mapByte >= FirstAnnotation) { - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if (annotation >= HasBytecodePC) { - if ((annotation == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - while (1) { - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - if (isInBlock) { - if (bcpc >= endbcpc) { - errCode = 0; - goto l9; - } - } - else { - if (((descriptor->isReturn)) - && (bcpc >= latestContinuation)) { - errCode = 0; - goto l9; - } - if ((isBranch(descriptor)) - || ((descriptor->isBlockCreation))) { - /* begin latestContinuationPCFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj); - targetPC = (bcpc + ((descriptor->numBytes))) + (((distance < 0) ? 0 : distance)); - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - /* begin maybeUnsafeJumpContinuation:at:for:in: */ - newContinuation = latestContinuation; - if ((descriptor->hasUnsafeJump)) { - byte01 = fetchByteofObject(bcpc + 1, aMethodObj); - - /* pushIntegerLong */ - byte02 = fetchByteofObject(bcpc + 2, aMethodObj); - /* begin decodePushIntegerLongBefore:in: */ - distance1 = fetchByteofObject(bcpc - 1, methodObj); - upperByte = fetchByteofObject(bcpc - 3, methodObj); - if (upperByte > 0x7F) { - upperByte -= 0x100; - } - distance2 = (((sqInt)((usqInt)(upperByte) << 8))) + distance1; - targetPC1 = (bcpc + ((descriptor->numBytes))) + distance2; - if (!((descriptor->isMapped))) { - if ((((usqInt)(byte02)) >> 5) == 4) { - - /* inlined sista primitive */ - prim = (((sqInt)((usqInt)((byte02 & 0x1F)) << 8))) + byte01; - if (prim >= 7000) { - - /* branch forward */ - newContinuation = ((latestContinuation < targetPC1) ? targetPC1 : latestContinuation); - } - } - } - } - latestContinuation = newContinuation; - } - nextBcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) - : 0)); - if (((descriptor->isMapped)) - || (isInBlock - && ((descriptor->isMappedInBlock)))) break; - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - isBackwardBranch = (isBranch(descriptor)) - && ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) < 0)); - result = collectCogConstituentForAnnotationMcpcBcpcMethod(descriptor, ((isBackwardBranch - ? (((sqInt)((usqInt)(annotation) << 1))) + 1 - : ((sqInt)((usqInt)(annotation) << 1)))), (((char *) mcpc)), ((isBackwardBranch - ? bcpc - (2 * nExts) - : bcpc)), (((void *)cogMethod))); - if (result != 0) { - errCode = result; - goto l9; - } - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - } - else { - assert(((((usqInt)(mapByte)) >> AnnotationShift) == IsDisplacementX2N) - || ((((usqInt)(mapByte)) >> AnnotationShift) == IsAnnotationExtension)); - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - errCode = 0; - l9: /* end mapFor:bcpc:performUntil:arg: */; - if (errCode != 0) { - popRemappableOop(); - return null; - } - if (cogConstituentIndex < nSlots) { - shortentoIndexableSize(topRemappableOop(), cogConstituentIndex); - } - return popRemappableOop(); -} - - /* Cogit>>#compactCogCompiledCode */ -void -compactCogCompiledCode(void) -{ - assertValidDualZone(); - assert(noCogMethodsMaximallyMarked()); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - markActiveMethodsAndReferents(); - freeOlderMethodsForCompaction(); - compactPICsWithFreedTargets(); - planCompaction(); - updateStackZoneReferencesToCompiledCodePreCompaction(); - relocateMethodsPreCompaction(); - assertValidDualZone(); - compactCompiledCode(); - stopsFromto(backEnd, freeStart(), (youngReferrers()) - 1); - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), ((usqInt)(youngReferrers()))); - assert(allMethodsHaveCorrectHeader()); - assert(kosherYoungReferrers()); - assertValidDualZone(); -} - - /* Cogit>>#compactPICsWithFreedTargets */ -static void -compactPICsWithFreedTargets(void) -{ - CogMethod *cogMethod; - sqInt count; - - cogMethod = ((CogMethod *) methodZoneBase); - count = 0; - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) == CMClosedPIC) - && (cPICCompactAndIsNowEmpty(cogMethod))) { - ((((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)))->cmType = CMFree); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - count += 1; - } - assert(count == (numMethods())); -} - - -/* The start of a CogMethod has a call to a run-time abort routine that - either handles an in-line cache failure or a stack overflow. The routine - selects the - path depending on ReceiverResultReg; if zero it takes the stack overflow - path; if nonzero the in-line cache miss path. Neither of these paths - returns. The abort routine must be called; In the callee the method is - located by - adding the relevant offset to the return address of the call. - - N.B. This code must match that in compilePICAbort: so that the offset of - the return address of the call is the same in methods and closed PICs. */ - - /* Cogit>>#compileAbort */ -static AbstractInstruction * -compileAbort(void) -{ - AbstractInstruction *anInstruction; - sqInt callTarget; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 0, ReceiverResultReg); - stackOverflowCall = anInstruction; - - /* If there is a link register it must be saved (pushed onto the stack) before it - is smashed by the abort call, and hence needs to be manually handled here */ - sendMiss = genoperand(PushR, LinkReg); - /* begin Call: */ - callTarget = methodAbortTrampolineFor(methodOrBlockNumArgs); - return genoperand(Call, callTarget); -} - - /* Cogit>>#compileBlockDispatchFrom:to: */ -static sqInt NoDbgRegParms -compileBlockDispatchFromto(sqInt lowBlockStartIndex, sqInt highBlockStartIndex) -{ - AbstractInstruction *anInstruction; - BlockStart *blockStart; - sqInt halfWay; - AbstractInstruction *jmp; - - if (lowBlockStartIndex == highBlockStartIndex) { - blockStart = blockStartAt(lowBlockStartIndex); - genoperand(Jump, ((sqInt)((blockStart->entryLabel)))); - return null; - } - halfWay = (highBlockStartIndex + lowBlockStartIndex) / 2; - assert(((halfWay >= lowBlockStartIndex) && (halfWay <= highBlockStartIndex))); - - /* N.B. FLAGS := TempReg - startpc */ - blockStart = blockStartAt(halfWay); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)(((blockStart->startpc)) + 1) << 1) | 1); - anInstruction = genoperandoperand(CmpCqR, (((usqInt)(((blockStart->startpc)) + 1) << 1) | 1), TempReg); - if (lowBlockStartIndex == halfWay) { - genConditionalBranchoperand(JumpLessOrEqual, ((sqInt)((blockStart->entryLabel)))); - compileBlockDispatchFromto(halfWay + 1, highBlockStartIndex); - return null; - } - if ((halfWay + 1) == highBlockStartIndex) { - blockStart = blockStartAt(highBlockStartIndex); - genConditionalBranchoperand(JumpGreater, ((sqInt)((blockStart->entryLabel)))); - return compileBlockDispatchFromto(lowBlockStartIndex, halfWay); - } - jmp = genConditionalBranchoperand(JumpGreater, ((sqInt)0)); - compileBlockDispatchFromto(lowBlockStartIndex, halfWay); - if (halfWay == highBlockStartIndex) { - blockStart = blockStartAt(highBlockStartIndex); - jmpTarget(jmp, (blockStart->entryLabel)); - } - else { - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileBlockDispatchFromto(halfWay + 1, highBlockStartIndex); - } - return 0; -} - - -/* Compile a block's entry. This looks like a dummy CogBlockMethod header - (for frame parsing) - followed by either a frame build, if a frame is required, or nothing. The - CogMethodHeader's objectHeader field is a back pointer to the method, but - this can't be filled in until code generation. */ - - /* Cogit>>#compileBlockEntry: */ -static void NoDbgRegParms -compileBlockEntry(BlockStart *blockStart) -{ - AbstractInstruction *abstractInstruction; - sqInt alignment; - - /* begin AlignmentNops: */ - alignment = blockAlignment(); - genoperand(AlignmentNops, alignment); - (blockStart->fakeHeader = genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - switch (sizeof(CogBlockMethod)) { - case 8: - genoperand(Fill32, 0); - genoperand(Fill32, 0); - break; - case 12: - genoperand(Fill32, 0); - genoperand(Fill32, 0); - genoperand(Fill32, 0); - break; - case 16: - genoperand(Fill32, 0); - genoperand(Fill32, 0); - genoperand(Fill32, 0); - genoperand(Fill32, 0); - break; - default: - error("Case not found and no otherwise clause"); - } - (blockStart->entryLabel = genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (needsFrame) { - compileBlockFrameBuild(blockStart); - if (recordBlockTrace()) { - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceTraceBlockActivationTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - } - } - else { - compileBlockFramelessEntry(blockStart); - } -} - - -/* Generate a call to aRoutine with up to 4 arguments. If resultRegOrNone is - not NoReg assign the C result to resultRegOrNone. If saveRegs, save all - registers. Hack: a negative arg value indicates an abstract register, a - non-negative value - indicates a constant. */ - - /* Cogit>>#compileCallFor:numArgs:arg:arg:arg:arg:resultReg:regsToSave: */ -static void NoDbgRegParms -compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt resultRegOrNone, sqInt regMask) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - const int cStackAlignment = STACK_ALIGN_BYTES; - sqInt delta; - sqInt numRegsPushed; - usqInt regMaskCopy; - sqInt regsToSave; - sqInt wordsPushedModAlignment; - - regsToSave = (resultRegOrNone == NoReg - ? regMask - : ((regMask | (1U << resultRegOrNone)) - (1U << resultRegOrNone))); - if (cStackAlignment > BytesPerWord) { - /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ - regMaskCopy = ((usqInt)regsToSave); - numRegsPushed = 0; - while (regMaskCopy != 0) { - numRegsPushed += regMaskCopy & 1; - regMaskCopy = ((regMaskCopy) >> 1); - } - if ((numRegsPushed == 0) - && ((numIntRegArgs(((AbstractInstruction *) backEnd))) >= numArgs)) { - goto l1; - } - wordsPushedModAlignment = (numRegsPushed + ((((numArgs - (numIntRegArgs(((AbstractInstruction *) backEnd)))) < 0) ? 0 : (numArgs - (numIntRegArgs(((AbstractInstruction *) backEnd))))))) % (cStackAlignment / BytesPerWord); - if (wordsPushedModAlignment != 0) { - delta = (cStackAlignment / BytesPerWord) - wordsPushedModAlignment; - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, delta * BytesPerWord, SPReg); - } - l1: /* end genAlignCStackSavingRegisters:numArgs:wordAlignment: */; - } - genSaveRegs(backEnd, regsToSave); - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - if (numArgs == 0) { - goto l13; - } - if (regOrConst0 < NoReg) { - /* begin MoveCq:R: */ - anInstruction4 = genoperandoperand(MoveCqR, -2 - regOrConst0, A0); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, regOrConst0, A0); - } - if (numArgs == 1) { - goto l13; - } - if (regOrConst1 < NoReg) { - /* begin MoveCq:R: */ - anInstruction11 = genoperandoperand(MoveCqR, -2 - regOrConst1, A1); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, regOrConst1, A1); - } - if (numArgs == 2) { - goto l13; - } - if (regOrConst2 < NoReg) { - /* begin MoveCq:R: */ - anInstruction21 = genoperandoperand(MoveCqR, -2 - regOrConst2, A2); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, regOrConst2, A2); - } - if (numArgs == 3) { - goto l13; - } - if (regOrConst3 < NoReg) { - /* begin MoveCq:R: */ - anInstruction3 = genoperandoperand(MoveCqR, -2 - regOrConst3, A3); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, regOrConst3, A3); - } - l13: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin checkLiteral:forInstruction: */ - anInstruction2 = genoperand(CallFull, ((usqInt)aRoutine)); - genWriteCResultIntoReg(backEnd, resultRegOrNone); - assert(numArgs <= 4); - genRestoreRegs(backEnd, regsToSave); -} - - -/* Compile the cache tag computation and the first comparison. Answer the - address of that comparison. */ - - /* Cogit>>#compileCPICEntry */ -static AbstractInstruction * -compileCPICEntry(void) -{ - entry = genGetInlineCacheClassTagFromintoforEntry(ReceiverResultReg, TempReg, 1); - /* begin CmpR:R: */ - assert(!((ClassReg == SPReg))); - genoperandoperand(CmpRR, ClassReg, TempReg); - return genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -} - - -/* Compile the abstract instructions for the entire full block method. */ - - /* Cogit>>#compileEntireFullBlockMethod: */ -static sqInt NoDbgRegParms -compileEntireFullBlockMethod(sqInt numCopied) -{ - sqInt result; - - /* begin preenMethodLabel */ - (((((AbstractInstruction *) methodLabel))->operands))[1] = 0; - compileFullBlockEntry(); - compileFullBlockMethodFrameBuild(numCopied); - if (((result = compileMethodBody())) < 0) { - return result; - } - assert(blockCount == 0); - return 0; -} - - -/* The entry code to a method checks that the class of the current receiver - matches that in the inline cache. Other non-obvious elements are that its - alignment must be - different from the alignment of the noCheckEntry so that the method map - machinery can distinguish normal and super sends (super sends bind to the - noCheckEntry). */ - - /* Cogit>>#compileEntry */ -static void -compileEntry(void) -{ - AbstractInstruction *anInstruction1; - AbstractInstruction * inst; - - entry = genGetInlineCacheClassTagFromintoforEntry(ReceiverResultReg, TempReg, 1); - /* begin CmpR:R: */ - assert(!((ClassReg == SPReg))); - genoperandoperand(CmpRR, ClassReg, TempReg); - genConditionalBranchoperand(JumpNonZero, ((sqInt)sendMiss)); - noCheckEntry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - if (((traceFlags & 0x100) == 0x100)) { - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - /* begin checkLiteral:forInstruction: */ - anInstruction1 = genoperand(CallFull, ceTraceLinkedSendTrampoline); - /* begin PopR: */ - genoperand(PopR, LinkReg); - } -} - - -/* Compile the abstract instructions for the entire method, including blocks. */ -/* Abort for stack overflow on full block activation (no inline cache miss - possible). The flag is SendNumArgsReg. */ - - /* Cogit>>#compileFullBlockEntry */ -static sqInt -compileFullBlockEntry(void) -{ - sqInt alignment; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt callTarget; - AbstractInstruction * jumpNoContextSwitch; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 0, ReceiverResultReg); - stackOverflowCall = anInstruction; - /* begin PushR: */ - genoperand(PushR, LinkReg); - /* begin Call: */ - callTarget = methodAbortTrampolineFor(methodOrBlockNumArgs); - genoperand(Call, callTarget); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, 0, SendNumArgsReg); - fullBlockNoContextSwitchEntry = anInstruction1; - jumpNoContextSwitch = genoperand(Jump, ((sqInt)0)); - /* begin AlignmentNops: */ - alignment = ((BytesPerWord < 8) ? 8 : BytesPerWord); - genoperand(AlignmentNops, alignment); - fullBlockEntry = genoperandoperand(MoveRR, ReceiverResultReg, SendNumArgsReg); - jmpTarget(jumpNoContextSwitch, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - -/* Compile the top-level method body. */ - - /* Cogit>>#compileMethodBody */ -static sqInt -compileMethodBody(void) -{ - if (endPC < initialPC) { - return 0; - } - return compileAbstractInstructionsFromthrough(initialPC + (deltaToSkipPrimAndErrorStoreInheader(methodObj, methodHeader)), endPC); -} - - -/* The start of a PIC has a call to a run-time abort routine that either - handles a dispatch to an - interpreted method or a dispatch of an MNU case. The routine selects the - path by testing - ClassReg, which holds the inline cache tag; if equal to the - picAbortDiscriminatorValue (zero) - it takes the MNU path; if nonzero the dispatch to interpreter path. - Neither of these paths - returns. The abort routine must be called; In the callee the PIC is - located by adding the - relevant offset to the return address of the call. - - N.B. This code must match that in compileAbort so that the offset of the - return address of - the call is the same in methods and closed PICs. */ - - /* Cogit>>#compilePICAbort: */ -static sqInt NoDbgRegParms -compilePICAbort(sqInt numArgs) -{ - AbstractInstruction *anInstruction; - sqInt callTarget; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 0 /* picAbortDiscriminatorValue */, ClassReg); - picMNUAbort = anInstruction; - - /* If there is a link register it must be saved (pushed onto the stack) before it - is smashed by the abort call, and hence needs to be manually handled here */ - picInterpretAbort = genoperand(PushR, LinkReg); - /* begin Call: */ - callTarget = picAbortTrampolineFor(numArgs); - genoperand(Call, callTarget); - return 0; -} - - -/* Compile the compare of stackLimit against the stack pointer, jumping to - the stackOverflowCall if - the stack pointer is below the limit. Answer a bytecode annotated label - that follows the sequence. - - The stack check functions both as a genuine stack limit check to prevent - calls overflowing stack pages, - and as an event/context-switch break out. To cause an event check - (including a check for a required - context switch), stackLimit is set to the highest possible value, and - hence all stack limit checks will - fail. A path in the stack overflow abort then arranges to call event - checking if it has been requested. - - Certain block activations (e.g. valueNoContextSwitch:) must not context - switch, and in that - case, SendNumArgs is set to zero to communicate to the stack overflow - abort that it should - not perform event/context-switch (yet). */ - - /* Cogit>>#compileStackOverflowCheck: */ -static AbstractInstruction * NoDbgRegParms -compileStackOverflowCheck(sqInt canContextSwitch) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction * jumpSkip; - AbstractInstruction * label; - - /* begin checkLiteral:forInstruction: */ - stackLimitAddress(); - anInstruction1 = genoperandoperand(MoveAwR, stackLimitAddress(), TempReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, SPReg); - if (canContextSwitch) { - genConditionalBranchoperand(JumpBelow, ((sqInt)stackOverflowCall)); - label = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - else { - jumpSkip = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 0, SendNumArgsReg); - genoperand(Jump, ((sqInt)stackOverflowCall)); - jmpTarget(jumpSkip, (label = genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - } - /* begin annotateBytecode: */ - (label->annotation = HasBytecodePC); - return label; -} - - -/* Generate a trampoline with up to four arguments. Generate either a call or - a jump to aRoutine - as requested by callJumpBar. If generating a call and resultRegOrNone is - not NoReg pass the C - result back in resultRegOrNone. - Hack: a negative value indicates an abstract register, a non-negative - value indicates a constant. */ - - /* Cogit>>#compileTrampolineFor:numArgs:arg:arg:arg:arg:regsToSave:pushLinkReg:resultReg: */ -static void NoDbgRegParms -compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone) -{ - genSmalltalkToCStackSwitch(pushLinkReg); - compileCallFornumArgsargargargargresultRegregsToSave(aRoutine, numArgs, regOrConst0, regOrConst1, regOrConst2, regOrConst3, resultRegOrNone, regMask); - genLoadStackPointers(backEnd); - genTrampolineReturn(pushLinkReg); -} - - -/* Generate the entry code for a method to determine cmEntryOffset and - cmNoCheckEntryOffset. We - need cmNoCheckEntryOffset up front to be able to generate the map starting - from cmNoCheckEntryOffset */ -/* stack allocate the various collections so that they - are effectively garbage collected on return. */ - - /* Cogit>>#computeEntryOffsets */ -static void -computeEntryOffsets(void) -{ - sqInt fixupSize; - sqInt opcodeSize; - AbstractInstruction *sendMissCall; - - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 24; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - methodOrBlockNumArgs = 0; - sendMissCall = compileAbort(); - compileEntry(); - computeMaximumSizes(); - generateInstructionsAt(methodZoneBase + (sizeof(CogMethod))); - cmEntryOffset = ((entry->address)) - methodZoneBase; - cmNoCheckEntryOffset = ((noCheckEntry->address)) - methodZoneBase; - missOffset = (((sendMissCall->address)) + ((sendMissCall->machineCodeSize))) - methodZoneBase; - entryPointMask = BytesPerWord - 1; - while ((cmEntryOffset & entryPointMask) == (cmNoCheckEntryOffset & entryPointMask)) { - entryPointMask = (entryPointMask + entryPointMask) + 1; - } - if (entryPointMask >= (roundUpToMethodAlignment(backEnd(), 1))) { - error("cannot differentiate checked and unchecked entry-points with current cog method alignment"); - } - checkedEntryAlignment = cmEntryOffset & entryPointMask; - uncheckedEntryAlignment = cmNoCheckEntryOffset & entryPointMask; - assert(checkedEntryAlignment != uncheckedEntryAlignment); -} - - -/* Generate the entry code for a method to determine cmEntryOffset and - cmNoCheckEntryOffset. We - need cmNoCheckEntryOffset up front to be able to generate the map starting - from cmNoCheckEntryOffset */ -/* stack allocate the various collections so that they - are effectively garbage collected on return. */ - - /* Cogit>>#computeFullBlockEntryOffsets */ -static void -computeFullBlockEntryOffsets(void) -{ - sqInt fixupSize; - sqInt opcodeSize; - - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 24; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - methodOrBlockNumArgs = 0; - compileFullBlockEntry(); - computeMaximumSizes(); - generateInstructionsAt(methodZoneBase + (sizeof(CogMethod))); - cbEntryOffset = ((fullBlockEntry->address)) - methodZoneBase; - cbNoSwitchEntryOffset = ((fullBlockNoContextSwitchEntry->address)) - methodZoneBase; -} - - -/* While we order variables in the CoInterpreter in order of dynamic - frequency, and hence - expect that stackPointer will be output first, C optimizers and linkers - may get their own - ideas and ``improve upon'' this ordering. So we cannot depend on - stackPointer being - at the lowest address of the variables we want to access through - VarBaseReg. Here we - choose the minimum amongst a set to try to choose a varBaseAddress that is - just less - than but iwht in range of all variables we want to access through it. */ - - /* Cogit>>#computeGoodVarBaseAddress */ -static usqInt -computeGoodVarBaseAddress(void) -{ - usqInt minAddress; - - - /* stackLimit is e.g. lowest using the clang toolchain on MacOS X */ - minAddress = stackLimitAddress(); - if ((stackPointerAddress()) < minAddress) { - minAddress = stackPointerAddress(); - } - if ((framePointerAddress()) < minAddress) { - minAddress = framePointerAddress(); - } - if ((instructionPointerAddress()) < minAddress) { - minAddress = instructionPointerAddress(); - } - if ((argumentCountAddress()) < minAddress) { - minAddress = argumentCountAddress(); - } - if ((primFailCodeAddress()) < minAddress) { - minAddress = primFailCodeAddress(); - } - return minAddress; -} - - -/* This pass assigns maximum sizes to all abstract instructions and - eliminates jump fixups. - It hence assigns the maximum address an instruction will occur at which - allows the next - pass to conservatively size jumps. */ - - /* Cogit>>#computeMaximumSizes */ -static void -computeMaximumSizes(void) -{ - AbstractInstruction *abstractInstruction; - sqInt i; - sqInt relativeAddress; - - relativeAddress = 0; - for (i = 0; i < opcodeIndex; i += 1) { - maybeBreakGeneratingInstructionWithIndex(i); - abstractInstruction = abstractInstructionAt(i); - (abstractInstruction->address = relativeAddress); - (abstractInstruction->maxSize = computeMaximumSize(abstractInstruction)); - relativeAddress += (abstractInstruction->maxSize); - } -} - - -/* Configure a copy of the prototype CPIC for a two-case PIC for - case0CogMethod and - case1Method - case1Tag. - The tag for case0CogMethod is at the send site and so doesn't need to be - generated. case1Method may be any of - - a Cog method; jump to its unchecked entry-point - - a CompiledMethod; jump to the ceInterpretFromPIC trampoline - - nil; call ceMNUFromPIC - addDelta is the address change from the prototype to the new CPIC - location, needed - because the loading of the CPIC label at the end may use a literal instead - of a pc relative load. */ -/* self disassembleFrom: cPIC asInteger + (self sizeof: CogMethod) to: cPIC - asInteger + closedPICSize - */ - - /* Cogit>>#configureCPIC:Case0:Case1Method:tag:isMNUCase:numArgs:delta: */ -static sqInt NoDbgRegParms -configureCPICCase0Case1MethodtagisMNUCasenumArgsdelta(CogMethod *cPIC, CogMethod *case0CogMethod, sqInt case1Method, sqInt case1Tag, sqInt isMNUCase, sqInt numArgs, sqInt addrDelta) -{ - sqInt caseEndAddress; - int operand; - sqInt targetEntry; - - assert(case1Method != null); - rewriteCallAttarget(backEnd, (((sqInt)cPIC)) + missOffset, picAbortTrampolineFor(numArgs)); - assert(!(inlineCacheTagIsYoung(case1Tag))); - if ((!isMNUCase) - && (methodHasCogMethod(case1Method))) { - operand = 0; - targetEntry = (((sqInt)(cogMethodOf(case1Method)))) + cmNoCheckEntryOffset; - } - else { - - /* We do not scavenge PICs, hence we cannot cache the MNU method if it is in new space. */ - operand = ((case1Method == null) - || (isYoungObject(case1Method)) - ? 0 - : case1Method); - targetEntry = (case1Method == null - ? (((sqInt)cPIC)) + (sizeof(CogMethod)) - : (((sqInt)cPIC)) + (picInterpretAbortOffset())); - } - rewriteJumpLongAttarget(backEnd, (((sqInt)cPIC)) + firstCPICCaseOffset, (((sqInt)case0CogMethod)) + cmNoCheckEntryOffset); - - /* update the cpic case */ - caseEndAddress = addressOfEndOfCaseinCPIC(2, cPIC); - rewriteCPICCaseAttagobjReftarget(caseEndAddress, case1Tag, operand, ((sqInt)((isMNUCase - ? (((sqInt)cPIC)) + (sizeof(CogMethod)) - : targetEntry)))); - relocateMethodReferenceBeforeAddressby(backEnd, ((((sqInt)cPIC)) + cPICEndOfCodeOffset) - (jumpLongByteSize(backEnd)), addrDelta); - rewriteJumpLongAttarget(backEnd, (((sqInt)cPIC)) + cPICEndOfCodeOffset, cPICMissTrampolineFor(numArgs)); - return 0; -} - - -/* Configure a copy of the prototype CPIC for a one-case MNU CPIC that calls - ceMNUFromPIC for - case0Tag The tag for case0 is at the send site and so doesn't need to be - generated. addDelta is the address change from the prototype to the new - CPIC location, needed - because the loading of the CPIC label at the end may be a literal instead - of a pc-relative load. */ -/* adjust the jump at missOffset, the ceAbortXArgs */ - - /* Cogit>>#configureMNUCPIC:methodOperand:numArgs:delta: */ -static sqInt NoDbgRegParms -configureMNUCPICmethodOperandnumArgsdelta(CogMethod *cPIC, sqInt methodOperand, sqInt numArgs, sqInt addrDelta) -{ - int operand; - sqInt target; - - rewriteCallAttarget(backEnd, (((sqInt)cPIC)) + missOffset, picAbortTrampolineFor(numArgs)); - - /* set the jump to the case0 method */ - operand = ((methodOperand == null) - || (isYoungObject(methodOperand)) - ? 0 - : methodOperand); - rewriteJumpLongAttarget(backEnd, (((sqInt)cPIC)) + firstCPICCaseOffset, (((sqInt)cPIC)) + (sizeof(CogMethod))); - storeLiteralbeforeFollowingAddress(backEnd, operand, ((((sqInt)cPIC)) + firstCPICCaseOffset) - (jumpLongByteSize(backEnd))); - rewriteJumpLongAttarget(backEnd, (((sqInt)cPIC)) + cPICEndOfCodeOffset, cPICMissTrampolineFor(numArgs)); - relocateMethodReferenceBeforeAddressby(backEnd, ((((sqInt)cPIC)) + cPICEndOfCodeOffset) - (jumpLongByteSize(backEnd)), addrDelta); - /* begin rewriteCPIC:caseJumpTo: */ - target = addressOfEndOfCaseinCPIC(2, cPIC); - rewriteCPICJumpAttarget(backEnd, (((((sqInt)cPIC)) + firstCPICCaseOffset) - (jumpLongByteSize(backEnd))) - 8 /* loadLiteralByteSize */, target); - return 0; -} - - -/* Scan the CPIC for target methods that have been freed and eliminate them. - Since the first entry cannot be eliminated, answer that the PIC should be - freed if the first entry is to a free target. Answer if the PIC is now - empty or should be freed. */ - - /* Cogit>>#cPICCompactAndIsNowEmpty: */ -static sqInt NoDbgRegParms -cPICCompactAndIsNowEmpty(CogMethod *cPIC) -{ - usqInt entryPoint; - sqInt followingAddress; - sqInt i; - sqInt methods[MaxCPICCases]; - sqInt pc; - int tags[MaxCPICCases]; - CogMethod *targetMethod; - sqInt targets[MaxCPICCases]; - sqInt used; - sqInt valid; - - used = 0; - for (i = 1; i <= ((cPIC->cPICNumCases)); i += 1) { - pc = addressOfEndOfCaseinCPIC(i, cPIC); - entryPoint = (i == 1 - ? jumpLongTargetBeforeFollowingAddress(backEnd, pc) - : jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc)); - - /* Collect all target triples except for triples whose entry-point is a freed method */ - valid = 1; - if (!(((((usqInt)cPIC)) <= (((usqInt)entryPoint))) - && (((((usqInt)cPIC)) + ((cPIC->blockSize))) >= (((usqInt)entryPoint))))) { - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - assert((((targetMethod->cmType)) == CMMethod) - || (((targetMethod->cmType)) == CMFree)); - if (((targetMethod->cmType)) == CMFree) { - if (i == 1) { - return 1; - } - valid = 0; - } - } - if (valid) { - tags[used] = ((i > 1 - ? (/* begin literal32BeforeFollowingAddress: */ - (followingAddress = pc - 16 /* jumpLongConditionalByteSize */), - literalBeforeFollowingAddress(((AbstractInstruction *) backEnd), followingAddress)) - : 0)); - targets[used] = entryPoint; - methods[used] = (literalBeforeFollowingAddress(backEnd, pc - ((i == 1 - ? jumpLongByteSize(backEnd) - : 24)))); - used += 1; - } - } - if (used == ((cPIC->cPICNumCases))) { - return 0; - } - if (used == 0) { - return 1; - } - ((((CogMethod *) ((((usqInt)cPIC)) + codeToDataDelta)))->cPICNumCases = used); - if (used == 1) { - pc = addressOfEndOfCaseinCPIC(2, cPIC); - /* begin rewriteCPIC:caseJumpTo: */ - rewriteCPICJumpAttarget(backEnd, (((((sqInt)cPIC)) + firstCPICCaseOffset) - (jumpLongByteSize(backEnd))) - 8 /* loadLiteralByteSize */, pc); - return 0; - } - for (i = 1; i < used; i += 1) { - pc = addressOfEndOfCaseinCPIC(i + 1, cPIC); - rewriteCPICCaseAttagobjReftarget(pc, tags[i], methods[i], targets[i]); - } - /* begin rewriteCPIC:caseJumpTo: */ - rewriteCPICJumpAttarget(backEnd, (((((sqInt)cPIC)) + firstCPICCaseOffset) - (jumpLongByteSize(backEnd))) - 8 /* loadLiteralByteSize */, pc - cPICCaseSize); - return 0; -} - - -/* The first case in a CPIC doesn't have a class reference so we need only - step over actually usd subsequent cases. - */ - - /* Cogit>>#cPICHasForwardedClass: */ -static sqInt NoDbgRegParms -cPICHasForwardedClass(CogMethod *cPIC) -{ - usqInt classIndex; - sqInt i; - sqInt pc; - - - /* start by finding the address of the topmost case, the cPICNumCases'th one */ - pc = (addressOfEndOfCaseinCPIC((cPIC->cPICNumCases), cPIC)) - 16 /* jumpLongConditionalByteSize */; - for (i = 2; i <= ((cPIC->cPICNumCases)); i += 1) { - /* begin literal32BeforeFollowingAddress: */ - classIndex = literalBeforeFollowingAddress(((AbstractInstruction *) backEnd), pc); - if (isForwardedClassIndex(classIndex)) { - return 1; - } - pc += cPICCaseSize; - } - return 0; -} - - -/* scan the CPIC for target methods that have been freed. */ - - /* Cogit>>#cPICHasFreedTargets: */ -static sqInt NoDbgRegParms -cPICHasFreedTargets(CogMethod *cPIC) -{ - usqInt entryPoint; - sqInt i; - sqInt pc; - CogMethod *targetMethod; - - for (i = 1; i <= ((cPIC->cPICNumCases)); i += 1) { - pc = addressOfEndOfCaseinCPIC(i, cPIC); - - /* Find target from jump. Ignore jumps to the interpret and MNU calls within this PIC */ - entryPoint = (i == 1 - ? jumpLongTargetBeforeFollowingAddress(backEnd, pc) - : jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc)); - if (!(((((usqInt)cPIC)) <= (((usqInt)entryPoint))) - && (((((usqInt)cPIC)) + ((cPIC->blockSize))) >= (((usqInt)entryPoint))))) { - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - assert((((targetMethod->cmType)) == CMMethod) - || (((targetMethod->cmType)) == CMFree)); - if (((targetMethod->cmType)) == CMFree) { - return 1; - } - } - } - return 0; -} - - -/* Whimsey; we want 16rCA5E10 + cPICPrototypeCaseOffset to be somewhere in - the middle of the zone. - */ - - /* Cogit>>#cPICPrototypeCaseOffset */ -static usqInt -cPICPrototypeCaseOffset(void) -{ - return ((methodZoneBase + (youngReferrers())) / 2) - 13262352; -} - - -/* Are any of the jumps from this CPIC to targetMethod? */ - - /* Cogit>>#cPIC:HasTarget: */ -static sqInt NoDbgRegParms -cPICHasTarget(CogMethod *cPIC, CogMethod *targetMethod) -{ - sqInt i; - sqInt pc; - sqInt target; - - target = (((usqInt)targetMethod)) + cmNoCheckEntryOffset; - - /* Since this is a fast test doing simple compares we don't need to care that some - cases have nonsense addresses in there. Just zip on through. */ - /* First jump is unconditional; subsequent ones are conditional */ - pc = (((sqInt)cPIC)) + firstCPICCaseOffset; - if (target == (jumpLongTargetBeforeFollowingAddress(backEnd, pc))) { - return 1; - } - for (i = 2; i <= MaxCPICCases; i += 1) { - pc += cPICCaseSize; - if (target == (jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc))) { - return 1; - } - } - return 0; -} - - -/* Answer an Array of the PIC's selector, followed by class and - targetMethod/doesNotUnderstand: for each entry in the PIC. - */ - - /* Cogit>>#createCPICData: */ -static sqInt NoDbgRegParms -createCPICData(CogMethod *cPIC) -{ - sqInt class; - usqInt entryPoint; - sqInt i; - sqInt pc; - sqInt picData; - sqInt target; - CogMethod *targetMethod; - - assert((((cPIC->methodObject)) == 0) - || (addressCouldBeOop((cPIC->methodObject)))); - picData = instantiateClassindexableSize(classArray(), (((cPIC->cPICNumCases)) * 2) + 1); - if (!picData) { - return picData; - } - storePointerUncheckedofObjectwithValue(0, picData, (cPIC->selector)); - for (i = 1; i <= ((cPIC->cPICNumCases)); i += 1) { - pc = addressOfEndOfCaseinCPIC(i, cPIC); - if (i == 1) { - - /* first case may have been collected and stored here by collectCogConstituentFor:Annotation:Mcpc:Bcpc:Method: */ - class = (cPIC->methodObject); - if (class == 0) { - class = nilObject(); - } - entryPoint = jumpLongTargetBeforeFollowingAddress(backEnd, pc); - } - else { - class = classForInlineCacheTag(literalBeforeFollowingAddress(backEnd, pc - 16 /* jumpLongConditionalByteSize */)); - entryPoint = jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc); - } - if (((((usqInt)cPIC)) <= (((usqInt)entryPoint))) - && (((((usqInt)cPIC)) + ((cPIC->blockSize))) >= (((usqInt)entryPoint)))) { - target = splObj(SelectorDoesNotUnderstand); - } - else { - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - assert(((targetMethod->cmType)) == CMMethod); - target = (targetMethod->methodObject); - } - storePointerUncheckedofObjectwithValue((i * 2) - 1, picData, class); - storePointerUncheckedofObjectwithValue(i * 2, picData, target); - } - beRootIfOld(picData); - (cPIC->methodObject = 0); - return picData; -} - - -/* Division is a little weird on some processors. Defer to the backEnd - to allow it to generate any special code it may need to. */ - - /* Cogit>>#DivR:R:Quo:Rem: */ -static AbstractInstruction * NoDbgRegParms -gDivRRQuoRem(sqInt rDivisor, sqInt rDividend, sqInt rQuotient, sqInt rRemainder) -{ - genDivRRQuoRem(backEnd, rDivisor, rDividend, rQuotient, rRemainder); - return abstractInstructionAt(opcodeIndex - 1); -} - - -/* Answer the number of bytecodes to skip to get to the first bytecode - past the primitive call and any store of the error code. */ - - /* Cogit>>#deltaToSkipPrimAndErrorStoreIn:header: */ -static sqInt NoDbgRegParms -deltaToSkipPrimAndErrorStoreInheader(sqInt aMethodObj, sqInt aMethodHeader) -{ - return (((primitiveIndexOfMethodheader(aMethodObj, aMethodHeader)) > 0) - && ((longStoreBytecodeForHeader(aMethodHeader)) == (fetchByteofObject((startPCOfMethod(aMethodObj)) + (sizeOfCallPrimitiveBytecode(aMethodHeader)), aMethodObj))) - ? (sizeOfCallPrimitiveBytecode(aMethodHeader)) + (sizeOfLongStoreTempBytecode(aMethodHeader)) - : 0); -} - - /* Cogit>>#endPCOf: */ -static sqInt NoDbgRegParms -endPCOf(sqInt aMethod) -{ - sqInt bsOffset; - sqInt byte; - sqInt byte01; - sqInt byte02; - BytecodeDescriptor *descriptor; - sqInt distance; - sqInt distance1; - sqInt distance2; - sqInt end; - sqInt latestContinuation; - sqInt nExts; - sqInt newContinuation; - sqInt pc; - sqInt prim; - sqInt prim1; - sqInt targetPC; - sqInt targetPC1; - sqInt upperByte; - - pc = (latestContinuation = startPCOfMethod(aMethod)); - if (((prim = primitiveIndexOf(aMethod))) > 0) { - if (isQuickPrimitiveIndex(prim)) { - return pc - 1; - } - } - /* begin bytecodeSetOffsetFor: */ - bsOffset = -# if MULTIPLEBYTECODESETS - (methodUsesAlternateBytecodeSet(aMethod) - ? 0x100 - : 0) -# else - (assert(!((methodUsesAlternateBytecodeSet(aMethod)))), - 0) -# endif - ; - nExts = 0; - end = numBytesOf(aMethod); - while (pc <= end) { - byte = fetchByteofObject(pc, aMethod); - descriptor = generatorAt(byte + bsOffset); - if (((descriptor->isReturn)) - && (pc >= latestContinuation)) { - end = pc; - } - if ((isBranch(descriptor)) - || ((descriptor->isBlockCreation))) { - distance = ((descriptor->spanFunction))(descriptor, pc, nExts, aMethod); - targetPC = (pc + ((descriptor->numBytes))) + distance; - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - if ((descriptor->isBlockCreation)) { - pc += distance; - } - } - else { - /* begin maybeUnsafeJumpContinuation:at:for:in: */ - newContinuation = latestContinuation; - if ((descriptor->hasUnsafeJump)) { - byte01 = fetchByteofObject(pc + 1, aMethod); - - /* pushIntegerLong */ - byte02 = fetchByteofObject(pc + 2, aMethod); - /* begin decodePushIntegerLongBefore:in: */ - distance1 = fetchByteofObject(pc - 1, methodObj); - upperByte = fetchByteofObject(pc - 3, methodObj); - if (upperByte > 0x7F) { - upperByte -= 0x100; - } - distance2 = (((sqInt)((usqInt)(upperByte) << 8))) + distance1; - targetPC1 = (pc + ((descriptor->numBytes))) + distance2; - if (!((descriptor->isMapped))) { - if ((((usqInt)(byte02)) >> 5) == 4) { - - /* inlined sista primitive */ - prim1 = (((sqInt)((usqInt)((byte02 & 0x1F)) << 8))) + byte01; - if (prim1 >= 7000) { - - /* branch forward */ - newContinuation = ((latestContinuation < targetPC1) ? targetPC1 : latestContinuation); - } - } - } - } - latestContinuation = newContinuation; - } - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - pc += (descriptor->numBytes); - } - return end; -} - - -/* This is a static version of ceEnterCogCodePopReceiverReg - for break-pointing when debugging in C. */ -/* This exists only for break-pointing. */ - - /* Cogit>>#enterCogCodePopReceiver */ -void -enterCogCodePopReceiver(void) -{ - realCEEnterCogCodePopReceiverReg(); - error("what??"); -} - - -/* Answer if the entryPoint's tag is expected to be a selector reference, as - opposed to a class tag. - */ - - /* Cogit>>#entryPointTagIsSelector: */ -static sqInt NoDbgRegParms -entryPointTagIsSelector(sqInt entryPoint) -{ - return (entryPoint < methodZoneBase) - || (((entryPoint & entryPointMask) == uncheckedEntryAlignment) - || (((entryPoint & entryPointMask) == checkedEntryAlignment) - && ((((((CogMethod *) (entryPoint - cmEntryOffset)))->cmType)) == CMOpenPIC))); -} - - -/* Use asserts to check if the ClosedPICPrototype is as expected from - compileClosedPICPrototype, and can be updated as required via - rewriteCPICCaseAt:tag:objRef:target:. If all asserts pass, answer - 0, otherwise answer a bit mask identifying all the errors. */ -/* self disassembleFrom: methodZoneBase + (self sizeof: CogMethod) to: - methodZoneBase + closedPICSize - */ - - /* Cogit>>#expectedClosedPICPrototype: */ -static sqInt NoDbgRegParms -expectedClosedPICPrototype(CogMethod *cPIC) -{ - usqInt classTag; - sqInt classTagPC; - usqInt entryPoint; - sqInt errors; - sqInt i; - sqInt methodObjPC; - usqInt object; - sqInt pc; - - errors = 0; - - /* First jump is unconditional; subsequent ones are conditional */ - pc = (((usqInt)cPIC)) + firstCPICCaseOffset; - object = literalBeforeFollowingAddress(backEnd, pc - (jumpLongByteSize(backEnd))); - if (!(asserta(object == (firstPrototypeMethodOop())))) { - errors = 1; - } - entryPoint = jumpLongTargetBeforeFollowingAddress(backEnd, pc); - if (!(asserta(entryPoint == ((cPICPrototypeCaseOffset()) + 13262352)))) { - errors += 2; - } - for (i = 1; i < MaxCPICCases; i += 1) { - - /* verify information in case is as expected. */ - pc += cPICCaseSize; - methodObjPC = (pc - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */; - object = literalBeforeFollowingAddress(backEnd, methodObjPC); - if (!(asserta(object == ((subsequentPrototypeMethodOop()) + i)))) { - errors = errors | 4; - } - classTagPC = pc - 16 /* jumpLongConditionalByteSize */; - /* begin literal32BeforeFollowingAddress: */ - classTag = literalBeforeFollowingAddress(((AbstractInstruction *) backEnd), classTagPC); - if (!(asserta(classTag == (3133021973U + i)))) { - errors = errors | 8; - } - entryPoint = jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc); - if (!(asserta(entryPoint == (((cPICPrototypeCaseOffset()) + 13262352) + (i * 16))))) { - errors = errors | 16; - } - rewriteCPICCaseAttagobjReftarget(pc, classTag ^ 0x5A5A5A5A, object ^ 0xA5A5A5A5U, entryPoint ^ 0x55AA50); - object = literalBeforeFollowingAddress(backEnd, methodObjPC); - if (!(asserta(object == (((subsequentPrototypeMethodOop()) + i) ^ 0xA5A5A5A5U)))) { - errors = errors | 32; - } - /* begin literal32BeforeFollowingAddress: */ - classTag = literalBeforeFollowingAddress(((AbstractInstruction *) backEnd), classTagPC); - if (!(asserta(classTag == ((3133021973U + i) ^ 0x5A5A5A5A)))) { - errors = errors | 64; - } - entryPoint = jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc); - if (!(asserta(entryPoint == ((((cPICPrototypeCaseOffset()) + 13262352) + (i * 16)) ^ 0x55AA50)))) { - errors = errors | 128; - } - rewriteCPICCaseAttagobjReftarget(pc, classTag ^ 0x5A5A5A5A, object ^ 0xA5A5A5A5U, entryPoint ^ 0x55AA50); - } - entryPoint = jumpLongTargetBeforeFollowingAddress(backEnd, (((usqInt)cPIC)) + cPICEndOfCodeOffset); - if (!(asserta(entryPoint == (cPICMissTrampolineFor(0))))) { - errors += 0x100; - } - return errors; -} - - -/* 224 11100000 aaaaaaaa Extend A (Ext A = Ext A prev * 256 + Ext A) */ - - /* Cogit>>#extABytecode */ -static sqInt -extABytecode(void) -{ - extA = ((((sqInt)((usqInt)(extA) << 8)))) + byte1; - return 0; -} - - -/* 225 11100001 sbbbbbbb Extend B (Ext B = Ext B prev * 256 + Ext B) */ - - /* Cogit>>#extBBytecode */ -static sqInt -extBBytecode(void) -{ - extB = ((numExtB == 0) - && (byte1 > 0x7F) - ? byte1 - 0x100 - : ((((sqInt)((usqInt)(extB) << 8)))) + byte1); - numExtB += 1; - return 0; -} - - -/* Fill in the block headers now we know the exact layout of the code. */ - - /* Cogit>>#fillInBlockHeadersAt: */ -static sqInt NoDbgRegParms -fillInBlockHeadersAt(sqInt startAddress) -{ - sqInt aCogMethodOrInteger; - CogBlockMethod *blockHeader; - BlockStart *blockStart; - sqInt i; - - if (!(needsFrame - && (blockCount > 0))) { - return null; - } - if (blockNoContextSwitchOffset == null) { - blockNoContextSwitchOffset = ((blockEntryLabel->address)) - ((blockEntryNoContextSwitch->address)); - } - else { - assert(blockNoContextSwitchOffset == (((blockEntryLabel->address)) - ((blockEntryNoContextSwitch->address)))); - } - for (i = 0; i < blockCount; i += 1) { - blockStart = blockStartAt(i); - /* begin writableBlockMethodFor: */ - aCogMethodOrInteger = (((blockStart->fakeHeader))->address); - blockHeader = ((CogBlockMethod *) ((((usqInt)aCogMethodOrInteger)) + codeToDataDelta)); - (blockHeader->homeOffset = ((((blockStart->fakeHeader))->address)) - startAddress); - (blockHeader->startpc = (blockStart->startpc)); - (blockHeader->cmType = CMBlock); - (blockHeader->cmNumArgs = (blockStart->numArgs)); - (blockHeader->cbUsesInstVars = (blockStart->hasInstVarRef)); - (blockHeader->stackCheckOffset = (((blockStart->stackCheckLabel)) == null - ? 0 - : ((((blockStart->stackCheckLabel))->address)) - ((((blockStart->fakeHeader))->address)))); - } - return 0; -} - - /* Cogit>>#findBackwardBranch:IsBackwardBranch:Mcpc:Bcpc:MatchingBcpc: */ -static sqInt NoDbgRegParms -findBackwardBranchIsBackwardBranchMcpcBcpcMatchingBcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *targetBcpc) -{ - return ((((isBackwardBranchAndAnnotation & 1) != 0)) - && ((((sqInt)targetBcpc)) == bcpc) - ? ((sqInt)mcpc) - : 0); -} - - /* Cogit>>#findBlockMethodWithEntry:startBcpc: */ -static usqInt NoDbgRegParms -findBlockMethodWithEntrystartBcpc(sqInt blockEntryMcpc, sqInt startBcpc) -{ - CogBlockMethod *cogBlockMethod; - - cogBlockMethod = ((CogBlockMethod *) (blockEntryMcpc - (sizeof(CogBlockMethod)))); - if (((cogBlockMethod->startpc)) == startBcpc) { - return ((usqInt)cogBlockMethod); - } - return 0; -} - - /* Cogit>>#findMapLocationForMcpc:inMethod: */ -static usqInt NoDbgRegParms -findMapLocationForMcpcinMethod(usqInt targetMcpc, CogMethod *cogMethod) -{ - sqInt annotation; - usqInt map; - sqInt mapByte; - sqInt mcpc; - - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - if (mcpc == targetMcpc) { - return map; - } - while (((mapByte = byteAt(map))) != MapEnd) { - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - if (annotation != IsAnnotationExtension) { - mcpc += 4 /* codeGranularity */ * ((annotation == IsDisplacementX2N - ? ((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift)) - : mapByte & DisplacementMask)); - } - if (mcpc >= targetMcpc) { - assert(mcpc == targetMcpc); - if (annotation == IsDisplacementX2N) { - map -= 1; - mapByte = byteAt(map); - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - assert(annotation > IsAnnotationExtension); - } - return map; - } - map -= 1; - } - return 0; -} - - -/* Find the CMMethod or CMBlock that has zero-relative startbcpc as its first - bytecode pc. - As this is for cannot resume processing and/or conversion to machine-code - on backward - branch, it doesn't have to be fast. Enumerate block returns and map to - bytecode pcs. */ - - /* Cogit>>#findMethodForStartBcpc:inHomeMethod: */ -CogBlockMethod * -findMethodForStartBcpcinHomeMethod(sqInt startbcpc, CogMethod *cogMethod) -{ - assert(((cogMethod->cmType)) == CMMethod); - if (startbcpc == (startPCOfMethodHeader((cogMethod->methodHeader)))) { - return ((CogBlockMethod *) cogMethod); - } - assert(((cogMethod->blockEntryOffset)) != 0); - return ((CogBlockMethod *) (blockDispatchTargetsForperformarg(cogMethod, findBlockMethodWithEntrystartBcpc, startbcpc))); -} - - -/* Machine code addresses map to the following bytecode for all bytecodes - except backward branches, where they map to the backward branch itself. - This is so that loops continue, rather than terminate prematurely. */ - - /* Cogit>>#find:IsBackwardBranch:Mcpc:Bcpc:MatchingMcpc: */ -static sqInt NoDbgRegParms -findIsBackwardBranchMcpcBcpcMatchingMcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *targetMcpc) -{ - return (targetMcpc == mcpc - ? ((descriptor == null) - || (((isBackwardBranchAndAnnotation & 1) != 0)) - ? bcpc - : bcpc + ((descriptor->numBytes))) - : 0); -} - - /* Cogit>>#firstMappedPCFor: */ -static sqInt NoDbgRegParms -firstMappedPCFor(CogMethod *cogMethod) -{ - return ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); -} - - -/* Answer a fake value for the first method oop in the PIC prototype. - Since we use MoveUniqueCw:R: it must not be confused with a - method-relative address. */ - - /* Cogit>>#firstPrototypeMethodOop */ -static sqInt -firstPrototypeMethodOop(void) -{ - return (addressIsInCurrentCompilation(99282957) - ? 212332557 - : 99282957); -} - - /* Cogit>>#fixupAt: */ -static BytecodeFixup * NoDbgRegParms -fixupAt(sqInt fixupPC) -{ - return fixupAtIndex(fixupPC - initialPC); -} - - /* Cogit>>#followForwardedLiteralsIn: */ -void -followForwardedLiteralsIn(CogMethod *cogMethod) -{ - sqInt annotation; - sqInt hasYoungObj; - sqInt hasYoungObjPtr; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - CogMethod * writableCogMethod; - - assert((((cogMethod->cmType)) != CMMethod) - || (!(isForwarded((cogMethod->methodObject))))); - writableCogMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - hasYoungObj = isYoung((cogMethod->methodObject)); - if (shouldRemapOop((cogMethod->selector))) { - (writableCogMethod->selector = remapObj((cogMethod->selector))); - if (isYoung((cogMethod->selector))) { - hasYoungObj = 1; - } - } - hasYoungObjPtr = ((sqInt)((&hasYoungObj))); - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = remapIfObjectRefpchasYoung(annotation, (((char *) mcpc)), (((void *)hasYoungObjPtr))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - if (hasYoungObj) { - ensureInYoungReferrers(cogMethod); - } - else { - (writableCogMethod->cmRefersToYoung = 0); - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - /* Cogit>>#followForwardedMethods */ -void -followForwardedMethods(void) -{ - CogMethod * cogMethod; - sqInt freedPIC; - - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - freedPIC = 0; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - if (isForwarded((cogMethod->methodObject))) { - (cogMethod->methodObject = followForwarded((cogMethod->methodObject))); - if (isYoungObject((cogMethod->methodObject))) { - ensureInYoungReferrers(cogMethod); - } - } - } - if (((cogMethod->cmType)) == CMClosedPIC) { - if (followMethodReferencesInClosedPIC(cogMethod)) { - freedPIC = 1; - freeMethod(cogMethod); - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (freedPIC) { - unlinkSendsToFree(); - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - -/* Follow a potential object reference from a closed PIC. - This may be a method reference or null. - Answer if the followed literal is young. - 'mcpc' refers to the jump/branch instruction at the end of - each cpic case */ - - /* Cogit>>#followMaybeObjRefInClosedPICAt: */ -static sqInt NoDbgRegParms -followMaybeObjRefInClosedPICAt(sqInt mcpc) -{ - usqInt object; - sqInt subject; - - object = literalBeforeFollowingAddress(backEnd, mcpc); - if (!(couldBeObject(object))) { - return 0; - } - if (!(isForwarded(object))) { - return isYoungObject(object); - } - subject = followForwarded(object); - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - storeLiteralbeforeFollowingAddress(backEnd, subject, mcpc); - return isYoungObject(subject); -} - - -/* Remap all object references in the closed PIC. Answer if any references - are young. - Set codeModified if any modifications are made. */ - - /* Cogit>>#followMethodReferencesInClosedPIC: */ -static sqInt NoDbgRegParms -followMethodReferencesInClosedPIC(CogMethod *cPIC) -{ - sqInt i; - sqInt pc; - sqInt refersToYoung; - - - /* first we check the potential method oop load at the beginning of the CPIC */ - pc = addressOfEndOfCaseinCPIC(1, cPIC); - - /* We find the end address of the cPICNumCases'th case and can then just step forward by the case size thereafter */ - refersToYoung = followMaybeObjRefInClosedPICAt(pc - (jumpLongByteSize(backEnd))); - - /* Next we check the potential potential method oop load for each case. */ - pc = addressOfEndOfCaseinCPIC((cPIC->cPICNumCases), cPIC); - for (i = 2; i <= ((cPIC->cPICNumCases)); i += 1) { - if (followMaybeObjRefInClosedPICAt((pc - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */)) { - refersToYoung = 1; - } - pc += cPICCaseSize; - } - return refersToYoung; -} - - -/* To avoid runtime checks on literal variable and literal accesses in == and - ~~, - we follow literals in methods having movable literals in the postBecome - action. To avoid scanning every method, we annotate cogMethods with the - cmHasMovableLiteral flag. */ - - /* Cogit>>#followMovableLiteralsAndUpdateYoungReferrers */ -void -followMovableLiteralsAndUpdateYoungReferrers(void) -{ - CogMethod *cogMethod; - - assert(kosherYoungReferrers()); - codeModified = 0; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - if ((cogMethod->cmHasMovableLiteral)) { - followForwardedLiteralsIn(cogMethod); - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - pruneYoungReferrers(); - if (codeModified) { - - /* After updating oops in inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)codeBase), freeStart()); - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - /* Cogit>>#freeCogMethod: */ -void -freeCogMethod(CogMethod *cogMethod) -{ - freeMethod(cogMethod); - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - -/* Free machine-code methods whose compiled methods are unmarked - and open PICs whose selectors are not marked, and closed PICs that - refer to unmarked objects. */ - - /* Cogit>>#freeUnmarkedMachineCode */ -void -freeUnmarkedMachineCode(void) -{ - CogMethod *cogMethod; - sqInt freedMethod; - - freedMethod = 0; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) == CMMethod) - && (!(isMarked((cogMethod->methodObject))))) { - freedMethod = 1; - freeMethod(cogMethod); - } - if ((((cogMethod->cmType)) == CMOpenPIC) - && ((!(isImmediate((cogMethod->selector)))) - && (!(isMarked((cogMethod->selector)))))) { - freedMethod = 1; - freeMethod(cogMethod); - } - if ((((cogMethod->cmType)) == CMClosedPIC) - && (closedPICRefersToUnmarkedObject(cogMethod))) { - freedMethod = 1; - freeMethod(cogMethod); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (freedMethod) { - unlinkSendsToFree(); - } -} - - -/* Call ceSendMustBeBooleanTo: via the relevant trampoline. */ - - /* Cogit>>#genCallMustBeBooleanFor: */ -static AbstractInstruction * NoDbgRegParms -genCallMustBeBooleanFor(sqInt boolean) -{ - AbstractInstruction *abstractInstruction; - sqInt callTarget; - - /* begin CallRT: */ - callTarget = (boolean == (falseObject()) - ? ceSendMustBeBooleanAddFalseTrampoline - : ceSendMustBeBooleanAddTrueTrampoline); - /* begin annotateCall: */ - abstractInstruction = genoperand(Call, callTarget); - (abstractInstruction->annotation = IsRelativeCall); - return abstractInstruction; -} - - /* Cogit>>#genConditionalBranch:operand: */ -static AbstractInstruction * NoDbgRegParms -genConditionalBranchoperand(sqInt opcode, sqInt operandOne) -{ - return noteFollowingConditionalBranch(previousInstruction(), genoperand(opcode, operandOne)); -} - - -/* An enilopmart (the reverse of a trampoline) is a piece of code that makes - the system-call-like transition from the C runtime into generated machine - code. The desired arguments and entry-point are pushed on a stackPage's - stack. The enilopmart pops off the values to be loaded into registers and - then executes a return instruction to pop off the entry-point and jump to - it. - BEFORE AFTER (stacks grow down) - whatever stackPointer -> whatever - target address => reg1 = reg1val, etc - reg1val pc = target address - reg2val - stackPointer -> reg3val */ - - /* Cogit>>#genEnilopmartFor:and:and:forCall:called: */ -static void (*genEnilopmartForandandforCallcalled(sqInt regArg1, sqInt regArg2OrNone, sqInt regArg3OrNone, sqInt forCall, char *trampolineName))(void) - -{ - AbstractInstruction *anInstruction; - sqInt endAddress; - usqInt enilopmart; - sqInt quickConstant; - sqInt size; - - zeroOpcodeIndex(); - /* begin MoveCq:R: */ - quickConstant = varBaseAddress(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - genLoadStackPointers(backEnd); - if (regArg3OrNone != NoReg) { - genoperand(PopR, regArg3OrNone); - } - if (regArg2OrNone != NoReg) { - genoperand(PopR, regArg2OrNone); - } - genoperand(PopR, regArg1); - genEnilopmartReturn(forCall); - computeMaximumSizes(); - size = generateInstructionsAt(methodZoneBase); - endAddress = outputInstructionsAt(methodZoneBase); - assert((methodZoneBase + size) == endAddress); - enilopmart = methodZoneBase; - methodZoneBase = alignUptoRoutineBoundary(endAddress); - stopsFromto(backEnd, endAddress, methodZoneBase - 1); - recordGeneratedRunTimeaddress(trampolineName, enilopmart); - return ((void (*)(void)) enilopmart); -} - - -/* An enilopmart (the reverse of a trampoline) is a piece of code that makes - the system-call-like transition from the C runtime into generated machine - code. At the point the enilopmart enters machine code via a return - instruction, any argument registers have been loaded with their values and - the stack, if - for call, looks like - ret pc - stackPointer -> target address - - and if not for call, looks like - whatever - stackPointer -> target address - - If forCall and running on a CISC, ret pc must be left on the stack. If - forCall and - running on a RISC, ret pc must be popped into LinkReg. In either case, - target address must be removed from the stack and jumped/returned to. */ - - /* Cogit>>#genEnilopmartReturn: */ -static void NoDbgRegParms -genEnilopmartReturn(sqInt forCall) -{ - if (forCall) { - genoperand(PopR, RISCTempReg); - genoperand(PopR, LinkReg); - genoperand(JumpR, RISCTempReg); - } - else { - genoperand(PopR, RISCTempReg); - genoperand(JumpR, RISCTempReg); - } -} - - -/* Generate the routine that writes the current values of the C frame and - stack pointers into - variables. These are used to establish the C stack in trampolines back - into the C run-time. - This routine assumes the system's frame pointer is the same as that used - in generated code. */ - - /* Cogit>>#generateCaptureCStackPointers: */ -static void NoDbgRegParms NeverInline -generateCaptureCStackPointers(sqInt captureFramePointer) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - sqInt callerSavedReg; - sqInt fixupSize; - sqInt offset; - sqInt opcodeSize; - sqInt pushedVarBaseReg; - sqInt quickConstant; - usqInt startAddress; - - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 32; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - - /* Must happen first; value may be used in accessing any of the following addresses */ - startAddress = methodZoneBase; - callerSavedReg = 0; - pushedVarBaseReg = 0; - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { - - /* VarBaseReg is not caller-saved; must save and restore it, either by using an available caller-saved reg or push/pop. */ - - /* TempReg used below */ - callerSavedReg = availableRegisterOrNoneIn(((ABICallerSavedRegisterMask | (1U << TempReg)) - (1U << TempReg))); - if (callerSavedReg == NoReg) { - gNativePushR(VarBaseReg); - pushedVarBaseReg = 1; - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, VarBaseReg, callerSavedReg); - } - } - /* begin MoveCq:R: */ - quickConstant = varBaseAddress(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - if (captureFramePointer) { - /* begin checkLiteral:forInstruction: */ - cFramePointerAddress(); - anInstruction1 = genoperandoperand(MoveRAw, FPReg, cFramePointerAddress()); - } - if (pushedVarBaseReg) { - /* begin LoadEffectiveAddressMw:r:R: */ - offset = (pushedVarBaseReg - ? 0 /* leafCallStackPointerDelta */ + BytesPerWord - : 0 /* leafCallStackPointerDelta */); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(LoadEffectiveAddressMwrR, offset, NativeSPReg, TempReg); - /* begin checkLiteral:forInstruction: */ - cStackPointerAddress(); - anInstruction3 = genoperandoperand(MoveRAw, TempReg, cStackPointerAddress()); - } - else { - /* begin checkLiteral:forInstruction: */ - cStackPointerAddress(); - anInstruction4 = genoperandoperand(MoveRAw, NativeSPReg, cStackPointerAddress()); - } - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { - if (pushedVarBaseReg) { - gNativePopR(VarBaseReg); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, callerSavedReg, VarBaseReg); - } - } - gNativeRetN(0); - outputInstructionsForGeneratedRuntimeAt(startAddress); - flushICacheFromto(backEnd, ((usqInt)startAddress), ((usqInt)methodZoneBase)); - recordGeneratedRunTimeaddress("ceCaptureCStackPointers", startAddress); - ceCaptureCStackPointers = ((void (*)(void)) startAddress); -} - - -/* Generate the prototype ClosedPIC to determine how much space a full closed - PIC takes. - When we first allocate a closed PIC it only has one or two cases and we - want to grow it. - So we have to determine how big a full one is before hand. */ -/* stack allocate the various collections so that they - are effectively garbage collected on return. */ - - /* Cogit>>#generateClosedPICPrototype */ -static void -generateClosedPICPrototype(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - CogMethod * cPIC; - AbstractInstruction * cPICEndOfCodeLabel; - sqInt endAddress; - AbstractInstruction * endCPICCase1; - sqInt fixupSize; - sqInt h; - AbstractInstruction *jumpNext; - sqInt jumpTarget; - sqInt jumpTarget1; - sqInt jumpTarget2; - sqInt numArgs; - sqInt opcode; - sqInt opcodeSize; - sqInt wordConstant; - sqInt wordConstant1; - - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = MaxCPICCases * 9; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - (methodLabel->address = methodZoneBase); - (methodLabel->dependent = null); - /* begin compileClosedPICPrototype */ - compilePICAbort((numArgs = 0)); - - /* At the end of the entry code we need to jump to the first case code, which is actually the last chunk. - On each entension we must update this jump to move back one case. */ - jumpNext = compileCPICEntry(); - /* begin MoveUniqueCw:R: */ - wordConstant1 = firstPrototypeMethodOop(); - /* begin uniqueLiteral:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCwR, wordConstant1, SendNumArgsReg); - /* begin JumpLong: */ - jumpTarget1 = (((methodZoneBase + (youngReferrers())) / 2) - 13262352) + 13262352; - genoperand(JumpLong, jumpTarget1); - endCPICCase0 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - for (h = 1; h < MaxCPICCases; h += 1) { - if (h == (MaxCPICCases - 1)) { - jmpTarget(jumpNext, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - /* begin MoveUniqueCw:R: */ - wordConstant = (subsequentPrototypeMethodOop()) + h; - /* begin uniqueLiteral:forInstruction: */ - anInstruction = genoperandoperand(MoveCwR, wordConstant, SendNumArgsReg); - /* begin gen:literal32:operand: */ - opcode = CmpCwR; - /* begin checkLiteral32:forInstruction: */ - anInstruction1 = genoperandoperand(opcode, 3133021973U + h, TempReg); - /* begin JumpLongZero: */ - jumpTarget = ((((methodZoneBase + (youngReferrers())) / 2) - 13262352) + 13262352) + (h * 16); - genConditionalBranchoperand(JumpLongZero, ((sqInt)jumpTarget)); - if (h == 1) { - endCPICCase1 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - } - /* begin checkLiteral:forInstruction: */ - (methodLabel->address); - anInstruction3 = genoperandoperand(MoveCwR, (methodLabel->address), ClassReg); - /* begin JumpLong: */ - jumpTarget2 = cPICMissTrampolineFor(numArgs); - genoperand(JumpLong, jumpTarget2); - cPICEndOfCodeLabel = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - computeMaximumSizes(); - cPIC = ((CogMethod *) methodZoneBase); - closedPICSize = (sizeof(CogMethod)) + (generateInstructionsAt(methodZoneBase + (sizeof(CogMethod)))); - endAddress = outputInstructionsAt(methodZoneBase + (sizeof(CogMethod))); - assert((methodZoneBase + closedPICSize) == endAddress); - firstCPICCaseOffset = ((endCPICCase0->address)) - methodZoneBase; - cPICEndOfCodeOffset = ((cPICEndOfCodeLabel->address)) - methodZoneBase; - cPICCaseSize = ((endCPICCase1->address)) - ((endCPICCase0->address)); - cPICEndSize = closedPICSize - (((MaxCPICCases - 1) * cPICCaseSize) + firstCPICCaseOffset); - closedPICSize = roundUpToMethodAlignment(backEnd(), closedPICSize); - assert(((picInterpretAbort->address)) == (((methodLabel->address)) + (picInterpretAbortOffset()))); - assert((expectedClosedPICPrototype(cPIC)) == 0); - storeLiteralbeforeFollowingAddress(backEnd, 0, ((endCPICCase0->address)) - (jumpLongByteSize(backEnd))); - methodZoneBase = alignUptoRoutineBoundary(endAddress); - cPICPrototype = cPIC; -} - - -/* We handle jump sizing simply. First we make a pass that asks each - instruction to compute its maximum size. Then we make a pass that - sizes jumps based on the maxmimum sizes. Then we make a pass - that fixes up jumps. When fixing up a jump the jump is not allowed to - choose a smaller offset but must stick to the size set in the second pass. */ - - /* Cogit>>#generateCogFullBlock */ -static CogMethod * -generateCogFullBlock(void) -{ - sqInt codeSize; - usqIntptr_t headerSize; - sqInt mapSize; - CogMethod *method; - sqInt result; - usqInt startAddress; - sqInt totalSize; - - headerSize = sizeof(CogMethod); - (methodLabel->address = freeStart()); - computeMaximumSizes(); - concretizeAt(methodLabel, freeStart()); - codeSize = generateInstructionsAt(((methodLabel->address)) + headerSize); - mapSize = generateMapAtstart(null, ((methodLabel->address)) + cbNoSwitchEntryOffset); - totalSize = roundUpToMethodAlignment(backEnd(), (headerSize + codeSize) + mapSize); - if (totalSize > MaxMethodSize) { - return ((CogMethod *) MethodTooBig); - } - startAddress = allocate(totalSize); - if (startAddress == 0) { - return ((CogMethod *) InsufficientCodeSpace); - } - assert((startAddress + cbEntryOffset) == ((fullBlockEntry->address))); - assert((startAddress + cbNoSwitchEntryOffset) == ((fullBlockNoContextSwitchEntry->address))); - result = outputInstructionsAt(startAddress + headerSize); - assert(((startAddress + headerSize) + codeSize) == result); - padIfPossibleWithStopsFromto(backEnd, result, ((startAddress + totalSize) - mapSize) - 1); - generateMapAtstart((startAddress + totalSize) - 1, startAddress + cbNoSwitchEntryOffset); - flag("TOCHECK"); - method = ((CogMethod *) ((((usqInt)startAddress)) + codeToDataDelta)); - fillInMethodHeadersizeselector(method, totalSize, nilObject()); - (method->cpicHasMNUCaseOrCMIsFullBlock = 1); - flushICacheFromto(backEnd, startAddress, startAddress + totalSize); - return ((CogMethod *) startAddress); -} - - -/* We handle jump sizing simply. First we make a pass that asks each - instruction to compute its maximum size. Then we make a pass that - sizes jumps based on the maxmimum sizes. Then we make a pass - that fixes up jumps. When fixing up a jump the jump is not allowed to - choose a smaller offset but must stick to the size set in the second pass. */ - - /* Cogit>>#generateCogMethod: */ -static CogMethod * NoDbgRegParms -generateCogMethod(sqInt selector) -{ - sqInt codeSize; - usqIntptr_t headerSize; - sqInt mapSize; - sqInt result; - usqInt startAddress; - sqInt totalSize; - - headerSize = sizeof(CogMethod); - (methodLabel->address = freeStart()); - computeMaximumSizes(); - concretizeAt(methodLabel, freeStart()); - codeSize = generateInstructionsAt(((methodLabel->address)) + headerSize); - mapSize = generateMapAtstart(null, ((methodLabel->address)) + cmNoCheckEntryOffset); - totalSize = roundUpToMethodAlignment(backEnd(), (headerSize + codeSize) + mapSize); - if (totalSize > MaxMethodSize) { - return ((CogMethod *) MethodTooBig); - } - startAddress = allocate(totalSize); - if (startAddress == 0) { - return ((CogMethod *) InsufficientCodeSpace); - } - assert((startAddress + cmEntryOffset) == ((entry->address))); - assert((startAddress + cmNoCheckEntryOffset) == ((noCheckEntry->address))); - result = outputInstructionsAt(startAddress + headerSize); - assert(((startAddress + headerSize) + codeSize) == result); - padIfPossibleWithStopsFromto(backEnd, result, ((startAddress + totalSize) - mapSize) - 1); - generateMapAtstart((startAddress + totalSize) - 1, startAddress + cmNoCheckEntryOffset); - fillInBlockHeadersAt(startAddress); - fillInMethodHeadersizeselector(((CogMethod *) ((((usqInt)startAddress)) + codeToDataDelta)), totalSize, selector); - flushICacheFromto(backEnd, startAddress, startAddress + totalSize); - return ((CogMethod *) startAddress); -} - - -/* Generate the method map at addressrNull (or compute it if addressOrNull is - null). Answer the length of the map in byes. Each entry in the map is in - two parts. In the - least signficant bits are a displacement of how far from the start or - previous entry, - unless it is an IsAnnotationExtension byte, in which case those bits are - the extension. - In the most signficant bits are the type of annotation at the point - reached. A null - byte ends the map. */ - - /* Cogit>>#generateMapAt:start: */ -static sqInt NoDbgRegParms -generateMapAtstart(usqInt addressOrNull, usqInt startAddress) -{ - unsigned char annotation; - sqInt delta; - sqInt i; - AbstractInstruction *instruction; - sqInt length; - usqInt location; - sqInt mapEntry; - sqInt maxDelta; - usqInt mcpc; - - length = 0; - location = startAddress; - for (i = 0; i < opcodeIndex; i += 1) { - instruction = abstractInstructionAt(i); - annotation = (instruction->annotation); - if (!(annotation == null)) { - /* begin mapEntryAddress */ - mcpc = ((instruction->address)) + ((instruction->machineCodeSize)); - while (((delta = (mcpc - location) / 4 /* codeGranularity */)) > DisplacementMask) { - maxDelta = (((((delta < MaxX2NDisplacement) ? delta : MaxX2NDisplacement)) | DisplacementMask) - DisplacementMask); - assert((((usqInt)(maxDelta)) >> AnnotationShift) <= DisplacementMask); - if (!(addressOrNull == null)) { - /* begin addToMap:instruction:byte:at:for: */ - codeByteAtput(addressOrNull - length, (((usqInt)(maxDelta)) >> AnnotationShift) + DisplacementX2N); - } - location += maxDelta * 4 /* codeGranularity */; - length += 1; - } - if (!(addressOrNull == null)) { - mapEntry = delta + (((sqInt)((usqInt)((((annotation < IsSendCall) ? annotation : IsSendCall))) << AnnotationShift))); - /* begin addToMap:instruction:byte:at:for: */ - codeByteAtput(addressOrNull - length, mapEntry); - } - location += delta * 4 /* codeGranularity */; - length += 1; - if (annotation > IsSendCall) { - - /* Add the necessary IsAnnotationExtension */ - if (!(addressOrNull == null)) { - mapEntry = (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift))) + (annotation - IsSendCall); - /* begin addToMap:instruction:byte:at:for: */ - codeByteAtput(addressOrNull - length, mapEntry); - } - length += 1; - } - } - } - if (!(addressOrNull == null)) { - /* begin addToMap:instruction:byte:at:for: */ - codeByteAtput(addressOrNull - length, MapEnd); - } - return length + 1; -} - - -/* Generate the prototype OpenPIC to determine how much space an open PIC - takes. - */ -/* stack allocate the various collections so that they - are effectively garbage collected on return. */ - - /* Cogit>>#generateOpenPICPrototype */ -static void -generateOpenPICPrototype(void) -{ - sqInt codeSize; - sqInt fixupSize; - sqInt mapSize; - sqInt opcodeSize; - - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 100; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - (methodLabel->address = methodZoneBase); - (methodLabel->dependent = null); - compileOpenPICnumArgs(specialSelector(0), 2 /* numRegArgs */); - computeMaximumSizes(); - concretizeAt(methodLabel, methodZoneBase); - codeSize = generateInstructionsAt(methodZoneBase + (sizeof(CogMethod))); - mapSize = generateMapAtstart(null, methodZoneBase + cmNoCheckEntryOffset); - openPICSize = (roundUpLength((sizeof(CogMethod)) + codeSize)) + (roundUpToMethodAlignment(backEnd(), mapSize)); -} - - -/* Generate the run-time entries at the base of the native code zone and - update the base. - */ - - /* Cogit>>#generateRunTimeTrampolines */ -static void -generateRunTimeTrampolines(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction2; - - ceSendMustBeBooleanAddFalseTrampoline = genMustBeBooleanTrampolineForcalled(falseObject(), "ceSendMustBeBooleanAddFalseTrampoline"); - ceSendMustBeBooleanAddTrueTrampoline = genMustBeBooleanTrampolineForcalled(trueObject(), "ceSendMustBeBooleanAddTrueTrampoline"); - /* begin genNonLocalReturnTrampoline */ - zeroOpcodeIndex(); - /* begin checkLiteral:forInstruction: */ - instructionPointerAddress(); - anInstruction2 = genoperandoperand(MoveRAw, LinkReg, instructionPointerAddress()); - ceNonLocalReturnTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNonLocalReturn, "ceNonLocalReturnTrampoline", 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 0, NoReg, 1); - /* begin genCheckForInterruptsTrampoline */ - zeroOpcodeIndex(); - /* begin checkLiteral:forInstruction: */ - instructionPointerAddress(); - anInstruction = genoperandoperand(MoveRAw, LinkReg, instructionPointerAddress()); - ceCheckForInterruptTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceCheckForInterrupt, "ceCheckForInterruptTrampoline", 0, null, null, null, null, 0 /* emptyRegisterMask */, 0, NoReg, 1); - ceFetchContextInstVarTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceContextinstVar, "ceFetchContextInstVarTrampoline", 2, ReceiverResultReg, SendNumArgsReg, null, null, 0 /* emptyRegisterMask */, 1, SendNumArgsReg, 0); - ceStoreContextInstVarTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceContextinstVarvalue, "ceStoreContextInstVarTrampoline", 3, ReceiverResultReg, SendNumArgsReg, ClassReg, null, 0 /* emptyRegisterMask */, 1, ReceiverResultReg, 0); - - /* ceInvokeInterpreter is an optimization and a work-around. Historically we used setjmp/longjmp to reenter the - interpreter at the current C stack base. The C stack base is set at start-up and on each callback enter and - callback return. The interpreter must be invoked whenever a non-machine-code method must be run. That might - be when invoking an interpreter method from one of the send linking routines (ceSend:...), or on continuing from - an evaluation primitive such as primitiveExecuteMethod. The problem here is that such primitives could have - been invoked by the interpreter or by machine code. So some form of non-local jump is required. But at least as - early as MSVC Community 2017, the Microshaft longjmp performs stack unwinding which gets hoplessly confused - (bless its little heart) by any stack switch between machine code and C stack, and raises a spurious - Stack cookie instrumentation code detected a stack-based buffer overrun - error from the bowels of gs_report.c _GSHandlerCheck. - Since the CoInterpreter maintains the base of the C stack in CFramePointer & CStackPointer, it is straight-forward - for us to simply call interpret after doing the switch to the C stack, avoiding the stack unwind issue altogether. */ - ceCannotResumeTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceCannotResume, "ceCannotResumeTrampoline", 0, null, null, null, null, 0 /* emptyRegisterMask */, 1, NoReg, 0); - - /* These two are unusual; they are reached by return instructions. */ - ceInvokeInterpret = genInvokeInterpretTrampoline(); - ceReturnToInterpreterTrampoline = genReturnToInterpreterTrampoline(); - ceBaseFrameReturnTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceBaseFrameReturn, "ceBaseFrameReturnTrampoline", 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 0, NoReg, 0); - } - - -/* Generate a routine ceCaptureCStackPointers that will capture the C stack - pointer, and, if it is in use, the C frame pointer. These are used in - trampolines to call - run-time routines in the interpreter from machine-code. */ - - /* Cogit>>#generateStackPointerCapture */ -static void -generateStackPointerCapture(void) -{ - usqInt oldMethodZoneBase; - sqInt oldTrampolineTableIndex; - - - /* For the benefit of the following assert, assume the minimum at first. */ - cFramePointerInUse = 0; - assertCStackWellAligned(); - oldMethodZoneBase = methodZoneBase; - oldTrampolineTableIndex = trampolineTableIndex; - generateCaptureCStackPointers(1); - ceCaptureCStackPointers(); - if (!((cFramePointerInUse = checkIfCFramePointerInUse()))) { - methodZoneBase = oldMethodZoneBase; - trampolineTableIndex = oldTrampolineTableIndex; - generateCaptureCStackPointers(0); - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - assertCStackWellAligned(); -} - - -/* Generate the run-time entries and exits at the base of the native code - zone and update the base. - Read the class-side method trampolines for documentation on the various - trampolines - */ - - /* Cogit>>#generateTrampolines */ -static void -generateTrampolines(void) -{ - sqInt fixupSize; - usqInt methodZoneStart; - sqInt opcodeSize; - - methodZoneStart = methodZoneBase; - (methodLabel->address = methodZoneStart); - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 80; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - setHasYoungReferent(0); - generateSendTrampolines(); - generateMissAbortTrampolines(); - generateObjectRepresentationTrampolines(); - generateRunTimeTrampolines(); - generateSistaRuntime(); - generateEnilopmarts(); - generateTracingTrampolines(); - recordGeneratedRunTimeaddress("methodZoneBase", methodZoneBase); -} - - /* Cogit>>#generatorForPC: */ -static BytecodeDescriptor * NoDbgRegParms -generatorForPC(sqInt pc) -{ - return generatorAt(bytecodeSetOffset + (fetchByteofObject(pc, methodObj))); -} - - -/* Generate a pair of routines that answer the frame pointer, and the stack - pointer immediately - after a leaf call, used for checking stack pointer alignment, frame - pointer usage, etc. N.B. - these are exported to the CoInterpreter et al via Cogit - class>>mustBeGlobal:. - */ - - /* Cogit>>#genGetLeafCallStackPointers */ -static void -genGetLeafCallStackPointers(void) -{ - sqInt fixupSize; - sqInt opcodeSize; - usqInt startAddress; - - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 4; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - startAddress = methodZoneBase; - genoperandoperand(MoveRR, FPReg, ABIResultReg); - genoperand(RetN, 0); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress("ceGetFP", startAddress); - ceGetFP = ((usqIntptr_t (*)(void)) startAddress); - startAddress = methodZoneBase; - zeroOpcodeIndex(); - genoperandoperand(MoveRR, NativeSPReg, ABIResultReg); - genoperand(RetN, 0); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress("ceGetSP", startAddress); - ceGetSP = ((usqIntptr_t (*)(void)) startAddress); -} - - -/* Generate the abort for a PIC. This abort performs either a call of - ceInterpretMethodFromPIC:receiver: to handle invoking an uncogged target - or a call of ceMNUFromPICMNUMethod:receiver: to handle an MNU dispatch - in a closed PIC. It distinguishes the two by testing ClassReg. If the - register is zero then this is an MNU. - - This poses a problem in 32-bit Spur, where zero is the cache tag for - immediate characters (tag pattern 2r10) because SmallIntegers have tag - patterns 2r11 - and 2r01, so anding with 1 reduces these to 0 & 1. We solve the ambiguity - by patching send sites with a 0 cache tag to open PICs instead of closed - PICs. */ - - /* Cogit>>#genInnerPICAbortTrampoline: */ -static usqInt NoDbgRegParms -genInnerPICAbortTrampoline(char *name) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *jumpMNUCase; - - /* begin CmpCq:R: */ - anInstruction = genoperandoperand(CmpCqR, 0 /* picAbortDiscriminatorValue */, ClassReg); - jumpMNUCase = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(ceInterpretMethodFromPICreceiver, 2, SendNumArgsReg, ReceiverResultReg, null, null, 0 /* emptyRegisterMask */, 0, NoReg); - jmpTarget(jumpMNUCase, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceMNUFromPICMNUMethodreceiver, name, 2, SendNumArgsReg, ReceiverResultReg, null, null, 0 /* emptyRegisterMask */, 0, NoReg, 1); -} - - -/* Switch to the C stack (do *not* save the Smalltalk stack pointers; - this is the caller's responsibility), and invoke interpret PDQ. */ - - /* Cogit>>#genInvokeInterpretTrampoline */ -static void (*genInvokeInterpretTrampoline(void))(void) - -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - sqInt quickConstant; - usqInt startAddress; - - startAddress = methodZoneBase; - zeroOpcodeIndex(); - /* begin MoveCq:R: */ - quickConstant = varBaseAddress(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - if (cFramePointerInUse) { - genLoadCStackPointers(backEnd); - } - else { - genLoadCStackPointer(backEnd); - } - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l16; - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction5 = genoperandoperand(MoveCqR, -2 - null, A0); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A0); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction11 = genoperandoperand(MoveCqR, -2 - null, A1); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A1); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction21 = genoperandoperand(MoveCqR, -2 - null, A2); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A2); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction31 = genoperandoperand(MoveCqR, -2 - null, A3); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A3); - } - l16: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin checkLiteral:forInstruction: */ - cReturnAddressAddress(); - anInstruction1 = genoperandoperand(MoveAwR, cReturnAddressAddress(), LinkReg); - /* begin checkLiteral:forInstruction: */ - ((sqInt)(((usqInt)interpret))); - anInstruction4 = genoperand(JumpFull, ((sqInt)(((usqInt)interpret)))); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress("ceInvokeInterpret", startAddress); - return ((void (*)(void)) startAddress); -} - - -/* The in-line cache for a send is implemented as a constant load into - ClassReg. We always use a 32-bit load, even in 64-bits. - - In the initial (unlinked) state the in-line cache is notionally loaded - with the selector. - But since in 64-bits an arbitrary selector oop won't fit in a 32-bit - constant load, we - instead load the cache with the selector's index, either into the literal - frame of the - current method, or into the special selector array. Negative values are - 1-relative indices into the special selector array. - - When a send is linked, the load of the selector, or selector index, is - overwritten with a - load of the receiver's class, or class tag. Hence, the 64-bit VM is - currently constrained - to use class indices as cache tags. If out-of-line literals are used, - distinct caches /must - not/ share acche locations, for if they do, send cacheing will be confused - by the sharing. - Hence we use the MoveUniqueC32:R: instruction that will not share literal - locations. */ - - /* Cogit>>#genLoadInlineCacheWithSelector: */ -static void NoDbgRegParms -genLoadInlineCacheWithSelector(sqInt selectorIndex) -{ - AbstractInstruction *anInstruction; - sqInt cacheValue; - sqInt opcode; - sqInt selector; - - assert((selectorIndex < 0 - ? (((-selectorIndex) >= 1) && ((-selectorIndex) <= (numSpecialSelectors()))) - : ((selectorIndex >= 0) && (selectorIndex <= ((literalCountOf(methodObj)) - 1))))); - selector = (selectorIndex < 0 - ? specialSelector(-1 - selectorIndex) - : getLiteral(selectorIndex)); - assert(addressCouldBeOop(selector)); - if (isNonImmediate(selector)) { - setHasMovableLiteral(1); - } - if (isYoung(selector)) { - setHasYoungReferent(1); - } - cacheValue = selector; - /* begin gen:uniqueLiteral32:operand: */ - opcode = MoveCwR; - /* begin uniqueLiteral32:forInstruction: */ - anInstruction = genoperandoperand(opcode, cacheValue, ClassReg); -} - - /* Cogit>>#genReturnToInterpreterTrampoline */ -static usqInt -genReturnToInterpreterTrampoline(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - usqInt startAddress; - - startAddress = methodZoneBase; - zeroOpcodeIndex(); - genoperand(PushR, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperandoperand(MoveMwrR, FoxIFSavedIP, FPReg, TempReg); - /* begin checkLiteral:forInstruction: */ - instructionPointerAddress(); - anInstruction5 = genoperandoperand(MoveRAw, TempReg, instructionPointerAddress()); - genSmalltalkToCStackSwitch(0); - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l17; - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction6 = genoperandoperand(MoveCqR, -2 - null, A0); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A0); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction11 = genoperandoperand(MoveCqR, -2 - null, A1); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A1); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction21 = genoperandoperand(MoveCqR, -2 - null, A2); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A2); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction31 = genoperandoperand(MoveCqR, -2 - null, A3); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A3); - } - l17: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin checkLiteral:forInstruction: */ - cReturnAddressAddress(); - anInstruction = genoperandoperand(MoveAwR, cReturnAddressAddress(), LinkReg); - /* begin checkLiteral:forInstruction: */ - ((sqInt)(((usqInt)interpret))); - anInstruction3 = genoperand(JumpFull, ((sqInt)(((usqInt)interpret)))); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress("ceReturnToInterpreterTrampoline", startAddress); - return startAddress; -} - - -/* If the client requires, then on an ARM-like RISC processor, the return - address needs to - be pushed to the stack so that the interpreter sees the same stack layout - as on CISC. - */ - - /* Cogit>>#genSmalltalkToCStackSwitch: */ -static sqInt NoDbgRegParms -genSmalltalkToCStackSwitch(sqInt pushLinkReg) -{ - if (pushLinkReg) { - genoperand(PushR, LinkReg); - } - genSaveStackPointers(backEnd); - if (cFramePointerInUse) { - genLoadCStackPointers(backEnd); - } - else { - genLoadCStackPointer(backEnd); - } - return 0; -} - - -/* Generate a trampoline with up to four arguments. Generate either a call or - a jump to aRoutineOrNil - as requested by callJumpBar. If generating a call and resultRegOrNone is - not NoReg pass the C result - back in resultRegOrNone. - Hack: a negative value indicates an abstract register, a non-negative - value indicates a constant. */ - - /* Cogit>>#genTrampolineFor:called:numArgs:arg:arg:arg:arg:regsToSave:pushLinkReg:resultReg:appendOpcodes: */ -static usqInt NoDbgRegParms -genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(void *aRoutine, char *trampolineName, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone, sqInt appendBoolean) -{ - usqInt startAddress; - - startAddress = methodZoneBase; - if (!appendBoolean) { - zeroOpcodeIndex(); - } - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(aRoutine, numArgs, regOrConst0, regOrConst1, regOrConst2, regOrConst3, regMask, pushLinkReg, resultRegOrNone); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress(trampolineName, startAddress); - recordRunTimeObjectReferences(); - /* begin assertValidDualZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, codeBase + cmNoCheckEntryOffset, codeToDataDelta); -# endif - return startAddress; -} - - -/* To return from a trampoline call we have to take the return address off - the stack, - iof it has been saved */ - - /* Cogit>>#genTrampolineReturn: */ -static void NoDbgRegParms -genTrampolineReturn(sqInt lnkRegWasPushed) -{ - if (lnkRegWasPushed - && (1)) { - genoperand(PopR, LinkReg); - genoperand(RetN, 0); - } - else { - genoperand(RetN, 0); - } -} - - -/* */ - - /* Cogit>>#gen: */ -static AbstractInstruction * NoDbgRegParms -gen(sqInt opcode) -{ - AbstractInstruction *abstractInstruction; - - assert(opcodeIndex < numAbstractOpcodes); - abstractInstruction = abstractInstructionAt(opcodeIndex); - opcodeIndex += 1; - (abstractInstruction->opcode = opcode); - return abstractInstruction; -} - - -/* */ -/* */ - - /* Cogit>>#gen:operand: */ -static AbstractInstruction * NoDbgRegParms -genoperand(sqInt opcode, sqInt operand) -{ - AbstractInstruction *abstractInstruction; - - assert(opcodeIndex < numAbstractOpcodes); - abstractInstruction = abstractInstructionAt(opcodeIndex); - opcodeIndex += 1; - (abstractInstruction->opcode = opcode); - ((abstractInstruction->operands))[0] = operand; - return abstractInstruction; -} - - -/* */ -/* */ -/* */ - - /* Cogit>>#gen:operand:operand: */ -static AbstractInstruction * NoDbgRegParms -genoperandoperand(sqInt opcode, sqInt operandOne, sqInt operandTwo) -{ - AbstractInstruction *abstractInstruction; - - assert(opcodeIndex < numAbstractOpcodes); - abstractInstruction = abstractInstructionAt(opcodeIndex); - opcodeIndex += 1; - (abstractInstruction->opcode = opcode); - ((abstractInstruction->operands))[0] = operandOne; - ((abstractInstruction->operands))[1] = operandTwo; - return abstractInstruction; -} - - -/* */ -/* */ -/* */ -/* */ - - /* Cogit>>#gen:operand:operand:operand: */ -static AbstractInstruction * NoDbgRegParms -genoperandoperandoperand(sqInt opcode, sqInt operandOne, sqInt operandTwo, sqInt operandThree) -{ - AbstractInstruction *abstractInstruction; - - assert(opcodeIndex < numAbstractOpcodes); - abstractInstruction = abstractInstructionAt(opcodeIndex); - opcodeIndex += 1; - (abstractInstruction->opcode = opcode); - ((abstractInstruction->operands))[0] = operandOne; - ((abstractInstruction->operands))[1] = operandTwo; - ((abstractInstruction->operands))[2] = operandThree; - return abstractInstruction; -} - - /* Cogit>>#getLiteral: */ -static sqInt NoDbgRegParms -getLiteral(sqInt litIndex) -{ - if (maxLitIndex < litIndex) { - maxLitIndex = litIndex; - } - return literalofMethod(litIndex, methodObj); -} - - /* Cogit>>#incrementUsageOfTargetIfLinkedSend:mcpc:ignored: */ -static sqInt NoDbgRegParms -incrementUsageOfTargetIfLinkedSendmcpcignored(sqInt annotation, char *mcpc, sqInt superfluity) -{ - sqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - - if (annotation >= IsSendCall) { - assert(annotation != IsNSSendCall); - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (((targetMethod1->cmUsageCount)) < (CMMaxUsageCount / 2)) { - ((((CogMethod *) ((((usqInt)targetMethod1)) + codeToDataDelta)))->cmUsageCount = ((targetMethod1->cmUsageCount)) + 1); - } - } - } - return 0; -} - - -/* Answer a usage count that reflects likely long-term usage. */ - - /* Cogit>>#initialClosedPICUsageCount */ -static sqInt -initialClosedPICUsageCount(void) -{ - return CMMaxUsageCount / 2; -} - - /* Cogit>>#initializeBackend */ -static void -initializeBackend(void) -{ - (methodLabel->machineCodeSize = 0); - (methodLabel->opcode = Label); - ((methodLabel->operands))[0] = 0; - ((methodLabel->operands))[1] = 0; - assert((!((registerMaskFor(VarBaseReg)) & CallerSavedRegisterMask))); - varBaseAddress = computeGoodVarBaseAddress(); - assert((stackLimitAddress()) >= varBaseAddress); - assert((cStackPointerAddress()) >= varBaseAddress); - assert((cFramePointerAddress()) >= varBaseAddress); - assert((cReturnAddressAddress()) >= varBaseAddress); - assert((nextProfileTickAddress()) >= varBaseAddress); - } - - -/* Answer a usage count that reflects likely long-term usage. - Answer 1 for non-primitives or quick primitives (inst var accessors), - 2 for methods with interpreter primitives, and 3 for compiled primitives. */ - - /* Cogit>>#initialMethodUsageCount */ -static sqInt -initialMethodUsageCount(void) -{ - if ((primitiveIndex == 1) - || (isQuickPrimitiveIndex(primitiveIndex))) { - return 1; - } - if (!(primitiveGeneratorOrNil())) { - return 2; - } - return 3; -} - - -/* Answer a usage count that reflects likely long-term usage. */ - - /* Cogit>>#initialOpenPICUsageCount */ -static sqInt -initialOpenPICUsageCount(void) -{ - return CMMaxUsageCount - 1; -} - - /* Cogit>>#inverseBranchFor: */ -static sqInt NoDbgRegParms -inverseBranchFor(sqInt opcode) -{ - switch (opcode) { - case JumpLongZero: - return JumpLongNonZero; - - case JumpLongNonZero: - return JumpLongZero; - - case JumpZero: - return JumpNonZero; - - case JumpNonZero: - return JumpZero; - - case JumpNegative: - return JumpNonNegative; - - case JumpNonNegative: - return JumpNegative; - - case JumpOverflow: - return JumpNoOverflow; - - case JumpNoOverflow: - return JumpOverflow; - - case JumpCarry: - return JumpNoCarry; - - case JumpNoCarry: - return JumpCarry; - - case JumpLess: - return JumpGreaterOrEqual; - - case JumpGreaterOrEqual: - return JumpLess; - - case JumpGreater: - return JumpLessOrEqual; - - case JumpLessOrEqual: - return JumpGreater; - - case JumpBelow: - return JumpAboveOrEqual; - - case JumpAboveOrEqual: - return JumpBelow; - - case JumpAbove: - return JumpBelowOrEqual; - - case JumpBelowOrEqual: - return JumpAbove; - - default: - error("Case not found and no otherwise clause"); - } - error("invalid opcode for inverse"); - return 0; -} - - -/* See Cogit class>>initializeAnnotationConstants */ - - /* Cogit>>#isPCMappedAnnotation: */ -static sqInt NoDbgRegParms -isPCMappedAnnotation(sqInt annotation) -{ - return annotation >= HasBytecodePC; -} - - /* Cogit>>#isPCWithinMethodZone: */ -sqInt -isPCWithinMethodZone(void *address) -{ - return (((((usqInt)address)) >= methodZoneBase) && ((((usqInt)address)) <= (freeStart()))); -} - - -/* Answer if the instruction preceding retpc is a call instruction. */ - - /* Cogit>>#isSendReturnPC: */ -sqInt -isSendReturnPC(sqInt retpc) -{ - usqInt target; - - if (!(isCallPrecedingReturnPC(backEnd, retpc))) { - return 0; - } - target = callTargetFromReturnAddress(backEnd, retpc); - return (((target >= firstSend) && (target <= lastSend))) - || (((target >= methodZoneBase) && (target <= (freeStart())))); -} - - -/* Floating-point jumps are a little weird on some processors. Defer to - the backEnd to allow it to generate any special code it may need to. */ - - /* Cogit>>#JumpFPEqual: */ -static AbstractInstruction * NoDbgRegParms -gJumpFPEqual(void *jumpTarget) -{ - /* begin genJumpFPEqual: */ - return genoperand(JumpFPEqual, ((sqInt)jumpTarget)); -} - - -/* Floating-point jumps are a little weird on some processors. Defer to - the backEnd to allow it to generate any special code it may need to. */ - - /* Cogit>>#JumpFPGreaterOrEqual: */ -static AbstractInstruction * NoDbgRegParms -gJumpFPGreaterOrEqual(void *jumpTarget) -{ - /* begin genJumpFPGreaterOrEqual: */ - return genoperand(JumpFPGreaterOrEqual, ((sqInt)jumpTarget)); -} - - -/* Floating-point jumps are a little weird on some processors. Defer to - the backEnd to allow it to generate any special code it may need to. */ - - /* Cogit>>#JumpFPGreater: */ -static AbstractInstruction * NoDbgRegParms -gJumpFPGreater(void *jumpTarget) -{ - /* begin genJumpFPGreater: */ - return genoperand(JumpFPGreater, ((sqInt)jumpTarget)); -} - - -/* Floating-point jumps are a little weird on some processors. Defer to - the backEnd to allow it to generate any special code it may need to. */ - - /* Cogit>>#JumpFPNotEqual: */ -static AbstractInstruction * NoDbgRegParms -gJumpFPNotEqual(void *jumpTarget) -{ - /* begin genJumpFPNotEqual: */ - return genoperand(JumpFPNotEqual, ((sqInt)jumpTarget)); -} - - /* Cogit>>#LogicalShiftLeftCq:R: */ -static AbstractInstruction * NoDbgRegParms -gLogicalShiftLeftCqR(sqInt quickConstant, sqInt reg) -{ - return genoperandoperand(LogicalShiftLeftCqR, quickConstant, reg); -} - - -/* destReg := srcReg << quickConstant */ - - /* Cogit>>#LogicalShiftLeftCq:R:R: */ -static AbstractInstruction * NoDbgRegParms -gLogicalShiftLeftCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) -{ - AbstractInstruction * first; - - return genoperandoperandoperand(LogicalShiftLeftCqRR, quickConstant, srcReg, destReg); - first = genoperandoperand(MoveRR, srcReg, destReg); - genoperandoperand(LogicalShiftLeftCqR, quickConstant, destReg); - return first; -} - - -/* destReg := (unsigned)srcReg >> quickConstant */ - - /* Cogit>>#LogicalShiftRightCq:R:R: */ -static AbstractInstruction * NoDbgRegParms -gLogicalShiftRightCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) -{ - AbstractInstruction * first; - - return genoperandoperandoperand(LogicalShiftRightCqRR, quickConstant, srcReg, destReg); - first = genoperandoperand(MoveRR, srcReg, destReg); - genoperandoperand(LogicalShiftRightCqR, quickConstant, destReg); - return first; -} - - /* Cogit>>#lastOpcode */ -static AbstractInstruction * -lastOpcode(void) -{ - assert(opcodeIndex > 0); - return abstractInstructionAt(opcodeIndex - 1); -} - - /* Cogit>>#linkSendAt:in:to:offset:receiver: */ -void -linkSendAtintooffsetreceiver(sqInt callSiteReturnAddress, CogMethod *sendingMethod, CogMethod *targetMethod, sqInt theEntryOffset, sqInt receiver) -{ - sqInt extent; - sqInt inlineCacheTag; - - assert((theEntryOffset == cmEntryOffset) - || (theEntryOffset == cmNoCheckEntryOffset)); - assert(((callSiteReturnAddress >= methodZoneBase) && (callSiteReturnAddress <= (freeStart())))); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - if (theEntryOffset == cmNoCheckEntryOffset) { - - /* no need to change selector cache tag */ - extent = rewriteCallAttarget(backEnd, callSiteReturnAddress, (((sqInt)targetMethod)) + cmNoCheckEntryOffset); - } - else { - inlineCacheTag = inlineCacheTagForInstance(receiver); - extent = rewriteInlineCacheAttagtarget(backEnd, callSiteReturnAddress, inlineCacheTag, (((sqInt)targetMethod)) + theEntryOffset); - } - flushICacheFromto(backEnd, (((usqInt)callSiteReturnAddress)) - extent, ((usqInt)callSiteReturnAddress)); -} - - /* Cogit>>#loadBytesAndGetDescriptor */ -static BytecodeDescriptor * -loadBytesAndGetDescriptor(void) -{ - BytecodeDescriptor *descriptor; - - byte0 = (fetchByteofObject(bytecodePC, methodObj)) + bytecodeSetOffset; - descriptor = generatorAt(byte0); - loadSubsequentBytesForDescriptorat(descriptor, bytecodePC); - return descriptor; -} - - /* Cogit>>#loadSubsequentBytesForDescriptor:at: */ -static void NoDbgRegParms -loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc) -{ - if (((descriptor->numBytes)) > 1) { - byte1 = fetchByteofObject(pc + 1, methodObj); - if (((descriptor->numBytes)) > 2) { - byte2 = fetchByteofObject(pc + 2, methodObj); - if (((descriptor->numBytes)) > 3) { - byte3 = fetchByteofObject(pc + 3, methodObj); - if (((descriptor->numBytes)) > 4) { - notYetImplemented(); - } - } - } - } -} - - /* Cogit>>#MoveCw:R: */ -static AbstractInstruction * NoDbgRegParms -gMoveCwR(sqInt wordConstant, sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkLiteral:forInstruction: */ - anInstruction = genoperandoperand(MoveCwR, wordConstant, reg); - return anInstruction; -} - - -/* Answer the address of the null byte at the end of the method map. */ - - /* Cogit>>#mapEndFor: */ -static usqInt NoDbgRegParms -mapEndFor(CogMethod *cogMethod) -{ - usqInt end; - - end = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while ((byteAt(end)) != MapEnd) { - end -= 1; - assert(end > (firstMappedPCFor(cogMethod))); - } - return end; -} - - -/* Unlinking/GC/Disassembly support */ -/* most of the time arg is a CogMethod... */ - - /* Cogit>>#mapFor:performUntil:arg: */ -static sqInt NoDbgRegParms -mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg) -{ - sqInt annotation; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - - /* begin firstMappedPCFor: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = functionSymbol(annotation, (((char *) mcpc)), arg); - if (result != 0) { - return result; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - return 0; -} - - -/* Remap all object references in the closed PIC. Answer if any references - are young. - Set codeModified if any modifications are made. */ - - /* Cogit>>#mapObjectReferencesInClosedPIC: */ -static sqInt NoDbgRegParms -mapObjectReferencesInClosedPIC(CogMethod *cPIC) -{ - sqInt i; - sqInt pc; - sqInt refersToYoung; - - - /* first we check the potential method oop load at the beginning of the CPIC */ - pc = addressOfEndOfCaseinCPIC(1, cPIC); - - /* We find the end address of the cPICNumCases'th case and can then just step forward by the case size thereafter */ - refersToYoung = remapMaybeObjRefInClosedPICAt(pc - (jumpLongByteSize(backEnd))); - - /* Next we check the potential class ref in the compare instruction, and the potential method oop load for each case. */ - pc = addressOfEndOfCaseinCPIC((cPIC->cPICNumCases), cPIC); - for (i = 2; i <= ((cPIC->cPICNumCases)); i += 1) { - if (remapMaybeObjRefInClosedPICAt((pc - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */)) { - refersToYoung = 1; - } - pc += cPICCaseSize; - } - return refersToYoung; -} - - -/* Update all references to objects in the generated runtime. */ - - /* Cogit>>#mapObjectReferencesInGeneratedRuntime */ -static void -mapObjectReferencesInGeneratedRuntime(void) -{ - sqInt i; - usqInt literal; - sqInt mappedLiteral; - usqInt mcpc; - - for (i = 0; i < runtimeObjectRefIndex; i += 1) { - mcpc = objectReferencesInRuntime[i]; - literal = literalBeforeFollowingAddress(backEnd, mcpc); - mappedLiteral = remapObject(literal); - if (mappedLiteral != literal) { - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - storeLiteralbeforeFollowingAddress(backEnd, mappedLiteral, mcpc); - } - } -} - - -/* Update all references to objects in machine code for a become. - Unlike incrementalGC or fullGC a method that does not refer to young may - refer to young as a result of the become operation. Unlike incrementalGC - or fullGC the reference from a Cog method to its methodObject *must not* - change since the two are two halves of the same object. */ - - /* Cogit>>#mapObjectReferencesInMachineCodeForBecome */ -static void -mapObjectReferencesInMachineCodeForBecome(void) -{ - sqInt annotation; - CogMethod * cogMethod; - sqInt freedPIC; - sqInt hasYoungObj; - sqInt hasYoungObjPtr; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt remappedMethod; - sqInt result; - CogMethod * writableCogMethod; - - hasYoungObj = 0; - hasYoungObjPtr = ((sqInt)((&hasYoungObj))); - codeModified = (freedPIC = 0); - mapObjectReferencesInGeneratedRuntime(); - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - assert(!hasYoungObj); - if (((cogMethod->cmType)) != CMFree) { - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - writableCogMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - (writableCogMethod->selector = remapOop((cogMethod->selector))); - if (((cogMethod->cmType)) == CMClosedPIC) { - if ((isYoung((cogMethod->selector))) - || (mapObjectReferencesInClosedPIC(cogMethod))) { - freedPIC = 1; - freeMethod(cogMethod); - } - } - else { - if (isYoung((cogMethod->selector))) { - hasYoungObj = 1; - } - if (((cogMethod->cmType)) == CMMethod) { - assert(((cogMethod->objectHeader)) == (nullHeaderForMachineCodeMethod())); - remappedMethod = remapOop((cogMethod->methodObject)); - if (remappedMethod != ((cogMethod->methodObject))) { - if (methodHasCogMethod(remappedMethod)) { - error("attempt to become two cogged methods"); - } - if (!(withoutForwardingOnandwithsendToCogit((cogMethod->methodObject), remappedMethod, (cogMethod->cmUsesPenultimateLit), methodhasSameCodeAscheckPenultimate))) { - error("attempt to become cogged method into different method"); - } - if ((rawHeaderOf((cogMethod->methodObject))) == (((sqInt)cogMethod))) { - rawHeaderOfput((cogMethod->methodObject), (cogMethod->methodHeader)); - (writableCogMethod->methodHeader = rawHeaderOf(remappedMethod)); - (writableCogMethod->methodObject = remappedMethod); - rawHeaderOfput(remappedMethod, ((sqInt)cogMethod)); - } - else { - assert((noAssertMethodClassAssociationOf((cogMethod->methodObject))) == (nilObject())); - (writableCogMethod->methodHeader = rawHeaderOf(remappedMethod)); - (writableCogMethod->methodObject = remappedMethod); - } - } - if (isYoung((cogMethod->methodObject))) { - hasYoungObj = 1; - } - } - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = remapIfObjectRefpchasYoung(annotation, (((char *) mcpc)), (((CogMethod *) hasYoungObjPtr))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - if (hasYoungObj) { - ensureInYoungReferrers(cogMethod); - hasYoungObj = 0; - } - else { - (cogMethod->cmRefersToYoung = 0); - } - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - pruneYoungReferrers(); - if (freedPIC) { - unlinkSendsToFree(); - } - if (codeModified) { - - /* After updating oops in inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)codeBase), freeStart()); - } -} - - -/* Update all references to objects in machine code for a full gc. Since - the current (New)ObjectMemory GC makes everything old in a full GC - a method not referring to young will not refer to young afterwards */ - - /* Cogit>>#mapObjectReferencesInMachineCodeForFullGC */ -static void -mapObjectReferencesInMachineCodeForFullGC(void) -{ - sqInt annotation; - CogMethod * cogMethod; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - CogMethod * writableCogMethod; - - codeModified = 0; - mapObjectReferencesInGeneratedRuntime(); - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - writableCogMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - (writableCogMethod->selector = remapOop((cogMethod->selector))); - if (((cogMethod->cmType)) == CMClosedPIC) { - assert(!((cogMethod->cmRefersToYoung))); - mapObjectReferencesInClosedPIC(cogMethod); - } - else { - if (((cogMethod->cmType)) == CMMethod) { - assert(((cogMethod->objectHeader)) == (nullHeaderForMachineCodeMethod())); - (writableCogMethod->methodObject = remapOop((cogMethod->methodObject))); - } - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = remapIfObjectRefpchasYoung(annotation, (((char *) mcpc)), 0); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - pruneYoungReferrers(); - if (codeModified) { - - /* After updating oops in inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)codeBase), freeStart()); - } -} - - -/* Update all references to objects in machine code for either a Spur - scavenging gc - or a Squeak V3 incremental GC. Avoid scanning all code by using the - youngReferrers list. In a young gc a method referring to young may no - longer refer to young, but a - method not referring to young cannot and will not refer to young - afterwards. */ - - /* Cogit>>#mapObjectReferencesInMachineCodeForYoungGC */ -static void -mapObjectReferencesInMachineCodeForYoungGC(void) -{ - sqInt annotation; - CogMethod * cogMethod; - sqInt hasYoungObj; - sqInt hasYoungObjPtr; - usqInt map; - sqInt mapByte; - sqInt mcpc; - usqInt pointer; - sqInt result; - CogMethod * writableCogMethod; - sqInt zoneIsWritable; - - codeModified = (zoneIsWritable = (hasYoungObj = 0)); - hasYoungObjPtr = ((sqInt)((&hasYoungObj))); - pointer = youngReferrers(); - while (pointer < limitAddress) { - assert(!hasYoungObj); - cogMethod = ((CogMethod *) (longAt(pointer))); - if (((cogMethod->cmType)) == CMFree) { - assert(!((cogMethod->cmRefersToYoung))); - } - else { - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - if ((cogMethod->cmRefersToYoung)) { - assert((((cogMethod->cmType)) == CMMethod) - || (((cogMethod->cmType)) == CMOpenPIC)); - if (!zoneIsWritable) { - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - zoneIsWritable = 1; - } - writableCogMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - (writableCogMethod->selector = remapOop((cogMethod->selector))); - if (isYoung((cogMethod->selector))) { - hasYoungObj = 1; - } - if (((cogMethod->cmType)) == CMMethod) { - assert(((cogMethod->objectHeader)) == (nullHeaderForMachineCodeMethod())); - (writableCogMethod->methodObject = remapOop((cogMethod->methodObject))); - if (isYoung((cogMethod->methodObject))) { - hasYoungObj = 1; - } - } - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = remapIfObjectRefpchasYoung(annotation, (((char *) mcpc)), (((void *)hasYoungObjPtr))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - if (hasYoungObj) { - hasYoungObj = 0; - } - else { - (writableCogMethod->cmRefersToYoung = 0); - } - } - } - pointer += BytesPerWord; - } - pruneYoungReferrers(); - if (codeModified) { - - /* After updating oops in inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } -} - - -/* Update all references to objects in machine code. */ - - /* Cogit>>#mapObjectReferencesInMachineCode: */ -void -mapObjectReferencesInMachineCode(sqInt gcMode) -{ - switch (gcMode) { - case GCModeNewSpace: - - /* N.B. do *not* ensureWritableCodeZone for every scavenge. */ - mapObjectReferencesInMachineCodeForYoungGC(); - break; - case GCModeFull: - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - mapObjectReferencesInMachineCodeForFullGC(); - break; - case GCModeBecome: - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - mapObjectReferencesInMachineCodeForBecome(); - break; - default: - error("Case not found and no otherwise clause"); - } - if (!(asserta((freeStart()) <= (youngReferrers())))) { - error("youngReferrers list overflowed"); - } -} - - -/* Mark objects in machine-code of marked methods (or open PICs with marked - selectors). - */ - - /* Cogit>>#markAndTraceMachineCodeOfMarkedMethods */ -void -markAndTraceMachineCodeOfMarkedMethods(void) -{ - sqInt annotation; - sqInt annotation1; - CogMethod *cogMethod; - usqInt map; - usqInt map1; - sqInt mapByte; - sqInt mapByte1; - sqInt mcpc; - sqInt mcpc1; - sqInt result; - sqInt result1; - usqInt theCounters; - usqInt theCounters1; - - if (leakCheckFullGC()) { - asserta(allMachineCodeObjectReferencesValid()); - } - codeModified = 0; - markAndTraceObjectReferencesInGeneratedRuntime(); - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) == CMMethod) - && (isMarked((cogMethod->methodObject)))) { - /* begin markAndTraceLiteralsIn: */ - assert(((((cogMethod->cmType)) == CMMethod) - && (isMarked((cogMethod->methodObject)))) - || ((((cogMethod->cmType)) == CMOpenPIC) - && ((isImmediate((cogMethod->selector))) - || (isMarked((cogMethod->selector)))))); - markAndTraceLiteralinat((cogMethod->selector), cogMethod, (&((cogMethod->selector)))); - /* begin maybeMarkCountersIn: */ - theCounters = (cogMethod->counters); - if (theCounters != 0) { - markAndTrace(theCounters - BaseHeaderSize); - } - /* begin maybeMarkIRCsIn: */ - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = markLiteralspcmethod(annotation, (((char *) mcpc)), cogMethod); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - if ((((cogMethod->cmType)) == CMOpenPIC) - && ((isImmediate((cogMethod->selector))) - || (isMarked((cogMethod->selector))))) { - /* begin markAndTraceLiteralsIn: */ - assert(((((cogMethod->cmType)) == CMMethod) - && (isMarked((cogMethod->methodObject)))) - || ((((cogMethod->cmType)) == CMOpenPIC) - && ((isImmediate((cogMethod->selector))) - || (isMarked((cogMethod->selector)))))); - markAndTraceLiteralinat((cogMethod->selector), cogMethod, (&((cogMethod->selector)))); - /* begin maybeMarkCountersIn: */ - theCounters1 = (cogMethod->counters); - if (theCounters1 != 0) { - markAndTrace(theCounters1 - BaseHeaderSize); - } - /* begin maybeMarkIRCsIn: */ - /* begin mapFor:performUntil:arg: */ - mcpc1 = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map1 = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte1 = byteAt(map1))) != MapEnd) { - if (mapByte1 >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc1 += (mapByte1 & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation1 = ((usqInt)(mapByte1)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte1 = byteAt(map1 - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation1 += mapByte1 & DisplacementMask; - map1 -= 1; - } - result1 = markLiteralspcmethod(annotation1, (((char *) mcpc1)), cogMethod); - if (result1 != 0) { - goto l4; - } - } - else { - if (mapByte1 < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc1 += (((sqInt)((usqInt)((mapByte1 - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map1 -= 1; - } - l4: /* end mapFor:performUntil:arg: */; - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (leakCheckFullGC()) { - asserta(allMachineCodeObjectReferencesValid()); - } - if (codeModified) { - - /* After updating oops in inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } -} - - -/* Mark and trace any object references in the generated run-time. */ - - /* Cogit>>#markAndTraceObjectReferencesInGeneratedRuntime */ -static void -markAndTraceObjectReferencesInGeneratedRuntime(void) -{ - sqInt i; - usqInt literal; - usqInt mcpc; - - for (i = 0; i < runtimeObjectRefIndex; i += 1) { - mcpc = objectReferencesInRuntime[i]; - literal = literalBeforeFollowingAddress(backEnd, mcpc); - markAndTraceLiteralinatpc(literal, ((CogMethod *) null), ((usqInt)mcpc)); - } -} - - -/* Mark and trace objects in the argument and free if it is appropriate. - Answer if the method has been freed. firstVisit is a hint used to avoid - scanning methods we've already seen. False positives are fine. - For a CMMethod this - frees if the bytecode method isnt marked, - marks and traces object literals and selectors, - unlinks sends to targets that should be freed. - For a CMClosedPIC this - frees if it refers to anything that should be freed or isn't marked. - For a CMOpenPIC this - frees if the selector isn't marked. */ -/* this recurses at most one level down */ - - /* Cogit>>#markAndTraceOrFreeCogMethod:firstVisit: */ -static sqInt NoDbgRegParms -markAndTraceOrFreeCogMethodfirstVisit(CogMethod *cogMethod, sqInt firstVisit) -{ - sqInt annotation; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - usqInt theCounters; - - if (((cogMethod->cmType)) == CMFree) { - return 1; - } - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - if (((cogMethod->cmType)) == CMMethod) { - if (!(isMarked((cogMethod->methodObject)))) { - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - freeMethod(cogMethod); - return 1; - } - if (firstVisit) { - /* begin markLiteralsAndUnlinkUnmarkedSendsIn: */ - assert(((cogMethod->cmType)) == CMMethod); - assert(isMarked((cogMethod->methodObject))); - markAndTraceLiteralinat((cogMethod->selector), cogMethod, (&((cogMethod->selector)))); - /* begin maybeMarkCountersIn: */ - theCounters = (cogMethod->counters); - if (theCounters != 0) { - markAndTrace(theCounters - BaseHeaderSize); - } - /* begin maybeMarkIRCsIn: */ - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = markLiteralsAndUnlinkIfUnmarkedSendpcmethod(annotation, (((char *) mcpc)), cogMethod); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - return 0; - } - if (((cogMethod->cmType)) == CMClosedPIC) { - if (!(closedPICRefersToUnmarkedObject(cogMethod))) { - return 0; - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - freeMethod(cogMethod); - return 1; - } - if (((cogMethod->cmType)) == CMOpenPIC) { - if (isMarked((cogMethod->selector))) { - return 0; - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - freeMethod(cogMethod); - return 1; - } - assert((((cogMethod->cmType)) == CMMethod) - || ((((cogMethod->cmType)) == CMClosedPIC) - || (((cogMethod->cmType)) == CMOpenPIC))); - return 0; -} - - -/* If entryPoint is that of some method, then mark and trace objects in it - and free if it is appropriate. - Answer if the method has been freed. */ - - /* Cogit>>#markAndTraceOrFreePICTarget:in: */ -static sqInt NoDbgRegParms -markAndTraceOrFreePICTargetin(sqInt entryPoint, CogMethod *cPIC) -{ - CogMethod *targetMethod; - - assert((entryPoint > methodZoneBase) - && (entryPoint < (freeStart()))); - if (((((usqInt)cPIC)) <= (((usqInt)entryPoint))) - && (((((usqInt)cPIC)) + ((cPIC->blockSize))) >= (((usqInt)entryPoint)))) { - return 0; - } - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - assert((((targetMethod->cmType)) == CMMethod) - || (((targetMethod->cmType)) == CMFree)); - return markAndTraceOrFreeCogMethodfirstVisit(targetMethod, (((usqInt)targetMethod)) > (((usqInt)cPIC))); -} - - -/* Mark and trace literals. Unlink sends that have unmarked cache tags or - targets. - */ - - /* Cogit>>#markLiteralsAndUnlinkIfUnmarkedSend:pc:method: */ -static sqInt NoDbgRegParms -markLiteralsAndUnlinkIfUnmarkedSendpcmethod(sqInt annotation, char *mcpc, sqInt cogMethod) -{ - usqInt cacheTag1; - sqInt cacheTagMarked; - usqInt entryPoint1; - usqInt literal; - sqInt offset1; - sqInt *sendTable1; - sqInt tagCouldBeObj1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - literal = 0; - if (annotation == IsObjectReference) { - literal = literalBeforeFollowingAddress(backEnd, ((usqInt)mcpc)); - if (markAndTraceLiteralinatpc(literal, ((CogMethod *) cogMethod), ((usqInt)mcpc))) { - codeModified = 1; - } - } - if (annotation >= IsSendCall) { - /* begin entryCacheTagAndCouldBeObjectAt:annotation:into: */ - cacheTag1 = inlineCacheTagAt(backEnd, ((sqInt)mcpc)); - - /* in-line cache tags are the selectors of sends if sends are unlinked, - the selectors of super sends (entry offset = cmNoCheckEntryOffset), - the selectors of open PIC sends (entry offset = cmEntryOffset, target is an Open PIC) - or in-line cache tags (classes, class indices, immediate bit patterns, etc). - Note that selectors can be immediate so there is no guarantee that they - are markable/remappable objects. */ - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - tagCouldBeObj1 = entryPointTagIsSelector(entryPoint1); - cacheTagMarked = tagCouldBeObj1 - && (1); - if (entryPoint1 > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint1 - offset1)); - if ((!cacheTagMarked) - || (markAndTraceOrFreeCogMethodfirstVisit(targetMethod1, (((usqInt)targetMethod1)) > (((usqInt)mcpc))))) { - - /* Either the cacheTag is unmarked (e.g. new class) or the target - has been freed (because it is unmarked), so unlink the send. */ - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - markAndTraceLiteralinat((targetMethod1->selector), targetMethod1, (&((targetMethod1->selector)))); - } - } - else { - - /* cacheTag is selector */ - if (markAndTraceCacheTagLiteralinatpc(cacheTag1, ((CogMethod *) cogMethod), ((usqInt)mcpc))) { - codeModified = 1; - } - } - } - return 0; -} - - -/* Mark and trace literals. - Additionally in Newspeak, void push implicits that have unmarked classes. */ - - /* Cogit>>#markLiterals:pc:method: */ -static sqInt NoDbgRegParms -markLiteralspcmethod(sqInt annotation, char *mcpc, CogMethod *cogMethod) -{ - usqInt cacheTag1; - usqInt entryPoint1; - usqInt literal; - sqInt tagCouldBeObj1; - - literal = 0; - if (annotation == IsObjectReference) { - literal = literalBeforeFollowingAddress(backEnd, ((usqInt)mcpc)); - if (markAndTraceLiteralinatpc(literal, cogMethod, ((usqInt)mcpc))) { - codeModified = 1; - } - } - if (annotation >= IsSendCall) { - /* begin entryCacheTagAndCouldBeObjectAt:annotation:into: */ - cacheTag1 = inlineCacheTagAt(backEnd, ((sqInt)mcpc)); - - /* in-line cache tags are the selectors of sends if sends are unlinked, - the selectors of super sends (entry offset = cmNoCheckEntryOffset), - the selectors of open PIC sends (entry offset = cmEntryOffset, target is an Open PIC) - or in-line cache tags (classes, class indices, immediate bit patterns, etc). - Note that selectors can be immediate so there is no guarantee that they - are markable/remappable objects. */ - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - tagCouldBeObj1 = entryPointTagIsSelector(entryPoint1); - if (tagCouldBeObj1 - && (markAndTraceCacheTagLiteralinatpc(cacheTag1, cogMethod, ((usqInt)mcpc)))) { - - /* cacheTag is selector */ - codeModified = 1; - } - } - return 0; -} - - /* Cogit>>#markMethodAndReferents: */ -void -markMethodAndReferents(CogBlockMethod *aCogMethod) -{ - sqInt annotation; - CogMethod * cogMethod; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - CogMethod * writableMethod; - - assert((((aCogMethod->cmType)) == CMMethod) - || (((aCogMethod->cmType)) == CMBlock)); - cogMethod = (((aCogMethod->cmType)) == CMMethod - ? ((CogMethod *) aCogMethod) - : cmHomeMethod(aCogMethod)); - writableMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - (writableMethod->cmUsageCount = CMMaxUsageCount); - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = incrementUsageOfTargetIfLinkedSendmcpcignored(annotation, (((char *) mcpc)), 0); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; -} - - /* Cogit>>#maxCogMethodAddress */ -usqInt -maxCogMethodAddress(void) -{ - return ((usqInt)(limitZony())); -} - - -/* If this is the Newspeak VM and the objectRepresentation supports pinning - then allocate space for the implicit receiver caches on the heap. */ - - /* Cogit>>#maybeAllocAndInitIRCs */ -static sqInt -maybeAllocAndInitIRCs(void) -{ - return 1; -} - - -/* Check that the header fields are consistent with the type. - Answer 0 if it is ok, otherwise answer a code for the error. */ - - /* Cogit>>#maybeFreeCogMethodDoesntLookKosher: */ -static sqInt NoDbgRegParms -maybeFreeCogMethodDoesntLookKosher(CogMethod *cogMethod) -{ - sqInt result; - - result = cogMethodDoesntLookKosher(cogMethod); - return (result == 2 - ? 0 - : result); -} - - /* Cogit>>#mclassIsSmallInteger */ -static sqInt -mclassIsSmallInteger(void) -{ - return (receiverTags & 1); -} - - -/* Answer the absolute machine code pc matching the zero-relative - bytecode pc of a backward branch in cogMethod, given the start - of the bytecodes for cogMethod's block or method object. */ - - /* Cogit>>#mcPCForBackwardBranch:startBcpc:in: */ -usqInt -mcPCForBackwardBranchstartBcpcin(sqInt bcpc, sqInt startbcpc, CogBlockMethod *cogMethod) -{ - sqInt aMethodHeader; - sqInt aMethodHeader1; - sqInt aMethodObj; - sqInt annotation; - sqInt bcpc1; - sqInt bsOffset; - sqInt byte; - sqInt byte01; - sqInt byte02; - BytecodeDescriptor *descriptor; - sqInt distance; - sqInt distance1; - sqInt distance2; - sqInt endbcpc; - CogMethod *homeMethod; - sqInt isBackwardBranch; - sqInt isInBlock; - sqInt latestContinuation; - usqInt map; - sqInt mapByte; - usqInt mcpc; - sqInt nExts; - sqInt newContinuation; - sqInt nextBcpc; - sqInt prim; - sqInt result; - sqInt targetPC; - sqInt targetPC1; - sqInt upperByte; - - latestContinuation = 0; - /* begin mapFor:bcpc:performUntil:arg: */ - assert(((cogMethod->stackCheckOffset)) > 0); - - /* The stack check maps to the start of the first bytecode, - the first bytecode being effectively after frame build. */ - mcpc = (((usqInt)cogMethod)) + ((cogMethod->stackCheckOffset)); - result = (((((0 + (((int)((usqInt)(HasBytecodePC) << 1)))) & 1) != 0)) - && ((((sqInt)(((void *)bcpc)))) == startbcpc) - ? ((sqInt)(((char *) mcpc))) - : 0); - if (result != 0) { - return result; - } - - /* In both CMMethod and CMBlock cases find the start of the map and - skip forward to the bytecode pc map entry for the stack check. */ - bcpc1 = startbcpc; - if (((cogMethod->cmType)) == CMMethod) { - /* begin cmIsFullBlock */ - isInBlock = (cogMethod->cpicHasMNUCaseOrCMIsFullBlock); - homeMethod = ((CogMethod *) cogMethod); - assert(startbcpc == (startPCOfMethodHeader((homeMethod->methodHeader)))); - map = ((((usqInt)homeMethod)) + ((homeMethod->blockSize))) - 1; - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert((annotation == IsAbsPCReference) - || ((annotation == IsObjectReference) - || ((annotation == IsRelativeCall) - || (annotation == IsDisplacementX2N)))); - latestContinuation = startbcpc; - aMethodObj = (homeMethod->methodObject); - endbcpc = (numBytesOf(aMethodObj)) - 1; - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader) - ? 0x100 - : 0) -# else - 0 -# endif - ; - bcpc1 += deltaToSkipPrimAndErrorStoreInheader(aMethodObj, (homeMethod->methodHeader)); - } - else { - isInBlock = 1; - assert(bcpc1 == ((cogMethod->startpc))); - homeMethod = cmHomeMethod(cogMethod); - map = findMapLocationForMcpcinMethod((((usqInt)cogMethod)) + (sizeof(CogBlockMethod)), homeMethod); - assert(map != 0); - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert(((((usqInt)(annotation)) >> AnnotationShift) == HasBytecodePC) - || ((((usqInt)(annotation)) >> AnnotationShift) == IsDisplacementX2N)); - while (((annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift)) != HasBytecodePC) { - map -= 1; - } - - /* skip fiducial; i.e. the map entry for the pc immediately following the method header. */ - map -= 1; - aMethodObj = (homeMethod->methodObject); - bcpc1 = startbcpc - ( -#if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet((homeMethod->methodHeader)) - ? AltBlockCreationBytecodeSize - : BlockCreationBytecodeSize) -#else // MULTIPLEBYTECODESETS - BlockCreationBytecodeSize -#endif - ); - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader1 = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader1) - ? 0x100 - : 0) -# else - 0 -# endif - ; - byte = (fetchByteofObject(bcpc1, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - endbcpc = (bcpc1 + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc1, -1, aMethodObj)) - : 0)); - bcpc1 = startbcpc; - } - nExts = 0; - while ((((usqInt)((byteAt(map)))) >> AnnotationShift) != HasBytecodePC) { - map -= 1; - } - map -= 1; - while (((mapByte = byteAt(map))) != MapEnd) { - - /* defensive; we exit on bcpc */ - if (mapByte >= FirstAnnotation) { - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if (annotation >= HasBytecodePC) { - if ((annotation == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - while (1) { - byte = (fetchByteofObject(bcpc1, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - if (isInBlock) { - if (bcpc1 >= endbcpc) { - return 0; - } - } - else { - if (((descriptor->isReturn)) - && (bcpc1 >= latestContinuation)) { - return 0; - } - if ((isBranch(descriptor)) - || ((descriptor->isBlockCreation))) { - /* begin latestContinuationPCFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, bcpc1, nExts, aMethodObj); - targetPC = (bcpc1 + ((descriptor->numBytes))) + (((distance < 0) ? 0 : distance)); - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - /* begin maybeUnsafeJumpContinuation:at:for:in: */ - newContinuation = latestContinuation; - if ((descriptor->hasUnsafeJump)) { - byte01 = fetchByteofObject(bcpc1 + 1, aMethodObj); - - /* pushIntegerLong */ - byte02 = fetchByteofObject(bcpc1 + 2, aMethodObj); - /* begin decodePushIntegerLongBefore:in: */ - distance1 = fetchByteofObject(bcpc1 - 1, methodObj); - upperByte = fetchByteofObject(bcpc1 - 3, methodObj); - if (upperByte > 0x7F) { - upperByte -= 0x100; - } - distance2 = (((sqInt)((usqInt)(upperByte) << 8))) + distance1; - targetPC1 = (bcpc1 + ((descriptor->numBytes))) + distance2; - if (!((descriptor->isMapped))) { - if ((((usqInt)(byte02)) >> 5) == 4) { - - /* inlined sista primitive */ - prim = (((sqInt)((usqInt)((byte02 & 0x1F)) << 8))) + byte01; - if (prim >= 7000) { - - /* branch forward */ - newContinuation = ((latestContinuation < targetPC1) ? targetPC1 : latestContinuation); - } - } - } - } - latestContinuation = newContinuation; - } - nextBcpc = (bcpc1 + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc1, nExts, aMethodObj)) - : 0)); - if (((descriptor->isMapped)) - || (isInBlock - && ((descriptor->isMappedInBlock)))) break; - bcpc1 = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - isBackwardBranch = (isBranch(descriptor)) - && ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, bcpc1, nExts, aMethodObj)) < 0)); - result = findBackwardBranchIsBackwardBranchMcpcBcpcMatchingBcpc(descriptor, ((isBackwardBranch - ? (((sqInt)((usqInt)(annotation) << 1))) + 1 - : ((sqInt)((usqInt)(annotation) << 1)))), (((char *) mcpc)), ((isBackwardBranch - ? bcpc1 - (2 * nExts) - : bcpc1)), (((void *)bcpc))); - if (result != 0) { - return result; - } - bcpc1 = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - } - else { - assert(((((usqInt)(mapByte)) >> AnnotationShift) == IsDisplacementX2N) - || ((((usqInt)(mapByte)) >> AnnotationShift) == IsAnnotationExtension)); - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - return 0; -} - - -/* For the purposes of become: see if the two methods are similar, i.e. can - be safely becommed. - This is pretty strict. All literals and bytecodes must be identical. Only - trailer bytes and header - flags can differ. */ - - /* Cogit>>#method:hasSameCodeAs:checkPenultimate: */ -static sqInt NoDbgRegParms -methodhasSameCodeAscheckPenultimate(sqInt methodA, sqInt methodB, sqInt comparePenultimateLiteral) -{ - sqInt bi; - sqInt endPCA; - sqInt headerA; - sqInt headerB; - sqInt li; - sqInt numLitsA; - - headerA = methodHeaderOf(methodA); - headerB = methodHeaderOf(methodB); - numLitsA = literalCountOfMethodHeader(headerA); - endPCA = endPCOf(methodA); - if (((argumentCountOfMethodHeader(headerA)) != (argumentCountOfMethodHeader(headerB))) - || (((temporaryCountOfMethodHeader(headerA)) != (temporaryCountOfMethodHeader(headerB))) - || (((primitiveIndexOfMethodheader(methodA, headerA)) != (primitiveIndexOfMethodheader(methodB, headerB))) - || ((numLitsA != (literalCountOfMethodHeader(headerB))) - || (endPCA > (numBytesOf(methodB))))))) { - return 0; - } - for (li = 1; li < numLitsA; li += 1) { - if ((fetchPointerofObject(li, methodA)) != (fetchPointerofObject(li, methodB))) { - if ((li < (numLitsA - 1)) - || (comparePenultimateLiteral)) { - return 0; - } - } - } - for (bi = (startPCOfMethod(methodA)); bi <= endPCA; bi += 1) { - if ((fetchByteofObject(bi, methodA)) != (fetchByteofObject(bi, methodB))) { - return 0; - } - } - return 1; -} - - /* Cogit>>#mnuOffset */ -sqInt -mnuOffset(void) -{ - return missOffset; -} - - /* Cogit>>#NativePopR: */ -static AbstractInstruction * NoDbgRegParms -gNativePopR(sqInt reg) -{ - return genoperand(PopR, reg); -} - - /* Cogit>>#NativePushR: */ -static AbstractInstruction * NoDbgRegParms -gNativePushR(sqInt reg) -{ - return genoperand(PushR, reg); -} - - /* Cogit>>#NativeRetN: */ -static AbstractInstruction * NoDbgRegParms -gNativeRetN(sqInt offset) -{ - return genoperand(RetN, offset); -} - - /* Cogit>>#needsFrameIfImmutability: */ -static sqInt NoDbgRegParms -needsFrameIfImmutability(sqInt stackDelta) -{ - return IMMUTABILITY; -} - - /* Cogit>>#needsFrameIfInBlock: */ -static sqInt NoDbgRegParms -needsFrameIfInBlock(sqInt stackDelta) -{ - return inBlock > 0; -} - - /* Cogit>>#needsFrameNever: */ -static sqInt NoDbgRegParms -needsFrameNever(sqInt stackDelta) -{ - return 0; -} - - /* Cogit>>#noAssertMethodClassAssociationOf: */ -static sqInt NoDbgRegParms -noAssertMethodClassAssociationOf(sqInt methodPointer) -{ - return literalofMethod((literalCountOfMethodHeader(noAssertHeaderOf(methodPointer))) - 1, methodPointer); -} - - -/* Check that no method is maximally marked. A maximal mark is an indication - the method has been scanned to increase the usage count of its referent - methods. */ - - /* Cogit>>#noCogMethodsMaximallyMarked */ -static sqInt -noCogMethodsMaximallyMarked(void) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) != CMFree) - && (((cogMethod->cmUsageCount)) == CMMaxUsageCount)) { - return 0; - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return 1; -} - - -/* Answer if all targets in the PIC are in-use methods. */ - - /* Cogit>>#noTargetsFreeInClosedPIC: */ -static sqInt NoDbgRegParms -noTargetsFreeInClosedPIC(CogMethod *cPIC) -{ - return !(cPICHasFreedTargets(cPIC)); -} - - /* Cogit>>#OrCq:R:R: */ -static AbstractInstruction * NoDbgRegParms -gOrCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction * first; - - /* begin gen:quickConstant:operand:operand: */ - anInstruction = genoperandoperandoperand(OrCqRR, quickConstant, srcReg, destReg); - return anInstruction; - if (srcReg == destReg) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(OrCqR, quickConstant, destReg); - return anInstruction1; - } - first = genoperandoperand(MoveRR, srcReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(OrCqR, quickConstant, destReg); - return first; -} - - -/* Store the generated machine code, answering the last address */ - - /* Cogit>>#outputInstructionsAt: */ -static sqInt NoDbgRegParms -outputInstructionsAt(sqInt startAddress) -{ - sqInt absoluteAddress; - AbstractInstruction * abstractInstruction; - sqInt i; - sqInt j; - - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - absoluteAddress = startAddress; - for (i = 0; i < opcodeIndex; i += 1) { - maybeBreakGeneratingInstructionWithIndex(i); - abstractInstruction = abstractInstructionAt(i); - assert(((abstractInstruction->address)) == absoluteAddress); - /* begin outputMachineCodeAt: */ - for (j = 0; j < ((abstractInstruction->machineCodeSize)); j += 4) { - longAtput(absoluteAddress + j, ((abstractInstruction->machineCode))[j / 4]); - } - absoluteAddress += (abstractInstruction->machineCodeSize); - } - return absoluteAddress; -} - - -/* Output instructions generated for one of the generated run-time routines, - a trampoline, etc - */ - - /* Cogit>>#outputInstructionsForGeneratedRuntimeAt: */ -static sqInt NoDbgRegParms -outputInstructionsForGeneratedRuntimeAt(sqInt startAddress) -{ - sqInt endAddress; - sqInt size; - - computeMaximumSizes(); - (methodLabel->address = startAddress); - size = generateInstructionsAt(startAddress); - endAddress = outputInstructionsAt(startAddress); - assert((startAddress + size) == endAddress); - methodZoneBase = alignUptoRoutineBoundary(endAddress); - stopsFromto(backEnd, endAddress, methodZoneBase - 1); - return startAddress; -} - - /* Cogit>>#PushCw: */ -static AbstractInstruction * NoDbgRegParms -gPushCw(sqInt wordConstant) -{ - AbstractInstruction *anInstruction; - - /* begin checkLiteral:forInstruction: */ - anInstruction = genoperand(PushCw, wordConstant); - return anInstruction; -} - - -/* Code entry closed PIC full or miss to an instance of a young class or to a - young target method. - Attempt to patch the send site to an open PIC. Answer if the attempt - succeeded; in fact it will - only return if the attempt failed. - The stack looks like: - receiver - args - sp=> sender return address */ - - /* Cogit>>#patchToOpenPICFor:numArgs:receiver: */ -sqInt -patchToOpenPICFornumArgsreceiver(sqInt selector, sqInt numArgs, sqInt receiver) -{ - sqInt extent; - CogMethod *oPIC; - sqInt outerReturn; - - - /* See if an Open PIC is already available. */ - outerReturn = stackTop(); - oPIC = openPICWithSelector(selector); - if (!oPIC) { - - /* otherwise attempt to create an Open PIC. */ - oPIC = cogOpenPICSelectornumArgs(selector, numArgs); - if ((((((sqInt)oPIC)) >= MaxNegativeErrorCode) && ((((sqInt)oPIC)) <= -1))) { - - /* For some reason the PIC couldn't be generated, most likely a lack of code memory. */ - if ((((sqInt)oPIC)) == InsufficientCodeSpace) { - callForCogCompiledCodeCompaction(); - } - return 0; - } - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - extent = rewriteInlineCacheAttagtarget(backEnd, outerReturn, inlineCacheValueForSelectorin(backEnd, selector, mframeHomeMethodExport()), (((sqInt)oPIC)) + cmEntryOffset); - flushICacheFromto(backEnd, (((usqInt)outerReturn)) - extent, ((usqInt)outerReturn)); - flushICacheFromto(backEnd, ((usqInt)oPIC), (((usqInt)oPIC)) + openPICSize); - executeCogMethodfromLinkedSendWithReceiver(oPIC, receiver); - return 1; -} - - -/* This value is used to decide between MNU processing - or interpretation in the closed PIC aborts. */ - - /* Cogit>>#picAbortDiscriminatorValue */ -static sqInt -picAbortDiscriminatorValue(void) -{ - return 0; -} - - -/* Answer the start of the abort sequence for invoking the interpreter in a - closed PIC. - */ - - /* Cogit>>#picInterpretAbortOffset */ -static sqInt -picInterpretAbortOffset(void) -{ - return (interpretOffset()) - (8 /* pushLinkRegisterByteSize */ + (callInstructionByteSize(backEnd))); -} - - /* Cogit>>#previousInstruction */ -static AbstractInstruction * -previousInstruction(void) -{ - assert(opcodeIndex > 0); - return abstractInstructionAt(opcodeIndex - 1); -} - - /* Cogit>>#printCogMethodFor: */ -void -printCogMethodFor(void *address) -{ - CogMethod * cogMethod; - - cogMethod = methodFor(address); - if (cogMethod == null) { - if ((codeEntryFor(address)) == null) { - print("not a method"); - cr(); - } - else { - print("trampoline "); - print(codeEntryNameFor(address)); - cr(); - } - } - else { - printCogMethod(cogMethod); - } -} - - /* Cogit>>#printTrampolineTable */ -void -printTrampolineTable(void) -{ - sqInt i; - - for (i = 0; i < trampolineTableIndex; i += 2) { - printHex(((sqInt)(trampolineAddresses[i + 1]))); - print(": "); - print(((char *) (trampolineAddresses[i]))); - cr(); - } -} - - /* Cogit>>#processorHasDivQuoRemAndMClassIsSmallInteger */ -static sqInt -processorHasDivQuoRemAndMClassIsSmallInteger(void) -{ - return mclassIsSmallInteger(); -} - - /* Cogit>>#processorHasDoublePrecisionFloatingPointSupport */ -static sqInt -processorHasDoublePrecisionFloatingPointSupport(void) -{ - return 0; -} - - /* Cogit>>#processorHasMultiplyAndMClassIsSmallInteger */ -static sqInt -processorHasMultiplyAndMClassIsSmallInteger(void) -{ - return 0; -} - - /* Cogit>>#recordGeneratedRunTime:address: */ -static void NoDbgRegParms -recordGeneratedRunTimeaddress(char *aString, sqInt address) -{ - assert((trampolineTableIndex + 2) <= (NumTrampolines * 2)); - trampolineAddresses[trampolineTableIndex] = aString; - trampolineAddresses[trampolineTableIndex + 1] = (((char *) address)); - - /* self printTrampolineTable */ - trampolineTableIndex += 2; -} - - -/* This one for C support code. */ - - /* Cogit>>#recordPrimTraceFunc */ -sqInt -recordPrimTraceFunc(void) -{ - return recordPrimTrace(); -} - - /* Cogit>>#recordRunTimeObjectReferences */ -static void -recordRunTimeObjectReferences(void) -{ - sqInt i; - AbstractInstruction *instruction; - - for (i = 0; i < opcodeIndex; i += 1) { - instruction = abstractInstructionAt(i); - if (((instruction->annotation)) == IsObjectReference) { - assert(runtimeObjectRefIndex < NumObjRefsInRuntime); - assert(!hasYoungReferent); - if (hasYoungReferent) { - error("attempt to generate run-time routine containing young object reference. Cannot initialize Cogit run-time."); - } - objectReferencesInRuntime[runtimeObjectRefIndex] = (((usqInt)(((instruction->address)) + ((instruction->machineCodeSize))))); - runtimeObjectRefIndex += 1; - } - } -} - - /* Cogit>>#registerMaskFor: */ -static sqInt NoDbgRegParms -registerMaskFor(sqInt reg) -{ - return 1U << reg; -} - - /* Cogit>>#registerMaskFor:and:and: */ -static sqInt NoDbgRegParms -registerMaskForandand(sqInt reg1, sqInt reg2, sqInt reg3) -{ - return ((1U << reg1) | (1U << reg2)) | (1U << reg3); -} - - /* Cogit>>#relocateCallsAndSelfReferencesInMethod: */ -static void NoDbgRegParms -relocateCallsAndSelfReferencesInMethod(CogMethod *cogMethod) -{ - sqInt annotation; - sqInt callDelta; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqLong refDelta; - sqInt result; - - refDelta = (cogMethod->objectHeader); - callDelta = 0; - assert((((cogMethod->cmType)) == CMMethod) - || (((cogMethod->cmType)) == CMOpenPIC)); - assert((callTargetFromReturnAddress(backEnd, (((sqInt)cogMethod)) + missOffset)) == ((((cogMethod->cmType)) == CMMethod - ? methodAbortTrampolineFor((cogMethod->cmNumArgs)) - : picAbortTrampolineFor((cogMethod->cmNumArgs))))); - relocateCallBeforeReturnPCby(backEnd, (((sqInt)cogMethod)) + missOffset, -callDelta); - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = relocateIfCallOrMethodReferencemcpcdelta(annotation, (((char *) mcpc)), (((void *)refDelta))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; -} - - /* Cogit>>#relocateCallsInClosedPIC: */ -static void NoDbgRegParms -relocateCallsInClosedPIC(CogMethod *cPIC) -{ - sqInt callDelta; - usqInt entryPoint; - sqInt i; - sqInt pc; - sqLong refDelta; - CogMethod *targetMethod; - - refDelta = (cPIC->objectHeader); - callDelta = 0; - assert((callTargetFromReturnAddress(backEnd, (((sqInt)cPIC)) + missOffset)) == (picAbortTrampolineFor((cPIC->cmNumArgs)))); - relocateCallBeforeReturnPCby(backEnd, (((sqInt)cPIC)) + missOffset, -callDelta); - pc = (((sqInt)cPIC)) + firstCPICCaseOffset; - for (i = 1; i <= ((cPIC->cPICNumCases)); i += 1) { - pc = addressOfEndOfCaseinCPIC(i, cPIC); - entryPoint = (i == 1 - ? jumpLongTargetBeforeFollowingAddress(backEnd, pc) - : jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc)); - if (((((usqInt)cPIC)) <= (((usqInt)entryPoint))) - && (((((usqInt)cPIC)) + ((cPIC->blockSize))) >= (((usqInt)entryPoint)))) { - - /* Interpret/MNU */ - if (i == 1) { - relocateJumpLongBeforeFollowingAddressby(backEnd, pc, refDelta); - } - else { - relocateJumpLongConditionalBeforeFollowingAddressby(backEnd, pc, refDelta); - } - } - else { - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - assert(((targetMethod->cmType)) == CMMethod); - if (i == 1) { - relocateJumpLongBeforeFollowingAddressby(backEnd, pc, -(callDelta - ((targetMethod->objectHeader)))); - } - else { - relocateJumpLongConditionalBeforeFollowingAddressby(backEnd, pc, -(callDelta - ((targetMethod->objectHeader)))); - } - } - } - assert(((cPIC->cPICNumCases)) > 0); - relocateMethodReferenceBeforeAddressby(backEnd, (addressOfEndOfCaseinCPIC(2, cPIC)) + 8 /* loadLiteralByteSize */, refDelta); - relocateJumpLongBeforeFollowingAddressby(backEnd, (((sqInt)cPIC)) + cPICEndOfCodeOffset, -callDelta); -} - - -/* To placate the C static type system... */ - - /* Cogit>>#relocateIfCallOrMethodReference:mcpc:delta: */ -static sqInt NoDbgRegParms -relocateIfCallOrMethodReferencemcpcdelta(sqInt annotation, char *mcpc, CogMethod *refDeltaArg) -{ - sqInt callDelta; - sqInt entryPoint; - sqInt offset1; - sqInt refDelta; - sqInt *sendTable1; - CogMethod *targetMethod; - sqInt unlinkedRoutine; - - refDelta = ((sqInt) refDeltaArg); - callDelta = 0; - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint <= methodZoneBase) { - - /* send is not linked; just relocate */ - relocateCallBeforeReturnPCby(backEnd, ((sqInt)mcpc), -callDelta); - return 0; - } - /* begin offsetAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod = ((CogMethod *) (entryPoint - offset1)); - if (((targetMethod->cmType)) != CMFree) { - - /* send target not freed; just relocate. */ - relocateCallBeforeReturnPCby(backEnd, ((sqInt)mcpc), -(callDelta - ((targetMethod->objectHeader)))); - - /* See comment in planCompaction */ - restorePICUsageCount(targetMethod); - return 0; - } - unlinkedRoutine = sendTable1[((((targetMethod->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod->cmNumArgs)) : (NumSendTrampolines - 1))]; - unlinkedRoutine -= callDelta; - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod->selector), enumeratingCogMethod), unlinkedRoutine); - return 0; - } - if (annotation == IsRelativeCall) { - relocateCallBeforeReturnPCby(backEnd, ((sqInt)mcpc), -callDelta); - return 0; - } - if (annotation == IsAbsPCReference) { - relocateMethodReferenceBeforeAddressby(backEnd, ((sqInt)mcpc), refDelta); - } - return 0; -} - - -/* to placate the C static type system... */ - - /* Cogit>>#remapIfObjectRef:pc:hasYoung: */ -static sqInt NoDbgRegParms -remapIfObjectRefpchasYoung(sqInt annotation, char *mcpc, CogMethod *hasYoungPtr) -{ - usqInt cacheTag1; - usqInt entryPoint1; - usqInt literal; - sqInt mappedCacheTag; - sqInt mappedLiteral; - sqInt offset1; - sqInt *sendTable1; - sqInt tagCouldBeObj1; - CogMethod *targetMethod1; - - if (annotation == IsObjectReference) { - literal = literalBeforeFollowingAddress(backEnd, ((usqInt)mcpc)); - if (couldBeObject(literal)) { - mappedLiteral = remapObject(literal); - if (literal != mappedLiteral) { - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - storeLiteralbeforeFollowingAddress(backEnd, mappedLiteral, ((usqInt)mcpc)); - } - if ((hasYoungPtr != 0) - && (isYoung(mappedLiteral))) { - (*((sqInt *) hasYoungPtr) = 1); - } - } - } - if (annotation >= IsSendCall) { - /* begin entryCacheTagAndCouldBeObjectAt:annotation:into: */ - cacheTag1 = inlineCacheTagAt(backEnd, ((sqInt)mcpc)); - - /* in-line cache tags are the selectors of sends if sends are unlinked, - the selectors of super sends (entry offset = cmNoCheckEntryOffset), - the selectors of open PIC sends (entry offset = cmEntryOffset, target is an Open PIC) - or in-line cache tags (classes, class indices, immediate bit patterns, etc). - Note that selectors can be immediate so there is no guarantee that they - are markable/remappable objects. */ - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - tagCouldBeObj1 = entryPointTagIsSelector(entryPoint1); - if (tagCouldBeObj1 - && (couldBeObject(cacheTag1))) { - mappedCacheTag = remapObject(cacheTag1); - if (cacheTag1 != mappedCacheTag) { - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheTagat(backEnd, mappedCacheTag, ((usqInt)mcpc)); - } - if ((hasYoungPtr != 0) - && (isYoung(mappedCacheTag))) { - (*((sqInt *) hasYoungPtr) = 1); - } - } - if (hasYoungPtr != 0) { - - /* Since the unlinking routines may rewrite the cacheTag to the send's selector, and - since they don't have the cogMethod to hand and can't add it to youngReferrers, - the method must remain in youngReferrers if the targetMethod's selector is young. */ - if (entryPoint1 > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint1 - offset1)); - if (isYoung((targetMethod1->selector))) { - (*((sqInt *) hasYoungPtr) = 1); - } - } - } - } - return 0; -} - - -/* Remap a potential object reference from a closed PIC. - This may be an object reference, an inline cache tag or null. - Answer if the updated literal is young. - mcpc is the address of the next instruction following either - the load of the method literal or the compare of the class tag. */ - - /* Cogit>>#remapMaybeObjRefInClosedPICAt: */ -static sqInt NoDbgRegParms -remapMaybeObjRefInClosedPICAt(sqInt mcpc) -{ - usqInt object; - sqInt subject; - - object = literalBeforeFollowingAddress(backEnd, mcpc); - if (!(couldBeObject(object))) { - return 0; - } - subject = remapOop(object); - if (object != subject) { - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - storeLiteralbeforeFollowingAddress(backEnd, subject, mcpc); - } - return isYoungObject(subject); -} - - -/* Rewrite the three values involved in a CPIC case. Used by the initialize & - extend CPICs. - c.f. expectedClosedPICPrototype: */ -/* write the obj ref/operand via the second ldr */ - - /* Cogit>>#rewriteCPICCaseAt:tag:objRef:target: */ -static void NoDbgRegParms -rewriteCPICCaseAttagobjReftarget(sqInt followingAddress, sqInt newTag, sqInt newObjRef, sqInt newTarget) -{ - sqInt classTagPC; - sqInt methodObjPC; - - methodObjPC = (followingAddress - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */; - storeLiteralbeforeFollowingAddress(backEnd, newObjRef, methodObjPC); - - /* rewite the tag via the first ldr */ - classTagPC = followingAddress - 16 /* jumpLongConditionalByteSize */; - /* begin storeLiteral32:beforeFollowingAddress: */ - storeLiteralbeforeFollowingAddress(((AbstractInstruction *) backEnd), newTag, classTagPC); - rewriteConditionalJumpLongAttarget(backEnd, followingAddress, newTarget); -} - - -/* destReg := fromReg - subReg */ - - /* Cogit>>#SubR:R:R: */ -static AbstractInstruction * NoDbgRegParms -gSubRRR(sqInt subReg, sqInt fromReg, sqInt destReg) -{ - AbstractInstruction * first; - - return genoperandoperandoperand(SubRRR, subReg, fromReg, destReg); - assert(subReg != destReg); - first = genoperandoperand(MoveRR, fromReg, destReg); - genoperandoperand(SubRR, subReg, destReg); - return first; -} - - -/* Answer the number of clean blocks found in the literal frame */ - - /* Cogit>>#scanForCleanBlocks */ -static sqInt -scanForCleanBlocks(void) -{ - sqInt i; - sqInt iLimiT; - sqInt lit; - sqInt numCleanBlocks; - sqInt startPCOrNil; - - numCleanBlocks = 0; - for (i = 1, iLimiT = (literalCountOf(methodObj)); i <= iLimiT; i += 1) { - lit = fetchPointerofObject(i, methodObj); - startPCOrNil = startPCOrNilOfLiteralin(lit, methodObj); - if (!(startPCOrNil == null)) { - numCleanBlocks += 1; - } - } - return numCleanBlocks; -} - - /* Cogit>>#setBreakMethod: */ -void -setBreakMethod(sqInt anObj) -{ - breakMethod = anObj; -} - - -/* If a method is compiled to machine code via a block entry it won't have a - selector. A subsequent send can find the method and hence fill in the - selector. - */ -/* self disassembleMethod: cogMethod */ - - /* Cogit>>#setSelectorOf:to: */ -void -setSelectorOfto(CogMethod *cogMethod, sqInt aSelectorOop) -{ - compilationBreakpointisMNUCase(aSelectorOop, 0); - assert(((cogMethod->cmType)) == CMMethod); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - ((((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)))->selector = aSelectorOop); - if (isYoung(aSelectorOop)) { - ensureInYoungReferrers(cogMethod); - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - /* Cogit>>#spanForCleanBlockStartingAt: */ -static sqInt NoDbgRegParms -spanForCleanBlockStartingAt(sqInt startPC) -{ - BytecodeDescriptor *descriptor; - sqInt end; - sqInt pc; - - pc = startPC; - end = numBytesOf(methodObj); - while (pc <= end) { - /* begin generatorForPC: */ - descriptor = generatorAt(bytecodeSetOffset + (fetchByteofObject(pc, methodObj))); - pc += (descriptor->numBytes); - if ((descriptor->isReturn)) { - return pc - startPC; - } - } - error("couldn't locate end of clean block"); - return 0; -} - - /* Cogit>>#stackCheckOffsetOfBlockAt:isMcpc: */ -static usqInt NoDbgRegParms -stackCheckOffsetOfBlockAtisMcpc(sqInt blockEntryMcpc, sqInt mcpc) -{ - CogBlockMethod *cogBlockMethod; - - cogBlockMethod = ((CogBlockMethod *) (blockEntryMcpc - (sizeof(CogBlockMethod)))); - if (((((sqInt)cogBlockMethod)) + ((cogBlockMethod->stackCheckOffset))) == mcpc) { - return ((usqInt)cogBlockMethod); - } - return 0; -} - - -/* Answer a fake value for the method oop in other than the first case in the - PIC prototype. - Since we use MoveUniqueCw:R: it must not be confused with a - method-relative address. - */ - - /* Cogit>>#subsequentPrototypeMethodOop */ -static sqInt -subsequentPrototypeMethodOop(void) -{ - return (addressIsInCurrentCompilation(0xBADA550) - ? 0xDEADEAD - : 0xBADA550); -} - - /* Cogit>>#traceLinkedSendOffset */ -sqInt -traceLinkedSendOffset(void) -{ - return (cmNoCheckEntryOffset + (callFullInstructionByteSize(backEnd))) + (8 /* pushLinkRegisterByteSize */); -} - - -/* Encode true and false and 0 to N such that they can't be confused for - register numbers (including NoReg) - and can be tested for by isTrampolineArgConstant: and decoded by - trampolineArgValue: - */ - - /* Cogit>>#trampolineArgConstant: */ -static sqInt NoDbgRegParms -trampolineArgConstant(sqInt booleanOrInteger) -{ - assert(booleanOrInteger >= 0); - return -2 - booleanOrInteger; -} - - /* Cogit>>#trampolineName:numArgs: */ -static char * NoDbgRegParms -trampolineNamenumArgs(char *routinePrefix, sqInt numArgs) -{ - char *theString; - - /* begin trampolineName:numArgs:limit: */ - theString = malloc((strlen(routinePrefix)) + 6); - sprintf(theString, "%s%cArgs", routinePrefix, (numArgs <= (NumSendTrampolines - 2) - ? '0' + numArgs - : 'N')); - return theString; -} - - -/* Malloc a string with the contents for the trampoline table */ - - /* Cogit>>#trampolineName:numArgs:limit: */ -static char * NoDbgRegParms -trampolineNamenumArgslimit(char *routinePrefix, int numArgs, sqInt argsLimit) -{ - char *theString; - - theString = malloc((strlen(routinePrefix)) + 6); - sprintf(theString, "%s%cArgs", routinePrefix, (numArgs <= argsLimit - ? '0' + numArgs - : 'N')); - return theString; -} - - /* Cogit>>#trampolineName:numRegArgs: */ -static char * NoDbgRegParms -trampolineNamenumRegArgs(char *routinePrefix, sqInt numArgs) -{ - sqInt argsLimit; - char *theString; - - /* begin trampolineName:numArgs:limit: */ - argsLimit = 2 /* numRegArgs */; - theString = malloc((strlen(routinePrefix)) + 6); - sprintf(theString, "%s%cArgs", routinePrefix, (numArgs <= argsLimit - ? '0' + numArgs - : 'N')); - return theString; -} - - /* Cogit>>#unknownBytecode */ -static sqInt -unknownBytecode(void) -{ - return EncounteredUnknownBytecode; -} - - -/* Unlink all sends in cog methods. */ - - /* Cogit>>#unlinkAllSends */ -void -unlinkAllSends(void) -{ - sqInt annotation; - CogMethod *cogMethod; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - - if (!methodZoneBase) { - return; - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - cogMethod = ((CogMethod *) methodZoneBase); - voidOpenPICList(); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfLinkedSendpcignored(annotation, (((char *) mcpc)), 0); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - else { - if (((cogMethod->cmType)) != CMFree) { - freeMethod(cogMethod); - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); -} - - -/* To placate the C static type system... */ - - /* Cogit>>#unlinkIfFreeOrLinkedSend:pc:of: */ -static sqInt NoDbgRegParms -unlinkIfFreeOrLinkedSendpcof(sqInt annotation, char *mcpc, CogMethod *theSelector) -{ - sqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if ((((targetMethod1->cmType)) == CMFree) - || (((targetMethod1->selector)) == (((sqInt) theSelector)))) { - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - } - return 0; -} - - /* Cogit>>#unlinkIfInvalidClassSend:pc:ignored: */ -static sqInt NoDbgRegParms -unlinkIfInvalidClassSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity) -{ - usqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send, but maybe a super send or linked to an OpenPIC, in which case the cache tag will be a selector.... */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (!(((annotation == IsSuperSend) - || (((annotation >= IsDirectedSuperSend) && (annotation <= IsDirectedSuperBindingSend)))) - || (((targetMethod1->cmType)) == CMOpenPIC))) { - if (!(isValidClassTag(inlineCacheTagAt(backEnd, ((sqInt)mcpc))))) { - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - } - } - return 0; -} - - /* Cogit>>#unlinkIfLinkedSendToFree:pc:ignored: */ -static sqInt NoDbgRegParms -unlinkIfLinkedSendToFreepcignored(sqInt annotation, char *mcpc, sqInt superfluity) -{ - sqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (((targetMethod1->cmType)) == CMFree) { - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - } - return 0; -} - - -/* To placate the C static type system... */ - - /* Cogit>>#unlinkIfLinkedSend:pc:if: */ -static sqInt NoDbgRegParms -unlinkIfLinkedSendpcif(sqInt annotation, char *mcpc, CogMethod *criterionArg) -{ - sqInt (*criterion)(CogMethod *); - sqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - criterion = ((void *)criterionArg); - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (criterion(targetMethod1)) { - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - } - return 0; -} - - /* Cogit>>#unlinkIfLinkedSend:pc:ignored: */ -static sqInt NoDbgRegParms -unlinkIfLinkedSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity) -{ - usqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - return 0; -} - - /* Cogit>>#unlinkIfLinkedSend:pc:to: */ -static sqInt NoDbgRegParms -unlinkIfLinkedSendpcto(sqInt annotation, char *mcpc, sqInt theCogMethod) -{ - sqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if ((((sqInt)targetMethod1)) == theCogMethod) { - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - } - return 0; -} - - -/* Unlink all sends in cog methods whose class tag is that of a forwarded - class. - */ - - /* Cogit>>#unlinkSendsLinkedForInvalidClasses */ -void -unlinkSendsLinkedForInvalidClasses(void) -{ - sqInt annotation; - CogMethod *cogMethod; - sqInt freedPIC; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - - if (!methodZoneBase) { - return; - } - cogMethod = ((CogMethod *) methodZoneBase); - codeModified = (freedPIC = 0); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfInvalidClassSendpcignored(annotation, (((char *) mcpc)), 0); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - else { - if ((((cogMethod->cmType)) == CMClosedPIC) - && (cPICHasForwardedClass(cogMethod))) { - freeMethod(cogMethod); - freedPIC = 1; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (freedPIC) { - unlinkSendsToFree(); - } - else { - if (codeModified) { - - /* After possibly updating inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } - } -} - - -/* Unlink all sends in cog methods. Free all Closed PICs with the selector, - or with an MNU case if isMNUSelector. First check if any method actually - has the selector; if not there can't be any linked send to it. This - routine (including descendents) is performance critical. It contributes - perhaps 30% of entire execution time in Compiler recompileAll. */ - - /* Cogit>>#unlinkSendsOf:isMNUSelector: */ -void -unlinkSendsOfisMNUSelector(sqInt selector, sqInt isMNUSelector) -{ - sqInt annotation; - CogMethod *cogMethod; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt mustScanAndUnlink; - sqInt result; - - if (!methodZoneBase) { - return; - } - cogMethod = ((CogMethod *) methodZoneBase); - mustScanAndUnlink = 0; - if (isMNUSelector) { - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - if (((cogMethod->cpicHasMNUCaseOrCMIsFullBlock)) - && (((cogMethod->cmType)) == CMClosedPIC)) { - assert(((cogMethod->cmType)) == CMClosedPIC); - freeMethod(cogMethod); - mustScanAndUnlink = 1; - } - else { - if (((cogMethod->selector)) == selector) { - mustScanAndUnlink = 1; - if (((cogMethod->cmType)) == CMClosedPIC) { - freeMethod(cogMethod); - } - } - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - } - else { - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) != CMFree) - && (((cogMethod->selector)) == selector)) { - mustScanAndUnlink = 1; - if (((cogMethod->cmType)) == CMClosedPIC) { - freeMethod(cogMethod); - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - } - if (!mustScanAndUnlink) { - return; - } - codeModified = 0; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfFreeOrLinkedSendpcof(annotation, (((char *) mcpc)), (((CogMethod *) selector))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (codeModified) { - - /* After possibly updating inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - -/* Unlink all sends in cog methods to free methods and/or pics. */ - - /* Cogit>>#unlinkSendsToFree */ -void -unlinkSendsToFree(void) -{ - sqInt annotation; - CogMethod *cogMethod; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - - if (!methodZoneBase) { - return; - } - codeModified = 0; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfLinkedSendToFreepcignored(annotation, (((char *) mcpc)), 0); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - else { - if (((cogMethod->cmType)) == CMClosedPIC) { - assert(noTargetsFreeInClosedPIC(cogMethod)); - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (codeModified) { - - /* After possibly updating inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } -} - - -/* Unlink all sends in cog methods to methods with a machine code - primitive, and free machine code primitive methods if freeIfTrue. - To avoid having to scan PICs, free any and all PICs */ - - /* Cogit>>#unlinkSendsToMethodsSuchThat:AndFreeIf: */ -void -unlinkSendsToMethodsSuchThatAndFreeIf(sqInt (*criterion)(CogMethod *), sqInt freeIfTrue) -{ - sqInt annotation; - CogMethod *cogMethod; - sqInt freedSomething; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - - if (!methodZoneBase) { - return; - } - codeModified = (freedSomething = 0); - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - if (freeIfTrue - && (criterion(cogMethod))) { - freeMethod(cogMethod); - freedSomething = 1; - } - else { - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfLinkedSendpcif(annotation, (((char *) mcpc)), (((CogMethod *) criterion))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - } - else { - if (((cogMethod->cmType)) == CMClosedPIC) { - freeMethod(cogMethod); - freedSomething = 1; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (freedSomething) { - unlinkSendsToFree(); - } - else { - if (codeModified) { - - /* After possibly updating inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } - } -} - - -/* Unlink all sends in cog methods to a particular target method. - If targetMethodObject isn't actually a method (perhaps being - used via invokeAsMethod) then there's nothing to do. */ - - /* Cogit>>#unlinkSendsTo:andFreeIf: */ -void -unlinkSendsToandFreeIf(sqInt targetMethodObject, sqInt freeIfTrue) -{ - sqInt annotation; - CogMethod *cogMethod; - sqInt freedPIC; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - CogMethod *targetMethod; - - if (!((isOopCompiledMethod(targetMethodObject)) - && (methodHasCogMethod(targetMethodObject)))) { - return; - } - targetMethod = cogMethodOf(targetMethodObject); - if (!methodZoneBase) { - return; - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - codeModified = (freedPIC = 0); - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfLinkedSendpcto(annotation, (((char *) mcpc)), targetMethod); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - else { - if ((((cogMethod->cmType)) == CMClosedPIC) - && (cPICHasTarget(cogMethod, targetMethod))) { - freeMethod(cogMethod); - freedPIC = 1; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (freeIfTrue) { - freeMethod(targetMethod); - } - if (freedPIC) { - unlinkSendsToFree(); - } - else { - if (codeModified) { - - /* After possibly updating inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - /* Cogit>>#voidCogCompiledCode */ -void -voidCogCompiledCode(void) -{ - CogMethod *cogMethod; - - /* begin clearCogCompiledCode */ - cogMethod = ((CogMethod *) baseAddress); - while ((((usqInt)cogMethod)) < mzFreeStart) { - if (((cogMethod->cmType)) == CMMethod) { - freeMethod(cogMethod); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - /* begin manageFrom:to: */ - mzFreeStart = (/* baseAddress = */ baseAddress); - youngReferrers = (/* limitAddress = */ limitAddress); - openPICList = null; - methodBytesFreedSinceLastCompaction = 0; - methodCount = 0; - /* begin computeAllocationThreshold */ - allocationThreshold = ((((((usqInt)((limitAddress - baseAddress) * thresholdRatio))) + (7)) & ~7)) + baseAddress; - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - -/* Access for the object representations when they need to prepend code to - trampolines. - */ -/* Eliminate stale dependent info. */ - - /* Cogit>>#zeroOpcodeIndex */ -static void -zeroOpcodeIndex(void) -{ - sqInt i; - - for (i = 0; i < opcodeIndex; i += 1) { - ((abstractOpcodes[i]).dependent = null); - } - zeroOpcodeIndexForNewOpcodes(); -} - - -/* Access for the object representations when they need to prepend code to - trampolines. - */ - - /* Cogit>>#zeroOpcodeIndexForNewOpcodes */ -static void -zeroOpcodeIndexForNewOpcodes(void) -{ - opcodeIndex = 0; -} - - /* CogMethodZone>>#addToOpenPICList: */ -static void NoDbgRegParms -addToOpenPICList(CogMethod *anOpenPIC) -{ - assert(((anOpenPIC->cmType)) == CMOpenPIC); - assert((openPICList == null) - || (((openPICList->cmType)) == CMOpenPIC)); - assertValidDualZoneWriteAddress(anOpenPIC); - (anOpenPIC->nextOpenPIC = ((usqInt)openPICList)); - openPICList = ((CogMethod *) ((((usqInt)anOpenPIC)) - (getCodeToDataDelta()))); -} - - /* CogMethodZone>>#addToYoungReferrers: */ -static void NoDbgRegParms -addToYoungReferrers(CogMethod *cogMethod) -{ - assertValidDualZoneWriteAddress(cogMethod); - assert((occurrencesInYoungReferrers(cogMethod)) == 0); - assert((cogMethod->cmRefersToYoung)); - assert((youngReferrers <= limitAddress) - && (youngReferrers >= (limitAddress - (methodCount * BytesPerWord)))); - if (!(asserta((limitAddress - (methodCount * BytesPerWord)) >= mzFreeStart))) { - error("no room on youngReferrers list"); - } - youngReferrers -= BytesPerWord; - codeLongAtput(youngReferrers, (((usqInt)cogMethod)) - (getCodeToDataDelta())); -} - - /* CogMethodZone>>#allocate: */ -static usqInt NoDbgRegParms -allocate(sqInt numBytes) -{ - usqInt allocation; - sqInt roundedBytes; - - roundedBytes = (numBytes + 7) & -8; - if ((mzFreeStart + roundedBytes) >= ((((limitAddress - (methodCount * BytesPerWord)) < allocationThreshold) ? (limitAddress - (methodCount * BytesPerWord)) : allocationThreshold))) { - return 0; - } - allocation = mzFreeStart; - mzFreeStart += roundedBytes; - methodCount += 1; - return allocation; -} - - -/* Answer the method containing mcpc for the purposes of code zone - compaction, where mcpc is actually the value of instructionPointer at the - time of a compaction. */ - - /* CogMethodZone>>#cogMethodContaining: */ -CogMethod * -cogMethodContaining(usqInt mcpc) -{ - CogMethod * cogMethod; - CogMethod * prevMethod; - - if (mcpc > limitAddress) { - return null; - } - if (mcpc < baseAddress) { - /* begin assertMcpcIsPrimReturn: */ - assert((mcpc == cePrimReturnEnterCogCode) - || (mcpc == cePrimReturnEnterCogCodeProfiling)); - return null; - } - assert(mcpc < (freeStart())); - cogMethod = ((CogMethod *) baseAddress); - while ((((usqInt)cogMethod)) < mcpc) { - prevMethod = cogMethod; - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - assert((prevMethod != null) - && ((mcpc == ((((usqInt)prevMethod)) + ((prevMethod->stackCheckOffset)))) - || ((mcpcisAtStackCheckOfBlockMethodIn(mcpc, prevMethod)) - || (((primitiveIndexOfMethodheader((prevMethod->methodObject), (prevMethod->methodHeader))) > 0) - || ((isCallPrecedingReturnPC(backEnd(), mcpc)) - && ((callTargetFromReturnAddress(backEnd(), mcpc)) == (ceCheckForInterruptTrampoline()))))))); - return prevMethod; -} - - /* CogMethodZone>>#compactCompiledCode */ -static void -compactCompiledCode(void) -{ - unsigned short bytes; - CogMethod *dest; - sqLong objectHeaderValue; - CogMethod *source; - CogMethod * writableVersion; - - compactionInProgress = 1; - methodCount = 0; - objectHeaderValue = nullHeaderForMachineCodeMethod(); - source = ((CogMethod *) baseAddress); - voidOpenPICList(); - voidUnpairedMethodList(); - while ((source < (limitZony())) - && (((source->cmType)) != CMFree)) { - assert((cogMethodDoesntLookKosher(source)) == 0); - /* begin writableMethodFor: */ - writableVersion = ((CogMethod *) ((((usqInt)source)) + codeToDataDelta)); - (writableVersion->objectHeader = objectHeaderValue); - if (((source->cmUsageCount)) > 0) { - (writableVersion->cmUsageCount = ((source->cmUsageCount)) / 2); - } - /* begin maybeLinkOnUnpairedMethodList: */ - /* begin clearSavedPICUsageCount: */ - if (((writableVersion->cmType)) == CMClosedPIC) { - (writableVersion->blockEntryOffset = 0); - } - if (((source->cmType)) == CMOpenPIC) { - addToOpenPICList(writableVersion); - } - methodCount += 1; - source = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)source)) + ((source->blockSize))))); - } - if (source >= (limitZony())) { - haltmsg("no free methods; cannot compact."); - return; - } - dest = source; - while (source < (limitZony())) { - assert((maybeFreeCogMethodDoesntLookKosher(source)) == 0); - bytes = (source->blockSize); - if (((source->cmType)) != CMFree) { - methodCount += 1; - codeMemmove(dest, source, bytes); - /* begin maybeFlushWritableZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - if (codeToDataDelta > 0) { - flushDCacheFromto(backEnd, ((usqInt)dest), (((usqInt)dest)) + bytes); - } -# endif - ((writableVersion = ((CogMethod *) ((((usqInt)dest)) + codeToDataDelta)))->objectHeader = objectHeaderValue); - if (((dest->cmType)) == CMMethod) { - - /* For non-Newspeak there should be a one-to-one mapping between bytecoded and - cog methods. For Newspeak not necessarily, but only for anonymous accessors. */ - /* Only update the original method's header if it is referring to this CogMethod. */ - if ((((sqInt)(rawHeaderOf((dest->methodObject))))) == (((sqInt)source))) { - rawHeaderOfput((dest->methodObject), ((sqInt)dest)); - } - else { - assert((noAssertMethodClassAssociationOf((dest->methodObject))) == (nilObject())); - /* begin linkOnUnpairedMethodList: */ - } - } - else { - /* begin clearSavedPICUsageCount: */ - if (((writableVersion->cmType)) == CMClosedPIC) { - (writableVersion->blockEntryOffset = 0); - } - if (((dest->cmType)) == CMOpenPIC) { - addToOpenPICList(writableVersion); - } - } - if (((dest->cmUsageCount)) > 0) { - (writableVersion->cmUsageCount = ((dest->cmUsageCount)) / 2); - } - /* begin maybeFlushWritableZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - if (codeToDataDelta > 0) { - flushDCacheFromto(backEnd, ((usqInt)dest), ((usqInt)(dest + 1))); - } -# endif - dest = ((CogMethod *) ((((usqInt)dest)) + bytes)); - } - source = ((CogMethod *) ((((usqInt)source)) + bytes)); - } - mzFreeStart = ((usqInt)dest); - methodBytesFreedSinceLastCompaction = 0; - compactionInProgress = 0; -} - - /* CogMethodZone>>#ensureInYoungReferrers: */ -static void NoDbgRegParms -ensureInYoungReferrers(CogMethod *cogMethod) -{ - CogMethod * writableMethod; - - assertValidDualZoneReadAddress(cogMethod); - if (!((cogMethod->cmRefersToYoung))) { - assert((occurrencesInYoungReferrers(cogMethod)) == 0); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - ((writableMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)))->cmRefersToYoung = 1); - addToYoungReferrers(writableMethod); - } -} - - /* CogMethodZone>>#followForwardedLiteralsInOpenPICList */ -static void -followForwardedLiteralsInOpenPICList(void) -{ - CogMethod *openPIC; - - openPIC = openPICList; - while (openPIC != null) { - followForwardedLiteralsIn(openPIC); - openPIC = ((CogMethod *) ((openPIC->nextOpenPIC))); - } - pruneYoungReferrers(); -} - - /* CogMethodZone>>#freeMethod: */ -static void NoDbgRegParms -freeMethod(CogMethod *cogMethod) -{ - usqInt theCounters; - CogMethod * writableMethod; - - assert(((cogMethod->cmType)) != CMFree); - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - if (((cogMethod->cmType)) == CMMethod) { - - /* For non-Newspeak there should be a one-to-one mapping between bytecoded and - cog methods. For Newspeak not necessarily, but only for anonymous accessors. */ - /* Only reset the original method's header if it is referring to this CogMethod. */ - if ((((sqInt)(rawHeaderOf((cogMethod->methodObject))))) == (((sqInt)cogMethod))) { - rawHeaderOfput((cogMethod->methodObject), (cogMethod->methodHeader)); - } - else { - assert((noAssertMethodClassAssociationOf((cogMethod->methodObject))) == (nilObject())); - } - /* begin maybeFreeCountersOf: */ - theCounters = (cogMethod->counters); - if (theCounters != 0) { - freeObject(theCounters - BaseHeaderSize); - } - } - if (((cogMethod->cmType)) == CMOpenPIC) { - removeFromOpenPICList(cogMethod); - } - /* begin writableMethodFor: */ - writableMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - (writableMethod->cmRefersToYoung = 0); - (writableMethod->cmType = CMFree); - methodBytesFreedSinceLastCompaction += (cogMethod->blockSize); -} - - -/* Free methods, preferring older methods for compaction, up to some - fraction, currently a quarter. - */ - - /* CogMethodZone>>#freeOlderMethodsForCompaction */ -static void -freeOlderMethodsForCompaction(void) -{ - sqInt amountToFree; - CogMethod *cogMethod; - sqInt freeableUsage; - sqInt freedSoFar; - sqInt initialFreeSpace; - sqInt zoneSize; - - zoneSize = ((((limitAddress) < allocationThreshold) ? (limitAddress) : allocationThreshold)) - baseAddress; - initialFreeSpace = (((((limitAddress) < allocationThreshold) ? (limitAddress) : allocationThreshold)) - mzFreeStart) + methodBytesFreedSinceLastCompaction; - freedSoFar = initialFreeSpace; - - /* 4 needs to be e.g. a start-up parameter */ - amountToFree = zoneSize / 4; - freeableUsage = 0; - do { - cogMethod = ((CogMethod *) baseAddress); - while (((((usqInt)cogMethod)) < mzFreeStart) - && (freedSoFar < amountToFree)) { - if ((((cogMethod->cmType)) == CMMethod - ? ((cogMethod->cmUsageCount)) <= freeableUsage - : (((cogMethod->cmType)) != CMFree) - && (((cogMethod->cmUsageCount)) == 0))) { - freeMethod(cogMethod); - freedSoFar += (cogMethod->blockSize); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - } while((freedSoFar < amountToFree) - && (((freeableUsage += 1)) < CMMaxUsageCount)); -} - - -/* Answer that all entries in youngReferrers are in-use and have the - cmRefersToYoung flag set. - Used to check that the youngreferrers pruning routines work correctly. */ - - /* CogMethodZone>>#kosherYoungReferrers */ -sqInt -kosherYoungReferrers(void) -{ - CogMethod * cogMethod; - usqInt pointer; - CogMethod * prevMethod; - - if ((youngReferrers > limitAddress) - || (youngReferrers < mzFreeStart)) { - return 0; - } - pointer = youngReferrers; - while (pointer < limitAddress) { - cogMethod = ((CogMethod *) (longAt(pointer))); - if (((cogMethod->cmType)) != CMFree) { - if (!((cogMethod->cmRefersToYoung))) { - return 0; - } - if ((occurrencesInYoungReferrers(cogMethod)) != 1) { - return 0; - } - } - pointer += BytesPerWord; - } - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - prevMethod = cogMethod; - if (((cogMethod->cmType)) != CMFree) { - if ((occurrencesInYoungReferrers(cogMethod)) != (((cogMethod->cmRefersToYoung) - ? 1 - : 0))) { - return 0; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - if (cogMethod == prevMethod) { - return 0; - } - } - return 1; -} - - -/* For assert checking... */ - - /* CogMethodZone>>#mcpc:isAtStackCheckOfBlockMethodIn: */ -static sqInt NoDbgRegParms -mcpcisAtStackCheckOfBlockMethodIn(sqInt mcpc, CogMethod *cogMethod) -{ - if (((cogMethod->blockEntryOffset)) == 0) { - return 0; - } - return (blockDispatchTargetsForperformarg(cogMethod, stackCheckOffsetOfBlockAtisMcpc, mcpc)) != 0; -} - - /* CogMethodZone>>#methodFor: */ -CogMethod * -methodFor(void *address) -{ - CogMethod * cogMethod; - CogMethod * nextMethod; - - cogMethod = ((CogMethod *) baseAddress); - while ((cogMethod < (limitZony())) - && ((((usqInt)cogMethod)) <= (((usqInt)address)))) { - /* begin methodAfter: */ - nextMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - if (nextMethod == cogMethod) { - return null; - } - if (((((usqInt)address)) >= (((usqInt)cogMethod))) - && ((((usqInt)address)) < (((usqInt)nextMethod)))) { - return cogMethod; - } - cogMethod = nextMethod; - } - return null; -} - - /* CogMethodZone>>#methodsCompiledToMachineCodeInto: */ -sqInt -methodsCompiledToMachineCodeInto(sqInt arrayObj) -{ - CogMethod *cogMethod; - sqInt methodIndex; - - methodIndex = 0; - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - storePointerUncheckedofObjectwithValue(methodIndex, arrayObj, (cogMethod->methodObject)); - methodIndex += 1; - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return methodIndex; -} - - /* CogMethodZone>>#numMethods */ -sqInt -numMethods(void) -{ - return methodCount; -} - - /* CogMethodZone>>#numMethodsOfType: */ -sqInt -numMethodsOfType(sqInt cogMethodType) -{ - CogMethod *cogMethod; - sqInt n; - - n = 0; - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == cogMethodType) { - n += 1; - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return n; -} - - /* CogMethodZone>>#occurrencesInYoungReferrers: */ -static sqInt NoDbgRegParms -occurrencesInYoungReferrers(CogMethod *cogMethod) -{ - sqInt count; - usqInt pointer; - - assert(youngReferrers <= limitAddress); - count = 0; - pointer = youngReferrers; - while (pointer < limitAddress) { - if ((((sqInt)cogMethod)) == (longAt(pointer))) { - count += 1; - } - pointer += BytesPerWord; - } - return count; -} - - /* CogMethodZone>>#openPICWithSelector: */ -static CogMethod * NoDbgRegParms -openPICWithSelector(sqInt aSelector) -{ - CogMethod *openPIC; - - openPIC = openPICList; - do { - if ((openPIC == null) - || (((openPIC->selector)) == aSelector)) { - return openPIC; - } - openPIC = ((CogMethod *) ((openPIC->nextOpenPIC))); - } while(1); - return 0; -} - - -/* Some methods have been freed. Compute how much each survivor needs to - move during the ensuing compaction and record it in the objectHeader - field. - For Sista, where we want PICs to last so they can be observed, we need to - keep PICs unless - they are definitely unused. So we need to identify unused PICs. So in - planCompact, zero the - usage counts of all PICs, saving the actual usage count in - blockEntryOffset. Then in - relocateMethodsPreCompaction (actually in - relocateIfCallOrMethodReference:mcpc:delta:) restore the usage counts of - used PICs. Finally in compactCompiledCode, clear the blockEntryOffset - of the unused PICs; they will then have a zero count and be reclaimed in - the next code compaction. */ - - /* CogMethodZone>>#planCompaction */ -static void -planCompaction(void) -{ - CogMethod *cogMethod; - sqInt delta; - - delta = 0; - cogMethod = ((CogMethod *) baseAddress); - while ((((usqInt)cogMethod)) < mzFreeStart) { - if (((cogMethod->cmType)) == CMFree) { - delta -= (cogMethod->blockSize); - } - else { - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - ((((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)))->objectHeader = delta); - savePICUsageCount(cogMethod); - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* CogMethodZone>>#printCogMethods */ -void -printCogMethods(void) -{ - CogMethod *cogMethod; - sqInt nc; - sqInt nf; - sqInt nm; - sqInt no; - sqInt nu; - - /* begin printCogMethodsSummarizing: */ - nm = (nc = (no = (nf = (nu = 0)))); - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - printCogMethod(cogMethod); - switch ((cogMethod->cmType)) { - case CMFree: - nf += 1; - break; - case CMMethod: - nm += 1; - break; - case CMClosedPIC: - nc += 1; - break; - case CMOpenPIC: - no += 1; - break; - default: - nu += 1; - - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - print("CMMethod "); - printNum(nm); - print(" CMClosedPIC "); - printNum(nc); - print(" CMOpenPIC "); - printNum(no); - print(" CMFree "); - printNum(nf); - if (nu > 0) { - print(" UNKNOWN "); - printNum(nu); - } - print(" total "); - printNum((((nm + nc) + no) + nf) + nu); - cr(); -} - - /* CogMethodZone>>#printCogMethodsOfType: */ -void -printCogMethodsOfType(sqInt cmType) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == cmType) { - printCogMethod(cogMethod); - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* CogMethodZone>>#printCogMethodsWithMethod: */ -void -printCogMethodsWithMethod(sqInt methodOop) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) != CMFree) - && (((cogMethod->methodObject)) == methodOop)) { - printCogMethod(cogMethod); - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* CogMethodZone>>#printCogMethodsWithPrimitive: */ -void -printCogMethodsWithPrimitive(sqInt primIdx) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) == CMMethod) - && (primIdx == (primitiveIndexOfMethodheader((cogMethod->methodObject), (cogMethod->methodHeader))))) { - printCogMethod(cogMethod); - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* CogMethodZone>>#printCogMethodsWithSelector: */ -void -printCogMethodsWithSelector(sqInt selectorOop) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) != CMFree) - && (((cogMethod->selector)) == selectorOop)) { - printCogMethod(cogMethod); - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* CogMethodZone>>#printCogYoungReferrers */ -void -printCogYoungReferrers(void) -{ - CogMethod *cogMethod; - usqInt pointer; - - pointer = youngReferrers; - while (pointer < limitAddress) { - cogMethod = ((CogMethod *) (longAt(pointer))); - if (!((cogMethod->cmRefersToYoung))) { - print("*"); - } - if (((cogMethod->cmType)) == CMFree) { - print("!"); - } - if (!(((cogMethod->cmRefersToYoung)) - && (((cogMethod->cmType)) != CMFree))) { - print(" "); - } - printCogMethod(cogMethod); - pointer += BytesPerWord; - } -} - - /* CogMethodZone>>#printOpenPICList */ -sqInt -printOpenPICList(void) -{ - sqInt n; - CogMethod *openPIC; - - /* begin printOpenPICListSummarizing: */ - n = 0; - openPIC = openPICList; - while (!(openPIC == null)) { - n += 1; - printCogMethod(openPIC); - openPIC = ((CogMethod *) ((openPIC->nextOpenPIC))); - } - return n; -} - - /* CogMethodZone>>#pruneYoungReferrers */ -sqInt -pruneYoungReferrers(void) -{ - usqInt dest; - usqInt next; - usqInt source; - - assert(youngReferrers <= limitAddress); - if (youngReferrers == limitAddress) { - return null; - } - dest = limitAddress; - while (1) { - next = dest - BytesPerWord; - if (!((next >= youngReferrers) - && (((((CogMethod *) (longAt(next))))->cmRefersToYoung)))) break; - dest = next; - } - assert(dest >= youngReferrers); - source = dest - BytesPerWord; - while (source >= youngReferrers) { - if (((((CogMethod *) (longAt(source))))->cmRefersToYoung)) { - assert(source < (dest - BytesPerWord)); - if (!(next == null)) { - - /* convenient first-time flag */ - next = null; - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - } - codeLongAtput((dest -= BytesPerWord), longAt(source)); - } - source -= BytesPerWord; - } - youngReferrers = dest; - assert(kosherYoungReferrers()); - return 0; -} - - /* CogMethodZone>>#relocateAndPruneYoungReferrers */ -static sqInt -relocateAndPruneYoungReferrers(void) -{ - CogMethod *cogMethod; - usqInt dest; - usqInt next; - usqInt source; - - assert(youngReferrers <= limitAddress); - if (youngReferrers == limitAddress) { - return null; - } - dest = limitAddress; - while (1) { - next = dest - BytesPerWord; - if (!((next >= youngReferrers) - && (((((cogMethod = ((CogMethod *) (longAt(next))))->cmType)) != CMFree) - && ((cogMethod->cmRefersToYoung))))) break; - if (((cogMethod->objectHeader)) != 0) { - codeLongAtput(next, (((sqInt)cogMethod)) + ((cogMethod->objectHeader))); - } - dest = next; - } - assert(dest >= youngReferrers); - source = dest - BytesPerWord; - while (source >= youngReferrers) { - cogMethod = ((CogMethod *) (longAt(source))); - if ((((cogMethod->cmType)) != CMFree) - && ((cogMethod->cmRefersToYoung))) { - assert(source < (dest - BytesPerWord)); - if (((cogMethod->objectHeader)) != 0) { - cogMethod = ((CogMethod *) ((((sqInt)cogMethod)) + (((sqInt)((cogMethod->objectHeader)))))); - } - codeLongAtput((dest -= BytesPerWord), ((sqInt)cogMethod)); - } - source -= BytesPerWord; - } - youngReferrers = dest; - return 0; -} - - -/* All surviving methods have had the amount they are going to relocate by - stored in their objectHeader fields. Relocate all relative calls so that - after the compaction of both the method containing each call and the call - target the calls invoke the same target. */ - - /* CogMethodZone>>#relocateMethodsPreCompaction */ -static sqInt -relocateMethodsPreCompaction(void) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) baseAddress); - while ((((usqInt)cogMethod)) < mzFreeStart) { - if (((cogMethod->cmType)) != CMFree) { - if (((cogMethod->cmType)) == CMClosedPIC) { - relocateCallsInClosedPIC(cogMethod); - } - else { - relocateCallsAndSelfReferencesInMethod(cogMethod); - } - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - relocateAndPruneYoungReferrers(); - return 1; -} - - /* CogMethodZone>>#removeFromOpenPICList: */ -static sqInt NoDbgRegParms -removeFromOpenPICList(CogMethod *anOpenPIC) -{ - CogMethod *prevPIC; - - assert(((anOpenPIC->cmType)) == CMOpenPIC); - if (!openPICList) { - return null; - } - assert((((openPICList->cmType)) == CMOpenPIC) - && ((((openPICList->nextOpenPIC)) == null) - || ((((((CogMethod *) ((openPICList->nextOpenPIC))))->cmType)) == CMOpenPIC))); - if (anOpenPIC == openPICList) { - - /* N.B. Use self rather than coInterpreter to avoid attempting to cast nil. - Conversion to CogMethod done in the nextOpenPIC accessor. */ - openPICList = ((CogMethod *) ((anOpenPIC->nextOpenPIC))); - return null; - } - prevPIC = openPICList; - do { - assert((prevPIC != null) - && (((prevPIC->cmType)) == CMOpenPIC)); - if (((prevPIC->nextOpenPIC)) == (((usqInt)anOpenPIC))) { - ((((CogMethod *) ((((usqInt)prevPIC)) + codeToDataDelta)))->nextOpenPIC = (anOpenPIC->nextOpenPIC)); - return null; - } - prevPIC = ((CogMethod *) ((prevPIC->nextOpenPIC))); - } while(1); - return 0; -} - - -/* For Sista, where we want PICs to last so they can be observed, we need to - keep PICs unless - they are definitely unused. So we need to identify unused PICs. So in - planCompact, zero the - usage counts of all PICs, saving the actual usage count in - blockEntryOffset. Then in - relocateMethodsPreCompaction (actually in - relocateIfCallOrMethodReference:mcpc:delta:) restore the usage counts of - used PICs. Finally in compactCompiledCode, clear the blockEntryOffset - of the unused PICs; they will then have a zero count and be reclaimed in - the next code compaction. */ - - /* CogMethodZone>>#restorePICUsageCount: */ -static void NoDbgRegParms -restorePICUsageCount(CogMethod *cogMethod) -{ - if ((((cogMethod->cmType)) == CMClosedPIC) - && (((cogMethod->blockEntryOffset)) != 0)) { - (cogMethod->cmUsageCount = (cogMethod->blockEntryOffset)); - (cogMethod->blockEntryOffset = 0); - } -} - - -/* Determine the default alignment for the start of a CogMethod, which in - turn determines the size of the mask used to distinguish the checked and - unchecked entry-points, used to distinguish normal and super sends on - method unlinking. - This is passed onto the backEnd to allow processors with coarse - instructions (ARM) to increase the alignment if required. */ - - /* CogMethodZone>>#roundUpLength: */ -static sqInt NoDbgRegParms -roundUpLength(sqInt numBytes) -{ - return roundUpToMethodAlignment(backEnd(), numBytes); -} - - -/* For Sista, where we want PICs to last so they can be observed, we need to - keep PICs unless - they are definitely unused. So we need to identify unused PICs. So in - planCompact, zero the - usage counts of all PICs, saving the actual usage count in - blockEntryOffset. Then in - relocateMethodsPreCompaction (actually in - relocateIfCallOrMethodReference:mcpc:delta:) restore the usage counts of - used PICs. Finally in compactCompiledCode, clear the blockEntryOffset - of the unused PICs; they will then have a zero count and be reclaimed in - the next code compaction. */ - - /* CogMethodZone>>#savePICUsageCount: */ -static void NoDbgRegParms -savePICUsageCount(CogMethod *cogMethod) -{ - if (((cogMethod->cmType)) == CMClosedPIC) { - (cogMethod->blockEntryOffset = (cogMethod->cmUsageCount)); - (cogMethod->cmUsageCount = 0); - } -} - - /* CogMethodZone>>#voidOpenPICList */ -static void -voidOpenPICList(void) -{ - openPICList = null; -} - - /* CogMethodZone>>#voidUnpairedMethodList */ -static void -voidUnpairedMethodList(void) -{ - } - - /* CogMethodZone>>#voidYoungReferrersPostTenureAll */ -static void -voidYoungReferrersPostTenureAll(void) -{ - CogMethod *cogMethod; - usqInt pointer; - - assert(youngReferrers <= limitAddress); - pointer = youngReferrers; - while (pointer < limitAddress) { - cogMethod = ((CogMethod *) (longAt(pointer))); - if (((cogMethod->cmType)) != CMFree) { - (cogMethod->cmRefersToYoung = 0); - } - pointer += BytesPerWord; - } - youngReferrers = limitAddress; -} - - -/* useful for VM debugging; use export: so it will be accessible on win32 */ - - /* CogMethodZone>>#whereIsMaybeCodeThing: */ -EXPORT(char *) -whereIsMaybeCodeThing(sqInt anOop) -{ - if (oopisGreaterThanOrEqualToandLessThan(anOop, codeBase, limitAddress)) { - if (oopisLessThan(anOop, minCogMethodAddress())) { - return " is in generated runtime"; - } - if (oopisLessThan(anOop, mzFreeStart)) { - return " is in generated methods"; - } - if (oopisLessThan(anOop, youngReferrers)) { - return " is in code zone"; - } - return " is in young referrers"; - } - return null; -} - - /* CogMIPSELCompiler>>#addiuR:R:C: */ -static sqInt NoDbgRegParms -addiuRRC(AbstractInstruction * self_in_addiuRRC, sqInt destReg, sqInt srcReg, sqInt imm) -{ - return itypersrtsignedImmediate(self_in_addiuRRC, ADDIU, srcReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#adduR:R:R: */ -static sqInt NoDbgRegParms -adduRRR(AbstractInstruction * self_in_adduRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_adduRRR, SPECIAL, leftReg, rightReg, destReg, 0, ADDU); -} - - /* CogMIPSELCompiler>>#andiR:R:C: */ -static sqInt NoDbgRegParms -andiRRC(AbstractInstruction * self_in_andiRRC, sqInt destReg, sqInt srcReg, sqInt imm) -{ - return itypersrteitherImmediate(self_in_andiRRC, ANDI, srcReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#andR:R:R: */ -static sqInt NoDbgRegParms -andRRR(AbstractInstruction * self_in_andRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_andRRR, SPECIAL, leftReg, rightReg, destReg, 0, AND); -} - - /* CogMIPSELCompiler>>#beqR:R:offset: */ -static sqInt NoDbgRegParms -beqRRoffset(AbstractInstruction * self_in_beqRRoffset, sqInt leftReg, sqInt rightReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_beqRRoffset, BEQ, leftReg, rightReg, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#bgezR:offset: */ -static sqInt NoDbgRegParms -bgezRoffset(AbstractInstruction * self_in_bgezRoffset, sqInt cmpReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_bgezRoffset, REGIMM, cmpReg, BGEZ, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#bgtzR:offset: */ -static sqInt NoDbgRegParms -bgtzRoffset(AbstractInstruction * self_in_bgtzRoffset, sqInt cmpReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_bgtzRoffset, BGTZ, cmpReg, 0, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#blezR:offset: */ -static sqInt NoDbgRegParms -blezRoffset(AbstractInstruction * self_in_blezRoffset, sqInt cmpReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_blezRoffset, BLEZ, cmpReg, 0, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#bltzR:offset: */ -static sqInt NoDbgRegParms -bltzRoffset(AbstractInstruction * self_in_bltzRoffset, sqInt cmpReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_bltzRoffset, REGIMM, cmpReg, BLTZ, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#bneR:R:offset: */ -static sqInt NoDbgRegParms -bneRRoffset(AbstractInstruction * self_in_bneRRoffset, sqInt leftReg, sqInt rightReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_bneRRoffset, BNE, leftReg, rightReg, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#callInstructionByteSize */ -static sqInt NoDbgRegParms -callInstructionByteSize(AbstractInstruction * self_in_callInstructionByteSize) -{ - flag("todo"); - return 16; -} - - -/* csra - 16: lui t9, high - csra - 12: ori t9, low - csra - 8: jalr t9 - csra - 4: nop (delay slot) */ - - /* CogMIPSELCompiler>>#callTargetFromReturnAddress: */ -static usqInt NoDbgRegParms -callTargetFromReturnAddress(AbstractInstruction * self_in_callTargetFromReturnAddress, sqInt callSiteReturnAddress) -{ - assert((opcodeAtAddress(self_in_callTargetFromReturnAddress, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_callTargetFromReturnAddress, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_callTargetFromReturnAddress, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_callTargetFromReturnAddress, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_callTargetFromReturnAddress))); - return literalAtAddress(self_in_callTargetFromReturnAddress, callSiteReturnAddress - 12); -} - - /* CogMIPSELCompiler>>#canDivQuoRem */ -static sqInt NoDbgRegParms -canDivQuoRem(AbstractInstruction * self_in_canDivQuoRem) -{ - return 1; -} - - -/* NOTE: the right reg (rt) MUST equal dest reg (rd) or behavior is undefined */ - - /* CogMIPSELCompiler>>#clzR:R:R: */ -static sqInt NoDbgRegParms -clzRRR(AbstractInstruction * self_in_clzRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_clzRRR, SPECIAL, leftReg, rightReg, destReg, 0, 32); -} - - /* CogMIPSELCompiler>>#cmpC32RTempByteSize */ -static sqInt NoDbgRegParms -cmpC32RTempByteSize(AbstractInstruction * self_in_cmpC32RTempByteSize) -{ - return 8; -} - - -/* Each MIPS instruction has 4 bytes. Many abstract opcodes need more than - one instruction. Instructions that refer to constants and/or literals - depend on literals - being stored in-line or out-of-line. - - N.B. The ^N forms are to get around the bytecode compiler's long branch - limits which are exceeded when each case jumps around the otherwise. */ - - /* CogMIPSELCompiler>>#computeMaximumSize */ -static sqInt NoDbgRegParms -computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize) -{ - switch ((self_in_computeMaximumSize->opcode)) { - case BrEqualRR: - case BrNotEqualRR: - case JumpR: - case Jump: - case JumpZero: - case JumpNonZero: - case JumpNegative: - case JumpNonNegative: - case JumpOverflow: - case JumpNoOverflow: - case JumpCarry: - case JumpNoCarry: - case JumpLess: - case JumpGreaterOrEqual: - case JumpGreater: - case JumpLessOrEqual: - case JumpBelow: - case JumpAboveOrEqual: - case JumpAbove: - case JumpBelowOrEqual: - case JumpFPEqual: - case JumpFPNotEqual: - case JumpFPLess: - case JumpFPGreaterOrEqual: - case JumpFPGreater: - case JumpFPLessOrEqual: - case JumpFPOrdered: - case JumpFPUnordered: - case RetN: - case MoveCwR: - case MoveXbrRR: - case MoveRXbrR: - case PopR: - case PushR: - case ConvertRRd: - return 8; - - case BrUnsignedLessRR: - case BrUnsignedLessEqualRR: - case BrUnsignedGreaterRR: - case BrUnsignedGreaterEqualRR: - case BrSignedLessRR: - case BrSignedLessEqualRR: - case BrSignedGreaterRR: - case BrSignedGreaterEqualRR: - case XorCqR: - case AddCwR: - case AndCwR: - case OrCwR: - case SubCwR: - case XorCwR: - case MoveXwrRR: - case MoveRXwrR: - case PrefetchAw: - return 12; - - case BrLongEqualRR: - case BrLongNotEqualRR: - case PushCw: - case PushCq: - return 16; - - case MulRR: - case DivRR: - case MoveLowR: - case MoveHighR: - case Literal: - case Fill32: - case Nop: - case Stop: - case AddRR: - case AndRR: - case OrRR: - case XorRR: - case SubRR: - case NegateR: - case AddRRR: - case SubRRR: - case LogicalShiftLeftCqR: - case LogicalShiftRightCqR: - case ArithmeticShiftRightCqR: - case LogicalShiftLeftRR: - case LogicalShiftRightRR: - case ArithmeticShiftRightRR: - case AddRdRd: - case CmpRdRd: - case SubRdRd: - case MulRdRd: - case DivRdRd: - case SqrtRd: - case ClzRR: - case MoveRR: - case MoveRdRd: - case MoveRMwr: - case MoveMbrR: - case MoveRMbr: - case MoveM16rR: - case MoveRM16r: - return 4; - - case Label: - return 0; - - case AlignmentNops: - return (((self_in_computeMaximumSize->operands))[0]) - 4; - - case Call: - case CallFull: - case JumpFull: - case JumpLong: - case JumpLongZero: - case JumpLongNonZero: - return 16; - - case AddCqR: - case OrCqR: - case OrCqRR: - case SubCqR: - case TstCqR: - case LoadEffectiveAddressMwrR: - return (isShortOffset(self_in_computeMaximumSize, ((self_in_computeMaximumSize->operands))[0]) - ? 4 - : 12); - - case AndCqR: - case AndCqRR: - return ((((((self_in_computeMaximumSize->operands))[0]) >= 0) && ((((self_in_computeMaximumSize->operands))[0]) <= 0xFFFF)) - ? 4 - : 12); - - case CmpCqR: - case CmpCwR: - case AddCheckOverflowCqR: - case SubCheckOverflowCqR: - return 28; - - case CmpRR: - case AddCheckOverflowRR: - case SubCheckOverflowRR: - case MulCheckOverflowRR: - return 20; - - case MoveCqR: - return (isShortOffset(self_in_computeMaximumSize, ((self_in_computeMaximumSize->operands))[0]) - ? 4 - : 8); - - case MoveAwR: - case MoveAbR: - return (((((self_in_computeMaximumSize->operands))[0]) != null) - && ((((varBaseAddress()) - (0x8000)) < (((self_in_computeMaximumSize->operands))[0])) - && ((((self_in_computeMaximumSize->operands))[0]) < ((varBaseAddress()) + (0x8000)))) - ? 4 - : 12); - - case MoveRAw: - case MoveRAb: - return (((((self_in_computeMaximumSize->operands))[1]) != null) - && ((((varBaseAddress()) - (0x8000)) < (((self_in_computeMaximumSize->operands))[1])) - && ((((self_in_computeMaximumSize->operands))[1]) < ((varBaseAddress()) + (0x8000)))) - ? 4 - : 12); - - case MoveRdM64r: - case MoveM64rRd: - return 12; - - case MoveMwrR: - return (isShortOffset(self_in_computeMaximumSize, ((self_in_computeMaximumSize->operands))[0]) - ? 4 - : 16); - - default: - error("Case not found and no otherwise clause"); - } - return 0; -} - - /* CogMIPSELCompiler>>#concretizeAddCheckOverflowCqR */ -static sqInt NoDbgRegParms -concretizeAddCheckOverflowCqR(AbstractInstruction * self_in_concretizeAddCheckOverflowCqR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - sqInt aWord4; - sqInt aWord5; - sqInt aWord6; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeAddCheckOverflowCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAddCheckOverflowCqR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeAddCheckOverflowCqR, AT, high16BitsOf(self_in_concretizeAddCheckOverflowCqR, rightImm)); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeAddCheckOverflowCqR, AT, AT, low16BitsOf(self_in_concretizeAddCheckOverflowCqR, rightImm)); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = adduRRR(self_in_concretizeAddCheckOverflowCqR, OverflowTemp1, leftReg, ZR); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = adduRRR(self_in_concretizeAddCheckOverflowCqR, destReg, leftReg, AT); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[12 / 4] = aWord3; - /* begin machineCodeAt:put: */ - aWord4 = xorRRR(self_in_concretizeAddCheckOverflowCqR, OverflowTemp2, destReg, AT); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[16 / 4] = aWord4; - /* begin machineCodeAt:put: */ - aWord5 = xorRRR(self_in_concretizeAddCheckOverflowCqR, OverflowTemp1, destReg, OverflowTemp1); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[20 / 4] = aWord5; - /* begin machineCodeAt:put: */ - aWord6 = andRRR(self_in_concretizeAddCheckOverflowCqR, Overflow, OverflowTemp1, OverflowTemp2); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[24 / 4] = aWord6; - return 28; -} - - /* CogMIPSELCompiler>>#concretizeAddCheckOverflowRR */ -static sqInt NoDbgRegParms -concretizeAddCheckOverflowRR(AbstractInstruction * self_in_concretizeAddCheckOverflowRR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - sqInt aWord4; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeAddCheckOverflowRR->operands))[0]; - - /* Save original LHS */ - destReg = (leftReg = ((self_in_concretizeAddCheckOverflowRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeAddCheckOverflowRR, OverflowTemp1, leftReg, ZR); - ((self_in_concretizeAddCheckOverflowRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = adduRRR(self_in_concretizeAddCheckOverflowRR, destReg, leftReg, rightReg); - ((self_in_concretizeAddCheckOverflowRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = xorRRR(self_in_concretizeAddCheckOverflowRR, OverflowTemp2, destReg, rightReg); - ((self_in_concretizeAddCheckOverflowRR->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = xorRRR(self_in_concretizeAddCheckOverflowRR, OverflowTemp1, destReg, OverflowTemp1); - ((self_in_concretizeAddCheckOverflowRR->machineCode))[12 / 4] = aWord3; - /* begin machineCodeAt:put: */ - aWord4 = andRRR(self_in_concretizeAddCheckOverflowRR, Overflow, OverflowTemp1, OverflowTemp2); - ((self_in_concretizeAddCheckOverflowRR->machineCode))[16 / 4] = aWord4; - return 20; -} - - /* CogMIPSELCompiler>>#concretizeAddCqR */ -static sqInt NoDbgRegParms -concretizeAddCqR(AbstractInstruction * self_in_concretizeAddCqR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeAddCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAddCqR->operands))[1]); - if (!(isShortOffset(self_in_concretizeAddCqR, rightImm))) { - return concretizeAddCwR(self_in_concretizeAddCqR); - } - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizeAddCqR, destReg, leftReg, rightImm); - ((self_in_concretizeAddCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeAddCwR */ -static sqInt NoDbgRegParms -concretizeAddCwR(AbstractInstruction * self_in_concretizeAddCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeAddCwR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAddCwR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeAddCwR, AT, high16BitsOf(self_in_concretizeAddCwR, rightImm)); - ((self_in_concretizeAddCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeAddCwR, AT, AT, low16BitsOf(self_in_concretizeAddCwR, rightImm)); - ((self_in_concretizeAddCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = adduRRR(self_in_concretizeAddCwR, destReg, leftReg, AT); - ((self_in_concretizeAddCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeAddRRDest: */ -static sqInt NoDbgRegParms -concretizeAddRRDest(AbstractInstruction * self_in_concretizeAddRRDest, sqInt destReg) -{ - sqInt aWord; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeAddRRDest->operands))[0]; - leftReg = ((self_in_concretizeAddRRDest->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeAddRRDest, destReg, leftReg, rightReg); - ((self_in_concretizeAddRRDest->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeAlignmentNops */ -static usqInt NoDbgRegParms -concretizeAlignmentNops(AbstractInstruction * self_in_concretizeAlignmentNops) -{ - sqInt p; - - assert((((self_in_concretizeAlignmentNops->machineCodeSize)) % 4) == 0); - for (p = 0; p < ((self_in_concretizeAlignmentNops->machineCodeSize)); p += 4) { - /* begin machineCodeAt:put: */ - ((self_in_concretizeAlignmentNops->machineCode))[p / 4] = 0 /* nop */; - } - return (self_in_concretizeAlignmentNops->machineCodeSize); -} - - /* CogMIPSELCompiler>>#concretizeAndCqR */ -static sqInt NoDbgRegParms -concretizeAndCqR(AbstractInstruction * self_in_concretizeAndCqR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeAndCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAndCqR->operands))[1]); - if (!(isShortOffset(self_in_concretizeAndCqR, rightImm))) { - return concretizeAndCwR(self_in_concretizeAndCqR); - } - /* begin machineCodeAt:put: */ - aWord = andiRRC(self_in_concretizeAndCqR, destReg, leftReg, rightImm); - ((self_in_concretizeAndCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeAndCqRDest: */ -static sqInt NoDbgRegParms -concretizeAndCqRDest(AbstractInstruction * self_in_concretizeAndCqRDest, sqInt destReg) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt srcReg; - usqInt value; - - value = ((self_in_concretizeAndCqRDest->operands))[0]; - srcReg = ((self_in_concretizeAndCqRDest->operands))[1]; - if (((value >= 0) && (value <= 0xFFFF))) { - /* begin machineCodeAt:put: */ - aWord = andiRRC(self_in_concretizeAndCqRDest, destReg, srcReg, value); - ((self_in_concretizeAndCqRDest->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeAndCqRDest, AT, high16BitsOf(self_in_concretizeAndCqRDest, value)); - ((self_in_concretizeAndCqRDest->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeAndCqRDest, AT, AT, low16BitsOf(self_in_concretizeAndCqRDest, value)); - ((self_in_concretizeAndCqRDest->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = andRRR(self_in_concretizeAndCqRDest, destReg, srcReg, AT); - ((self_in_concretizeAndCqRDest->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeAndCwR */ -static sqInt NoDbgRegParms -concretizeAndCwR(AbstractInstruction * self_in_concretizeAndCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeAndCwR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAndCwR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeAndCwR, AT, high16BitsOf(self_in_concretizeAndCwR, rightImm)); - ((self_in_concretizeAndCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeAndCwR, AT, AT, low16BitsOf(self_in_concretizeAndCwR, rightImm)); - ((self_in_concretizeAndCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = andRRR(self_in_concretizeAndCwR, destReg, leftReg, AT); - ((self_in_concretizeAndCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeAndRR */ -static sqInt NoDbgRegParms -concretizeAndRR(AbstractInstruction * self_in_concretizeAndRR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeAndRR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAndRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = andRRR(self_in_concretizeAndRR, destReg, leftReg, rightReg); - ((self_in_concretizeAndRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeArithmeticShiftRightCqR */ -static sqInt NoDbgRegParms -concretizeArithmeticShiftRightCqR(AbstractInstruction * self_in_concretizeArithmeticShiftRightCqR) -{ - sqInt aWord; - sqInt distance; - usqInt reg; - - distance = (((((self_in_concretizeArithmeticShiftRightCqR->operands))[0]) < 0x1F) ? (((self_in_concretizeArithmeticShiftRightCqR->operands))[0]) : 0x1F); - reg = ((self_in_concretizeArithmeticShiftRightCqR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = sraRRC(self_in_concretizeArithmeticShiftRightCqR, reg, reg, distance); - ((self_in_concretizeArithmeticShiftRightCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeArithmeticShiftRightRR */ -static sqInt NoDbgRegParms -concretizeArithmeticShiftRightRR(AbstractInstruction * self_in_concretizeArithmeticShiftRightRR) -{ - sqInt aWord; - usqInt destReg; - usqInt distReg; - - distReg = ((self_in_concretizeArithmeticShiftRightRR->operands))[0]; - destReg = ((self_in_concretizeArithmeticShiftRightRR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = sravRRR(self_in_concretizeArithmeticShiftRightRR, destReg, destReg, distReg); - ((self_in_concretizeArithmeticShiftRightRR->machineCode))[0 / 4] = aWord; - return 4; -} - - -/* Generate concrete machine code for the instruction at actualAddress, - setting machineCodeSize, and answer the following address. */ -/* Generate concrete machine code for the instruction at actualAddress, - setting machineCodeSize, and answer the following address. */ - - /* CogMIPSELCompiler>>#concretizeAt: */ -static sqInt NoDbgRegParms -concretizeAt(AbstractInstruction * self_in_concretizeAt, sqInt actualAddress) -{ - assert((actualAddress % 4) == 0); - (self_in_concretizeAt->address) = actualAddress; - (self_in_concretizeAt->machineCodeSize) = dispatchConcretize(self_in_concretizeAt); - assert((((self_in_concretizeAt->maxSize)) == null) - || (((self_in_concretizeAt->maxSize)) >= ((self_in_concretizeAt->machineCodeSize)))); - return actualAddress + ((self_in_concretizeAt->machineCodeSize)); -} - - /* CogMIPSELCompiler>>#concretizeBrEqualRR */ -static sqInt NoDbgRegParms -concretizeBrEqualRR(AbstractInstruction * self_in_concretizeBrEqualRR) -{ - sqInt aWord; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrEqualRR->address)) + 4))); - leftReg = ((self_in_concretizeBrEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrEqualRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = beqRRoffset(self_in_concretizeBrEqualRR, leftReg, rightReg, offset); - ((self_in_concretizeBrEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrEqualRR->machineCode))[4 / 4] = 0 /* nop */; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeBrLongEqualRR */ -static sqInt NoDbgRegParms -concretizeBrLongEqualRR(AbstractInstruction * self_in_concretizeBrLongEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - usqInt jumpTargetAddr; - AbstractInstruction *jumpTargetInstruction; - usqInt leftReg; - usqInt rightReg; - - /* begin longJumpTargetAddress */ - jumpTarget = ((AbstractInstruction *) (((self_in_concretizeBrLongEqualRR->operands))[0])); - if ((addressIsInInstructions(jumpTarget)) - || (jumpTarget == (methodLabel()))) { - jumpTarget = ((AbstractInstruction *) ((jumpTarget->address))); - } - assert(jumpTarget != 0); - jumpTargetInstruction = jumpTarget; - flag("todo"); - jumpTargetAddr = (((usqInt)jumpTargetInstruction)) & 0xFFFFFFF; - leftReg = ((self_in_concretizeBrLongEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrLongEqualRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = bneRRoffset(self_in_concretizeBrLongEqualRR, leftReg, rightReg, 12); - ((self_in_concretizeBrLongEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrLongEqualRR->machineCode))[4 / 4] = 0 /* nop */; - /* begin machineCodeAt:put: */ - aWord1 = jA(self_in_concretizeBrLongEqualRR, jumpTargetAddr); - ((self_in_concretizeBrLongEqualRR->machineCode))[8 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrLongEqualRR->machineCode))[12 / 4] = 0 /* nop */; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeBrLongNotEqualRR */ -static sqInt NoDbgRegParms -concretizeBrLongNotEqualRR(AbstractInstruction * self_in_concretizeBrLongNotEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - usqInt jumpTargetAddr; - AbstractInstruction *jumpTargetInstruction; - usqInt leftReg; - usqInt rightReg; - - /* begin longJumpTargetAddress */ - jumpTarget = ((AbstractInstruction *) (((self_in_concretizeBrLongNotEqualRR->operands))[0])); - if ((addressIsInInstructions(jumpTarget)) - || (jumpTarget == (methodLabel()))) { - jumpTarget = ((AbstractInstruction *) ((jumpTarget->address))); - } - assert(jumpTarget != 0); - jumpTargetInstruction = jumpTarget; - flag("todo"); - jumpTargetAddr = (((usqInt)jumpTargetInstruction)) & 0xFFFFFFF; - leftReg = ((self_in_concretizeBrLongNotEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrLongNotEqualRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = beqRRoffset(self_in_concretizeBrLongNotEqualRR, leftReg, rightReg, 12); - ((self_in_concretizeBrLongNotEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrLongNotEqualRR->machineCode))[4 / 4] = 0 /* nop */; - /* begin machineCodeAt:put: */ - aWord1 = jA(self_in_concretizeBrLongNotEqualRR, jumpTargetAddr); - ((self_in_concretizeBrLongNotEqualRR->machineCode))[8 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrLongNotEqualRR->machineCode))[12 / 4] = 0 /* nop */; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeBrNotEqualRR */ -static sqInt NoDbgRegParms -concretizeBrNotEqualRR(AbstractInstruction * self_in_concretizeBrNotEqualRR) -{ - sqInt aWord; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrNotEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrNotEqualRR->address)) + 4))); - leftReg = ((self_in_concretizeBrNotEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrNotEqualRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = bneRRoffset(self_in_concretizeBrNotEqualRR, leftReg, rightReg, offset); - ((self_in_concretizeBrNotEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrNotEqualRR->machineCode))[4 / 4] = 0 /* nop */; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeBrSignedGreaterEqualRR */ -static sqInt NoDbgRegParms -concretizeBrSignedGreaterEqualRR(AbstractInstruction * self_in_concretizeBrSignedGreaterEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrSignedGreaterEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrSignedGreaterEqualRR->address)) + 8))); - leftReg = ((self_in_concretizeBrSignedGreaterEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrSignedGreaterEqualRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltRRR(self_in_concretizeBrSignedGreaterEqualRR, BranchTemp, leftReg, rightReg); - ((self_in_concretizeBrSignedGreaterEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = beqRRoffset(self_in_concretizeBrSignedGreaterEqualRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrSignedGreaterEqualRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrSignedGreaterEqualRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrSignedGreaterRR */ -static sqInt NoDbgRegParms -concretizeBrSignedGreaterRR(AbstractInstruction * self_in_concretizeBrSignedGreaterRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrSignedGreaterRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrSignedGreaterRR->address)) + 8))); - leftReg = ((self_in_concretizeBrSignedGreaterRR->operands))[1]; - rightReg = ((self_in_concretizeBrSignedGreaterRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltRRR(self_in_concretizeBrSignedGreaterRR, BranchTemp, rightReg, leftReg); - ((self_in_concretizeBrSignedGreaterRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = bneRRoffset(self_in_concretizeBrSignedGreaterRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrSignedGreaterRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrSignedGreaterRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrSignedLessEqualRR */ -static sqInt NoDbgRegParms -concretizeBrSignedLessEqualRR(AbstractInstruction * self_in_concretizeBrSignedLessEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrSignedLessEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrSignedLessEqualRR->address)) + 8))); - leftReg = ((self_in_concretizeBrSignedLessEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrSignedLessEqualRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltRRR(self_in_concretizeBrSignedLessEqualRR, BranchTemp, rightReg, leftReg); - ((self_in_concretizeBrSignedLessEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = beqRRoffset(self_in_concretizeBrSignedLessEqualRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrSignedLessEqualRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrSignedLessEqualRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrSignedLessRR */ -static sqInt NoDbgRegParms -concretizeBrSignedLessRR(AbstractInstruction * self_in_concretizeBrSignedLessRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrSignedLessRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrSignedLessRR->address)) + 8))); - leftReg = ((self_in_concretizeBrSignedLessRR->operands))[1]; - rightReg = ((self_in_concretizeBrSignedLessRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltRRR(self_in_concretizeBrSignedLessRR, BranchTemp, leftReg, rightReg); - ((self_in_concretizeBrSignedLessRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = bneRRoffset(self_in_concretizeBrSignedLessRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrSignedLessRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrSignedLessRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrUnsignedGreaterEqualRR */ -static sqInt NoDbgRegParms -concretizeBrUnsignedGreaterEqualRR(AbstractInstruction * self_in_concretizeBrUnsignedGreaterEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrUnsignedGreaterEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrUnsignedGreaterEqualRR->address)) + 8))); - leftReg = ((self_in_concretizeBrUnsignedGreaterEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrUnsignedGreaterEqualRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltuRRR(self_in_concretizeBrUnsignedGreaterEqualRR, BranchTemp, leftReg, rightReg); - ((self_in_concretizeBrUnsignedGreaterEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = beqRRoffset(self_in_concretizeBrUnsignedGreaterEqualRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrUnsignedGreaterEqualRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrUnsignedGreaterEqualRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrUnsignedGreaterRR */ -static sqInt NoDbgRegParms -concretizeBrUnsignedGreaterRR(AbstractInstruction * self_in_concretizeBrUnsignedGreaterRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrUnsignedGreaterRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrUnsignedGreaterRR->address)) + 8))); - leftReg = ((self_in_concretizeBrUnsignedGreaterRR->operands))[1]; - rightReg = ((self_in_concretizeBrUnsignedGreaterRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltuRRR(self_in_concretizeBrUnsignedGreaterRR, BranchTemp, rightReg, leftReg); - ((self_in_concretizeBrUnsignedGreaterRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = bneRRoffset(self_in_concretizeBrUnsignedGreaterRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrUnsignedGreaterRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrUnsignedGreaterRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrUnsignedLessEqualRR */ -static sqInt NoDbgRegParms -concretizeBrUnsignedLessEqualRR(AbstractInstruction * self_in_concretizeBrUnsignedLessEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrUnsignedLessEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrUnsignedLessEqualRR->address)) + 8))); - leftReg = ((self_in_concretizeBrUnsignedLessEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrUnsignedLessEqualRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltuRRR(self_in_concretizeBrUnsignedLessEqualRR, BranchTemp, rightReg, leftReg); - ((self_in_concretizeBrUnsignedLessEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = beqRRoffset(self_in_concretizeBrUnsignedLessEqualRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrUnsignedLessEqualRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrUnsignedLessEqualRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrUnsignedLessRR */ -static sqInt NoDbgRegParms -concretizeBrUnsignedLessRR(AbstractInstruction * self_in_concretizeBrUnsignedLessRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrUnsignedLessRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrUnsignedLessRR->address)) + 8))); - leftReg = ((self_in_concretizeBrUnsignedLessRR->operands))[1]; - rightReg = ((self_in_concretizeBrUnsignedLessRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltuRRR(self_in_concretizeBrUnsignedLessRR, BranchTemp, leftReg, rightReg); - ((self_in_concretizeBrUnsignedLessRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = bneRRoffset(self_in_concretizeBrUnsignedLessRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrUnsignedLessRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrUnsignedLessRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - -/* Call is used only for calls within code-space, See CallFull for general - anywhere in address space calling - */ -/* Relative branches in MIPS have a displacement of +/- 131kB (signed 18 - bits), which is too small to cover - the method zone. */ - - /* CogMIPSELCompiler>>#concretizeCall */ -static sqInt NoDbgRegParms -concretizeCall(AbstractInstruction * self_in_concretizeCall) -{ - return concretizeCallFull(self_in_concretizeCall); -} - - /* CogMIPSELCompiler>>#concretizeCallFull */ -static sqInt NoDbgRegParms -concretizeCallFull(AbstractInstruction * self_in_concretizeCallFull) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - AbstractInstruction *jumpTarget; - usqInt jumpTargetAddr; - AbstractInstruction *jumpTargetInstruction; - - /* begin longJumpTargetAddress */ - jumpTarget = ((AbstractInstruction *) (((self_in_concretizeCallFull->operands))[0])); - if ((addressIsInInstructions(jumpTarget)) - || (jumpTarget == (methodLabel()))) { - jumpTarget = ((AbstractInstruction *) ((jumpTarget->address))); - } - assert(jumpTarget != 0); - jumpTargetInstruction = jumpTarget; - jumpTargetAddr = ((usqInt)jumpTargetInstruction); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeCallFull, TargetReg, high16BitsOf(self_in_concretizeCallFull, jumpTargetAddr)); - ((self_in_concretizeCallFull->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeCallFull, TargetReg, TargetReg, low16BitsOf(self_in_concretizeCallFull, jumpTargetAddr)); - ((self_in_concretizeCallFull->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = jalR(self_in_concretizeCallFull, TargetReg); - ((self_in_concretizeCallFull->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - ((self_in_concretizeCallFull->machineCode))[12 / 4] = 0 /* nop */; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeClzRR */ -static sqInt NoDbgRegParms -concretizeClzRR(AbstractInstruction * self_in_concretizeClzRR) -{ - sqInt aWord; - usqInt destReg; - usqInt maskReg; - usqInt rightReg; - - maskReg = ((self_in_concretizeClzRR->operands))[0]; - destReg = (rightReg = ((self_in_concretizeClzRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = clzRRR(self_in_concretizeClzRR, destReg, maskReg, rightReg); - ((self_in_concretizeClzRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeCmpCqR */ -static sqInt NoDbgRegParms -concretizeCmpCqR(AbstractInstruction * self_in_concretizeCmpCqR) -{ - return concretizeCmpCwR(self_in_concretizeCmpCqR); -} - - /* CogMIPSELCompiler>>#concretizeCmpCwR */ -static sqInt NoDbgRegParms -concretizeCmpCwR(AbstractInstruction * self_in_concretizeCmpCwR) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeCmpRR */ -static sqInt NoDbgRegParms -concretizeCmpRR(AbstractInstruction * self_in_concretizeCmpRR) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeDivRR */ -static sqInt NoDbgRegParms -concretizeDivRR(AbstractInstruction * self_in_concretizeDivRR) -{ - sqInt aWord; - usqInt dividendReg; - usqInt divisorReg; - - dividendReg = ((self_in_concretizeDivRR->operands))[0]; - divisorReg = ((self_in_concretizeDivRR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = divRR(self_in_concretizeDivRR, dividendReg, divisorReg); - ((self_in_concretizeDivRR->machineCode))[0 / 4] = aWord; - return 4; -} - - -/* fill with operand 0 according to the processor's endianness. - You might think this is bogus and we should fill with stop instrurctions - instead, but this is used to leave room for a CMBlock header before the - code for a block; - the gaps get filled in by fillInBlockHeadersAt: after code has been - generated. */ - - /* CogMIPSELCompiler>>#concretizeFill32 */ -static sqInt NoDbgRegParms -concretizeFill32(AbstractInstruction * self_in_concretizeFill32) -{ - sqInt aWord; - - /* begin machineCodeAt:put: */ - aWord = ((self_in_concretizeFill32->operands))[0]; - ((self_in_concretizeFill32->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeJump */ -static sqInt NoDbgRegParms -concretizeJump(AbstractInstruction * self_in_concretizeJump) -{ - sqInt aWord; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - sqInt offset; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeJump->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeJump->address)) + 4))); - flag("BranchRange"); - /* begin machineCodeAt:put: */ - aWord = beqRRoffset(self_in_concretizeJump, ZR, ZR, offset); - ((self_in_concretizeJump->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeJump->machineCode))[4 / 4] = 0 /* nop */; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeJumpFull */ -static sqInt NoDbgRegParms -concretizeJumpFull(AbstractInstruction * self_in_concretizeJumpFull) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - AbstractInstruction *jumpTarget; - usqInt jumpTargetAddr; - AbstractInstruction *jumpTargetInstruction; - - /* begin longJumpTargetAddress */ - jumpTarget = ((AbstractInstruction *) (((self_in_concretizeJumpFull->operands))[0])); - if ((addressIsInInstructions(jumpTarget)) - || (jumpTarget == (methodLabel()))) { - jumpTarget = ((AbstractInstruction *) ((jumpTarget->address))); - } - assert(jumpTarget != 0); - jumpTargetInstruction = jumpTarget; - jumpTargetAddr = ((usqInt)jumpTargetInstruction); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeJumpFull, TargetReg, high16BitsOf(self_in_concretizeJumpFull, jumpTargetAddr)); - ((self_in_concretizeJumpFull->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeJumpFull, TargetReg, TargetReg, low16BitsOf(self_in_concretizeJumpFull, jumpTargetAddr)); - ((self_in_concretizeJumpFull->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = jR(self_in_concretizeJumpFull, TargetReg); - ((self_in_concretizeJumpFull->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - ((self_in_concretizeJumpFull->machineCode))[12 / 4] = 0 /* nop */; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeJumpLong */ -static sqInt NoDbgRegParms -concretizeJumpLong(AbstractInstruction * self_in_concretizeJumpLong) -{ - return concretizeJumpFull(self_in_concretizeJumpLong); -} - - /* CogMIPSELCompiler>>#concretizeJumpLongNonZero */ -static sqInt NoDbgRegParms -concretizeJumpLongNonZero(AbstractInstruction * self_in_concretizeJumpLongNonZero) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpLongZero */ -static sqInt NoDbgRegParms -concretizeJumpLongZero(AbstractInstruction * self_in_concretizeJumpLongZero) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpNonZero */ -static sqInt NoDbgRegParms -concretizeJumpNonZero(AbstractInstruction * self_in_concretizeJumpNonZero) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpNoOverflow */ -static sqInt NoDbgRegParms -concretizeJumpNoOverflow(AbstractInstruction * self_in_concretizeJumpNoOverflow) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpOverflow */ -static sqInt NoDbgRegParms -concretizeJumpOverflow(AbstractInstruction * self_in_concretizeJumpOverflow) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpR */ -static sqInt NoDbgRegParms -concretizeJumpR(AbstractInstruction * self_in_concretizeJumpR) -{ - sqInt aWord; - usqInt reg; - - flag("OABI"); - reg = ((self_in_concretizeJumpR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = jR(self_in_concretizeJumpR, reg); - ((self_in_concretizeJumpR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeJumpR->machineCode))[4 / 4] = 0 /* nop */; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeJumpSignedGreaterEqual */ -static sqInt NoDbgRegParms -concretizeJumpSignedGreaterEqual(AbstractInstruction * self_in_concretizeJumpSignedGreaterEqual) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpSignedGreaterThan */ -static sqInt NoDbgRegParms -concretizeJumpSignedGreaterThan(AbstractInstruction * self_in_concretizeJumpSignedGreaterThan) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpSignedLessEqual */ -static sqInt NoDbgRegParms -concretizeJumpSignedLessEqual(AbstractInstruction * self_in_concretizeJumpSignedLessEqual) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpSignedLessThan */ -static sqInt NoDbgRegParms -concretizeJumpSignedLessThan(AbstractInstruction * self_in_concretizeJumpSignedLessThan) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpUnsignedGreaterEqual */ -static sqInt NoDbgRegParms -concretizeJumpUnsignedGreaterEqual(AbstractInstruction * self_in_concretizeJumpUnsignedGreaterEqual) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpUnsignedGreaterThan */ -static sqInt NoDbgRegParms -concretizeJumpUnsignedGreaterThan(AbstractInstruction * self_in_concretizeJumpUnsignedGreaterThan) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpUnsignedLessEqual */ -static sqInt NoDbgRegParms -concretizeJumpUnsignedLessEqual(AbstractInstruction * self_in_concretizeJumpUnsignedLessEqual) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpUnsignedLessThan */ -static sqInt NoDbgRegParms -concretizeJumpUnsignedLessThan(AbstractInstruction * self_in_concretizeJumpUnsignedLessThan) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpZero */ -static sqInt NoDbgRegParms -concretizeJumpZero(AbstractInstruction * self_in_concretizeJumpZero) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeLoadEffectiveAddressMwrR */ -static sqInt NoDbgRegParms -concretizeLoadEffectiveAddressMwrR(AbstractInstruction * self_in_concretizeLoadEffectiveAddressMwrR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt baseReg; - usqInt destReg; - sqInt offset; - - offset = ((self_in_concretizeLoadEffectiveAddressMwrR->operands))[0]; - baseReg = ((self_in_concretizeLoadEffectiveAddressMwrR->operands))[1]; - destReg = ((self_in_concretizeLoadEffectiveAddressMwrR->operands))[2]; - if (isShortOffset(self_in_concretizeLoadEffectiveAddressMwrR, offset)) { - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizeLoadEffectiveAddressMwrR, destReg, baseReg, offset); - ((self_in_concretizeLoadEffectiveAddressMwrR->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeLoadEffectiveAddressMwrR, AT, high16BitsOf(self_in_concretizeLoadEffectiveAddressMwrR, offset)); - ((self_in_concretizeLoadEffectiveAddressMwrR->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeLoadEffectiveAddressMwrR, AT, AT, low16BitsOf(self_in_concretizeLoadEffectiveAddressMwrR, offset)); - ((self_in_concretizeLoadEffectiveAddressMwrR->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = adduRRR(self_in_concretizeLoadEffectiveAddressMwrR, destReg, baseReg, AT); - ((self_in_concretizeLoadEffectiveAddressMwrR->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeLogicalShiftLeftCqR */ -static sqInt NoDbgRegParms -concretizeLogicalShiftLeftCqR(AbstractInstruction * self_in_concretizeLogicalShiftLeftCqR) -{ - sqInt aWord; - sqInt distance; - usqInt reg; - - distance = (((((self_in_concretizeLogicalShiftLeftCqR->operands))[0]) < 0x1F) ? (((self_in_concretizeLogicalShiftLeftCqR->operands))[0]) : 0x1F); - reg = ((self_in_concretizeLogicalShiftLeftCqR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = sllRRC(self_in_concretizeLogicalShiftLeftCqR, reg, reg, distance); - ((self_in_concretizeLogicalShiftLeftCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeLogicalShiftLeftRR */ -static sqInt NoDbgRegParms -concretizeLogicalShiftLeftRR(AbstractInstruction * self_in_concretizeLogicalShiftLeftRR) -{ - sqInt aWord; - usqInt destReg; - usqInt distReg; - - distReg = ((self_in_concretizeLogicalShiftLeftRR->operands))[0]; - destReg = ((self_in_concretizeLogicalShiftLeftRR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = sllvRRR(self_in_concretizeLogicalShiftLeftRR, destReg, destReg, distReg); - ((self_in_concretizeLogicalShiftLeftRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeLogicalShiftRightCqR */ -static sqInt NoDbgRegParms -concretizeLogicalShiftRightCqR(AbstractInstruction * self_in_concretizeLogicalShiftRightCqR) -{ - sqInt aWord; - sqInt distance; - usqInt reg; - - distance = (((((self_in_concretizeLogicalShiftRightCqR->operands))[0]) < 0x1F) ? (((self_in_concretizeLogicalShiftRightCqR->operands))[0]) : 0x1F); - reg = ((self_in_concretizeLogicalShiftRightCqR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = srlRRC(self_in_concretizeLogicalShiftRightCqR, reg, reg, distance); - ((self_in_concretizeLogicalShiftRightCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeLogicalShiftRightRR */ -static sqInt NoDbgRegParms -concretizeLogicalShiftRightRR(AbstractInstruction * self_in_concretizeLogicalShiftRightRR) -{ - sqInt aWord; - usqInt destReg; - usqInt distReg; - - distReg = ((self_in_concretizeLogicalShiftRightRR->operands))[0]; - destReg = ((self_in_concretizeLogicalShiftRightRR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = srlvRRR(self_in_concretizeLogicalShiftRightRR, destReg, destReg, distReg); - ((self_in_concretizeLogicalShiftRightRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveAbR */ -static sqInt NoDbgRegParms -concretizeMoveAbR(AbstractInstruction * self_in_concretizeMoveAbR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt destReg; - usqInt srcAddr; - - srcAddr = ((self_in_concretizeMoveAbR->operands))[0]; - destReg = ((self_in_concretizeMoveAbR->operands))[1]; - if ((srcAddr != null) - && ((((varBaseAddress()) - (0x8000)) < srcAddr) - && (srcAddr < ((varBaseAddress()) + (0x8000))))) { - /* begin machineCodeAt:put: */ - aWord = lwRbaseoffset(self_in_concretizeMoveAbR, destReg, ConcreteVarBaseReg, srcAddr - (varBaseAddress())); - ((self_in_concretizeMoveAbR->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeMoveAbR, AT, high16BitsOf(self_in_concretizeMoveAbR, srcAddr)); - ((self_in_concretizeMoveAbR->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeMoveAbR, AT, AT, low16BitsOf(self_in_concretizeMoveAbR, srcAddr)); - ((self_in_concretizeMoveAbR->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = lbuRbaseoffset(self_in_concretizeMoveAbR, destReg, AT, 0); - ((self_in_concretizeMoveAbR->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMoveAwR */ -static sqInt NoDbgRegParms -concretizeMoveAwR(AbstractInstruction * self_in_concretizeMoveAwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt destReg; - usqInt srcAddr; - - srcAddr = ((self_in_concretizeMoveAwR->operands))[0]; - destReg = ((self_in_concretizeMoveAwR->operands))[1]; - if ((srcAddr != null) - && ((((varBaseAddress()) - (0x8000)) < srcAddr) - && (srcAddr < ((varBaseAddress()) + (0x8000))))) { - /* begin machineCodeAt:put: */ - aWord = lwRbaseoffset(self_in_concretizeMoveAwR, destReg, ConcreteVarBaseReg, srcAddr - (varBaseAddress())); - ((self_in_concretizeMoveAwR->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeMoveAwR, AT, high16BitsOf(self_in_concretizeMoveAwR, srcAddr)); - ((self_in_concretizeMoveAwR->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeMoveAwR, AT, AT, low16BitsOf(self_in_concretizeMoveAwR, srcAddr)); - ((self_in_concretizeMoveAwR->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = lwRbaseoffset(self_in_concretizeMoveAwR, destReg, AT, 0); - ((self_in_concretizeMoveAwR->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMoveCqR */ -static sqInt NoDbgRegParms -concretizeMoveCqR(AbstractInstruction * self_in_concretizeMoveCqR) -{ - sqInt aWord; - usqInt reg; - sqInt word; - - word = ((self_in_concretizeMoveCqR->operands))[0]; - reg = ((self_in_concretizeMoveCqR->operands))[1]; - if (!(isShortOffset(self_in_concretizeMoveCqR, word))) { - return concretizeMoveCwR(self_in_concretizeMoveCqR); - } - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizeMoveCqR, reg, ZR, word); - ((self_in_concretizeMoveCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveCwR */ -static sqInt NoDbgRegParms -concretizeMoveCwR(AbstractInstruction * self_in_concretizeMoveCwR) -{ - sqInt aWord; - sqInt aWord1; - usqInt reg; - sqInt word; - - word = ((self_in_concretizeMoveCwR->operands))[0]; - reg = ((self_in_concretizeMoveCwR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeMoveCwR, reg, high16BitsOf(self_in_concretizeMoveCwR, word)); - ((self_in_concretizeMoveCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeMoveCwR, reg, reg, low16BitsOf(self_in_concretizeMoveCwR, word)); - ((self_in_concretizeMoveCwR->machineCode))[4 / 4] = aWord1; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeMoveHighR */ -static sqInt NoDbgRegParms -concretizeMoveHighR(AbstractInstruction * self_in_concretizeMoveHighR) -{ - sqInt aWord; - usqInt destReg; - - destReg = ((self_in_concretizeMoveHighR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = mfhiR(self_in_concretizeMoveHighR, destReg); - ((self_in_concretizeMoveHighR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveLowR */ -static sqInt NoDbgRegParms -concretizeMoveLowR(AbstractInstruction * self_in_concretizeMoveLowR) -{ - sqInt aWord; - usqInt destReg; - - destReg = ((self_in_concretizeMoveLowR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = mfloR(self_in_concretizeMoveLowR, destReg); - ((self_in_concretizeMoveLowR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveM16rR */ -static sqInt NoDbgRegParms -concretizeMoveM16rR(AbstractInstruction * self_in_concretizeMoveM16rR) -{ - sqInt aWord; - usqInt destReg; - sqInt offset; - usqInt srcReg; - - offset = ((self_in_concretizeMoveM16rR->operands))[0]; - srcReg = ((self_in_concretizeMoveM16rR->operands))[1]; - destReg = ((self_in_concretizeMoveM16rR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = lhuRbaseoffset(self_in_concretizeMoveM16rR, destReg, srcReg, offset); - ((self_in_concretizeMoveM16rR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveMbrR */ -static sqInt NoDbgRegParms -concretizeMoveMbrR(AbstractInstruction * self_in_concretizeMoveMbrR) -{ - sqInt aWord; - usqInt destReg; - sqInt offset; - usqInt srcReg; - - offset = ((self_in_concretizeMoveMbrR->operands))[0]; - srcReg = ((self_in_concretizeMoveMbrR->operands))[1]; - destReg = ((self_in_concretizeMoveMbrR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = lbuRbaseoffset(self_in_concretizeMoveMbrR, destReg, srcReg, offset); - ((self_in_concretizeMoveMbrR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveMwrR */ -static sqInt NoDbgRegParms -concretizeMoveMwrR(AbstractInstruction * self_in_concretizeMoveMwrR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - sqInt aWord4; - usqInt baseReg; - usqInt destReg; - sqInt offset; - - offset = ((self_in_concretizeMoveMwrR->operands))[0]; - baseReg = ((self_in_concretizeMoveMwrR->operands))[1]; - destReg = ((self_in_concretizeMoveMwrR->operands))[2]; - if (isShortOffset(self_in_concretizeMoveMwrR, offset)) { - /* begin machineCodeAt:put: */ - aWord = lwRbaseoffset(self_in_concretizeMoveMwrR, destReg, baseReg, offset); - ((self_in_concretizeMoveMwrR->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeMoveMwrR, AT, high16BitsOf(self_in_concretizeMoveMwrR, offset)); - ((self_in_concretizeMoveMwrR->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeMoveMwrR, AT, AT, low16BitsOf(self_in_concretizeMoveMwrR, offset)); - ((self_in_concretizeMoveMwrR->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = adduRRR(self_in_concretizeMoveMwrR, AT, baseReg, AT); - ((self_in_concretizeMoveMwrR->machineCode))[8 / 4] = aWord3; - /* begin machineCodeAt:put: */ - aWord4 = lwRbaseoffset(self_in_concretizeMoveMwrR, destReg, AT, 0); - ((self_in_concretizeMoveMwrR->machineCode))[12 / 4] = aWord4; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeMoveRAb */ -static sqInt NoDbgRegParms -concretizeMoveRAb(AbstractInstruction * self_in_concretizeMoveRAb) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt destAddr; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRAb->operands))[0]; - destAddr = ((self_in_concretizeMoveRAb->operands))[1]; - if ((destAddr != null) - && ((((varBaseAddress()) - (0x8000)) < destAddr) - && (destAddr < ((varBaseAddress()) + (0x8000))))) { - /* begin machineCodeAt:put: */ - aWord = swRbaseoffset(self_in_concretizeMoveRAb, srcReg, ConcreteVarBaseReg, destAddr - (varBaseAddress())); - ((self_in_concretizeMoveRAb->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeMoveRAb, AT, high16BitsOf(self_in_concretizeMoveRAb, destAddr)); - ((self_in_concretizeMoveRAb->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeMoveRAb, AT, AT, low16BitsOf(self_in_concretizeMoveRAb, destAddr)); - ((self_in_concretizeMoveRAb->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = sbRbaseoffset(self_in_concretizeMoveRAb, srcReg, AT, 0); - ((self_in_concretizeMoveRAb->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMoveRAw */ -static sqInt NoDbgRegParms -concretizeMoveRAw(AbstractInstruction * self_in_concretizeMoveRAw) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt destAddr; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRAw->operands))[0]; - destAddr = ((self_in_concretizeMoveRAw->operands))[1]; - if ((destAddr != null) - && ((((varBaseAddress()) - (0x8000)) < destAddr) - && (destAddr < ((varBaseAddress()) + (0x8000))))) { - /* begin machineCodeAt:put: */ - aWord = swRbaseoffset(self_in_concretizeMoveRAw, srcReg, ConcreteVarBaseReg, destAddr - (varBaseAddress())); - ((self_in_concretizeMoveRAw->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeMoveRAw, AT, high16BitsOf(self_in_concretizeMoveRAw, destAddr)); - ((self_in_concretizeMoveRAw->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeMoveRAw, AT, AT, low16BitsOf(self_in_concretizeMoveRAw, destAddr)); - ((self_in_concretizeMoveRAw->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = swRbaseoffset(self_in_concretizeMoveRAw, srcReg, AT, 0); - ((self_in_concretizeMoveRAw->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMoveRM16r */ -static sqInt NoDbgRegParms -concretizeMoveRM16r(AbstractInstruction * self_in_concretizeMoveRM16r) -{ - sqInt aWord; - usqInt destReg; - sqInt offset; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRM16r->operands))[0]; - offset = ((self_in_concretizeMoveRM16r->operands))[1]; - destReg = ((self_in_concretizeMoveRM16r->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = shRbaseoffset(self_in_concretizeMoveRM16r, srcReg, destReg, offset); - ((self_in_concretizeMoveRM16r->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveRMbr */ -static sqInt NoDbgRegParms -concretizeMoveRMbr(AbstractInstruction * self_in_concretizeMoveRMbr) -{ - sqInt aWord; - usqInt destReg; - sqInt offset; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRMbr->operands))[0]; - offset = ((self_in_concretizeMoveRMbr->operands))[1]; - destReg = ((self_in_concretizeMoveRMbr->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = sbRbaseoffset(self_in_concretizeMoveRMbr, srcReg, destReg, offset); - ((self_in_concretizeMoveRMbr->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveRMwr */ -static sqInt NoDbgRegParms -concretizeMoveRMwr(AbstractInstruction * self_in_concretizeMoveRMwr) -{ - sqInt aWord; - usqInt baseReg; - sqInt offset; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRMwr->operands))[0]; - offset = ((self_in_concretizeMoveRMwr->operands))[1]; - baseReg = ((self_in_concretizeMoveRMwr->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = swRbaseoffset(self_in_concretizeMoveRMwr, srcReg, baseReg, offset); - ((self_in_concretizeMoveRMwr->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveRR */ -static sqInt NoDbgRegParms -concretizeMoveRR(AbstractInstruction * self_in_concretizeMoveRR) -{ - sqInt aWord; - usqInt destReg; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRR->operands))[0]; - destReg = ((self_in_concretizeMoveRR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeMoveRR, destReg, srcReg, ZR); - ((self_in_concretizeMoveRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveRXbrR */ -static sqInt NoDbgRegParms -concretizeMoveRXbrR(AbstractInstruction * self_in_concretizeMoveRXbrR) -{ - sqInt aWord; - sqInt aWord1; - usqInt baseReg; - usqInt indexReg; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRXbrR->operands))[0]; - indexReg = ((self_in_concretizeMoveRXbrR->operands))[1]; - baseReg = ((self_in_concretizeMoveRXbrR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeMoveRXbrR, AT, baseReg, indexReg); - ((self_in_concretizeMoveRXbrR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = sbRbaseoffset(self_in_concretizeMoveRXbrR, srcReg, AT, 0); - ((self_in_concretizeMoveRXbrR->machineCode))[4 / 4] = aWord1; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeMoveRXwrR */ -static sqInt NoDbgRegParms -concretizeMoveRXwrR(AbstractInstruction * self_in_concretizeMoveRXwrR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt baseReg; - usqInt indexReg; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRXwrR->operands))[0]; - indexReg = ((self_in_concretizeMoveRXwrR->operands))[1]; - baseReg = ((self_in_concretizeMoveRXwrR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = sllRRC(self_in_concretizeMoveRXwrR, AT, indexReg, 2); - ((self_in_concretizeMoveRXwrR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = adduRRR(self_in_concretizeMoveRXwrR, AT, baseReg, AT); - ((self_in_concretizeMoveRXwrR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = swRbaseoffset(self_in_concretizeMoveRXwrR, srcReg, AT, 0); - ((self_in_concretizeMoveRXwrR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMoveXbrRR */ -static sqInt NoDbgRegParms -concretizeMoveXbrRR(AbstractInstruction * self_in_concretizeMoveXbrRR) -{ - sqInt aWord; - sqInt aWord1; - usqInt baseReg; - usqInt destReg; - usqInt indexReg; - - - /* index is number of *bytes* */ - indexReg = ((self_in_concretizeMoveXbrRR->operands))[0]; - baseReg = ((self_in_concretizeMoveXbrRR->operands))[1]; - destReg = ((self_in_concretizeMoveXbrRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeMoveXbrRR, AT, baseReg, indexReg); - ((self_in_concretizeMoveXbrRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = lbuRbaseoffset(self_in_concretizeMoveXbrRR, destReg, AT, 0); - ((self_in_concretizeMoveXbrRR->machineCode))[4 / 4] = aWord1; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeMoveXwrRR */ -static sqInt NoDbgRegParms -concretizeMoveXwrRR(AbstractInstruction * self_in_concretizeMoveXwrRR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt baseReg; - usqInt destReg; - usqInt indexReg; - - indexReg = ((self_in_concretizeMoveXwrRR->operands))[0]; - baseReg = ((self_in_concretizeMoveXwrRR->operands))[1]; - destReg = ((self_in_concretizeMoveXwrRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = sllRRC(self_in_concretizeMoveXwrRR, AT, indexReg, 2); - ((self_in_concretizeMoveXwrRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = adduRRR(self_in_concretizeMoveXwrRR, AT, baseReg, AT); - ((self_in_concretizeMoveXwrRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = lwRbaseoffset(self_in_concretizeMoveXwrRR, destReg, AT, 0); - ((self_in_concretizeMoveXwrRR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMulCheckOverflowRR */ -static sqInt NoDbgRegParms -concretizeMulCheckOverflowRR(AbstractInstruction * self_in_concretizeMulCheckOverflowRR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeMulCheckOverflowRR->operands))[0]; - - /* Overflow occured if the sign bit of the low part is different from the high part. */ - destReg = (leftReg = ((self_in_concretizeMulCheckOverflowRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = multRR(self_in_concretizeMulCheckOverflowRR, leftReg, rightReg); - ((self_in_concretizeMulCheckOverflowRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = mfloR(self_in_concretizeMulCheckOverflowRR, destReg); - ((self_in_concretizeMulCheckOverflowRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = sraRRC(self_in_concretizeMulCheckOverflowRR, OverflowTemp1, destReg, 0x1F); - ((self_in_concretizeMulCheckOverflowRR->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = mfhiR(self_in_concretizeMulCheckOverflowRR, OverflowTemp2); - ((self_in_concretizeMulCheckOverflowRR->machineCode))[12 / 4] = aWord3; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeNegateR */ -static sqInt NoDbgRegParms -concretizeNegateR(AbstractInstruction * self_in_concretizeNegateR) -{ - sqInt aWord; - usqInt reg; - - reg = ((self_in_concretizeNegateR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = subuRRR(self_in_concretizeNegateR, reg, ZR, reg); - ((self_in_concretizeNegateR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeNop */ -static sqInt NoDbgRegParms -concretizeNop(AbstractInstruction * self_in_concretizeNop) -{ - /* begin machineCodeAt:put: */ - ((self_in_concretizeNop->machineCode))[0 / 4] = 0 /* nop */; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeOrCqR */ -static sqInt NoDbgRegParms -concretizeOrCqR(AbstractInstruction * self_in_concretizeOrCqR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeOrCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeOrCqR->operands))[1]); - if (!(((rightImm >= 0) && (rightImm <= 0xFFFF)))) { - return concretizeOrCwR(self_in_concretizeOrCqR); - } - /* begin machineCodeAt:put: */ - aWord = oriRRC(self_in_concretizeOrCqR, destReg, leftReg, rightImm); - ((self_in_concretizeOrCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeOrCqRR */ -static sqInt NoDbgRegParms -concretizeOrCqRR(AbstractInstruction * self_in_concretizeOrCqRR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt dstReg; - usqInt srcReg; - usqInt value; - - value = ((self_in_concretizeOrCqRR->operands))[0]; - srcReg = ((self_in_concretizeOrCqRR->operands))[1]; - dstReg = ((self_in_concretizeOrCqRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeOrCqRR, AT, high16BitsOf(self_in_concretizeOrCqRR, value)); - ((self_in_concretizeOrCqRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeOrCqRR, AT, AT, low16BitsOf(self_in_concretizeOrCqRR, value)); - ((self_in_concretizeOrCqRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = orRRR(self_in_concretizeOrCqRR, dstReg, srcReg, AT); - ((self_in_concretizeOrCqRR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeOrCwR */ -static sqInt NoDbgRegParms -concretizeOrCwR(AbstractInstruction * self_in_concretizeOrCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeOrCwR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeOrCwR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeOrCwR, AT, high16BitsOf(self_in_concretizeOrCwR, rightImm)); - ((self_in_concretizeOrCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeOrCwR, AT, AT, low16BitsOf(self_in_concretizeOrCwR, rightImm)); - ((self_in_concretizeOrCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = orRRR(self_in_concretizeOrCwR, destReg, leftReg, AT); - ((self_in_concretizeOrCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeOrRR */ -static sqInt NoDbgRegParms -concretizeOrRR(AbstractInstruction * self_in_concretizeOrRR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeOrRR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeOrRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = orRRR(self_in_concretizeOrRR, destReg, leftReg, rightReg); - ((self_in_concretizeOrRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizePopR */ -static sqInt NoDbgRegParms -concretizePopR(AbstractInstruction * self_in_concretizePopR) -{ - sqInt aWord; - sqInt aWord1; - usqInt destReg; - - destReg = ((self_in_concretizePopR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = lwRbaseoffset(self_in_concretizePopR, destReg, SP, 0); - ((self_in_concretizePopR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = addiuRRC(self_in_concretizePopR, SP, SP, 4); - ((self_in_concretizePopR->machineCode))[4 / 4] = aWord1; - return 8; -} - - /* CogMIPSELCompiler>>#concretizePrefetchAw */ -static sqInt NoDbgRegParms -concretizePrefetchAw(AbstractInstruction * self_in_concretizePrefetchAw) -{ - usqInt addressOperand; - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - - addressOperand = ((self_in_concretizePrefetchAw->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizePrefetchAw, AT, high16BitsOf(self_in_concretizePrefetchAw, addressOperand)); - ((self_in_concretizePrefetchAw->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizePrefetchAw, AT, AT, low16BitsOf(self_in_concretizePrefetchAw, addressOperand)); - ((self_in_concretizePrefetchAw->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = prefRoffsethint(self_in_concretizePrefetchAw, AT, 0, HintLoad); - ((self_in_concretizePrefetchAw->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizePushCq */ -static sqInt NoDbgRegParms -concretizePushCq(AbstractInstruction * self_in_concretizePushCq) -{ - return concretizePushCw(self_in_concretizePushCq); -} - - /* CogMIPSELCompiler>>#concretizePushCw */ -static sqInt NoDbgRegParms -concretizePushCw(AbstractInstruction * self_in_concretizePushCw) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt value; - - value = ((self_in_concretizePushCw->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizePushCw, AT, high16BitsOf(self_in_concretizePushCw, value)); - ((self_in_concretizePushCw->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizePushCw, AT, AT, low16BitsOf(self_in_concretizePushCw, value)); - ((self_in_concretizePushCw->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = addiuRRC(self_in_concretizePushCw, SP, SP, -4); - ((self_in_concretizePushCw->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = swRbaseoffset(self_in_concretizePushCw, AT, SP, 0); - ((self_in_concretizePushCw->machineCode))[12 / 4] = aWord3; - return 16; -} - - /* CogMIPSELCompiler>>#concretizePushR */ -static sqInt NoDbgRegParms -concretizePushR(AbstractInstruction * self_in_concretizePushR) -{ - sqInt aWord; - sqInt aWord1; - usqInt srcReg; - - srcReg = ((self_in_concretizePushR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizePushR, SP, SP, -4); - ((self_in_concretizePushR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = swRbaseoffset(self_in_concretizePushR, srcReg, SP, 0); - ((self_in_concretizePushR->machineCode))[4 / 4] = aWord1; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeRetN */ -static sqInt NoDbgRegParms -concretizeRetN(AbstractInstruction * self_in_concretizeRetN) -{ - sqInt aWord; - sqInt aWord1; - sqInt offset; - - offset = ((self_in_concretizeRetN->operands))[0]; - /* begin machineCodeAt:put: */ - aWord1 = jR(self_in_concretizeRetN, RA); - ((self_in_concretizeRetN->machineCode))[0 / 4] = aWord1; - if (offset == 0) { - /* begin machineCodeAt:put: */ - ((self_in_concretizeRetN->machineCode))[4 / 4] = 0 /* nop */; - } - else { - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizeRetN, SP, SP, offset); - ((self_in_concretizeRetN->machineCode))[4 / 4] = aWord; - } - return 8; -} - - /* CogMIPSELCompiler>>#concretizeStop */ -static sqInt NoDbgRegParms -concretizeStop(AbstractInstruction * self_in_concretizeStop) -{ - sqInt aWord; - - /* begin machineCodeAt:put: */ - aWord = stop(self_in_concretizeStop); - ((self_in_concretizeStop->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeSubCheckOverflowCqR */ -static sqInt NoDbgRegParms -concretizeSubCheckOverflowCqR(AbstractInstruction * self_in_concretizeSubCheckOverflowCqR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - sqInt aWord4; - sqInt aWord5; - sqInt aWord6; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeSubCheckOverflowCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeSubCheckOverflowCqR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeSubCheckOverflowCqR, AT, high16BitsOf(self_in_concretizeSubCheckOverflowCqR, rightImm)); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeSubCheckOverflowCqR, AT, AT, low16BitsOf(self_in_concretizeSubCheckOverflowCqR, rightImm)); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = adduRRR(self_in_concretizeSubCheckOverflowCqR, OverflowTemp1, leftReg, ZR); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = subuRRR(self_in_concretizeSubCheckOverflowCqR, destReg, leftReg, AT); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[12 / 4] = aWord3; - /* begin machineCodeAt:put: */ - aWord4 = xorRRR(self_in_concretizeSubCheckOverflowCqR, OverflowTemp2, destReg, AT); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[16 / 4] = aWord4; - /* begin machineCodeAt:put: */ - aWord5 = xorRRR(self_in_concretizeSubCheckOverflowCqR, OverflowTemp1, destReg, OverflowTemp1); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[20 / 4] = aWord5; - /* begin machineCodeAt:put: */ - aWord6 = andRRR(self_in_concretizeSubCheckOverflowCqR, Overflow, OverflowTemp1, OverflowTemp2); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[24 / 4] = aWord6; - return 28; -} - - /* CogMIPSELCompiler>>#concretizeSubCheckOverflowRR */ -static sqInt NoDbgRegParms -concretizeSubCheckOverflowRR(AbstractInstruction * self_in_concretizeSubCheckOverflowRR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - sqInt aWord4; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeSubCheckOverflowRR->operands))[0]; - - /* Save original LHS */ - destReg = (leftReg = ((self_in_concretizeSubCheckOverflowRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeSubCheckOverflowRR, OverflowTemp1, leftReg, ZR); - ((self_in_concretizeSubCheckOverflowRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = subuRRR(self_in_concretizeSubCheckOverflowRR, destReg, leftReg, rightReg); - ((self_in_concretizeSubCheckOverflowRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = xorRRR(self_in_concretizeSubCheckOverflowRR, OverflowTemp2, destReg, rightReg); - ((self_in_concretizeSubCheckOverflowRR->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = xorRRR(self_in_concretizeSubCheckOverflowRR, OverflowTemp1, destReg, OverflowTemp1); - ((self_in_concretizeSubCheckOverflowRR->machineCode))[12 / 4] = aWord3; - /* begin machineCodeAt:put: */ - aWord4 = andRRR(self_in_concretizeSubCheckOverflowRR, Overflow, OverflowTemp1, OverflowTemp2); - ((self_in_concretizeSubCheckOverflowRR->machineCode))[16 / 4] = aWord4; - return 20; -} - - /* CogMIPSELCompiler>>#concretizeSubCqR */ -static sqInt NoDbgRegParms -concretizeSubCqR(AbstractInstruction * self_in_concretizeSubCqR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeSubCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeSubCqR->operands))[1]); - if (!(isShortOffset(self_in_concretizeSubCqR, -rightImm))) { - return concretizeSubCwR(self_in_concretizeSubCqR); - } - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizeSubCqR, destReg, leftReg, -rightImm); - ((self_in_concretizeSubCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeSubCwR */ -static sqInt NoDbgRegParms -concretizeSubCwR(AbstractInstruction * self_in_concretizeSubCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeSubCwR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeSubCwR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeSubCwR, AT, high16BitsOf(self_in_concretizeSubCwR, rightImm)); - ((self_in_concretizeSubCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeSubCwR, AT, AT, low16BitsOf(self_in_concretizeSubCwR, rightImm)); - ((self_in_concretizeSubCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = subuRRR(self_in_concretizeSubCwR, destReg, leftReg, AT); - ((self_in_concretizeSubCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeSubRRDest: */ -static sqInt NoDbgRegParms -concretizeSubRRDest(AbstractInstruction * self_in_concretizeSubRRDest, sqInt destReg) -{ - sqInt aWord; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeSubRRDest->operands))[0]; - leftReg = ((self_in_concretizeSubRRDest->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = subuRRR(self_in_concretizeSubRRDest, destReg, leftReg, rightReg); - ((self_in_concretizeSubRRDest->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeTstCqR */ -static sqInt NoDbgRegParms -concretizeTstCqR(AbstractInstruction * self_in_concretizeTstCqR) -{ - sqInt aWord; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeTstCqR->operands))[0]; - leftReg = ((self_in_concretizeTstCqR->operands))[1]; - if (!(isShortOffset(self_in_concretizeTstCqR, rightImm))) { - return concretizeTstCwR(self_in_concretizeTstCqR); - } - /* begin machineCodeAt:put: */ - aWord = andiRRC(self_in_concretizeTstCqR, Cmp, leftReg, rightImm); - ((self_in_concretizeTstCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeTstCwR */ -static sqInt NoDbgRegParms -concretizeTstCwR(AbstractInstruction * self_in_concretizeTstCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeTstCwR->operands))[0]; - leftReg = ((self_in_concretizeTstCwR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeTstCwR, AT, high16BitsOf(self_in_concretizeTstCwR, rightImm)); - ((self_in_concretizeTstCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeTstCwR, AT, AT, low16BitsOf(self_in_concretizeTstCwR, rightImm)); - ((self_in_concretizeTstCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = andRRR(self_in_concretizeTstCwR, Cmp, leftReg, AT); - ((self_in_concretizeTstCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeUnimplemented */ -static sqInt NoDbgRegParms -concretizeUnimplemented(AbstractInstruction * self_in_concretizeUnimplemented) -{ - error("Unimplemented RTL instruction"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeXorCwR */ -static sqInt NoDbgRegParms -concretizeXorCwR(AbstractInstruction * self_in_concretizeXorCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeXorCwR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeXorCwR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeXorCwR, AT, high16BitsOf(self_in_concretizeXorCwR, rightImm)); - ((self_in_concretizeXorCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeXorCwR, AT, AT, low16BitsOf(self_in_concretizeXorCwR, rightImm)); - ((self_in_concretizeXorCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = xorRRR(self_in_concretizeXorCwR, destReg, leftReg, AT); - ((self_in_concretizeXorCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeXorRR */ -static sqInt NoDbgRegParms -concretizeXorRR(AbstractInstruction * self_in_concretizeXorRR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeXorRR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeXorRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = xorRRR(self_in_concretizeXorRR, destReg, leftReg, rightReg); - ((self_in_concretizeXorRR->machineCode))[0 / 4] = aWord; - return 4; -} - - -/* Attempt to generate concrete machine code for the instruction at address. - This is the inner dispatch of concretizeAt: actualAddress which exists - only to get around the branch size limits in the SqueakV3 (blue book - derived) bytecode set. */ - - /* CogMIPSELCompiler>>#dispatchConcretize */ -static sqInt NoDbgRegParms -dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) -{ - AbstractInstruction *dependentChain; - - switch ((self_in_dispatchConcretize->opcode)) { - case BrEqualRR: - return concretizeBrEqualRR(self_in_dispatchConcretize); - - case BrNotEqualRR: - return concretizeBrNotEqualRR(self_in_dispatchConcretize); - - case BrUnsignedLessRR: - return concretizeBrUnsignedLessRR(self_in_dispatchConcretize); - - case BrUnsignedLessEqualRR: - return concretizeBrUnsignedLessEqualRR(self_in_dispatchConcretize); - - case BrUnsignedGreaterRR: - return concretizeBrUnsignedGreaterRR(self_in_dispatchConcretize); - - case BrUnsignedGreaterEqualRR: - return concretizeBrUnsignedGreaterEqualRR(self_in_dispatchConcretize); - - case BrSignedLessRR: - return concretizeBrSignedLessRR(self_in_dispatchConcretize); - - case BrSignedLessEqualRR: - return concretizeBrSignedLessEqualRR(self_in_dispatchConcretize); - - case BrSignedGreaterRR: - return concretizeBrSignedGreaterRR(self_in_dispatchConcretize); - - case BrSignedGreaterEqualRR: - return concretizeBrSignedGreaterEqualRR(self_in_dispatchConcretize); - - case BrLongEqualRR: - return concretizeBrLongEqualRR(self_in_dispatchConcretize); - - case BrLongNotEqualRR: - return concretizeBrLongNotEqualRR(self_in_dispatchConcretize); - - case MulRR: - case JumpNegative: - case JumpNonNegative: - case JumpCarry: - case JumpNoCarry: - case JumpFPEqual: - case JumpFPNotEqual: - case JumpFPLess: - case JumpFPGreaterOrEqual: - case JumpFPGreater: - case JumpFPLessOrEqual: - case JumpFPOrdered: - case JumpFPUnordered: - case XorCqR: - case AddRdRd: - case CmpRdRd: - case DivRdRd: - case MulRdRd: - case SubRdRd: - case SqrtRd: - case MoveRMbr: - case MoveM64rRd: - case MoveRdM64r: - case ConvertRRd: - return concretizeUnimplemented(self_in_dispatchConcretize); - - case DivRR: - return concretizeDivRR(self_in_dispatchConcretize); - - case MoveLowR: - return concretizeMoveLowR(self_in_dispatchConcretize); - - case MoveHighR: - return concretizeMoveHighR(self_in_dispatchConcretize); - - case Label: - /* begin concretizeLabel */ - dependentChain = (self_in_dispatchConcretize->dependent); - while (!(dependentChain == null)) { - /* begin updateLabel: */ - assert((((dependentChain->opcode)) == MoveCwR) - || (((dependentChain->opcode)) == PushCw)); - ((dependentChain->operands))[0] = (((self_in_dispatchConcretize->address)) + (((self_in_dispatchConcretize->operands))[1])); - dependentChain = (dependentChain->dependent); - } - return 0; - - case AlignmentNops: - return concretizeAlignmentNops(self_in_dispatchConcretize); - - case Fill32: - return concretizeFill32(self_in_dispatchConcretize); - - case Nop: - return concretizeNop(self_in_dispatchConcretize); - - case Call: - return concretizeCall(self_in_dispatchConcretize); - - case CallFull: - return concretizeCallFull(self_in_dispatchConcretize); - - case JumpR: - return concretizeJumpR(self_in_dispatchConcretize); - - case JumpFull: - return concretizeJumpFull(self_in_dispatchConcretize); - - case JumpLong: - return concretizeJumpLong(self_in_dispatchConcretize); - - case JumpLongZero: - return concretizeJumpLongZero(self_in_dispatchConcretize); - - case JumpLongNonZero: - return concretizeJumpLongNonZero(self_in_dispatchConcretize); - - case Jump: - return concretizeJump(self_in_dispatchConcretize); - - case JumpZero: - return concretizeJumpZero(self_in_dispatchConcretize); - - case JumpNonZero: - return concretizeJumpNonZero(self_in_dispatchConcretize); - - case JumpOverflow: - return concretizeJumpOverflow(self_in_dispatchConcretize); - - case JumpNoOverflow: - return concretizeJumpNoOverflow(self_in_dispatchConcretize); - - case JumpLess: - return concretizeJumpSignedLessThan(self_in_dispatchConcretize); - - case JumpGreaterOrEqual: - return concretizeJumpSignedGreaterEqual(self_in_dispatchConcretize); - - case JumpGreater: - return concretizeJumpSignedGreaterThan(self_in_dispatchConcretize); - - case JumpLessOrEqual: - return concretizeJumpSignedLessEqual(self_in_dispatchConcretize); - - case JumpBelow: - return concretizeJumpUnsignedLessThan(self_in_dispatchConcretize); - - case JumpAboveOrEqual: - return concretizeJumpUnsignedGreaterEqual(self_in_dispatchConcretize); - - case JumpAbove: - return concretizeJumpUnsignedGreaterThan(self_in_dispatchConcretize); - - case JumpBelowOrEqual: - return concretizeJumpUnsignedLessEqual(self_in_dispatchConcretize); - - case RetN: - return concretizeRetN(self_in_dispatchConcretize); - - case Stop: - return concretizeStop(self_in_dispatchConcretize); - - case AddCqR: - return concretizeAddCqR(self_in_dispatchConcretize); - - case AndCqR: - return concretizeAndCqRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]); - - case AndCqRR: - return concretizeAndCqRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[2]); - - case OrCqRR: - return concretizeOrCqRR(self_in_dispatchConcretize); - - case CmpCqR: - return concretizeCmpCqR(self_in_dispatchConcretize); - - case OrCqR: - return concretizeOrCqR(self_in_dispatchConcretize); - - case SubCqR: - return concretizeSubCqR(self_in_dispatchConcretize); - - case TstCqR: - return concretizeTstCqR(self_in_dispatchConcretize); - - case AddCwR: - return concretizeAddCwR(self_in_dispatchConcretize); - - case AndCwR: - return concretizeAndCwR(self_in_dispatchConcretize); - - case CmpCwR: - return concretizeCmpCwR(self_in_dispatchConcretize); - - case OrCwR: - return concretizeOrCwR(self_in_dispatchConcretize); - - case SubCwR: - return concretizeSubCwR(self_in_dispatchConcretize); - - case XorCwR: - return concretizeXorCwR(self_in_dispatchConcretize); - - case AddRR: - return concretizeAddRRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]); - - case AndRR: - return concretizeAndRR(self_in_dispatchConcretize); - - case CmpRR: - return concretizeCmpRR(self_in_dispatchConcretize); - - case OrRR: - return concretizeOrRR(self_in_dispatchConcretize); - - case SubRR: - return concretizeSubRRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]); - - case XorRR: - return concretizeXorRR(self_in_dispatchConcretize); - - case AddRRR: - return concretizeAddRRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[2]); - - case SubRRR: - return concretizeSubRRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[2]); - - case NegateR: - return concretizeNegateR(self_in_dispatchConcretize); - - case LoadEffectiveAddressMwrR: - return concretizeLoadEffectiveAddressMwrR(self_in_dispatchConcretize); - - case ArithmeticShiftRightCqR: - return concretizeArithmeticShiftRightCqR(self_in_dispatchConcretize); - - case LogicalShiftRightCqR: - return concretizeLogicalShiftRightCqR(self_in_dispatchConcretize); - - case LogicalShiftLeftCqR: - return concretizeLogicalShiftLeftCqR(self_in_dispatchConcretize); - - case ArithmeticShiftRightRR: - return concretizeArithmeticShiftRightRR(self_in_dispatchConcretize); - - case LogicalShiftLeftRR: - return concretizeLogicalShiftLeftRR(self_in_dispatchConcretize); - - case LogicalShiftRightRR: - return concretizeLogicalShiftRightRR(self_in_dispatchConcretize); - - case ClzRR: - return concretizeClzRR(self_in_dispatchConcretize); - - case MoveCqR: - return concretizeMoveCqR(self_in_dispatchConcretize); - - case MoveCwR: - return concretizeMoveCwR(self_in_dispatchConcretize); - - case MoveRR: - return concretizeMoveRR(self_in_dispatchConcretize); - - case MoveAwR: - return concretizeMoveAwR(self_in_dispatchConcretize); - - case MoveRAw: - return concretizeMoveRAw(self_in_dispatchConcretize); - - case MoveAbR: - return concretizeMoveAbR(self_in_dispatchConcretize); - - case MoveRAb: - return concretizeMoveRAb(self_in_dispatchConcretize); - - case MoveMbrR: - return concretizeMoveMbrR(self_in_dispatchConcretize); - - case MoveM16rR: - return concretizeMoveM16rR(self_in_dispatchConcretize); - - case MoveRM16r: - return concretizeMoveRM16r(self_in_dispatchConcretize); - - case MoveMwrR: - return concretizeMoveMwrR(self_in_dispatchConcretize); - - case MoveXbrRR: - return concretizeMoveXbrRR(self_in_dispatchConcretize); - - case MoveRXbrR: - return concretizeMoveRXbrR(self_in_dispatchConcretize); - - case MoveXwrRR: - return concretizeMoveXwrRR(self_in_dispatchConcretize); - - case MoveRXwrR: - return concretizeMoveRXwrR(self_in_dispatchConcretize); - - case MoveRMwr: - return concretizeMoveRMwr(self_in_dispatchConcretize); - - case PopR: - return concretizePopR(self_in_dispatchConcretize); - - case PushR: - return concretizePushR(self_in_dispatchConcretize); - - case PushCq: - return concretizePushCq(self_in_dispatchConcretize); - - case PushCw: - return concretizePushCw(self_in_dispatchConcretize); - - case PrefetchAw: - return concretizePrefetchAw(self_in_dispatchConcretize); - - case AddCheckOverflowCqR: - return concretizeAddCheckOverflowCqR(self_in_dispatchConcretize); - - case AddCheckOverflowRR: - return concretizeAddCheckOverflowRR(self_in_dispatchConcretize); - - case SubCheckOverflowCqR: - return concretizeSubCheckOverflowCqR(self_in_dispatchConcretize); - - case SubCheckOverflowRR: - return concretizeSubCheckOverflowRR(self_in_dispatchConcretize); - - case MulCheckOverflowRR: - return concretizeMulCheckOverflowRR(self_in_dispatchConcretize); - - default: - error("Case not found and no otherwise clause"); - } - return 0; -} - - /* CogMIPSELCompiler>>#divR:R: */ -static sqInt NoDbgRegParms -divRR(AbstractInstruction * self_in_divRR, sqInt dividendReg, sqInt divisorReg) -{ - flag("todo"); - return rtypersrtrdsafunct(self_in_divRR, SPECIAL, dividendReg, divisorReg, 0, 0, DIV); -} - - -/* Answer if CallFull and/or JumpFull are relative and hence need relocating - on method - compation. If so, they are annotated with IsRelativeCall in methods and - relocated in - relocateIfCallOrMethodReference:mcpc:delta: */ - - /* CogMIPSELCompiler>>#fullCallsAreRelative */ -static sqInt NoDbgRegParms -fullCallsAreRelative(AbstractInstruction * self_in_fullCallsAreRelative) -{ - return 0; -} - - /* CogMIPSELCompiler>>#functionAtAddress: */ -static sqInt NoDbgRegParms -functionAtAddress(AbstractInstruction * self_in_functionAtAddress, sqInt mcpc) -{ - return (longAt(mcpc)) & 0x3F; -} - - /* CogMIPSELCompiler>>#genDivR:R:Quo:Rem: */ -static sqInt NoDbgRegParms -genDivRRQuoRem(AbstractInstruction * self_in_genDivRRQuoRem, sqInt abstractRegDivisor, sqInt abstractRegDividend, sqInt abstractRegQuotient, sqInt abstractRegRemainder) -{ - genoperandoperand(DivRR, abstractRegDividend, abstractRegDivisor); - genoperand(MoveLowR, abstractRegQuotient); - genoperand(MoveHighR, abstractRegRemainder); - return 0; -} - - /* CogMIPSELCompiler>>#genMulR:R: */ -static AbstractInstruction * NoDbgRegParms -genMulRR(AbstractInstruction * self_in_genMulRR, sqInt regSource, sqInt regDest) -{ - return genoperandoperand(MulRR, regSource, regDest); -} - - -/* Ensure that the register args are pushed before the outer and - inner retpcs at an entry miss for arity <= self numRegArgs. The - outer retpc is that of a call at a send site. The inner is the call - from a method or PIC abort/miss to the trampoline. */ -/* Putting the receiver and args above the return address means the - CoInterpreter has a single machine-code frame format which saves - us a lot of work. */ -/* Iff there are register args convert - sp -> outerRetpc (send site retpc) - linkReg = innerRetpc (PIC abort/miss retpc) - to - base -> receiver - (arg0) - (arg1) - sp -> outerRetpc (send site retpc) - sp -> linkReg/innerRetpc (PIC abort/miss retpc) */ - - /* CogMIPSELCompiler>>#genPushRegisterArgsForAbortMissNumArgs: */ -static void NoDbgRegParms -genPushRegisterArgsForAbortMissNumArgs(AbstractInstruction * self_in_genPushRegisterArgsForAbortMissNumArgs, sqInt numArgs) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - flag("inefficient"); - if (numArgs <= 2 /* numRegArgs */) { - assert((numRegArgs()) <= 2); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, SPReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveRMwr, ReceiverResultReg, 0, SPReg); - if (numArgs > 0) { - /* begin PushR: */ - genoperand(PushR, Arg0Reg); - if (numArgs > 1) { - /* begin PushR: */ - genoperand(PushR, Arg1Reg); - } - } - /* begin PushR: */ - genoperand(PushR, TempReg); - } - /* begin PushR: */ - genoperand(PushR, LinkReg); -} - - -/* Ensure that the register args are pushed before the retpc for arity <= - self numRegArgs. - */ -/* This is easy on a RISC like ARM because the return address is in the link - register. Putting - the receiver and args above the return address means the CoInterpreter has - a single - machine-code frame format which saves us a lot of work - NOTA BENE: we do NOT push the return address here, which means it must be - dealt with later. */ - - /* CogMIPSELCompiler>>#genPushRegisterArgsForNumArgs:scratchReg: */ -static void NoDbgRegParms -genPushRegisterArgsForNumArgsscratchReg(AbstractInstruction * self_in_genPushRegisterArgsForNumArgsscratchReg, sqInt numArgs, sqInt ignored) -{ - flag("inefficient"); - if (numArgs <= 2 /* numRegArgs */) { - assert((numRegArgs()) <= 2); - /* begin PushR: */ - genoperand(PushR, ReceiverResultReg); - if (numArgs > 0) { - /* begin PushR: */ - genoperand(PushR, Arg0Reg); - if (numArgs > 1) { - /* begin PushR: */ - genoperand(PushR, Arg1Reg); - } - } - } -} - - -/* This is a no-op on MIPS since the ABI passes up to 4 args in registers and - trampolines currently observe that limit. - */ - - /* CogMIPSELCompiler>>#genRemoveNArgsFromStack: */ -static sqInt NoDbgRegParms -genRemoveNArgsFromStack(AbstractInstruction * self_in_genRemoveNArgsFromStack, sqInt n) -{ - assert(n <= 4); - return 0; -} - - -/* Restore the registers in regMask as saved by genSaveRegs:. - We don't need to do anything because all of the abstract registers are - allocated to C preserved registers. But for the future... */ - - /* CogMIPSELCompiler>>#genRestoreRegs: */ -static sqInt NoDbgRegParms -genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask) -{ - sqInt reg; - - assert(regMask == 0); - assert(!((((regMask & (registerMaskForandand(SP, FP, RA))) != 0)))); - for (reg = R0; reg <= R28; reg += 1) { - if (((regMask & (1U << reg)) != 0)) { - /* begin PopR: */ - genoperand(PopR, reg); - } - } - return 0; -} - - -/* Save the registers in regMask for a call into the C run-time from a - trampoline. We don't need to do anything because all of the abstract - registers are - allocated to C preserved registers. But for the future... */ - - /* CogMIPSELCompiler>>#genSaveRegs: */ -static sqInt NoDbgRegParms -genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask) -{ - sqInt reg; - - assert(regMask == 0); - assert(!((((regMask & (registerMaskForandand(SP, FP, RA))) != 0)))); - for (reg = R28; reg >= R0; reg += -1) { - if (((regMask & (1U << reg)) != 0)) { - /* begin PushR: */ - genoperand(PushR, reg); - } - } - return 0; -} - - /* CogMIPSELCompiler>>#genSubstituteReturnAddress: */ -static AbstractInstruction * NoDbgRegParms -genSubstituteReturnAddress(AbstractInstruction * self_in_genSubstituteReturnAddress, sqInt retpc) -{ - AbstractInstruction *anInstruction; - - /* begin checkLiteral:forInstruction: */ - anInstruction = genoperandoperand(MoveCwR, retpc, RA); - return anInstruction; -} - - -/* Answer if the processor has a dedicated callee-saved register to point to - the base of commonly-accessed variables. */ - - /* CogMIPSELCompiler>>#hasVarBaseRegister */ -static sqInt NoDbgRegParms -hasVarBaseRegister(AbstractInstruction * self_in_hasVarBaseRegister) -{ - return 1; -} - - /* CogMIPSELCompiler>>#high16BitsOf: */ -static usqInt NoDbgRegParms -high16BitsOf(AbstractInstruction * self_in_high16BitsOf, usqInt word) -{ - return (word) >> 16; -} - - -/* Answer the inline cache tag for the return address of a send. */ -/* MoveCwR ClassReg selectorIndex/expectedClass - Call: unlinked send stub/expectedTarget - Push ReceiverResult <-- callSiteReturnAddress */ -/* lui s3, selector/tagHigh - ori s3, s3, selector/tagLow - lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jalr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#inlineCacheTagAt: */ -static usqInt NoDbgRegParms -inlineCacheTagAt(AbstractInstruction * self_in_inlineCacheTagAt, usqInt callSiteReturnAddress) -{ - assert((opcodeAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 24)) == LUI); - assert((opcodeAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 20)) == ORI); - assert((opcodeAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_inlineCacheTagAt))); - return literalAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 20); -} - - -/* Answer the instruction size at pc. */ - - /* CogMIPSELCompiler>>#instructionSizeAt: */ -static sqInt NoDbgRegParms -instructionSizeAt(AbstractInstruction * self_in_instructionSizeAt, sqInt pc) -{ - return 4; -} - - -/* Assuming mcpc is a send return pc answer if the instruction before it is a - call (not a CallFull). - */ -/* cogit disassembleFrom: mcpc - 8 to: mcpc. */ - - /* CogMIPSELCompiler>>#isCallPrecedingReturnPC: */ -static sqInt NoDbgRegParms -isCallPrecedingReturnPC(AbstractInstruction * self_in_isCallPrecedingReturnPC, sqInt mcpc) -{ - if ((opcodeAtAddress(self_in_isCallPrecedingReturnPC, mcpc - 8)) == JAL) { - return 1; - } - if (((opcodeAtAddress(self_in_isCallPrecedingReturnPC, mcpc - 8)) == SPECIAL) - && ((functionAtAddress(self_in_isCallPrecedingReturnPC, mcpc - 8)) == JALR)) { - return 1; - } - return 0; -} - - /* CogMIPSELCompiler>>#isJump */ -static sqInt NoDbgRegParms -isJump(AbstractInstruction * self_in_isJump) -{ - return (((((self_in_isJump->opcode)) >= FirstJump) && (((self_in_isJump->opcode)) <= LastJump))) - || (((((self_in_isJump->opcode)) >= BrEqualRR) && (((self_in_isJump->opcode)) <= BrLongNotEqualRR))); -} - - -/* cogit disassembleFrom: pc to: pc + 4. */ - - /* CogMIPSELCompiler>>#isJumpAt: */ -static sqInt NoDbgRegParms -isJumpAt(AbstractInstruction * self_in_isJumpAt, sqInt pc) -{ - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == J) { - return 1; - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == SPECIAL) { - if ((functionAtAddress(self_in_isJumpAt, pc)) == JR) { - return 1; - } - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == BEQ) { - return 1; - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == BNE) { - return 1; - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == BLEZ) { - return 1; - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == BGTZ) { - return 1; - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == REGIMM) { - if ((rtAtAddress(self_in_isJumpAt, pc)) == BLTZ) { - return 1; - } - if ((rtAtAddress(self_in_isJumpAt, pc)) == BGEZ) { - return 1; - } - } - return 0; -} - - -/* Answer if the receiver is a pc-dependent instruction. */ - - /* CogMIPSELCompiler>>#isPCDependent */ -static sqInt NoDbgRegParms -isPCDependent(AbstractInstruction * self_in_isPCDependent) -{ - return (isJump(self_in_isPCDependent)) - || (((self_in_isPCDependent->opcode)) == AlignmentNops); -} - - /* CogMIPSELCompiler>>#isShortOffset: */ -static sqInt NoDbgRegParms -isShortOffset(AbstractInstruction * self_in_isShortOffset, sqInt offset) -{ - return ((offset >= -32768) && (offset <= 0x7FFF)); -} - - /* CogMIPSELCompiler>>#itype:rs:rt:eitherImmediate: */ -static sqInt NoDbgRegParms -itypersrteitherImmediate(AbstractInstruction * self_in_itypersrteitherImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate) -{ - assert(((op >= 0) && (op <= 0x3F))); - assert(((rs >= 0) && (rs <= 0x1F))); - assert(((rt >= 0) && (rt <= 0x1F))); - return (((((sqInt)((usqInt)(op) << 26))) | (((sqInt)((usqInt)(rs) << 21)))) | (((sqInt)((usqInt)(rt) << 16)))) | (immediate & 0xFFFF); -} - - /* CogMIPSELCompiler>>#itype:rs:rt:signedImmediate: */ -static sqInt NoDbgRegParms -itypersrtsignedImmediate(AbstractInstruction * self_in_itypersrtsignedImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate) -{ - assert(((op >= 0) && (op <= 0x3F))); - assert(((rs >= 0) && (rs <= 0x1F))); - assert(((rt >= 0) && (rt <= 0x1F))); - assert(isShortOffset(self_in_itypersrtsignedImmediate, immediate)); - return (((((sqInt)((usqInt)(op) << 26))) | (((sqInt)((usqInt)(rs) << 21)))) | (((sqInt)((usqInt)(rt) << 16)))) | (immediate & 0xFFFF); -} - - /* CogMIPSELCompiler>>#itype:rs:rt:unsignedImmediate: */ -static sqInt NoDbgRegParms -itypersrtunsignedImmediate(AbstractInstruction * self_in_itypersrtunsignedImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate) -{ - assert(((op >= 0) && (op <= 0x3F))); - assert(((rs >= 0) && (rs <= 0x1F))); - assert(((rt >= 0) && (rt <= 0x1F))); - assert(((immediate >= 0) && (immediate <= 0xFFFF))); - return (((((sqInt)((usqInt)(op) << 26))) | (((sqInt)((usqInt)(rs) << 21)))) | (((sqInt)((usqInt)(rt) << 16)))) | immediate; -} - - /* CogMIPSELCompiler>>#jA: */ -static sqInt NoDbgRegParms -jA(AbstractInstruction * self_in_jA, sqInt target) -{ - assert((target & 3) == 0); - return jtypetarget(self_in_jA, J, ((usqInt)((target & 0xFFFFFFF))) >> 2); -} - - /* CogMIPSELCompiler>>#jalA: */ -static sqInt NoDbgRegParms -jalA(AbstractInstruction * self_in_jalA, sqInt target) -{ - assert((target & 3) == 0); - return jtypetarget(self_in_jalA, JAL, ((usqInt)((target & 0xFFFFFFF))) >> 2); -} - - /* CogMIPSELCompiler>>#jalR: */ -static sqInt NoDbgRegParms -jalR(AbstractInstruction * self_in_jalR, sqInt targetReg) -{ - return rtypersrtrdsafunct(self_in_jalR, SPECIAL, targetReg, 0, RA, 0, JALR); -} - - /* CogMIPSELCompiler>>#jR: */ -static sqInt NoDbgRegParms -jR(AbstractInstruction * self_in_jR, sqInt targetReg) -{ - return rtypersrtrdsafunct(self_in_jR, SPECIAL, targetReg, 0, 0, 0, JR); -} - - /* CogMIPSELCompiler>>#jtype:target: */ -static sqInt NoDbgRegParms -jtypetarget(AbstractInstruction * self_in_jtypetarget, sqInt op, sqInt target) -{ - assert(((op >= 0) && (op <= 0x3F))); - assert(((target >= 0) && (target <= 0x7FFFFFF))); - return (((sqInt)((usqInt)(op) << 26))) | target; -} - - /* CogMIPSELCompiler>>#jumpLongByteSize */ -static sqInt NoDbgRegParms -jumpLongByteSize(AbstractInstruction * self_in_jumpLongByteSize) -{ - flag("bogus"); - return 16; -} - - /* CogMIPSELCompiler>>#jumpLongConditionalByteSize */ -static sqInt NoDbgRegParms -jumpLongConditionalByteSize(AbstractInstruction * self_in_jumpLongConditionalByteSize) -{ - return 16; -} - - -/* mcpc - 16: beq/ne Cmp, ZR, +12 - mcpc - 12: nop (delay slot) - mcpc - 8: j psuedo-address - mcpc - 4: nop (delay slot) */ - - /* CogMIPSELCompiler>>#jumpLongConditionalTargetBeforeFollowingAddress: */ -static usqInt NoDbgRegParms -jumpLongConditionalTargetBeforeFollowingAddress(AbstractInstruction * self_in_jumpLongConditionalTargetBeforeFollowingAddress, sqInt mcpc) -{ - assert(((opcodeAtAddress(self_in_jumpLongConditionalTargetBeforeFollowingAddress, mcpc - 16)) == BEQ) - || ((opcodeAtAddress(self_in_jumpLongConditionalTargetBeforeFollowingAddress, mcpc - 16)) == BNE)); - assert((longAt(mcpc - 12)) == (nop(self_in_jumpLongConditionalTargetBeforeFollowingAddress))); - assert((opcodeAtAddress(self_in_jumpLongConditionalTargetBeforeFollowingAddress, mcpc - 8)) == J); - assert((longAt(mcpc - 4)) == (nop(self_in_jumpLongConditionalTargetBeforeFollowingAddress))); - return targetFromJTypeAtAddress(self_in_jumpLongConditionalTargetBeforeFollowingAddress, mcpc - 8); -} - - -/* Answer the target address for the long jump immediately preceding mcpc */ - - /* CogMIPSELCompiler>>#jumpLongTargetBeforeFollowingAddress: */ -static usqInt NoDbgRegParms -jumpLongTargetBeforeFollowingAddress(AbstractInstruction * self_in_jumpLongTargetBeforeFollowingAddress, sqInt mcpc) -{ - assert((longAt(mcpc - 4)) == (nop(self_in_jumpLongTargetBeforeFollowingAddress))); - assert((opcodeAtAddress(self_in_jumpLongTargetBeforeFollowingAddress, mcpc - 8)) == SPECIAL); - assert((functionAtAddress(self_in_jumpLongTargetBeforeFollowingAddress, mcpc - 8)) == JR); - return literalAtAddress(self_in_jumpLongTargetBeforeFollowingAddress, mcpc - 12); -} - - /* CogMIPSELCompiler>>#jumpShortByteSize */ -static sqInt NoDbgRegParms -jumpShortByteSize(AbstractInstruction * self_in_jumpShortByteSize) -{ - return 8; -} - - -/* cogit disassembleFrom: pc to: pc + 4. */ - - /* CogMIPSELCompiler>>#jumpTargetPCAt: */ -static usqInt NoDbgRegParms -jumpTargetPCAt(AbstractInstruction * self_in_jumpTargetPCAt, sqInt pc) -{ - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == J) { - return targetFromJTypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == BEQ) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == BNE) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == BLEZ) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == BGTZ) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == REGIMM) { - if ((rtAtAddress(self_in_jumpTargetPCAt, pc)) == BLTZ) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((rtAtAddress(self_in_jumpTargetPCAt, pc)) == BGEZ) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - } - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#lbR:base:offset: */ -static sqInt NoDbgRegParms -lbRbaseoffset(AbstractInstruction * self_in_lbRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_lbRbaseoffset, LB, baseReg, destReg, offset); -} - - /* CogMIPSELCompiler>>#lbuR:base:offset: */ -static sqInt NoDbgRegParms -lbuRbaseoffset(AbstractInstruction * self_in_lbuRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_lbuRbaseoffset, LBU, baseReg, destReg, offset); -} - - /* CogMIPSELCompiler>>#lhR:base:offset: */ -static sqInt NoDbgRegParms -lhRbaseoffset(AbstractInstruction * self_in_lhRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_lhRbaseoffset, LH, baseReg, destReg, offset); -} - - /* CogMIPSELCompiler>>#lhuR:base:offset: */ -static sqInt NoDbgRegParms -lhuRbaseoffset(AbstractInstruction * self_in_lhuRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_lhuRbaseoffset, LHU, baseReg, destReg, offset); -} - - /* CogMIPSELCompiler>>#literalAtAddress: */ -static usqInt NoDbgRegParms -literalAtAddress(AbstractInstruction * self_in_literalAtAddress, sqInt mcpc) -{ - usqInt high; - usqInt low; - - assert((opcodeAtAddress(self_in_literalAtAddress, mcpc)) == ORI); - assert((opcodeAtAddress(self_in_literalAtAddress, mcpc - 4)) == LUI); - low = (longAt(mcpc)) & 0xFFFF; - high = (longAt(mcpc - 4)) & 0xFFFF; - return (high << 16) | low; -} - - /* CogMIPSELCompiler>>#literalAtAddress:put: */ -static sqInt NoDbgRegParms -literalAtAddressput(AbstractInstruction * self_in_literalAtAddressput, sqInt mcpc, sqInt newLiteral) -{ - usqInt newLower; - usqInt newUpper; - usqInt oldLower; - usqInt oldUpper; - - assert((opcodeAtAddress(self_in_literalAtAddressput, mcpc - 4)) == LUI); - assert((opcodeAtAddress(self_in_literalAtAddressput, mcpc)) == ORI); - oldUpper = longAt(mcpc - 4); - newUpper = (oldUpper & 0xFFFF0000U) | (high16BitsOf(self_in_literalAtAddressput, newLiteral)); - longAtput(mcpc - 4, newUpper); - oldLower = longAt(mcpc); - newLower = (oldLower & 0xFFFF0000U) | (low16BitsOf(self_in_literalAtAddressput, newLiteral)); - longAtput(mcpc, newLower); - assert((opcodeAtAddress(self_in_literalAtAddressput, mcpc - 4)) == LUI); - assert((opcodeAtAddress(self_in_literalAtAddressput, mcpc)) == ORI); - assert((literalAtAddress(self_in_literalAtAddressput, mcpc)) == newLiteral); - return newLiteral; -} - - -/* Answer the literal embedded in the instruction immediately preceding - followingAddress. This is used in the MoveCwR, PushCw and CmpCwR cases. */ -/* Cmp/MoveCwR - pc-8 lui rx, uper - pc-4 ori rx, rx, lower */ - - /* CogMIPSELCompiler>>#literalBeforeFollowingAddress: */ -static usqInt NoDbgRegParms -literalBeforeFollowingAddress(AbstractInstruction * self_in_literalBeforeFollowingAddress, sqInt followingAddress) -{ - if ((opcodeAtAddress(self_in_literalBeforeFollowingAddress, followingAddress - 4)) == ORI) { - return literalAtAddress(self_in_literalBeforeFollowingAddress, followingAddress - 4); - } - if (((opcodeAtAddress(self_in_literalBeforeFollowingAddress, followingAddress - 4)) == SW) - && ((opcodeAtAddress(self_in_literalBeforeFollowingAddress, followingAddress - 8)) == ADDIU)) { - return literalAtAddress(self_in_literalBeforeFollowingAddress, followingAddress - 12); - } - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#loadLiteralByteSize */ -static sqInt NoDbgRegParms -loadLiteralByteSize(AbstractInstruction * self_in_loadLiteralByteSize) -{ - return 8; -} - - -/* Answer the byte size of a MoveCwR opcode's corresponding machine code - when the argument is a PIC. This is for the self-reference at the end of a - closed PIC. */ - - /* CogMIPSELCompiler>>#loadPICLiteralByteSize */ -static sqInt NoDbgRegParms -loadPICLiteralByteSize(AbstractInstruction * self_in_loadPICLiteralByteSize) -{ - /* begin loadLiteralByteSize */ - return 8; -} - - /* CogMIPSELCompiler>>#low16BitsOf: */ -static usqInt NoDbgRegParms -low16BitsOf(AbstractInstruction * self_in_low16BitsOf, usqInt word) -{ - return word & 0xFFFF; -} - - /* CogMIPSELCompiler>>#luiR:C: */ -static sqInt NoDbgRegParms -luiRC(AbstractInstruction * self_in_luiRC, sqInt destReg, sqInt imm) -{ - return itypersrteitherImmediate(self_in_luiRC, LUI, 0, destReg, imm); -} - - /* CogMIPSELCompiler>>#lwR:base:offset: */ -static sqInt NoDbgRegParms -lwRbaseoffset(AbstractInstruction * self_in_lwRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_lwRbaseoffset, LW, baseReg, destReg, offset); -} - - /* CogMIPSELCompiler>>#machineCodeBytes */ -static sqInt NoDbgRegParms -machineCodeBytes(AbstractInstruction * self_in_machineCodeBytes) -{ - return 28; -} - - -/* Answer the maximum number of words of machine code generated for any - abstract instruction. - e.g. AddCheckOverflowCqR */ - - /* CogMIPSELCompiler>>#machineCodeWords */ -static sqInt NoDbgRegParms -machineCodeWords(AbstractInstruction * self_in_machineCodeWords) -{ - return 7; -} - - /* CogMIPSELCompiler>>#mfhiR: */ -static sqInt NoDbgRegParms -mfhiR(AbstractInstruction * self_in_mfhiR, sqInt destReg) -{ - flag("todo"); - return rtypersrtrdsafunct(self_in_mfhiR, SPECIAL, 0, 0, destReg, 0, MFHI); -} - - /* CogMIPSELCompiler>>#mfloR: */ -static sqInt NoDbgRegParms -mfloR(AbstractInstruction * self_in_mfloR, sqInt destReg) -{ - flag("todo"); - return rtypersrtrdsafunct(self_in_mfloR, SPECIAL, 0, 0, destReg, 0, MFLO); -} - - /* CogMIPSELCompiler>>#mipsbreak: */ -static sqInt NoDbgRegParms -mipsbreak(AbstractInstruction * self_in_mipsbreak, sqInt code) -{ - assert(((code >= 0) && (code <= 0xFFFFF))); - return (((sqInt)((usqInt)(code) << 6))) | BREAK; -} - - /* CogMIPSELCompiler>>#multR:R: */ -static sqInt NoDbgRegParms -multRR(AbstractInstruction * self_in_multRR, sqInt leftReg, sqInt rightReg) -{ - flag("todo"); - return rtypersrtrdsafunct(self_in_multRR, SPECIAL, leftReg, rightReg, 0, 0, MULT); -} - - /* CogMIPSELCompiler>>#nop */ -static sqInt NoDbgRegParms -nop(AbstractInstruction * self_in_nop) -{ - return 0; -} - - -/* Support for processors without condition codes, such as the MIPS. - Answer the branch opcode. Modify the receiver and the branch to - implement a suitable conditional branch that doesn't depend on - condition codes being set by the receiver. */ - - /* CogMIPSELCompiler>>#noteFollowingConditionalBranch: */ -static AbstractInstruction * NoDbgRegParms -noteFollowingConditionalBranch(AbstractInstruction * self_in_noteFollowingConditionalBranch, AbstractInstruction *branch) -{ - usqInt newBranchLeft; - sqInt newBranchOpcode; - usqInt newBranchRight; - - if ((((branch->opcode)) == JumpOverflow) - || (((branch->opcode)) == JumpNoOverflow)) { - return noteFollowingOverflowBranch(self_in_noteFollowingConditionalBranch, branch); - } - switch ((branch->opcode)) { - case JumpZero: - newBranchOpcode = BrEqualRR; - break; - - case JumpNonZero: - newBranchOpcode = BrNotEqualRR; - break; - - case JumpBelow: - newBranchOpcode = BrUnsignedLessRR; - break; - - case JumpBelowOrEqual: - newBranchOpcode = BrUnsignedLessEqualRR; - break; - - case JumpAbove: - newBranchOpcode = BrUnsignedGreaterRR; - break; - - case JumpAboveOrEqual: - newBranchOpcode = BrUnsignedGreaterEqualRR; - break; - - case JumpLess: - case JumpNegative: - newBranchOpcode = BrSignedLessRR; - break; - - case JumpLessOrEqual: - newBranchOpcode = BrSignedLessEqualRR; - break; - - case JumpGreater: - newBranchOpcode = BrSignedGreaterRR; - break; - - case JumpGreaterOrEqual: - newBranchOpcode = BrSignedGreaterEqualRR; - break; - - case JumpLongZero: - newBranchOpcode = BrLongEqualRR; - break; - - case JumpLongNonZero: - newBranchOpcode = BrLongNotEqualRR; - break; - - default: - /* begin unreachable */ - error("UNREACHABLE"); - newBranchOpcode = 0;; - } - switch ((self_in_noteFollowingConditionalBranch->opcode)) { - case BrEqualRR: - case BrUnsignedLessRR: - - /* I.e., two jumps after a compare. */ - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[1]; - newBranchRight = ((self_in_noteFollowingConditionalBranch->operands))[2]; - break; - case CmpRR: - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[1]; - newBranchRight = ((self_in_noteFollowingConditionalBranch->operands))[0]; - (self_in_noteFollowingConditionalBranch->opcode) = Label; - break; - case CmpCqR: - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[1]; - newBranchRight = AT; - (self_in_noteFollowingConditionalBranch->opcode) = MoveCqR; - ((self_in_noteFollowingConditionalBranch->operands))[1] = AT; - break; - case CmpCwR: - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[1]; - newBranchRight = AT; - (self_in_noteFollowingConditionalBranch->opcode) = MoveCwR; - ((self_in_noteFollowingConditionalBranch->operands))[1] = AT; - break; - case TstCqR: - newBranchLeft = Cmp; - newBranchRight = ZR; - break; - case AndCqR: - case OrRR: - case XorRR: - case SubCwR: - case SubCqR: - case ArithmeticShiftRightCqR: - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[1]; - newBranchRight = ZR; - break; - case AndCqRR: - case OrCqRR: - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[2]; - newBranchRight = ZR; - break; - case ClzRR: - - /* we test if the destination register is zero */ - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[0]; - newBranchRight = ZR; - break; - default: - /* begin unreachable */ - error("UNREACHABLE"); - - } - /* begin rewriteOpcode:with:with: */ - (branch->opcode) = newBranchOpcode; - ((branch->operands))[1] = newBranchLeft; - ((branch->operands))[2] = newBranchRight; - return branch; -} - - -/* Support for processors without condition codes, such as the MIPS. - Answer the branch opcode. Modify the receiver and the branch to - implement a suitable conditional branch that doesn't depend on - condition codes being set by the receiver. */ - - /* CogMIPSELCompiler>>#noteFollowingOverflowBranch: */ -static AbstractInstruction * NoDbgRegParms -noteFollowingOverflowBranch(AbstractInstruction * self_in_noteFollowingOverflowBranch, AbstractInstruction *branch) -{ - sqInt newBranchOpcode; - - if (((self_in_noteFollowingOverflowBranch->opcode)) == MulRR) { - (self_in_noteFollowingOverflowBranch->opcode) = MulCheckOverflowRR; - switch ((branch->opcode)) { - case JumpOverflow: - newBranchOpcode = BrNotEqualRR; - break; - - case JumpNoOverflow: - newBranchOpcode = BrEqualRR; - break; - - default: - /* begin unreachable */ - error("UNREACHABLE"); - newBranchOpcode = 0;; - } - /* begin rewriteOpcode:with:with: */ - (branch->opcode) = newBranchOpcode; - ((branch->operands))[1] = OverflowTemp1; - ((branch->operands))[2] = OverflowTemp2; - return branch; - } - switch ((self_in_noteFollowingOverflowBranch->opcode)) { - case AddCqR: - (self_in_noteFollowingOverflowBranch->opcode) = AddCheckOverflowCqR; - break; - - case AddRR: - (self_in_noteFollowingOverflowBranch->opcode) = AddCheckOverflowRR; - break; - - case SubCqR: - (self_in_noteFollowingOverflowBranch->opcode) = SubCheckOverflowCqR; - break; - - case SubRR: - (self_in_noteFollowingOverflowBranch->opcode) = SubCheckOverflowRR; - break; - - default: - /* begin unreachable */ - error("UNREACHABLE"); - (self_in_noteFollowingOverflowBranch->opcode) = 0;; - } - switch ((branch->opcode)) { - case JumpOverflow: - newBranchOpcode = BrSignedLessRR; - break; - - case JumpNoOverflow: - newBranchOpcode = BrSignedGreaterEqualRR; - break; - - default: - /* begin unreachable */ - error("UNREACHABLE"); - newBranchOpcode = 0;; - } - /* begin rewriteOpcode:with:with: */ - (branch->opcode) = newBranchOpcode; - ((branch->operands))[1] = Overflow; - ((branch->operands))[2] = ZR; - return branch; -} - - /* CogMIPSELCompiler>>#numIntRegArgs */ -static sqInt NoDbgRegParms -numIntRegArgs(AbstractInstruction * self_in_numIntRegArgs) -{ - flag("OABI"); - return 4; -} - - /* CogMIPSELCompiler>>#opcodeAtAddress: */ -static sqInt NoDbgRegParms -opcodeAtAddress(AbstractInstruction * self_in_opcodeAtAddress, sqInt mcpc) -{ - return ((usqInt)((longAt(mcpc)))) >> 26; -} - - /* CogMIPSELCompiler>>#oriR:R:C: */ -static sqInt NoDbgRegParms -oriRRC(AbstractInstruction * self_in_oriRRC, sqInt destReg, sqInt srcReg, sqInt imm) -{ - return itypersrteitherImmediate(self_in_oriRRC, ORI, srcReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#orR:R:R: */ -static sqInt NoDbgRegParms -orRRR(AbstractInstruction * self_in_orRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_orRRR, SPECIAL, leftReg, rightReg, destReg, 0, OR); -} - - /* CogMIPSELCompiler>>#padIfPossibleWithStopsFrom:to: */ -static void NoDbgRegParms -padIfPossibleWithStopsFromto(AbstractInstruction * self_in_padIfPossibleWithStopsFromto, sqInt startAddr, sqInt endAddr) -{ - sqInt addr; - - for (addr = startAddr; addr < endAddr; addr += 4) { - longAtput(addr, stop(self_in_padIfPossibleWithStopsFromto)); - } -} - - /* CogMIPSELCompiler>>#prefR:offset:hint: */ -static sqInt NoDbgRegParms -prefRoffsethint(AbstractInstruction * self_in_prefRoffsethint, sqInt baseReg, sqInt offset, sqInt hint) -{ - flag("todo"); - assert((hint == HintLoad) - || (hint == HintStore)); - return itypersrtsignedImmediate(self_in_prefRoffsethint, PREF, baseReg, hint, offset); -} - - /* CogMIPSELCompiler>>#pushLinkRegisterByteSize */ -static sqInt NoDbgRegParms -pushLinkRegisterByteSize(AbstractInstruction * self_in_pushLinkRegisterByteSize) -{ - return 8; -} - - /* CogMIPSELCompiler>>#relocateCallBeforeReturnPC:by: */ -static AbstractInstruction * NoDbgRegParms -relocateCallBeforeReturnPCby(AbstractInstruction * self_in_relocateCallBeforeReturnPCby, sqInt retpc, sqInt delta) -{ - usqInt target; - - assert((delta % 4) == 0); - if (delta == 0) { - return self_in_relocateCallBeforeReturnPCby; - } - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 16)) == LUI); - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 12)) == ORI); - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 8)) == SPECIAL); - assert((functionAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 8)) == JALR); - assert((longAt(retpc - 4)) == (nop(self_in_relocateCallBeforeReturnPCby))); - target = literalAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 12); - target += delta; - literalAtAddressput(self_in_relocateCallBeforeReturnPCby, retpc - 12, target); - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 16)) == LUI); - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 12)) == ORI); - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 8)) == SPECIAL); - assert((functionAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 8)) == JALR); - assert((longAt(retpc - 4)) == (nop(self_in_relocateCallBeforeReturnPCby))); - return 0; -} - - -/* lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jr t9 - nop (delay slot) - ... <-- pc */ - - /* CogMIPSELCompiler>>#relocateJumpLongBeforeFollowingAddress:by: */ -static AbstractInstruction * NoDbgRegParms -relocateJumpLongBeforeFollowingAddressby(AbstractInstruction * self_in_relocateJumpLongBeforeFollowingAddressby, sqInt pc, sqInt delta) -{ - usqInt newTarget; - usqInt oldTarget; - - assert((delta % 4) == 0); - if (delta == 0) { - return self_in_relocateJumpLongBeforeFollowingAddressby; - } - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 16)) == LUI); - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 12)) == ORI); - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 8)) == SPECIAL); - assert((functionAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 8)) == JR); - assert((longAt(pc - 4)) == (nop(self_in_relocateJumpLongBeforeFollowingAddressby))); - oldTarget = literalAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 12); - newTarget = oldTarget + delta; - literalAtAddressput(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 12, newTarget); - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 16)) == LUI); - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 12)) == ORI); - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 8)) == SPECIAL); - assert((functionAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 8)) == JR); - assert((longAt(pc - 4)) == (nop(self_in_relocateJumpLongBeforeFollowingAddressby))); - return 0; -} - - -/* lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jalr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#relocateJumpLongConditionalBeforeFollowingAddress:by: */ -static void NoDbgRegParms -relocateJumpLongConditionalBeforeFollowingAddressby(AbstractInstruction * self_in_relocateJumpLongConditionalBeforeFollowingAddressby, sqInt pc, sqInt delta) -{ - assert((opcodeAtAddress(self_in_relocateJumpLongConditionalBeforeFollowingAddressby, pc - 16)) == BNE); - assert((longAt(pc - 12)) == (nop(self_in_relocateJumpLongConditionalBeforeFollowingAddressby))); - assert((opcodeAtAddress(self_in_relocateJumpLongConditionalBeforeFollowingAddressby, pc - 8)) == J); - assert((longAt(pc - 4)) == (nop(self_in_relocateJumpLongConditionalBeforeFollowingAddressby))); - rewriteJTypeAtAddressdelta(self_in_relocateJumpLongConditionalBeforeFollowingAddressby, pc - 8, delta); - assert((opcodeAtAddress(self_in_relocateJumpLongConditionalBeforeFollowingAddressby, pc - 16)) == BNE); - assert((longAt(pc - 12)) == (nop(self_in_relocateJumpLongConditionalBeforeFollowingAddressby))); - assert((opcodeAtAddress(self_in_relocateJumpLongConditionalBeforeFollowingAddressby, pc - 8)) == J); - assert((longAt(pc - 4)) == (nop(self_in_relocateJumpLongConditionalBeforeFollowingAddressby))); -} - - -/* cogit disassembleFrom: pc - 16 to: pc + 16 a StackToRegisterMappingCogit. */ - - /* CogMIPSELCompiler>>#relocateMethodReferenceBeforeAddress:by: */ -static AbstractInstruction * NoDbgRegParms -relocateMethodReferenceBeforeAddressby(AbstractInstruction * self_in_relocateMethodReferenceBeforeAddressby, sqInt pc, sqInt delta) -{ - usqInt newValue; - usqInt oldValue; - - if (((opcodeAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 8)) == ADDIU) - && ((opcodeAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 4)) == SW)) { - - /* PushCw */ - oldValue = literalAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 12); - newValue = oldValue + delta; - literalAtAddressput(self_in_relocateMethodReferenceBeforeAddressby, pc - 12, newValue); - assert((literalAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 12)) == newValue); - return self_in_relocateMethodReferenceBeforeAddressby; - } - oldValue = literalAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 4); - newValue = oldValue + delta; - literalAtAddressput(self_in_relocateMethodReferenceBeforeAddressby, pc - 4, newValue); - assert((literalAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 4)) == newValue); - return 0; -} - - -/* Rewrite a call instruction to call a different target. This variant is - used to link PICs - in ceSendMiss et al,. - Answer the extent of the code change which is used to compute the range of - the icache to flush. */ -/* lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jalr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#rewriteCallAt:target: */ -static sqInt NoDbgRegParms -rewriteCallAttarget(AbstractInstruction * self_in_rewriteCallAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress) -{ - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteCallAttarget))); - literalAtAddressput(self_in_rewriteCallAttarget, callSiteReturnAddress - 12, callTargetAddress); - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteCallAttarget))); - return 20; -} - - -/* Rewrite a jump instruction to call a different target. This variant is - used to reset the - jumps in the prototype CPIC to suit each use,. - Answer the extent of the code change which is used to compute the range of - the icache to flush. */ - - /* CogMIPSELCompiler>>#rewriteConditionalJumpLongAt:target: */ -static void NoDbgRegParms -rewriteConditionalJumpLongAttarget(AbstractInstruction * self_in_rewriteConditionalJumpLongAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress) -{ - assert((opcodeAtAddress(self_in_rewriteConditionalJumpLongAttarget, callSiteReturnAddress - 8)) == J); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteConditionalJumpLongAttarget))); - rewriteJTypeAtAddresstarget(self_in_rewriteConditionalJumpLongAttarget, callSiteReturnAddress - 8, callTargetAddress); - assert((opcodeAtAddress(self_in_rewriteConditionalJumpLongAttarget, callSiteReturnAddress - 8)) == J); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteConditionalJumpLongAttarget))); -} - - -/* Rewrite a jump instruction to call a different target. This variant is - used to reset the - jumps in the prototype CPIC to suit each use,. - Answer the extent of the code change which is used to compute the range of - the icache to flush. */ -/* self CmpR: ClassReg R: TempReg. - ^self JumpNonZero: 0 */ -/* bne s5, s3, +156 ; =BE7C - nop (delay slot) - .... <-- addressFollowingJump */ - - /* CogMIPSELCompiler>>#rewriteCPICJumpAt:target: */ -static void NoDbgRegParms -rewriteCPICJumpAttarget(AbstractInstruction * self_in_rewriteCPICJumpAttarget, usqInt addressFollowingJump, usqInt jumpTargetAddr) -{ - assert((opcodeAtAddress(self_in_rewriteCPICJumpAttarget, addressFollowingJump - 8)) == BNE); - assert((longAt(addressFollowingJump - 4)) == (nop(self_in_rewriteCPICJumpAttarget))); - rewriteITypeBranchAtAddresstarget(self_in_rewriteCPICJumpAttarget, addressFollowingJump - 8, jumpTargetAddr); - assert((opcodeAtAddress(self_in_rewriteCPICJumpAttarget, addressFollowingJump - 8)) == BNE); - assert((longAt(addressFollowingJump - 4)) == (nop(self_in_rewriteCPICJumpAttarget))); -} - - -/* Rewrite an inline cache to call a different target for a new tag. This - variant is used - to link unlinked sends in ceSend:to:numArgs: et al. Answer the extent of - the code - change which is used to compute the range of the icache to flush. */ -/* MoveCwR ClassReg selectorIndex/expectedClass - Call: unlinked send stub/expectedTarget - Push ReceiverResult <-- callSiteReturnAddress */ -/* lui s3, selector/tagHigh - ori s3, s3, selector/tagLow - lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jalr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#rewriteInlineCacheAt:tag:target: */ -static sqInt NoDbgRegParms -rewriteInlineCacheAttagtarget(AbstractInstruction * self_in_rewriteInlineCacheAttagtarget, usqInt callSiteReturnAddress, sqInt cacheTag, usqInt callTargetAddress) -{ - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 24)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 20)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteInlineCacheAttagtarget))); - literalAtAddressput(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 20, cacheTag); - literalAtAddressput(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 12, callTargetAddress); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 24)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 20)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteInlineCacheAttagtarget))); - return 24; -} - - -/* Rewrite an inline cache with a new tag. This variant is used - by the garbage collector. */ -/* MoveCwR ClassReg selectorIndex/expectedClass - Call: unlinked send stub/expectedTarget - Push ReceiverResult <-- callSiteReturnAddress */ -/* lui s3, selector/tagHigh - ori s3, s3, selector/tagLow - lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jalr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#rewriteInlineCacheTag:at: */ -static void NoDbgRegParms -rewriteInlineCacheTagat(AbstractInstruction * self_in_rewriteInlineCacheTagat, sqInt cacheTag, usqInt callSiteReturnAddress) -{ - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 24)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 20)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteInlineCacheTagat))); - literalAtAddressput(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 20, cacheTag); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 24)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 20)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteInlineCacheTagat))); -} - - /* CogMIPSELCompiler>>#rewriteITypeBranchAtAddress:target: */ -static void NoDbgRegParms -rewriteITypeBranchAtAddresstarget(AbstractInstruction * self_in_rewriteITypeBranchAtAddresstarget, sqInt mcpc, sqInt newTarget) -{ - sqInt newDisplacement; - unsigned int newInstruction; - sqInt oldInstruction; - - - /* Displacement is relative to delay slot. */ - newDisplacement = newTarget - (mcpc + 4); - - /* Displacement is in words. */ - newDisplacement = (newDisplacement) >> 2; - newDisplacement = newDisplacement & 0xFFFF; - oldInstruction = longAt(mcpc); - newInstruction = (oldInstruction & 0xFFFF0000U) | newDisplacement; - longAtput(mcpc, newInstruction); -} - - /* CogMIPSELCompiler>>#rewriteJTypeAtAddress:delta: */ -static void NoDbgRegParms -rewriteJTypeAtAddressdelta(AbstractInstruction * self_in_rewriteJTypeAtAddressdelta, sqInt mcpc, sqInt delta) -{ - usqInt newTarget; - usqInt oldTarget; - - oldTarget = targetFromJTypeAtAddress(self_in_rewriteJTypeAtAddressdelta, mcpc); - newTarget = oldTarget + delta; - rewriteJTypeAtAddresstarget(self_in_rewriteJTypeAtAddressdelta, mcpc, newTarget); -} - - /* CogMIPSELCompiler>>#rewriteJTypeAtAddress:target: */ -static void NoDbgRegParms -rewriteJTypeAtAddresstarget(AbstractInstruction * self_in_rewriteJTypeAtAddresstarget, sqInt mcpc, sqInt newTarget) -{ - sqInt regionMask; - - assert((opcodeAtAddress(self_in_rewriteJTypeAtAddresstarget, mcpc)) == J); - - /* mcpc + 4: relative to delay slot not j */ - regionMask = 0xF0000000U; - assert(((mcpc + 4) & regionMask) == (newTarget & regionMask)); - longAtput(mcpc, jA(self_in_rewriteJTypeAtAddresstarget, newTarget)); -} - - -/* Rewrite a jump instruction to call a different target. This variant is - used to reset the - jumps in the prototype CPIC to suit each use,. - Answer the extent of the code change which is used to compute the range of - the icache to flush. */ -/* lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#rewriteJumpLongAt:target: */ -static sqInt NoDbgRegParms -rewriteJumpLongAttarget(AbstractInstruction * self_in_rewriteJumpLongAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress) -{ - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 8)) == JR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteJumpLongAttarget))); - literalAtAddressput(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 12, callTargetAddress); - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 8)) == JR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteJumpLongAttarget))); - return 20; -} - - /* CogMIPSELCompiler>>#rtAtAddress: */ -static sqInt NoDbgRegParms -rtAtAddress(AbstractInstruction * self_in_rtAtAddress, sqInt mcpc) -{ - return (((usqInt)((longAt(mcpc)))) >> 16) & 0x1F; -} - - /* CogMIPSELCompiler>>#rtype:rs:rt:rd:sa:funct: */ -static sqInt NoDbgRegParms -rtypersrtrdsafunct(AbstractInstruction * self_in_rtypersrtrdsafunct, sqInt op, sqInt rs, sqInt rt, sqInt rd, sqInt sa, sqInt funct) -{ - assert(((op >= 0) && (op <= 0x3F))); - assert(((rs >= 0) && (rs <= 0x1F))); - assert(((rt >= 0) && (rt <= 0x1F))); - assert(((rd >= 0) && (rd <= 0x1F))); - assert(((sa >= 0) && (sa <= 0x1F))); - assert(((funct >= 0) && (funct <= 0x3F))); - return (((((((sqInt)((usqInt)(op) << 26))) | (((sqInt)((usqInt)(rs) << 21)))) | (((sqInt)((usqInt)(rt) << 16)))) | (((sqInt)((usqInt)(rd) << 11)))) | (((sqInt)((usqInt)(sa) << 6)))) | funct; -} - - /* CogMIPSELCompiler>>#sbR:base:offset: */ -static sqInt NoDbgRegParms -sbRbaseoffset(AbstractInstruction * self_in_sbRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_sbRbaseoffset, SB, baseReg, srcReg, offset); -} - - -/* Not really, but we can merge this in noteFollowingConditionalBranch:. */ - - /* CogMIPSELCompiler>>#setsConditionCodesFor: */ -static sqInt NoDbgRegParms -setsConditionCodesFor(AbstractInstruction * self_in_setsConditionCodesFor, sqInt aConditionalJumpOpcode) -{ - if (((self_in_setsConditionCodesFor->opcode)) == XorRR) { - return 1; - } - if (((self_in_setsConditionCodesFor->opcode)) == ArithmeticShiftRightCqR) { - return 1; - } - if ((((self_in_setsConditionCodesFor->opcode)) == ClzRR) - && (aConditionalJumpOpcode == JumpZero)) { - return 1; - } - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#shR:base:offset: */ -static sqInt NoDbgRegParms -shRbaseoffset(AbstractInstruction * self_in_shRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_shRbaseoffset, SH, baseReg, srcReg, offset); -} - - -/* Size a jump and set its address. The target may be another instruction - or an absolute address. On entry the address inst var holds our virtual - address. On exit address is set to eventualAbsoluteAddress, which is - where this instruction will be output. The span of a jump to a following - instruction is therefore between that instruction's address and this - instruction's address ((which are both still their virtual addresses), but - the span of a jump to a preceding instruction or to an absolute address is - between that instruction's address (which by now is its eventual absolute - address) or absolute address and eventualAbsoluteAddress. - - ARM is simple; the 26-bit call/jump range means no short jumps. This - routine only has to determine the targets of jumps, not determine sizes. */ - - /* CogMIPSELCompiler>>#sizePCDependentInstructionAt: */ -static usqInt NoDbgRegParms -sizePCDependentInstructionAt(AbstractInstruction * self_in_sizePCDependentInstructionAt, sqInt eventualAbsoluteAddress) -{ - usqInt alignment; - - if (((self_in_sizePCDependentInstructionAt->opcode)) == AlignmentNops) { - (self_in_sizePCDependentInstructionAt->address) = eventualAbsoluteAddress; - alignment = ((self_in_sizePCDependentInstructionAt->operands))[0]; - return ((self_in_sizePCDependentInstructionAt->machineCodeSize) = ((eventualAbsoluteAddress + (alignment - 1)) & (-alignment)) - eventualAbsoluteAddress); - } - assert((isJump(self_in_sizePCDependentInstructionAt)) - || ((((self_in_sizePCDependentInstructionAt->opcode)) == Call) - || (((self_in_sizePCDependentInstructionAt->opcode)) == CallFull))); - if (isJump(self_in_sizePCDependentInstructionAt)) { - resolveJumpTarget(self_in_sizePCDependentInstructionAt); - } - (self_in_sizePCDependentInstructionAt->address) = eventualAbsoluteAddress; - return ((self_in_sizePCDependentInstructionAt->machineCodeSize) = (self_in_sizePCDependentInstructionAt->maxSize)); -} - - /* CogMIPSELCompiler>>#sllR:R:C: */ -static sqInt NoDbgRegParms -sllRRC(AbstractInstruction * self_in_sllRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount) -{ - return rtypersrtrdsafunct(self_in_sllRRC, SPECIAL, 0, sourceReg, destReg, shiftAmount, SLL); -} - - /* CogMIPSELCompiler>>#sllvR:R:R: */ -static sqInt NoDbgRegParms -sllvRRR(AbstractInstruction * self_in_sllvRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_sllvRRR, SPECIAL, rightReg, leftReg, destReg, 0, SLLV); -} - - /* CogMIPSELCompiler>>#sltiR:R:C: */ -static sqInt NoDbgRegParms -sltiRRC(AbstractInstruction * self_in_sltiRRC, sqInt destReg, sqInt leftReg, sqInt imm) -{ - return itypersrtsignedImmediate(self_in_sltiRRC, SLTI, leftReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#sltiuR:R:C: */ -static sqInt NoDbgRegParms -sltiuRRC(AbstractInstruction * self_in_sltiuRRC, sqInt destReg, sqInt leftReg, sqInt imm) -{ - return itypersrtsignedImmediate(self_in_sltiuRRC, SLTIU, leftReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#sltR:R:R: */ -static sqInt NoDbgRegParms -sltRRR(AbstractInstruction * self_in_sltRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_sltRRR, SPECIAL, leftReg, rightReg, destReg, 0, SLT); -} - - /* CogMIPSELCompiler>>#sltuR:R:R: */ -static sqInt NoDbgRegParms -sltuRRR(AbstractInstruction * self_in_sltuRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_sltuRRR, SPECIAL, leftReg, rightReg, destReg, 0, SLTU); -} - - /* CogMIPSELCompiler>>#sraR:R:C: */ -static sqInt NoDbgRegParms -sraRRC(AbstractInstruction * self_in_sraRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount) -{ - return rtypersrtrdsafunct(self_in_sraRRC, SPECIAL, 0, sourceReg, destReg, shiftAmount, SRA); -} - - /* CogMIPSELCompiler>>#sravR:R:R: */ -static sqInt NoDbgRegParms -sravRRR(AbstractInstruction * self_in_sravRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_sravRRR, SPECIAL, rightReg, leftReg, destReg, 0, SRAV); -} - - /* CogMIPSELCompiler>>#srlR:R:C: */ -static sqInt NoDbgRegParms -srlRRC(AbstractInstruction * self_in_srlRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount) -{ - return rtypersrtrdsafunct(self_in_srlRRC, SPECIAL, 0, sourceReg, destReg, shiftAmount, SRL); -} - - /* CogMIPSELCompiler>>#srlvR:R:R: */ -static sqInt NoDbgRegParms -srlvRRR(AbstractInstruction * self_in_srlvRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_srlvRRR, SPECIAL, rightReg, leftReg, destReg, 0, SRLV); -} - - /* CogMIPSELCompiler>>#stop */ -static sqInt NoDbgRegParms -stop(AbstractInstruction * self_in_stop) -{ - return mipsbreak(self_in_stop, 0); -} - - /* CogMIPSELCompiler>>#stopsFrom:to: */ -static void NoDbgRegParms -stopsFromto(AbstractInstruction * self_in_stopsFromto, sqInt startAddr, sqInt endAddr) -{ - sqInt addr; - - assert((((endAddr - startAddr) + 1) % 4) == 0); - for (addr = startAddr; addr <= endAddr; addr += 4) { - codeLongAtput(addr, stop(self_in_stopsFromto)); - } -} - - -/* Rewrite the long constant loaded by a MoveCwR or PushCw before the given - address - */ - - /* CogMIPSELCompiler>>#storeLiteral:beforeFollowingAddress: */ -static sqInt NoDbgRegParms -storeLiteralbeforeFollowingAddress(AbstractInstruction * self_in_storeLiteralbeforeFollowingAddress, sqInt literal, sqInt followingAddress) -{ - flag("bogus"); - if ((opcodeAtAddress(self_in_storeLiteralbeforeFollowingAddress, followingAddress - 4)) == ORI) { - return literalAtAddressput(self_in_storeLiteralbeforeFollowingAddress, followingAddress - 4, literal); - } - if (((opcodeAtAddress(self_in_storeLiteralbeforeFollowingAddress, followingAddress - 4)) == SW) - && ((opcodeAtAddress(self_in_storeLiteralbeforeFollowingAddress, followingAddress - 8)) == ADDIU)) { - return literalAtAddressput(self_in_storeLiteralbeforeFollowingAddress, followingAddress - 12, literal); - } - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#subuR:R:R: */ -static sqInt NoDbgRegParms -subuRRR(AbstractInstruction * self_in_subuRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_subuRRR, SPECIAL, leftReg, rightReg, destReg, 0, SUBU); -} - - /* CogMIPSELCompiler>>#swR:base:offset: */ -static sqInt NoDbgRegParms -swRbaseoffset(AbstractInstruction * self_in_swRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_swRbaseoffset, SW, baseReg, srcReg, offset); -} - - /* CogMIPSELCompiler>>#targetFromITypeAtAddress: */ -static usqInt NoDbgRegParms -targetFromITypeAtAddress(AbstractInstruction * self_in_targetFromITypeAtAddress, usqInt mcpc) -{ - usqInt offset; - - offset = (longAt(mcpc)) & 0xFFFF; - offset = offset << 2; - return (mcpc + offset) + OneInstruction; -} - - /* CogMIPSELCompiler>>#targetFromJTypeAtAddress: */ -static usqInt NoDbgRegParms -targetFromJTypeAtAddress(AbstractInstruction * self_in_targetFromJTypeAtAddress, usqInt mcpc) -{ - sqInt targetLow; - - - /* mcpc + 4: relative to delay slot not j */ - targetLow = (longAt(mcpc)) & 0x3FFFFFF; - return ((mcpc + 4) & 0xF0000000U) + (((sqInt)((usqInt)(targetLow) << 2))); -} - - /* CogMIPSELCompiler>>#xoriR:R:C: */ -static sqInt NoDbgRegParms -xoriRRC(AbstractInstruction * self_in_xoriRRC, sqInt destReg, sqInt srcReg, sqInt imm) -{ - return itypersrteitherImmediate(self_in_xoriRRC, XORI, srcReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#xorR:R:R: */ -static sqInt NoDbgRegParms -xorRRR(AbstractInstruction * self_in_xorRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_xorRRR, SPECIAL, leftReg, rightReg, destReg, 0, XOR); -} - - -/* Answer if Call and JumpLong are relative and hence need to take the - caller's relocation delta into account during code compaction, rather than - just the - callee's delta. */ - - /* CogMIPSELCompiler>>#zoneCallsAreRelative */ -static sqInt NoDbgRegParms -zoneCallsAreRelative(AbstractInstruction * self_in_zoneCallsAreRelative) -{ - return 0; -} - - /* CogObjectRepresentation>>#checkValidObjectReference: */ -static sqInt NoDbgRegParms -checkValidObjectReference(sqInt anOop) -{ - return (!(isImmediate(anOop))) - && ((heapMapAtWord(pointerForOop(anOop))) != 0); -} - - /* CogObjectRepresentation>>#genCmpClassFloatCompactIndexR: */ -static AbstractInstruction * NoDbgRegParms -genCmpClassFloatCompactIndexR(sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, ClassFloatCompactIndex, reg); - return anInstruction; -} - - /* CogObjectRepresentation>>#genCmpClassMethodContextCompactIndexR: */ -static AbstractInstruction * NoDbgRegParms -genCmpClassMethodContextCompactIndexR(sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, reg); - return anInstruction; -} - - -/* Get the method header (first word) of a CompiledMethod into headerReg. - Deal with the method possibly being cogged. */ - - /* CogObjectRepresentation>>#genGetMethodHeaderOf:into:scratch: */ -static sqInt NoDbgRegParms -genGetMethodHeaderOfintoscratch(sqInt methodReg, sqInt headerReg, sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *jumpNotCogged; - sqInt offset; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, BaseHeaderSize, methodReg, headerReg); - jumpNotCogged = genJumpSmallInteger(headerReg); - /* begin MoveMw:r:R: */ - offset = offsetof(CogMethod, methodHeader); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, offset, headerReg, headerReg); - jmpTarget(jumpNotCogged, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - /* CogObjectRepresentation>>#genLoadSlot:sourceReg:destReg: */ -static sqInt NoDbgRegParms -genLoadSlotsourceRegdestReg(sqInt index, sqInt sourceReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, (index * BytesPerWord) + BaseHeaderSize, sourceReg, destReg); - return 0; -} - - /* CogObjectRepresentation>>#genPrimitiveAdd */ -static sqInt -genPrimitiveAdd(void) -{ - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpOvfl; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genRemoveSmallIntegerTagsInScratchReg(ClassReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, ReceiverResultReg, ClassReg); - /* begin JumpOverflow: */ - jumpOvfl = genConditionalBranchoperand(JumpOverflow, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpOvfl, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveBitAnd */ -static sqInt -genPrimitiveBitAnd(void) -{ - AbstractInstruction *jumpNotSI; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - /* begin AndR:R: */ - genoperandoperand(AndRR, Arg0Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveBitOr */ -static sqInt -genPrimitiveBitOr(void) -{ - AbstractInstruction *jumpNotSI; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - /* begin OrR:R: */ - genoperandoperand(OrRR, Arg0Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - -/* rTemp := rArg0 - rClass := tTemp - rTemp := rTemp & 1 - jz nonInt - rClass >>= 1 - cmp 0,rClass - jge neg - cmp 31,rClass // numSmallIntegerBits, jge for sign - jge tooBig - rTemp := rReceiver - rTemp <<= rClass - rTemp >>= rClass (arithmetic) - cmp rTemp,rReceiver - jnz ovfl - rReceiver := rReceiver - 1 - rReceiver := rReceiver <<= rClass - rReceiver := rReceiver + 1 - ret - neg: - rClass := 0 - rClass - cmp 31,rClass // numSmallIntegerBits - jge inRange - rClass := 31 - inRange - rReceiver := rReceiver >>= rClass. - rReceiver := rReceiver | smallIntegerTags. - ret - ovfl - tooBig - nonInt: - fail - */ - - /* CogObjectRepresentation>>#genPrimitiveBitShift */ -static sqInt -genPrimitiveBitShift(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *jumpInRange; - AbstractInstruction *jumpNegative; - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpOvfl; - AbstractInstruction *jumpTooBig; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genConvertSmallIntegerToIntegerInReg(ClassReg); - if (!(setsConditionCodesFor(lastOpcode(), JumpNegative))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, ClassReg); - } - /* begin JumpNegative: */ - jumpNegative = genConditionalBranchoperand(JumpNegative, ((sqInt)0)); - /* begin CmpCq:R: */ - anInstruction1 = genoperandoperand(CmpCqR, 0x1F /* numSmallIntegerBits */, ClassReg); - /* begin JumpGreaterOrEqual: */ - jumpTooBig = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - /* begin LogicalShiftLeftR:R: */ - genoperandoperand(LogicalShiftLeftRR, ClassReg, TempReg); - /* begin ArithmeticShiftRightR:R: */ - genoperandoperand(ArithmeticShiftRightRR, ClassReg, TempReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, ReceiverResultReg); - /* begin JumpNonZero: */ - jumpOvfl = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genRemoveSmallIntegerTagsInScratchReg(ReceiverResultReg); - /* begin LogicalShiftLeftR:R: */ - genoperandoperand(LogicalShiftLeftRR, ClassReg, ReceiverResultReg); - genAddSmallIntegerTagsTo(ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNegative, genoperand(NegateR, ClassReg)); - /* begin CmpCq:R: */ - anInstruction2 = genoperandoperand(CmpCqR, 0x1F /* numSmallIntegerBits */, ClassReg); - /* begin JumpLessOrEqual: */ - jumpInRange = genConditionalBranchoperand(JumpLessOrEqual, ((sqInt)0)); - /* begin MoveCq:R: */ - anInstruction3 = genoperandoperand(MoveCqR, 0x1F /* numSmallIntegerBits */, ClassReg); - jmpTarget(jumpInRange, genoperandoperand(ArithmeticShiftRightRR, ClassReg, ReceiverResultReg)); - genClearAndSetSmallIntegerTagsIn(ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotSI, jmpTarget(jumpTooBig, jmpTarget(jumpOvfl, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveBitXor */ -static sqInt -genPrimitiveBitXor(void) -{ - AbstractInstruction *jumpNotSI; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genRemoveSmallIntegerTagsInScratchReg(Arg0Reg); - /* begin XorR:R: */ - genoperandoperand(XorRR, Arg0Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveClass */ -static sqInt -genPrimitiveClass(void) -{ - sqInt reg; - - reg = ReceiverResultReg; - if (methodOrBlockNumArgs > 0) { - if (methodOrBlockNumArgs > 1) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - reg = Arg0Reg; - assert(0 < (numRegArgs())); - } - if ((genGetClassObjectOfintoscratchRegmayBeAForwarder(reg, ReceiverResultReg, TempReg, reg != ReceiverResultReg)) == BadRegisterSet) { - genGetClassObjectOfintoscratchRegmayBeAForwarder(reg, ClassReg, TempReg, reg != ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, ReceiverResultReg); - } - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - return UnfailingPrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveDiv */ -static sqInt -genPrimitiveDiv(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *convert; - AbstractInstruction *jumpExact; - AbstractInstruction *jumpIsSI; - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpSameSign; - AbstractInstruction *jumpZero; - - if (!(processorHasDivQuoRemAndMClassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, Arg1Reg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genShiftAwaySmallIntegerTagsInScratchReg(ClassReg); - if (!(setsConditionCodesFor(lastOpcode(), JumpZero))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, ClassReg); - } - /* begin JumpZero: */ - jumpZero = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - genShiftAwaySmallIntegerTagsInScratchReg(TempReg); - gDivRRQuoRem(ClassReg, TempReg, TempReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(CmpCqR, 0, ClassReg); - /* begin JumpZero: */ - jumpExact = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin XorR:R: */ - genoperandoperand(XorRR, ClassReg, Arg1Reg); - if (!(setsConditionCodesFor(lastOpcode(), JumpZero))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, Arg1Reg); - } - /* begin JumpGreaterOrEqual: */ - jumpSameSign = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(SubCqR, 1, TempReg); - jmpTarget(jumpSameSign, (convert = genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - genConvertIntegerInRegtoSmallIntegerInReg(TempReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpExact, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - jumpIsSI = genJumpIsSmallIntegerValuescratch(TempReg, Arg1Reg); - jmpTarget(jumpIsSI, convert); - jmpTarget(jumpZero, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveDivide */ -static sqInt -genPrimitiveDivide(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *jumpInexact; - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpOverflow; - AbstractInstruction *jumpZero; - - if (!(processorHasDivQuoRemAndMClassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genShiftAwaySmallIntegerTagsInScratchReg(ClassReg); - /* begin JumpZero: */ - jumpZero = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - genShiftAwaySmallIntegerTagsInScratchReg(TempReg); - gDivRRQuoRem(ClassReg, TempReg, TempReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, ClassReg); - /* begin JumpNonZero: */ - jumpInexact = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - jumpOverflow = genJumpNotSmallIntegerValuescratch(TempReg, Arg1Reg); - genConvertIntegerInRegtoSmallIntegerInReg(TempReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpOverflow, jmpTarget(jumpInexact, jmpTarget(jumpZero, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveEqual */ -static sqInt -genPrimitiveEqual(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpZero, gJumpFPEqual, 0) - : genSmallIntegerComparison(JumpZero)); -} - - /* CogObjectRepresentation>>#genPrimitiveGreaterOrEqual */ -static sqInt -genPrimitiveGreaterOrEqual(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpGreaterOrEqual, gJumpFPGreaterOrEqual, 0) - : genSmallIntegerComparison(JumpGreaterOrEqual)); -} - - /* CogObjectRepresentation>>#genPrimitiveGreaterThan */ -static sqInt -genPrimitiveGreaterThan(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpGreater, gJumpFPGreater, 0) - : genSmallIntegerComparison(JumpGreater)); -} - - -/* Implementation notes: there are two reasons to use TempReg - -1) if primitive fails, ReceiverResultReg must remain unchanged (we - CompletePrimitive) -2) CLZ/BSR only work on 64bits for registers R0-R7 on - Intel X64. But Win64 uses R9 - Normally, this should be backEnd dependent, but for now we have a single - 64bits target... - */ - - /* CogObjectRepresentation>>#genPrimitiveHighBit */ -static sqInt -genPrimitiveHighBit(void) -{ - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *jumpNegativeReceiver; - AbstractInstruction *jumpNegativeReceiver2; - - - /* remove excess tag bits from the receiver oop */ - - /* and use the abstract cogit facility for case of single tag-bit */ - /* begin genHighBitIn:ofSmallIntegerOopWithSingleTagBit: */ - /* begin genHighBitClzIn:ofSmallIntegerOopWithSingleTagBit: */ - genoperandoperand(ClzRR, ReceiverResultReg, TempReg); - if (!(setsConditionCodesFor(lastOpcode(), JumpZero))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(CmpCqR, 0, TempReg); - } - - /* Note the nice bit trick below: - highBit_1based_of_small_int_value = (BytesPerWord * 8) - leadingZeroCout_of_oop - 1 toAccountForTagBit. - This is like 2 complements (- reg - 1) on (BytesPerWord * 8) log2 bits, or exactly a bit invert operation... */ - jumpNegativeReceiver2 = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkLiteral:forInstruction: */ - anInstruction3 = genoperandoperand(XorCwR, (BytesPerWord * 8) - 1, TempReg); - jumpNegativeReceiver = jumpNegativeReceiver2; - goto l4; - l4: /* end genHighBitIn:ofSmallIntegerOopWithSingleTagBit: */; - if (jumpNegativeReceiver == 0) { - return UnimplementedPrimitive; - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - genConvertIntegerToSmallIntegerInReg(ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNegativeReceiver, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveIdentical */ -static sqInt -genPrimitiveIdentical(void) -{ - return genPrimitiveIdenticalOrNotIf(0); -} - - /* CogObjectRepresentation>>#genPrimitiveLessOrEqual */ -static sqInt -genPrimitiveLessOrEqual(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpLessOrEqual, gJumpFPGreaterOrEqual, 1) - : genSmallIntegerComparison(JumpLessOrEqual)); -} - - /* CogObjectRepresentation>>#genPrimitiveLessThan */ -static sqInt -genPrimitiveLessThan(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpLess, gJumpFPGreater, 1) - : genSmallIntegerComparison(JumpLess)); -} - - /* CogObjectRepresentation>>#genPrimitiveMod */ -static sqInt -genPrimitiveMod(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *jumpExact; - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpSameSign; - AbstractInstruction *jumpZero; - - if (!(processorHasDivQuoRemAndMClassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genRemoveSmallIntegerTagsInScratchReg(ClassReg); - /* begin JumpZero: */ - jumpZero = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, Arg1Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - genRemoveSmallIntegerTagsInScratchReg(TempReg); - gDivRRQuoRem(ClassReg, TempReg, TempReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, ClassReg); - /* begin JumpZero: */ - jumpExact = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin XorR:R: */ - genoperandoperand(XorRR, ClassReg, Arg1Reg); - if (!(setsConditionCodesFor(lastOpcode(), JumpZero))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, Arg1Reg); - } - /* begin JumpGreaterOrEqual: */ - jumpSameSign = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin XorR:R: */ - genoperandoperand(XorRR, ClassReg, Arg1Reg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg1Reg, ClassReg); - jmpTarget(jumpSameSign, jmpTarget(jumpExact, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - genSetSmallIntegerTagsIn(ClassReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpZero, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveMultiply */ -static sqInt -genPrimitiveMultiply(void) -{ - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpOvfl; - - if (!(processorHasMultiplyAndMClassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, Arg1Reg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genShiftAwaySmallIntegerTagsInScratchReg(ClassReg); - genRemoveSmallIntegerTagsInScratchReg(Arg1Reg); - /* begin MulOverflowR:R: */ - genMulRR(backEnd, Arg1Reg, ClassReg); - /* begin JumpOverflow: */ - jumpOvfl = genConditionalBranchoperand(JumpOverflow, ((sqInt)0)); - genSetSmallIntegerTagsIn(ClassReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpOvfl, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - -/* subclasses override if they can */ - - /* CogObjectRepresentation>>#genPrimitiveNewMethod */ -static sqInt -genPrimitiveNewMethod(void) -{ - return UnimplementedPrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveNotEqual */ -static sqInt -genPrimitiveNotEqual(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpNonZero, gJumpFPNotEqual, 0) - : genSmallIntegerComparison(JumpNonZero)); -} - - /* CogObjectRepresentation>>#genPrimitiveNotIdentical */ -static sqInt -genPrimitiveNotIdentical(void) -{ - return genPrimitiveIdenticalOrNotIf(1); -} - - /* CogObjectRepresentation>>#genPrimitiveQuo */ -static sqInt -genPrimitiveQuo(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *convert; - AbstractInstruction *jumpExact; - AbstractInstruction *jumpIsSI; - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpZero; - - if (!(processorHasDivQuoRemAndMClassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genShiftAwaySmallIntegerTagsInScratchReg(ClassReg); - if (!(setsConditionCodesFor(lastOpcode(), JumpZero))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, ClassReg); - } - /* begin JumpZero: */ - jumpZero = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - genShiftAwaySmallIntegerTagsInScratchReg(TempReg); - gDivRRQuoRem(ClassReg, TempReg, TempReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, ClassReg); - /* begin JumpZero: */ - jumpExact = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin Label */ - convert = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - genConvertIntegerInRegtoSmallIntegerInReg(TempReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpExact, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - jumpIsSI = genJumpIsSmallIntegerValuescratch(TempReg, Arg1Reg); - jmpTarget(jumpIsSI, convert); - jmpTarget(jumpZero, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveSubtract */ -static sqInt -genPrimitiveSubtract(void) -{ - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpOvfl; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, Arg0Reg, TempReg); - /* begin JumpOverflow: */ - jumpOvfl = genConditionalBranchoperand(JumpOverflow, ((sqInt)0)); - genAddSmallIntegerTagsTo(TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpOvfl, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genSmallIntegerComparison: */ -static sqInt NoDbgRegParms -genSmallIntegerComparison(sqInt jumpOpcode) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt constant; - AbstractInstruction *jumpFail; - AbstractInstruction *jumpTrue; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpFail = genJumpNotSmallInteger(Arg0Reg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, ReceiverResultReg); - jumpTrue = genConditionalBranchoperand(jumpOpcode, 0); - /* begin genMoveConstant:R: */ - constant = falseObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpTrue, (shouldAnnotateObjectReference(trueObject()) - ? annotateobjRef(checkLiteralforInstruction(trueObject(), genoperandoperand(MoveCwR, trueObject(), ReceiverResultReg)), trueObject()) - : (/* begin checkQuickConstant:forInstruction: */ - trueObject(), - (anInstruction1 = genoperandoperand(MoveCqR, trueObject(), ReceiverResultReg)), - anInstruction1))); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpFail, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - -/* Stack looks like - return address */ - - /* CogObjectRepresentation>>#genSmallIntegerComparison:orDoubleComparison:invert: */ -static sqInt NoDbgRegParms -genSmallIntegerComparisonorDoubleComparisoninvert(sqInt jumpOpcode, AbstractInstruction * NoDbgRegParms (*jumpFPOpcodeGenerator)(void *), sqInt invertComparison) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt constant; - AbstractInstruction *jumpCond; - AbstractInstruction * jumpFail; - AbstractInstruction * jumpNonInt; - sqInt r; - - jumpNonInt = ((AbstractInstruction *) 0); - r = genSmallIntegerComparison(jumpOpcode); - if (r < 0) { - return r; - } -# if defined(DPFPReg0) - - /* Fall through on non-SmallInteger argument. Argument may be a Float : let us check or fail */ - jumpNonInt = genJumpImmediate(Arg0Reg); - genGetCompactClassIndexNonImmOfinto(Arg0Reg, SendNumArgsReg); - genCmpClassFloatCompactIndexR(SendNumArgsReg); - /* begin JumpNonZero: */ - jumpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genConvertSmallIntegerToIntegerInReg(ReceiverResultReg); - /* begin ConvertR:Rd: */ - genoperandoperand(ConvertRRd, ReceiverResultReg, DPFPReg0); - genGetDoubleValueOfinto(Arg0Reg, DPFPReg1); - if (invertComparison) { - - /* May need to invert for NaNs */ - /* begin CmpRd:Rd: */ - genoperandoperand(CmpRdRd, DPFPReg0, DPFPReg1); - } - else { - /* begin CmpRd:Rd: */ - genoperandoperand(CmpRdRd, DPFPReg1, DPFPReg0); - } - - /* FP jumps are a little weird */ - jumpCond = jumpFPOpcodeGenerator(0); - /* begin genMoveConstant:R: */ - constant = falseObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpCond, (shouldAnnotateObjectReference(trueObject()) - ? annotateobjRef(checkLiteralforInstruction(trueObject(), genoperandoperand(MoveCwR, trueObject(), ReceiverResultReg)), trueObject()) - : (/* begin checkQuickConstant:forInstruction: */ - trueObject(), - (anInstruction1 = genoperandoperand(MoveCqR, trueObject(), ReceiverResultReg)), - anInstruction1))); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNonInt, jmpTarget(jumpFail, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); -# endif // defined(DPFPReg0) - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#isUnannotatableConstant: */ -static sqInt NoDbgRegParms -isUnannotatableConstant(CogSimStackEntry *simStackEntry) -{ - return (((simStackEntry->type)) == SSConstant) - && ((isImmediate((simStackEntry->constant))) - || (!(shouldAnnotateObjectReference((simStackEntry->constant))))); -} - - -/* Character gets mapped to zero. See inlineCacheTagForInstance:. */ - - /* CogObjectRepresentationFor32BitSpur>>#classForInlineCacheTag: */ -static sqInt NoDbgRegParms -classForInlineCacheTag(sqInt inlineCacheTag) -{ - return classOrNilAtIndex((inlineCacheTag == 0 - ? characterTag() - : inlineCacheTag)); -} - - /* CogObjectRepresentationFor32BitSpur>>#genAddSmallIntegerTagsTo: */ -static sqInt NoDbgRegParms -genAddSmallIntegerTagsTo(sqInt aRegister) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, 1, aRegister); - return 0; -} - - -/* Set the SmallInteger tag bits when the tag bits may be filled with - garbage. - */ - - /* CogObjectRepresentationFor32BitSpur>>#genClearAndSetSmallIntegerTagsIn: */ -static sqInt NoDbgRegParms -genClearAndSetSmallIntegerTagsIn(sqInt scratchReg) -{ - return genSetSmallIntegerTagsIn(scratchReg); -} - - -/* Convert the Character in reg to a SmallInteger, assuming - the Character's value is a valid character. */ -/* self assume: objectMemory smallIntegerTag = 1 */ - - /* CogObjectRepresentationFor32BitSpur>>#genConvertCharacterToSmallIntegerInReg: */ -static void NoDbgRegParms -genConvertCharacterToSmallIntegerInReg(sqInt reg) -{ - assert(((numCharacterBits()) + 1) == (numSmallIntegerBits())); - /* begin LogicalShiftRightCq:R: */ - genoperandoperand(LogicalShiftRightCqR, 1, reg); -} - - /* CogObjectRepresentationFor32BitSpur>>#genConvertIntegerInReg:toSmallIntegerInReg: */ -static sqInt NoDbgRegParms -genConvertIntegerInRegtoSmallIntegerInReg(sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - - gLogicalShiftLeftCqRR(1, srcReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, 1, destReg); - return 0; -} - - /* CogObjectRepresentationFor32BitSpur>>#genConvertIntegerToSmallIntegerInReg: */ -static sqInt NoDbgRegParms -genConvertIntegerToSmallIntegerInReg(sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, 1, reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, 1, reg); - return 0; -} - - -/* Convert the SmallInteger in reg to a Character, assuming - the SmallInteger's value is a valid character. */ -/* self assume: objectMemory smallIntegerTag = 1 */ - - /* CogObjectRepresentationFor32BitSpur>>#genConvertSmallIntegerToCharacterInReg: */ -static void NoDbgRegParms -genConvertSmallIntegerToCharacterInReg(sqInt reg) -{ - assert(((numCharacterBits()) + 1) == (numSmallIntegerBits())); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, 1, reg); -} - - /* CogObjectRepresentationFor32BitSpur>>#genConvertSmallIntegerToIntegerInReg: */ -static sqInt NoDbgRegParms -genConvertSmallIntegerToIntegerInReg(sqInt reg) -{ - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, 1, reg); - return 0; -} - - -/* Fetch the instance's identity hash into destReg, encoded as a - SmallInteger. - */ -/* Get header word in scratchReg */ - - /* CogObjectRepresentationFor32BitSpur>>#genGetHashFieldNonImmOf:asSmallIntegerInto: */ -static sqInt NoDbgRegParms -genGetHashFieldNonImmOfasSmallIntegerInto(sqInt instReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 4, instReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - identityHashHalfWordMask(); - anInstruction1 = genoperandoperand(AndCqR, identityHashHalfWordMask(), destReg); - genConvertIntegerToSmallIntegerInReg(destReg); - return 0; -} - - -/* Fetch the instance's identity hash into destReg, unencoded. */ - - /* CogObjectRepresentationFor32BitSpur>>#genGetHashFieldNonImmOf:into: */ -static sqInt NoDbgRegParms -genGetHashFieldNonImmOfinto(sqInt instReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 4, instReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - identityHashHalfWordMask(); - anInstruction1 = genoperandoperand(AndCqR, identityHashHalfWordMask(), destReg); - return 0; -} - - -/* Extract the inline cache tag for the object in sourceReg into destReg. The - inline cache tag for a given object is the value loaded in inline caches - to distinguish - objects of different classes. In Spur this is either the tags for - immediates, (with - 1 & 3 collapsed to 1 for SmallIntegers, and 2 collapsed to 0 for - Characters), or - the receiver's classIndex. - If forEntry is true answer the entry label at which control is to enter - (cmEntryOffset). If forEntry is false, control enters at the start. - If forEntry is true, generate something like this: - Limm: - andl $0x1, rDest - j Lcmp - Lentry: - movl rSource, rDest - andl $0x3, rDest - jnz Limm - movl 0(%edx), rDest - andl $0x3fffff, rDest - Lcmp: - If forEntry is false, generate something like the following. - At least on a 2.2GHz Intel Core i7 the following is slightly faster than - the above, - 136m sends/sec vs 130m sends/sec for nfib in tinyBenchmarks - Lentry: - movl rSource, rDest - andl $0x3, rDest - jz LnotImm - andl $1, rDest - j Lcmp - LnotImm: - movl 0(%edx), rDest - andl $0x3fffff, rDest - Lcmp: - But we expect most SmallInteger arithmetic to be performed in-line and so - prefer the - version that is faster for non-immediates (because it branches for - immediates only). */ - - /* CogObjectRepresentationFor32BitSpur>>#genGetInlineCacheClassTagFrom:into:forEntry: */ -static AbstractInstruction * NoDbgRegParms -genGetInlineCacheClassTagFromintoforEntry(sqInt sourceReg, sqInt destReg, sqInt forEntry) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *entryLabel; - AbstractInstruction *immLabel; - AbstractInstruction *jumpCompare; - AbstractInstruction *jumpNotImm; - - if (forEntry) { - /* begin AlignmentNops: */ - genoperand(AlignmentNops, BytesPerWord); - /* begin Label */ - immLabel = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, 1, destReg); - /* begin Jump: */ - jumpCompare = genoperand(Jump, ((sqInt)0)); - /* begin AlignmentNops: */ - genoperand(AlignmentNops, BytesPerWord); - /* begin Label */ - entryLabel = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - gAndCqRR(tagMask(), sourceReg, destReg); - /* begin JumpNonZero: */ - genConditionalBranchoperand(JumpNonZero, ((sqInt)immLabel)); - flag("endianness"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, 0, sourceReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - classIndexMask(); - anInstruction2 = genoperandoperand(AndCqR, classIndexMask(), destReg); - jmpTarget(jumpCompare, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - else { - /* begin Label */ - entryLabel = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - gAndCqRR(tagMask(), sourceReg, destReg); - /* begin JumpZero: */ - jumpNotImm = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(AndCqR, 1, destReg); - /* begin Jump: */ - jumpCompare = genoperand(Jump, ((sqInt)0)); - flag("endianness"); - jmpTarget(jumpNotImm, checkQuickConstantforInstruction(0, genoperandoperandoperand(MoveMwrR, 0, sourceReg, destReg))); - jmpTarget(jumpCompare, checkQuickConstantforInstruction(classIndexMask(), genoperandoperand(AndCqR, classIndexMask(), destReg))); - } - return entryLabel; -} - - -/* Get the size in byte-sized slots of the object in srcReg into destReg. - srcReg may equal destReg. - destReg <- numSlots << self shiftForWord - (fmt bitAnd: 3). - Assumes the object in srcReg has a byte format, i.e. 16 to 23 or 24 to 31 */ - - /* CogObjectRepresentationFor32BitSpur>>#genGetNumBytesOf:into: */ -static sqInt NoDbgRegParms -genGetNumBytesOfinto(sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *jmp; - - genGetRawSlotSizeOfNonImminto(srcReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - numSlotsMask(); - anInstruction = genoperandoperand(CmpCqR, numSlotsMask(), destReg); - /* begin JumpLess: */ - jmp = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - genGetOverflowSlotsOfinto(srcReg, destReg); - jmpTarget(jmp, genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), destReg)); - genGetBitsofFormatByteOfinto(3, srcReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, destReg); - return 0; -} - - /* CogObjectRepresentationFor32BitSpur>>#genGetOverflowSlotsOf:into: */ -static sqInt NoDbgRegParms -genGetOverflowSlotsOfinto(sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - -BaseHeaderSize; - anInstruction = genoperandoperandoperand(MoveMwrR, -BaseHeaderSize, srcReg, destReg); - return 0; -} - - -/* Generate a test for aRegister containing an integer value in the - SmallInteger range, and a jump if so, answering the jump. - c.f. Spur32BitMemoryManager>>isIntegerValue: */ - - /* CogObjectRepresentationFor32BitSpur>>#genJumpIsSmallIntegerValue:scratch: */ -static AbstractInstruction * NoDbgRegParms -genJumpIsSmallIntegerValuescratch(sqInt aRegister, sqInt scratchReg) -{ - return (gLogicalShiftLeftCqRR(1, aRegister, scratchReg), - /* begin XorR:R: */ - genoperandoperand(XorRR, aRegister, scratchReg), - /* begin JumpGreaterOrEqual: */ - genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0))); -} - - /* CogObjectRepresentationFor32BitSpur>>#genJumpNotSmallIntegerInScratchReg: */ -static AbstractInstruction * NoDbgRegParms -genJumpNotSmallIntegerInScratchReg(sqInt aRegister) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, 1, aRegister); - /* begin JumpZero: */ - return genConditionalBranchoperand(JumpZero, ((sqInt)0)); -} - - -/* Generate a test for aRegister containing an integer value outside the - SmallInteger range, and a jump if so, answering the jump. - c.f. Spur32BitMemoryManager>>isIntegerValue: */ - - /* CogObjectRepresentationFor32BitSpur>>#genJumpNotSmallIntegerValue:scratch: */ -static AbstractInstruction * NoDbgRegParms -genJumpNotSmallIntegerValuescratch(sqInt aRegister, sqInt scratchReg) -{ - return (gArithmeticShiftRightCqRR(1, aRegister, scratchReg), - /* begin XorR:R: */ - genoperandoperand(XorRR, aRegister, scratchReg), - /* begin JumpLess: */ - genConditionalBranchoperand(JumpLess, ((sqInt)0))); -} - - /* CogObjectRepresentationFor32BitSpur>>#genJumpNotSmallInteger: */ -static AbstractInstruction * NoDbgRegParms -genJumpNotSmallInteger(sqInt aRegister) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(TstCqR, 1, aRegister); - /* begin JumpZero: */ - return genConditionalBranchoperand(JumpZero, ((sqInt)0)); -} - - /* CogObjectRepresentationFor32BitSpur>>#genJumpSmallInteger: */ -static AbstractInstruction * NoDbgRegParms -genJumpSmallInteger(sqInt aRegister) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(TstCqR, 1, aRegister); - /* begin JumpNonZero: */ - return genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -} - - -/* c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: - fixedFieldsOf:format:length: - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveAtPut */ -static sqInt -genPrimitiveAtPut(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt formatReg; - AbstractInstruction *jumpArrayOutOfBounds; - AbstractInstruction *jumpBadIndex; - AbstractInstruction *jumpBytesOutOfBounds; - AbstractInstruction *jumpBytesOutOfRange; - AbstractInstruction * jumpFixedFieldsOutOfBounds; - AbstractInstruction *jumpHasFixedFields; - AbstractInstruction *jumpImmediate; - AbstractInstruction * jumpImmutable; - AbstractInstruction *jumpIsBytes; - AbstractInstruction * jumpIsCompiledMethod; - AbstractInstruction *jumpIsContext; - AbstractInstruction *jumpIsShorts; - AbstractInstruction * jumpNonSmallIntegerValue; - AbstractInstruction *jumpNotIndexableBits; - AbstractInstruction *jumpNotIndexablePointers; - AbstractInstruction * jumpNotPointers; - AbstractInstruction *jumpShortsOutOfBounds; - AbstractInstruction *jumpShortsOutOfRange; - AbstractInstruction *jumpWordsOutOfBounds; - AbstractInstruction *jumpWordsOutOfRange; - AbstractInstruction *methodInBounds; - sqInt nSlotsOrBytesReg; - - jumpImmutable = ((AbstractInstruction *) 0); - nSlotsOrBytesReg = ClassReg; - /* begin genLoadArgAtDepth:into: */ - assert(1 < (numRegArgs())); - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - jumpImmediate = genJumpImmediate(ReceiverResultReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpBadIndex = genJumpNotSmallInteger(Arg0Reg); - genConvertSmallIntegerToIntegerInReg(Arg0Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(SubCqR, 1, Arg0Reg); -# if IMMUTABILITY - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), TempReg); - /* begin genJumpBaseHeaderImmutable: */ - immutableBitMask(); - anInstruction17 = genoperandoperand(TstCqR, immutableBitMask(), TempReg); - /* begin JumpNonZero: */ - jumpImmutable = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -# else // IMMUTABILITY - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), NoReg); -# endif // IMMUTABILITY - genGetNumSlotsOfinto(ReceiverResultReg, nSlotsOrBytesReg); - /* begin checkQuickConstant:forInstruction: */ - weakArrayFormat(); - anInstruction2 = genoperandoperand(CmpCqR, weakArrayFormat(), formatReg); - /* begin JumpAbove: */ - jumpNotPointers = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - genStoreCheckReceiverRegvalueRegscratchReginFrame(ReceiverResultReg, Arg1Reg, TempReg, 0); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction3 = genoperandoperand(CmpCqR, arrayFormat(), formatReg); - /* begin JumpBelow: */ - jumpNotIndexablePointers = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin JumpNonZero: */ - jumpHasFixedFields = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpArrayOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddCq:R: */ - anInstruction4 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg0Reg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, Arg1Reg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpHasFixedFields, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genGetClassIndexOfNonImminto(ReceiverResultReg, formatReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, formatReg); - /* begin JumpZero: */ - jumpIsContext = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin PushR: */ - genoperand(PushR, nSlotsOrBytesReg); - genGetClassObjectOfClassIndexintoscratchReg(formatReg, nSlotsOrBytesReg, TempReg); - genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, nSlotsOrBytesReg, formatReg); - /* begin PopR: */ - genoperand(PopR, nSlotsOrBytesReg); - genConvertSmallIntegerToIntegerInReg(formatReg); - /* begin checkQuickConstant:forInstruction: */ - fixedFieldsOfClassFormatMask(); - anInstruction6 = genoperandoperand(AndCqR, fixedFieldsOfClassFormatMask(), formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, nSlotsOrBytesReg); - /* begin AddCq:R: */ - anInstruction7 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), formatReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpFixedFieldsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddR:R: */ - genoperandoperand(AddRR, formatReg, Arg0Reg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, Arg1Reg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotPointers, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNonSmallIntegerValue = genJumpNotSmallInteger(Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction8 = genoperandoperand(CmpCqR, firstByteFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsBytes = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstShortFormat(); - anInstruction9 = genoperandoperand(CmpCqR, firstShortFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsShorts = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction10 = genoperandoperand(CmpCqR, firstLongFormat(), formatReg); - /* begin JumpBelow: */ - jumpNotIndexableBits = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpWordsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - if (!(setsConditionCodesFor(lastOpcode(), JumpLess))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, TempReg); - } - /* begin JumpLess: */ - jumpWordsOutOfRange = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin AddCq:R: */ - anInstruction11 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg0Reg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, TempReg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsBytes, checkQuickConstantforInstruction((((usqInt)0xFF << 1) | 1), genoperandoperand(CmpCqR, (((usqInt)0xFF << 1) | 1), Arg1Reg))); - /* begin JumpAbove: */ - jumpBytesOutOfRange = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), nSlotsOrBytesReg); - gAndCqRR(BytesPerWord - 1, formatReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, nSlotsOrBytesReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpBytesOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction12 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsCompiledMethod = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - methodInBounds = genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperand(AddCqR, BaseHeaderSize, Arg0Reg); - /* begin MoveR:Xbr:R: */ - genoperandoperandoperand(MoveRXbrR, TempReg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsShorts, checkQuickConstantforInstruction((((usqInt)0xFFFF << 1) | 1), genoperandoperand(CmpCqR, (((usqInt)0xFFFF << 1) | 1), Arg1Reg))); - /* begin JumpAbove: */ - jumpShortsOutOfRange = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (shiftForWord()) - 1, nSlotsOrBytesReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(AndCqR, (BytesPerWord / 2) - 1, formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, nSlotsOrBytesReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpShortsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperandoperand(MoveRM16r, TempReg, BaseHeaderSize, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsCompiledMethod, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - getLiteralCountOfplusOneinBytesintoscratch(ReceiverResultReg, 1, 1, nSlotsOrBytesReg, TempReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelow: */ - genConditionalBranchoperand(JumpBelow, ((sqInt)methodInBounds)); - jmpTarget(jumpIsContext, jmpTarget(jumpNotIndexableBits, jmpTarget(jumpBytesOutOfRange, jmpTarget(jumpWordsOutOfRange, jmpTarget(jumpShortsOutOfRange, jmpTarget(jumpIsCompiledMethod, jmpTarget(jumpArrayOutOfBounds, jmpTarget(jumpBytesOutOfBounds, jmpTarget(jumpShortsOutOfBounds, jmpTarget(jumpWordsOutOfBounds, jmpTarget(jumpNotIndexablePointers, jmpTarget(jumpNonSmallIntegerValue, jmpTarget(jumpFixedFieldsOutOfBounds, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))))))))))))); -# if IMMUTABILITY - jmpTarget(jumpImmutable, ((AbstractInstruction *) (((jumpIsContext->operands))[0]))); -# endif - /* begin checkQuickConstant:forInstruction: */ - anInstruction16 = genoperandoperand(AddCqR, 1, Arg0Reg); - genConvertIntegerToSmallIntegerInReg(Arg0Reg); - jmpTarget(jumpBadIndex, jmpTarget(jumpImmediate, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return 0; -} - - -/* Generate the code for primitives 61 & 165, at:put:/basicAt:put: & - integerAt:put:. If signedVersion is true - then generate signed accesses to the bits classes (a la 164 & 165). If - signedVersion is false, - generate unsigned accesses (a la 60, 61, 63 & 64). */ -/* c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: - fixedFieldsOf:format:length: - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveAtPutSigned: */ -static sqInt NoDbgRegParms -genPrimitiveAtPutSigned(sqInt signedVersion) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt formatReg; - AbstractInstruction * jumpArrayOutOfBounds; - AbstractInstruction * jumpBadIndex; - AbstractInstruction * jumpBytesOutOfBounds; - AbstractInstruction * jumpBytesOutOfRange; - AbstractInstruction * jumpFixedFieldsOutOfBounds; - AbstractInstruction * jumpHasFixedFields; - AbstractInstruction * jumpImmediate; - AbstractInstruction * jumpImmutable; - AbstractInstruction * jumpIsBytes; - AbstractInstruction * jumpIsCompiledMethod; - AbstractInstruction * jumpIsContext; - AbstractInstruction * jumpIsShorts; - AbstractInstruction * jumpNonSmallIntegerValue; - AbstractInstruction * jumpNotIndexableBits; - AbstractInstruction * jumpNotIndexablePointers; - AbstractInstruction * jumpNotPointers; - AbstractInstruction * jumpShortsOutOfBounds; - AbstractInstruction * jumpShortsOutOfRange; - AbstractInstruction * jumpWordsOutOfBounds; - AbstractInstruction * jumpWordsOutOfRange; - AbstractInstruction * methodInBounds; - sqInt nSlotsOrBytesReg; - - jumpImmutable = ((AbstractInstruction *) 0); - jumpWordsOutOfRange = ((AbstractInstruction *) 0); - nSlotsOrBytesReg = ClassReg; - /* begin genLoadArgAtDepth:into: */ - assert(1 < (numRegArgs())); - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - jumpImmediate = genJumpImmediate(ReceiverResultReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpBadIndex = genJumpNotSmallInteger(Arg0Reg); - genConvertSmallIntegerToIntegerInReg(Arg0Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(SubCqR, 1, Arg0Reg); -# if IMMUTABILITY - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), TempReg); - /* begin genJumpBaseHeaderImmutable: */ - immutableBitMask(); - anInstruction21 = genoperandoperand(TstCqR, immutableBitMask(), TempReg); - /* begin JumpNonZero: */ - jumpImmutable = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -# else // IMMUTABILITY - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), NoReg); -# endif // IMMUTABILITY - genGetNumSlotsOfinto(ReceiverResultReg, nSlotsOrBytesReg); - /* begin checkQuickConstant:forInstruction: */ - weakArrayFormat(); - anInstruction6 = genoperandoperand(CmpCqR, weakArrayFormat(), formatReg); - /* begin JumpAbove: */ - jumpNotPointers = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - genStoreCheckReceiverRegvalueRegscratchReginFrame(ReceiverResultReg, Arg1Reg, TempReg, 0); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction7 = genoperandoperand(CmpCqR, arrayFormat(), formatReg); - /* begin JumpBelow: */ - jumpNotIndexablePointers = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin JumpNonZero: */ - jumpHasFixedFields = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpArrayOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddCq:R: */ - anInstruction8 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg0Reg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, Arg1Reg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpHasFixedFields, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genGetClassIndexOfNonImminto(ReceiverResultReg, formatReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, formatReg); - /* begin JumpZero: */ - jumpIsContext = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin PushR: */ - genoperand(PushR, nSlotsOrBytesReg); - genGetClassObjectOfClassIndexintoscratchReg(formatReg, nSlotsOrBytesReg, TempReg); - genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, nSlotsOrBytesReg, formatReg); - /* begin PopR: */ - genoperand(PopR, nSlotsOrBytesReg); - genConvertSmallIntegerToIntegerInReg(formatReg); - /* begin checkQuickConstant:forInstruction: */ - fixedFieldsOfClassFormatMask(); - anInstruction10 = genoperandoperand(AndCqR, fixedFieldsOfClassFormatMask(), formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, nSlotsOrBytesReg); - /* begin AddCq:R: */ - anInstruction11 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), formatReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpFixedFieldsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddR:R: */ - genoperandoperand(AddRR, formatReg, Arg0Reg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, Arg1Reg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotPointers, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNonSmallIntegerValue = genJumpNotSmallInteger(Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction12 = genoperandoperand(CmpCqR, firstByteFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsBytes = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstShortFormat(); - anInstruction13 = genoperandoperand(CmpCqR, firstShortFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsShorts = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction14 = genoperandoperand(CmpCqR, firstLongFormat(), formatReg); - /* begin JumpBelow: */ - jumpNotIndexableBits = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpWordsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - if (!signedVersion) { - if (!(setsConditionCodesFor(lastOpcode(), JumpLess))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, TempReg); - } - /* begin JumpLess: */ - jumpWordsOutOfRange = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - } - /* begin AddCq:R: */ - anInstruction15 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg0Reg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, TempReg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - if (signedVersion) { - jmpTarget(jumpIsBytes, gArithmeticShiftRightCqRR(8, Arg1Reg, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AddCqR, 1, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(CmpCqR, 1, TempReg); - } - else { - jmpTarget(jumpIsBytes, checkQuickConstantforInstruction((((usqInt)0xFF << 1) | 1), genoperandoperand(CmpCqR, (((usqInt)0xFF << 1) | 1), Arg1Reg))); - } - /* begin JumpAbove: */ - jumpBytesOutOfRange = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), nSlotsOrBytesReg); - gAndCqRR(BytesPerWord - 1, formatReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, nSlotsOrBytesReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpBytesOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction16 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsCompiledMethod = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - methodInBounds = genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperand(AddCqR, BaseHeaderSize, Arg0Reg); - /* begin MoveR:Xbr:R: */ - genoperandoperandoperand(MoveRXbrR, TempReg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - if (signedVersion) { - jmpTarget(jumpIsShorts, gArithmeticShiftRightCqRR(16, Arg1Reg, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(AddCqR, 1, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, 1, TempReg); - } - else { - jmpTarget(jumpIsShorts, checkQuickConstantforInstruction((((usqInt)0xFFFF << 1) | 1), genoperandoperand(CmpCqR, (((usqInt)0xFFFF << 1) | 1), Arg1Reg))); - } - /* begin JumpAbove: */ - jumpShortsOutOfRange = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (shiftForWord()) - 1, nSlotsOrBytesReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction18 = genoperandoperand(AndCqR, (BytesPerWord / 2) - 1, formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, nSlotsOrBytesReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpShortsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperandoperand(MoveRM16r, TempReg, BaseHeaderSize, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsCompiledMethod, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - getLiteralCountOfplusOneinBytesintoscratch(ReceiverResultReg, 1, 1, nSlotsOrBytesReg, TempReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelow: */ - genConditionalBranchoperand(JumpBelow, ((sqInt)methodInBounds)); - jmpTarget(jumpIsContext, jmpTarget(jumpNotIndexableBits, jmpTarget(jumpBytesOutOfRange, jmpTarget(jumpShortsOutOfRange, jmpTarget(jumpIsCompiledMethod, jmpTarget(jumpArrayOutOfBounds, jmpTarget(jumpBytesOutOfBounds, jmpTarget(jumpShortsOutOfBounds, jmpTarget(jumpWordsOutOfBounds, jmpTarget(jumpNotIndexablePointers, jmpTarget(jumpNonSmallIntegerValue, jmpTarget(jumpFixedFieldsOutOfBounds, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))))))))))); - if (!signedVersion) { - jmpTarget(jumpWordsOutOfRange, ((AbstractInstruction *) (((jumpIsContext->operands))[0]))); - } -# if IMMUTABILITY - jmpTarget(jumpImmutable, ((AbstractInstruction *) (((jumpIsContext->operands))[0]))); -# endif - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperand(AddCqR, 1, Arg0Reg); - genConvertIntegerToSmallIntegerInReg(Arg0Reg); - jmpTarget(jumpBadIndex, jmpTarget(jumpImmediate, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return 0; -} - - -/* Generate the code for primitives 60 & 164, at:/basicAt: & integerAt:. If - signedVersion is true - then generate signed accesses to the bits classes (a la 164 & 165). If - signedVersion is false, - generate unsigned accesses (a la 60, 61, 63 & 64). */ -/* c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: - fixedFieldsOf:format:length: - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveAtSigned: */ -static sqInt NoDbgRegParms -genPrimitiveAtSigned(sqInt signedVersion) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - AbstractInstruction * convertToIntAndReturn; - AbstractInstruction * first; - AbstractInstruction * first1; - sqInt formatReg; - AbstractInstruction * jumpArrayOutOfBounds; - AbstractInstruction * jumpBadIndex; - AbstractInstruction * jumpBytesOutOfBounds; - AbstractInstruction * jumpFixedFieldsOutOfBounds; - AbstractInstruction * jumpHasFixedFields; - AbstractInstruction * jumpImmediate; - AbstractInstruction * jumpIsArray; - AbstractInstruction * jumpIsBytes; - AbstractInstruction * jumpIsContext; - AbstractInstruction * jumpIsMethod; - AbstractInstruction * jumpIsShorts; - AbstractInstruction * jumpIsWords; - AbstractInstruction * jumpNotIndexable; - AbstractInstruction * jumpShortsOutOfBounds; - AbstractInstruction * jumpWordsOutOfBounds; - AbstractInstruction * jumpWordTooBig; - AbstractInstruction * methodInBounds; - sqInt nSlotsOrBytesReg; - - nSlotsOrBytesReg = ClassReg; - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - jumpImmediate = genJumpImmediate(ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, Arg1Reg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpBadIndex = genJumpNotSmallInteger(Arg0Reg); - genConvertSmallIntegerToIntegerInReg(Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, 1, Arg1Reg); - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), TempReg); - genGetNumSlotsOfinto(ReceiverResultReg, nSlotsOrBytesReg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction1 = genoperandoperand(CmpCqR, firstByteFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsBytes = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction2 = genoperandoperand(CmpCqR, arrayFormat(), formatReg); - /* begin JumpZero: */ - jumpIsArray = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin JumpBelow: */ - jumpNotIndexable = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - weakArrayFormat(); - anInstruction3 = genoperandoperand(CmpCqR, weakArrayFormat(), formatReg); - /* begin JumpBelowOrEqual: */ - jumpHasFixedFields = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstShortFormat(); - anInstruction4 = genoperandoperand(CmpCqR, firstShortFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsShorts = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction5 = genoperandoperand(CmpCqR, firstLongFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsWords = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - jmpTarget(jumpNotIndexable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin Jump: */ - jumpNotIndexable = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpIsArray, (assert(!((Arg1Reg == SPReg))), - genoperandoperand(CmpRR, Arg1Reg, nSlotsOrBytesReg))); - /* begin JumpBelowOrEqual: */ - jumpArrayOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddCq:R: */ - anInstruction6 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg1Reg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, Arg1Reg, ReceiverResultReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsBytes, genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), nSlotsOrBytesReg)); - gAndCqRR(BytesPerWord - 1, formatReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, nSlotsOrBytesReg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpBytesOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction7 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsMethod = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(AddCqR, BaseHeaderSize, Arg1Reg); - methodInBounds = anInstruction8; - if (signedVersion) { - /* begin MoveXbr:R:R: */ - genoperandoperandoperand(MoveXbrRR, Arg1Reg, ReceiverResultReg, ReceiverResultReg); - } - else { - - /* formatReg already contains a value <= 16r1f, so no need to zero it */ - /* begin MoveXbr:R:R: */ - genoperandoperandoperand(MoveXbrRR, Arg1Reg, ReceiverResultReg, formatReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, formatReg, ReceiverResultReg); - } - if (signedVersion) { - /* begin SignExtend8R:R: */ - /* begin LogicalShiftLeftCq:R: */ - first = genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 8, ReceiverResultReg); - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, (BytesPerWord * 8) - 8, ReceiverResultReg); - goto l8; - l8: /* end SignExtend8R:R: */; - } - /* begin Label */ - convertToIntAndReturn = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - genConvertIntegerToSmallIntegerInReg(ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsShorts, gLogicalShiftLeftCqR((shiftForWord()) - 1, nSlotsOrBytesReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(AndCqR, 1, formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, nSlotsOrBytesReg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpShortsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg1Reg, ReceiverResultReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg1Reg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveM16rR, BaseHeaderSize, ReceiverResultReg, ReceiverResultReg); - if (signedVersion) { - /* begin SignExtend16R:R: */ - /* begin LogicalShiftLeftCq:R: */ - first1 = genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 16, ReceiverResultReg); - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, (BytesPerWord * 8) - 16, ReceiverResultReg); - goto l13; - l13: /* end SignExtend16R:R: */; - } - /* begin Jump: */ - genoperand(Jump, ((sqInt)convertToIntAndReturn)); - jmpTarget(jumpIsWords, (assert(!((Arg1Reg == SPReg))), - genoperandoperand(CmpRR, Arg1Reg, nSlotsOrBytesReg))); - /* begin JumpBelowOrEqual: */ - jumpWordsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddCq:R: */ - anInstruction11 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg1Reg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, Arg1Reg, ReceiverResultReg, TempReg); - jumpWordTooBig = jumpNotSmallIntegerUnsignedValueInRegister(TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)convertToIntAndReturn)); - jmpTarget(jumpHasFixedFields, checkQuickConstantforInstruction(classIndexMask(), genoperandoperand(AndCqR, classIndexMask(), TempReg))); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, formatReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, TempReg); - /* begin JumpZero: */ - jumpIsContext = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin PushR: */ - genoperand(PushR, nSlotsOrBytesReg); - genGetClassObjectOfClassIndexintoscratchReg(formatReg, nSlotsOrBytesReg, TempReg); - genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, nSlotsOrBytesReg, formatReg); - /* begin PopR: */ - genoperand(PopR, nSlotsOrBytesReg); - genConvertSmallIntegerToIntegerInReg(formatReg); - /* begin checkQuickConstant:forInstruction: */ - fixedFieldsOfClassFormatMask(); - anInstruction13 = genoperandoperand(AndCqR, fixedFieldsOfClassFormatMask(), formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, nSlotsOrBytesReg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpFixedFieldsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddR:R: */ - genoperandoperand(AddRR, formatReg, Arg1Reg); - /* begin AddCq:R: */ - anInstruction14 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg1Reg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, Arg1Reg, ReceiverResultReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsMethod, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - getLiteralCountOfplusOneinBytesintoscratch(ReceiverResultReg, 1, 1, nSlotsOrBytesReg, TempReg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, nSlotsOrBytesReg); - /* begin JumpBelow: */ - genConditionalBranchoperand(JumpBelow, ((sqInt)methodInBounds)); - jmpTarget(jumpWordTooBig, jmpTarget(jumpFixedFieldsOutOfBounds, jmpTarget(jumpArrayOutOfBounds, jmpTarget(jumpBytesOutOfBounds, jmpTarget(jumpShortsOutOfBounds, jmpTarget(jumpWordsOutOfBounds, jmpTarget(jumpNotIndexable, jmpTarget(jumpIsContext, jmpTarget(jumpBadIndex, jmpTarget(jumpImmediate, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))))))))); - return 0; -} - - -/* Arguably we should fail for immediates, but so far no one has complained, - so... - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveIdentityHash */ -static sqInt -genPrimitiveIdentityHash(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction * inst; - AbstractInstruction *jumpImm; - AbstractInstruction *jumpNotSet; - AbstractInstruction *jumpSI; - AbstractInstruction * ret; - - jumpImm = genJumpImmediate(ReceiverResultReg); - genGetHashFieldNonImmOfasSmallIntegerInto(ReceiverResultReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, ConstZero, TempReg); - /* begin JumpZero: */ - jumpNotSet = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - ret = genoperand(RetN, 0); - } - else { - /* begin RetN: */ - ret = genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpImm, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - jumpSI = genJumpSmallInteger(ReceiverResultReg); - jmpTarget(jumpSI, ret); - genConvertCharacterToSmallIntegerInReg(ReceiverResultReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)ret)); - jmpTarget(jumpNotSet, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (!(primitiveIndex == 75)) { - return 0; - } - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceNewHashTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin PopR: */ - genoperand(PopR, LinkReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - return UnfailingPrimitive; -} - - -/* :Assume the receiuver is never a SmallInteger. One would use ^self for - that. - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveImmediateAsInteger */ -static sqInt -genPrimitiveImmediateAsInteger(void) -{ - genConvertCharacterToSmallIntegerInReg(ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - return UnfailingPrimitive; -} - - -/* Implement primitiveNew for convenient cases: - - the receiver has a hash - - the receiver is fixed size (excluding ephemerons to save instructions & - miniscule time) - - single word header/num slots < numSlotsMask - - the result fits in eden (actually below scavengeThreshold) - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveNew */ -static sqInt -genPrimitiveNew(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt byteSizeReg; - AbstractInstruction *fillLoop; - sqInt fillReg; - sqInt halfHeaderReg; - sqInt instSpecReg; - AbstractInstruction *jumpHasSlots; - AbstractInstruction *jumpNoSpace; - AbstractInstruction *jumpTooBig; - AbstractInstruction *jumpUnhashed; - AbstractInstruction *jumpVariableOrEphemeron; - sqInt quickConstant; - sqInt quickConstant1; - AbstractInstruction *skip; - - if (methodOrBlockNumArgs != 0) { - return UnimplementedPrimitive; - } - - /* inst spec will hold class's instance specification, then byte size and finally end of new object. */ - halfHeaderReg = (fillReg = SendNumArgsReg); - - /* get freeStart as early as possible so as not to wait later... */ - instSpecReg = (byteSizeReg = ClassReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction = genoperandoperand(MoveAwR, freeStartAddress(), Arg1Reg); - genGetHashFieldNonImmOfinto(ReceiverResultReg, halfHeaderReg); - /* begin JumpZero: */ - jumpUnhashed = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, ReceiverResultReg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, instSpecReg); - /* begin LogicalShiftRightCq:R: */ - quickConstant = fixedFieldsFieldWidth(); - genoperandoperand(LogicalShiftRightCqR, quickConstant, TempReg); - /* begin checkQuickConstant:forInstruction: */ - formatMask(); - anInstruction1 = genoperandoperand(AndCqR, formatMask(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - fixedFieldsOfClassFormatMask(); - anInstruction2 = genoperandoperand(AndCqR, fixedFieldsOfClassFormatMask(), instSpecReg); - /* begin checkQuickConstant:forInstruction: */ - nonIndexablePointerFormat(); - anInstruction3 = genoperandoperand(CmpCqR, nonIndexablePointerFormat(), TempReg); - /* begin JumpAbove: */ - jumpVariableOrEphemeron = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - numSlotsMask(); - anInstruction4 = genoperandoperand(CmpCqR, numSlotsMask(), instSpecReg); - /* begin JumpAboveOrEqual: */ - jumpTooBig = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - quickConstant1 = formatShift(); - genoperandoperand(LogicalShiftLeftCqR, quickConstant1, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, halfHeaderReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(MoveRMwr, halfHeaderReg, 0, Arg1Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instSpecReg, halfHeaderReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(CmpCqR, 0, byteSizeReg); - /* begin JumpNonZero: */ - jumpHasSlots = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(MoveCqR, BaseHeaderSize * 2, byteSizeReg); - /* begin Jump: */ - skip = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpHasSlots, genoperandoperand(MoveRR, byteSizeReg, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(AndCqR, 1, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, byteSizeReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(AddCqR, BaseHeaderSize / BytesPerWord, byteSizeReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), byteSizeReg); - jmpTarget(skip, genoperandoperand(LogicalShiftLeftCqR, numSlotsHalfShift(), halfHeaderReg)); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg1Reg, byteSizeReg); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction10 = genoperandoperand(CmpCqR, getScavengeThreshold(), byteSizeReg); - /* begin JumpAboveOrEqual: */ - jumpNoSpace = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction11 = genoperandoperand(MoveRAw, byteSizeReg, freeStartAddress()); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveRMwr, halfHeaderReg, 4, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperandoperand(LoadEffectiveAddressMwrR, BaseHeaderSize, ReceiverResultReg, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - nilObject(); - anInstruction14 = genoperandoperand(MoveCqR, nilObject(), fillReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperandoperand(MoveRMwr, fillReg, 0, Arg1Reg); - fillLoop = anInstruction15; - /* begin checkQuickConstant:forInstruction: */ - anInstruction16 = genoperandoperandoperand(MoveRMwr, fillReg, 4, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperand(AddCqR, 8, Arg1Reg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, byteSizeReg); - /* begin JumpAbove: */ - genConditionalBranchoperand(JumpAbove, ((sqInt)fillLoop)); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpUnhashed, jmpTarget(jumpVariableOrEphemeron, jmpTarget(jumpTooBig, jmpTarget(jumpNoSpace, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))); - return 0; -} - - -/* Implement primitiveNewWithArg for convenient cases: - - the receiver has a hash - - the receiver is variable and not compiled method - - single word header/num slots < numSlotsMask - - the result fits in eden - See superclass method for dynamic frequencies of formats. - For the moment we implement only arrayFormat, firstByteFormat & - firstLongFormat - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveNewWithArg */ -static sqInt -genPrimitiveNewWithArg(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction22; - AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt byteSizeReg; - AbstractInstruction *fillLoop; - sqInt fillReg; - sqInt halfHeaderReg; - sqInt instSpecReg; - AbstractInstruction *jumpArrayFormat; - AbstractInstruction *jumpArrayTooBig; - AbstractInstruction *jumpByteFormat; - AbstractInstruction *jumpBytePrepDone; - AbstractInstruction *jumpByteTooBig; - AbstractInstruction *jumpFailCuzFixed; - AbstractInstruction *jumpHasSlots; - AbstractInstruction *jumpLongPrepDone; - AbstractInstruction *jumpLongTooBig; - AbstractInstruction *jumpNElementsNonInt; - AbstractInstruction *jumpNoSpace; - AbstractInstruction *jumpUnhashed; - sqInt maxSlots; - sqInt quickConstant; - sqInt quickConstant1; - sqInt quickConstant2; - AbstractInstruction *skip; - - if (methodOrBlockNumArgs != 1) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - - /* inst spec will hold class's instance specification and then byte size and finally numSlots half of header */ - halfHeaderReg = (fillReg = SendNumArgsReg); - - /* The max slots we'll allocate here are those for a single header */ - instSpecReg = (byteSizeReg = ClassReg); - - /* get freeStart as early as possible so as not to wait later... */ - maxSlots = (numSlotsMask()) - 1; - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction = genoperandoperand(MoveAwR, freeStartAddress(), Arg1Reg); - genGetHashFieldNonImmOfinto(ReceiverResultReg, halfHeaderReg); - /* begin JumpZero: */ - jumpUnhashed = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - - /* get class's format inst var for inst spec (format field) */ - jumpNElementsNonInt = genJumpNotSmallInteger(Arg0Reg); - genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, ReceiverResultReg, instSpecReg); - /* begin LogicalShiftRightCq:R: */ - quickConstant = (fixedFieldsFieldWidth()) + 1 /* numSmallIntegerTagBits */; - genoperandoperand(LogicalShiftRightCqR, quickConstant, instSpecReg); - /* begin checkQuickConstant:forInstruction: */ - formatMask(); - anInstruction1 = genoperandoperand(AndCqR, formatMask(), instSpecReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instSpecReg, TempReg); - /* begin LogicalShiftLeftCq:R: */ - quickConstant1 = formatShift(); - genoperandoperand(LogicalShiftLeftCqR, quickConstant1, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, halfHeaderReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction2 = genoperandoperand(CmpCqR, arrayFormat(), instSpecReg); - /* begin JumpZero: */ - jumpArrayFormat = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction3 = genoperandoperand(CmpCqR, firstByteFormat(), instSpecReg); - /* begin JumpZero: */ - jumpByteFormat = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction4 = genoperandoperand(CmpCqR, firstLongFormat(), instSpecReg); - /* begin JumpNonZero: */ - jumpFailCuzFixed = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)maxSlots << 1) | 1); - anInstruction5 = genoperandoperand(CmpCqR, (((usqInt)maxSlots << 1) | 1), Arg0Reg); - /* begin JumpAbove: */ - jumpLongTooBig = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, instSpecReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperand(PushCq, 0); - /* begin Jump: */ - jumpLongPrepDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpByteFormat, checkQuickConstantforInstruction((((usqInt)(maxSlots * BytesPerWord) << 1) | 1), genoperandoperand(CmpCqR, (((usqInt)(maxSlots * BytesPerWord) << 1) | 1), Arg0Reg))); - /* begin JumpAbove: */ - jumpByteTooBig = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, instSpecReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(MoveCqR, BytesPerWord, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, instSpecReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(AndCqR, BytesPerWord - 1, TempReg); - /* begin LogicalShiftLeftCq:R: */ - quickConstant2 = formatShift(); - genoperandoperand(LogicalShiftLeftCqR, quickConstant2, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, halfHeaderReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(AddCqR, BytesPerWord - 1, instSpecReg); - /* begin LogicalShiftRightCq:R: */ - genoperandoperand(LogicalShiftRightCqR, shiftForWord(), instSpecReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperand(PushCq, 0); - /* begin Jump: */ - jumpBytePrepDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpArrayFormat, checkQuickConstantforInstruction((((usqInt)maxSlots << 1) | 1), genoperandoperand(CmpCqR, (((usqInt)maxSlots << 1) | 1), Arg0Reg))); - /* begin JumpAbove: */ - jumpArrayTooBig = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, instSpecReg); - /* begin checkLiteral:forInstruction: */ - nilObject(); - anInstruction11 = genoperand(PushCw, nilObject()); - jmpTarget(jumpBytePrepDone, jmpTarget(jumpLongPrepDone, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveRMwr, halfHeaderReg, 0, Arg1Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instSpecReg, halfHeaderReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperand(CmpCqR, 0, byteSizeReg); - /* begin JumpNonZero: */ - jumpHasSlots = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(MoveCqR, BaseHeaderSize * 2, byteSizeReg); - /* begin Jump: */ - skip = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpHasSlots, genoperandoperand(MoveRR, byteSizeReg, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperand(AndCqR, 1, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, byteSizeReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction16 = genoperandoperand(AddCqR, BaseHeaderSize / BytesPerWord, byteSizeReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), byteSizeReg); - jmpTarget(skip, genoperandoperand(LogicalShiftLeftCqR, numSlotsHalfShift(), halfHeaderReg)); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg1Reg, byteSizeReg); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction17 = genoperandoperand(CmpCqR, getScavengeThreshold(), byteSizeReg); - /* begin JumpAboveOrEqual: */ - jumpNoSpace = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction18 = genoperandoperand(MoveRAw, byteSizeReg, freeStartAddress()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperandoperand(MoveRMwr, halfHeaderReg, 4, ReceiverResultReg); - /* begin PopR: */ - genoperand(PopR, fillReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperandoperand(LoadEffectiveAddressMwrR, BaseHeaderSize, ReceiverResultReg, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperandoperand(MoveRMwr, fillReg, 0, Arg1Reg); - fillLoop = anInstruction21; - /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperandoperand(MoveRMwr, fillReg, 4, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction23 = genoperandoperand(AddCqR, 8, Arg1Reg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, byteSizeReg); - /* begin JumpAbove: */ - genConditionalBranchoperand(JumpAbove, ((sqInt)fillLoop)); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNoSpace, genoperand(PopR, TempReg)); - jmpTarget(jumpUnhashed, jmpTarget(jumpFailCuzFixed, jmpTarget(jumpArrayTooBig, jmpTarget(jumpByteTooBig, jmpTarget(jumpLongTooBig, jmpTarget(jumpNElementsNonInt, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))))); - return 0; -} - - -/* Implement primitiveShallowCopy/primitiveClone for convenient cases: - - the receiver is not a context - - the receiver is not a compiled method - - the result fits in eden (actually below scavengeThreshold) */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveShallowCopy */ -static sqInt -genPrimitiveShallowCopy(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction22; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - AbstractInstruction *continuance; - AbstractInstruction *copyLoop; - sqInt formatReg; - AbstractInstruction * jumpEmpty; - AbstractInstruction *jumpImmediate; - AbstractInstruction *jumpIsMethod; - AbstractInstruction *jumpNoSpace; - AbstractInstruction *jumpTooBig; - AbstractInstruction *jumpVariable; - sqInt ptrReg; - sqInt quickConstant; - sqInt quickConstant1; - sqInt resultReg; - sqInt slotsReg; - - jumpImmediate = genJumpImmediate(ReceiverResultReg); - resultReg = Arg0Reg; - - /* get freeStart as early as possible so as not to wait later... */ - slotsReg = Arg1Reg; - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction = genoperandoperand(MoveAwR, freeStartAddress(), resultReg); - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (ptrReg = (formatReg = SendNumArgsReg)), NoReg); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction1 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsMethod = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - indexablePointersFormat(); - anInstruction2 = genoperandoperand(CmpCqR, indexablePointersFormat(), formatReg); - /* begin JumpZero: */ - jumpVariable = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin Label */ - continuance = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - genGetRawSlotSizeOfNonImminto(ReceiverResultReg, slotsReg); - /* begin checkQuickConstant:forInstruction: */ - numSlotsMask(); - anInstruction3 = genoperandoperand(CmpCqR, numSlotsMask(), slotsReg); - /* begin JumpZero: */ - jumpTooBig = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, 0, slotsReg); - /* begin JumpZero: */ - jumpEmpty = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, slotsReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(AndCqR, 1, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, slotsReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(AddCqR, BaseHeaderSize / BytesPerWord, slotsReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), slotsReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, resultReg, slotsReg); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction7 = genoperandoperand(CmpCqR, getScavengeThreshold(), slotsReg); - /* begin JumpAboveOrEqual: */ - jumpNoSpace = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, resultReg, ptrReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction8 = genoperandoperand(MoveRAw, slotsReg, freeStartAddress()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(SubCqR, BytesPerWord * 2, slotsReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveMwrR, 0, ReceiverResultReg, TempReg); - /* begin AndCq:R: */ - quickConstant = (((sqInt)((usqInt)((formatMask())) << (formatShift())))) + (classIndexMask()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperand(AndCqR, quickConstant, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveRMwr, TempReg, 0, resultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperandoperand(MoveMwrR, BytesPerWord, ReceiverResultReg, TempReg); - /* begin AndCq:R: */ - quickConstant1 = ((sqInt)((usqInt)((numSlotsMask())) << (numSlotsHalfShift()))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(AndCqR, quickConstant1, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperandoperand(MoveRMwr, TempReg, BytesPerWord, resultReg); - /* begin Label */ - copyLoop = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - /* begin checkQuickConstant:forInstruction: */ - anInstruction16 = genoperandoperand(AddCqR, BytesPerWord * 2, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperand(AddCqR, BytesPerWord * 2, ptrReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction18 = genoperandoperandoperand(MoveMwrR, 0, ReceiverResultReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperandoperand(MoveRMwr, TempReg, 0, ptrReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperandoperand(MoveMwrR, BytesPerWord, ReceiverResultReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperandoperand(MoveRMwr, TempReg, BytesPerWord, ptrReg); - /* begin CmpR:R: */ - assert(!((ptrReg == SPReg))); - genoperandoperand(CmpRR, ptrReg, slotsReg); - /* begin JumpAbove: */ - genConditionalBranchoperand(JumpAbove, ((sqInt)copyLoop)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, resultReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpVariable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genGetClassIndexOfNonImminto(ReceiverResultReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, ClassReg); - /* begin JumpNonZero: */ - genConditionalBranchoperand(JumpNonZero, ((sqInt)continuance)); - jmpTarget(jumpImmediate, jmpTarget(jumpNoSpace, jmpTarget(jumpIsMethod, jmpTarget(jumpTooBig, jmpTarget(jumpEmpty, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))))); - return 0; -} - - -/* c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: - fixedFieldsOf:format:length: - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveStringAt */ -static sqInt -genPrimitiveStringAt(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - AbstractInstruction *done; - sqInt formatReg; - AbstractInstruction *jumpBadIndex; - AbstractInstruction *jumpBytesOutOfBounds; - AbstractInstruction *jumpIsBytes; - AbstractInstruction *jumpIsShorts; - AbstractInstruction *jumpNotIndexable; - AbstractInstruction *jumpShortsOutOfBounds; - AbstractInstruction *jumpWordsDone; - AbstractInstruction *jumpWordsOutOfBounds; - AbstractInstruction *jumpWordTooBig; - - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, Arg1Reg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpBadIndex = genJumpNotSmallInteger(Arg0Reg); - genConvertSmallIntegerToIntegerInReg(Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(SubCqR, 1, Arg1Reg); - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), NoReg); - genGetNumSlotsOfinto(ReceiverResultReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction2 = genoperandoperand(CmpCqR, firstByteFormat(), formatReg); - /* begin JumpGreaterOrEqual: */ - jumpIsBytes = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstShortFormat(); - anInstruction3 = genoperandoperand(CmpCqR, firstShortFormat(), formatReg); - /* begin JumpGreaterOrEqual: */ - jumpIsShorts = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction4 = genoperandoperand(CmpCqR, firstLongFormat(), formatReg); - /* begin JumpLess: */ - jumpNotIndexable = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, ClassReg); - /* begin JumpBelowOrEqual: */ - jumpWordsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddCq:R: */ - anInstruction5 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg1Reg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, Arg1Reg, ReceiverResultReg, TempReg); - jumpWordTooBig = jumpNotCharacterUnsignedValueInRegister(TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - /* begin Jump: */ - jumpWordsDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpIsBytes, genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), ClassReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(AndCqR, BytesPerWord - 1, formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, ClassReg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, ClassReg); - /* begin JumpBelowOrEqual: */ - jumpBytesOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(AddCqR, BaseHeaderSize, Arg1Reg); - /* begin MoveXbr:R:R: */ - genoperandoperandoperand(MoveXbrRR, Arg1Reg, ReceiverResultReg, ReceiverResultReg); - /* begin AndCq:R: */ - anInstruction = genoperandoperand(AndCqR, 0xFF, ReceiverResultReg); - jmpTarget(jumpWordsDone, (done = genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - genConvertIntegerToCharacterInReg(ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsShorts, gLogicalShiftLeftCqR((shiftForWord()) - 1, ClassReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(AndCqR, (BytesPerWord / 1) - 1, formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, ClassReg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, ClassReg); - /* begin JumpBelowOrEqual: */ - jumpShortsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg1Reg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperandoperand(MoveM16rR, BaseHeaderSize, ReceiverResultReg, ReceiverResultReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)done)); - jmpTarget(jumpWordTooBig, jmpTarget(jumpBytesOutOfBounds, jmpTarget(jumpShortsOutOfBounds, jmpTarget(jumpWordsOutOfBounds, jmpTarget(jumpNotIndexable, jmpTarget(jumpBadIndex, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))))); - return CompletePrimitive; -} - - -/* c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: - fixedFieldsOf:format:length: - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveStringAtPut */ -static sqInt -genPrimitiveStringAtPut(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt formatReg; - AbstractInstruction *jumpBadArg; - AbstractInstruction *jumpBadIndex; - AbstractInstruction *jumpBytesOutOfBounds; - AbstractInstruction *jumpBytesOutOfRange; - AbstractInstruction * jumpImmutable; - AbstractInstruction *jumpIsBytes; - AbstractInstruction * jumpIsCompiledMethod; - AbstractInstruction *jumpIsShorts; - AbstractInstruction * jumpNotString; - AbstractInstruction *jumpShortsOutOfBounds; - AbstractInstruction *jumpShortsOutOfRange; - AbstractInstruction *jumpWordsOutOfBounds; - AbstractInstruction *jumpWordsOutOfRange; - - jumpImmutable = ((AbstractInstruction *) 0); - /* begin genLoadArgAtDepth:into: */ - assert(1 < (numRegArgs())); - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - jumpBadIndex = genJumpNotSmallInteger(Arg0Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - jumpBadArg = genJumpNotCharacterInScratchReg(TempReg); - genConvertSmallIntegerToIntegerInReg(Arg0Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, 1, Arg0Reg); -# if IMMUTABILITY - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), TempReg); - /* begin genJumpBaseHeaderImmutable: */ - immutableBitMask(); - anInstruction12 = genoperandoperand(TstCqR, immutableBitMask(), TempReg); - /* begin JumpNonZero: */ - jumpImmutable = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -# else // IMMUTABILITY - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), NoReg); -# endif // IMMUTABILITY - genGetNumSlotsOfinto(ReceiverResultReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction1 = genoperandoperand(CmpCqR, firstLongFormat(), formatReg); - /* begin JumpBelow: */ - jumpNotString = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction2 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsCompiledMethod = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction3 = genoperandoperand(CmpCqR, firstByteFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsBytes = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstShortFormat(); - anInstruction4 = genoperandoperand(CmpCqR, firstShortFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsShorts = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(CmpCqR, 0, Arg1Reg); - /* begin JumpLess: */ - jumpWordsOutOfRange = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, ClassReg); - /* begin JumpBelowOrEqual: */ - jumpWordsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertCharacterToCodeInReg(TempReg); - /* begin AddCq:R: */ - anInstruction6 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg0Reg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, TempReg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsShorts, gCmpCqR(characterObjectOf(0xFFFF), Arg1Reg)); - /* begin JumpAbove: */ - jumpShortsOutOfRange = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (shiftForWord()) - 1, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(AndCqR, (BytesPerWord / 2) - 1, formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, ClassReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, ClassReg); - /* begin JumpBelowOrEqual: */ - jumpShortsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertCharacterToCodeInReg(TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperandoperand(MoveRM16r, TempReg, BaseHeaderSize, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsBytes, gCmpCqR(characterObjectOf(0xFF), Arg1Reg)); - /* begin JumpAbove: */ - jumpBytesOutOfRange = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(AndCqR, BytesPerWord - 1, formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, ClassReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, ClassReg); - /* begin JumpBelowOrEqual: */ - jumpBytesOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertCharacterToCodeInReg(TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperand(AddCqR, BaseHeaderSize, Arg0Reg); - /* begin MoveR:Xbr:R: */ - genoperandoperandoperand(MoveRXbrR, TempReg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotString, jmpTarget(jumpBytesOutOfRange, jmpTarget(jumpShortsOutOfRange, jmpTarget(jumpWordsOutOfRange, jmpTarget(jumpIsCompiledMethod, jmpTarget(jumpBytesOutOfBounds, jmpTarget(jumpShortsOutOfBounds, jmpTarget(jumpWordsOutOfBounds, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))))))); -# if IMMUTABILITY - jmpTarget(jumpImmutable, ((AbstractInstruction *) (((jumpNotString->operands))[0]))); -# endif - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperand(AddCqR, 1, Arg0Reg); - genConvertIntegerToSmallIntegerInReg(Arg0Reg); - jmpTarget(jumpBadArg, jmpTarget(jumpBadIndex, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - /* CogObjectRepresentationFor32BitSpur>>#genRemoveSmallIntegerTagsInScratchReg: */ -static sqInt NoDbgRegParms -genRemoveSmallIntegerTagsInScratchReg(sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, 1, scratchReg); - return 0; -} - - /* CogObjectRepresentationFor32BitSpur>>#genShiftAwaySmallIntegerTagsInScratchReg: */ -static sqInt NoDbgRegParms -genShiftAwaySmallIntegerTagsInScratchReg(sqInt scratchReg) -{ - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, 1, scratchReg); - return 0; -} - - -/* Get the literal count of a CompiledMethod into headerReg, plus one if - requested. If inBytes is true, scale the count by the word size. Deal with - the possibility of - the method being cogged. */ - - /* CogObjectRepresentationFor32BitSpur>>#getLiteralCountOf:plusOne:inBytes:into:scratch: */ -static sqInt NoDbgRegParms -getLiteralCountOfplusOneinBytesintoscratch(sqInt methodReg, sqInt plusOne, sqInt inBytes, sqInt litCountReg, sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - sqInt quickConstant; - sqInt quickConstant1; - - genGetMethodHeaderOfintoscratch(methodReg, litCountReg, scratchReg); - if (inBytes) { - /* begin AndCq:R: */ - quickConstant = ((sqInt)((usqInt)((alternateHeaderNumLiteralsMask())) << 1)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, quickConstant, litCountReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, 1, litCountReg); - } - else { - /* begin LogicalShiftRightCq:R: */ - genoperandoperand(LogicalShiftRightCqR, 1, litCountReg); - /* begin checkQuickConstant:forInstruction: */ - alternateHeaderNumLiteralsMask(); - anInstruction1 = genoperandoperand(AndCqR, alternateHeaderNumLiteralsMask(), litCountReg); - } - if (plusOne) { - /* begin AddCq:R: */ - quickConstant1 = (inBytes - ? BytesPerWord - : 1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AddCqR, quickConstant1, litCountReg); - } - return 0; -} - - -/* Answer the relevant inline cache tag for an instance. - c.f. getInlineCacheClassTagFrom:into: & inlineCacheTagForClass: */ - - /* CogObjectRepresentationFor32BitSpur>>#inlineCacheTagForInstance: */ -static sqInt NoDbgRegParms -inlineCacheTagForInstance(sqInt oop) -{ - return (isImmediate(oop) - ? oop & 1 - : classIndexOf(oop)); -} - - /* CogObjectRepresentationFor32BitSpur>>#jumpNotSmallIntegerUnsignedValueInRegister: */ -static AbstractInstruction * NoDbgRegParms -jumpNotSmallIntegerUnsignedValueInRegister(sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0x3FFFFFFF, reg); - /* begin JumpAbove: */ - return genConditionalBranchoperand(JumpAbove, ((sqInt)0)); -} - - -/* Mark and trace a literal in an inline cache preceding address in - cogMethodOrNil. Answer if code was modified. */ - - /* CogObjectRepresentationFor32BitSpur>>#markAndTraceCacheTagLiteral:in:atpc: */ -static sqInt NoDbgRegParms -markAndTraceCacheTagLiteralinatpc(sqInt literal, CogMethod *cogMethodOrNil, usqInt address) -{ - sqInt objOop; - - if (!(couldBeObject(literal))) { - return 0; - } - assert(addressCouldBeObj(literal)); - if (!(isForwarded(literal))) { - markAndTrace(literal); - return 0; - } - objOop = followForwarded(literal); - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheTagat(backEnd(), objOop, address); - markAndTraceUpdatedLiteralin(objOop, cogMethodOrNil); - return 1; -} - - /* CogObjectRepresentationFor32BitSpur>>#numCountersFor: */ -static usqInt NoDbgRegParms -numCountersFor(usqInt theCounters) -{ - sqInt objOop; - - if (theCounters == 0) { - return 0; - } - objOop = theCounters - BaseHeaderSize; - return numSlotsOf(objOop); -} - - /* CogObjectRepresentationFor32BitSpur>>#numSmallIntegerBits */ -static sqInt -numSmallIntegerBits(void) -{ - return 0x1F; -} - - -/* The two valid tag patterns are 0 (Character) and 1 (SmallInteger) */ - - /* CogObjectRepresentationFor32BitSpur>>#validInlineCacheTag: */ -static sqInt NoDbgRegParms -validInlineCacheTag(usqInt classIndexOrTagPattern) -{ - return (classIndexOrTagPattern <= 1) - || ((classAtIndex(classIndexOrTagPattern)) != null); -} - - -/* Generate a branch if reg is an instance of any of the classes in arrayObj, - otherwise fall-through. reg should not be edited. */ - - /* CogObjectRepresentationForSpur>>#branchIf:instanceOfBehaviors:target: */ -static sqInt NoDbgRegParms -branchIfinstanceOfBehaviorstarget(sqInt reg, sqInt arrayObj, AbstractInstruction *targetFixUp) -{ - sqInt allImmediate; - sqInt classObj; - sqInt i; - sqInt iLimiT; - sqInt immediateMask; - sqInt noneImmediate; - sqInt numNonImmediates; - - - /* let me tell you all about it, let me falsify */ - allImmediate = 1; - noneImmediate = 1; - immediateMask = 0; - numNonImmediates = 0; - for (i = 0, iLimiT = ((numSlotsOf(arrayObj)) - 1); i <= iLimiT; i += 1) { - classObj = fetchPointerofObject(i, arrayObj); - if (isImmediateClass(classObj)) { - noneImmediate = 0; - immediateMask += classTagForClass(classObj); - } - else { - allImmediate = 0; - numNonImmediates += 1; - } - } - if (noneImmediate) { - return noneImmediateBranchIfinstanceOfBehaviorstarget(reg, arrayObj, targetFixUp); - } - if (allImmediate) { - /* begin allImmediate:branchIf:instanceOfBehaviors:target: */ - assert(immediateMask == (tagMask())); - jmpTarget(genJumpImmediate(reg), targetFixUp); - return 0; - } - return mixedbranchIfinstanceOfBehaviorstarget(numNonImmediates, reg, arrayObj, targetFixUp); -} - - -/* Generate a branch if reg is an instance of any of the classes in arrayObj, - otherwise fall-through. reg should not be edited. */ - - /* CogObjectRepresentationForSpur>>#branchIf:notInstanceOfBehaviors:target: */ -static sqInt NoDbgRegParms -branchIfnotInstanceOfBehaviorstarget(sqInt reg, sqInt arrayObj, AbstractInstruction *targetFixUp) -{ - sqInt allImmediate; - sqInt classObj; - sqInt i; - sqInt iLimiT; - sqInt immediateMask; - sqInt noneImmediate; - sqInt numNonImmediates; - - - /* let me tell you all about it, let me falsify */ - allImmediate = 1; - noneImmediate = 1; - immediateMask = 0; - numNonImmediates = 0; - for (i = 0, iLimiT = ((numSlotsOf(arrayObj)) - 1); i <= iLimiT; i += 1) { - classObj = fetchPointerofObject(i, arrayObj); - if (isImmediateClass(classObj)) { - noneImmediate = 0; - immediateMask += classTagForClass(classObj); - } - else { - allImmediate = 0; - numNonImmediates += 1; - } - } - if (noneImmediate) { - return noneImmediateBranchIfnotInstanceOfBehaviorstarget(reg, arrayObj, targetFixUp); - } - if (allImmediate) { - /* begin allImmediate:branchIf:notInstanceOfBehaviors:target: */ - assert(immediateMask == (tagMask())); - jmpTarget(genJumpNotImmediate(reg), targetFixUp); - return 0; - } - return mixedbranchIfnotInstanceOfBehaviorstarget(numNonImmediates, reg, arrayObj, targetFixUp); -} - - /* CogObjectRepresentationForSpur>>#callStoreCheckTrampoline */ -static void -callStoreCheckTrampoline(void) -{ - AbstractInstruction *abstractInstruction; - - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceStoreCheckTrampoline); - (abstractInstruction->annotation = IsRelativeCall); -} - - /* CogObjectRepresentationForSpur>>#checkValidDerivedObjectReference: */ -static sqInt NoDbgRegParms -checkValidDerivedObjectReference(sqInt bodyAddress) -{ - return (heapMapAtWord(pointerForOop(bodyAddress - BaseHeaderSize))) != 0; -} - - /* CogObjectRepresentationForSpur>>#checkValidOopReference: */ -static sqInt NoDbgRegParms -checkValidOopReference(sqInt anOop) -{ - return (isImmediate(anOop)) - || ((heapMapAtWord(pointerForOop(anOop))) != 0); -} - - /* CogObjectRepresentationForSpur>>#couldBeDerivedObject: */ -static sqInt NoDbgRegParms -couldBeDerivedObject(sqInt bodyAddress) -{ - return oopisGreaterThanOrEqualTo(bodyAddress - BaseHeaderSize, startOfMemory()); -} - - /* CogObjectRepresentationForSpur>>#couldBeObject: */ -static sqInt NoDbgRegParms -couldBeObject(sqInt literal) -{ - return (isNonImmediate(literal)) - && (oopisGreaterThanOrEqualTo(literal, startOfMemory())); -} - - -/* Create a trampoline to answer the active context that will - answer it if a frame is already married, and create it otherwise. - Assume numArgs is in SendNumArgsReg and ClassReg is free. */ - - /* CogObjectRepresentationForSpur>>#genActiveContextTrampolineLarge:inBlock:called: */ -static usqInt NoDbgRegParms -genActiveContextTrampolineLargeinBlockcalled(sqInt isLarge, sqInt isInBlock, char *aString) -{ - usqInt startAddress; - - startAddress = methodZoneBase(); - zeroOpcodeIndex(); - genGetActiveContextLargeinBlock(isLarge, isInBlock); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress(aString, startAddress); - recordRunTimeObjectReferences(); - return startAddress; -} - - /* CogObjectRepresentationForSpur>>#genAllocFloatValue:into:scratchReg:scratchReg: */ -static AbstractInstruction * NoDbgRegParms -genAllocFloatValueintoscratchRegscratchReg(sqInt dpreg, sqInt resultReg, sqInt scratch1, sqInt scratch2) -{ - usqIntptr_t allocSize; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *jumpFail; - usqLong newFloatHeader; - - allocSize = BaseHeaderSize + (sizeof(double)); - newFloatHeader = headerForSlotsformatclassIndex((sizeof(double)) / BytesPerWord, firstLongFormat(), ClassFloatCompactIndex); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction = genoperandoperand(MoveAwR, freeStartAddress(), resultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(LoadEffectiveAddressMwrR, allocSize, resultReg, scratch1); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction2 = genoperandoperand(CmpCqR, getScavengeThreshold(), scratch1); - /* begin JumpAboveOrEqual: */ - jumpFail = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction3 = genoperandoperand(MoveRAw, scratch1, freeStartAddress()); - /* begin genStoreHeader:intoNewInstance:using: */ - anInstruction4 = genoperandoperand(MoveCqR, ((usqInt) newFloatHeader), scratch1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperandoperand(MoveRMwr, scratch1, 0, resultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperand(MoveCqR, (newFloatHeader) >> 32, scratch1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction31 = genoperandoperandoperand(MoveRMwr, scratch1, 4, resultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(MoveRdM64r, dpreg, BaseHeaderSize, resultReg); - return jumpFail; -} - - -/* Check the remembered bit of the object in objReg; answer the jump taken if - the bit is already set. - Only need to fetch the byte containing it, which reduces the size of the - mask constant. - */ - - /* CogObjectRepresentationForSpur>>#genCheckRememberedBitOf:scratch: */ -static AbstractInstruction * NoDbgRegParms -genCheckRememberedBitOfscratch(sqInt objReg, sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt mask; - sqInt rememberedBitByteOffset; - - rememberedBitByteOffset = (rememberedBitShift()) / 8; - mask = 1U << ((rememberedBitShift()) % 8); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMbrR, rememberedBitByteOffset, objReg, scratchReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(TstCqR, mask, scratchReg); - /* begin JumpNonZero: */ - return genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -} - - -/* It is safe to use a short comparison for the known classes; these will not - change with become, etc... But it's probably not safe to assume the hash - of some other class won't change over time, so to be sure of generating - the same size code over time, use a long comparison for unknown classes. */ - - /* CogObjectRepresentationForSpur>>#genCmpClassIndex:R: */ -static void NoDbgRegParms -genCmpClassIndexR(sqInt classIndex, sqInt reg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - if (classIndex < (classTablePageSize())) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, classIndex, TempReg); - } - else { - /* begin checkLiteral:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCwR, classIndex, TempReg); - } -} - - /* CogObjectRepresentationForSpur>>#genConvertCharacterToCodeInReg: */ -static sqInt NoDbgRegParms -genConvertCharacterToCodeInReg(sqInt reg) -{ - sqInt quickConstant; - - /* begin LogicalShiftRightCq:R: */ - quickConstant = numTagBits(); - genoperandoperand(LogicalShiftRightCqR, quickConstant, reg); - return 0; -} - - /* CogObjectRepresentationForSpur>>#genConvertIntegerToCharacterInReg: */ -static sqInt NoDbgRegParms -genConvertIntegerToCharacterInReg(sqInt reg) -{ - AbstractInstruction *anInstruction; - sqInt quickConstant; - - /* begin LogicalShiftLeftCq:R: */ - quickConstant = numTagBits(); - genoperandoperand(LogicalShiftLeftCqR, quickConstant, reg); - /* begin checkQuickConstant:forInstruction: */ - characterTag(); - anInstruction = genoperandoperand(AddCqR, characterTag(), reg); - return 0; -} - - -/* Create a closure with the given startpc, numArgs and numCopied - within a context with ctxtNumArgs, large if isLargeCtxt that is in a - block if isInBlock. If numCopied > 0 pop those values off the stack. */ - - /* CogObjectRepresentationForSpur>>#genCreateClosureAt:numArgs:numCopied:contextNumArgs:large:inBlock: */ -static sqInt NoDbgRegParms -genCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(sqInt bcpc, sqInt numArgs, sqInt numCopied, sqInt ctxtNumArgs, sqInt isLargeCtxt, sqInt isInBlock) -{ - AbstractInstruction *anInstruction; - sqInt i; - - genNoPopCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(bcpc, numArgs, numCopied, ctxtNumArgs, isLargeCtxt, isInBlock); - for (i = 1; i <= numCopied; i += 1) { - /* begin PopR: */ - genoperand(PopR, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveRMwr, TempReg, (((numCopied - i) + ClosureFirstCopiedValueIndex) * BytesPerOop) + BaseHeaderSize, ReceiverResultReg); - } - return 0; -} - - -/* Create a full closure with the given values. */ - - /* CogObjectRepresentationForSpur>>#genCreateFullClosure:numArgs:numCopied:ignoreContext:contextNumArgs:large:inBlock: */ -static sqInt NoDbgRegParms -genCreateFullClosurenumArgsnumCopiedignoreContextcontextNumArgslargeinBlock(sqInt compiledBlock, sqInt numArgs, sqInt numCopied, sqInt ignoreContext, sqInt contextNumArgs, sqInt contextIsLarge, sqInt contextIsBlock) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - usqInt byteSize; - sqInt constant; - usqLong header; - sqInt numSlots; - AbstractInstruction *skip; - - - /* First get thisContext into ReceiverResultReg and thence in ClassReg. */ - if (ignoreContext) { - /* begin genMoveConstant:R: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ClassReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperand(MoveCqR, constant, ClassReg); - } - } - else { - genGetActiveContextNumArgslargeinBlock(contextNumArgs, contextIsLarge, contextIsBlock); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, ClassReg); - } - numSlots = FullClosureFirstCopiedValueIndex + numCopied; - byteSize = smallObjectBytesForSlots(numSlots); - assert(ClassFullBlockClosureCompactIndex != 0); - header = headerForSlotsformatclassIndex(numSlots, indexablePointersFormat(), ClassFullBlockClosureCompactIndex); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction1 = genoperandoperand(MoveAwR, freeStartAddress(), ReceiverResultReg); - /* begin genStoreHeader:intoNewInstance:using: */ - anInstruction4 = genoperandoperand(MoveCqR, ((usqInt) header), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperandoperand(MoveRMwr, TempReg, 0, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, (header) >> 32, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperandoperand(MoveRMwr, TempReg, 4, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(LoadEffectiveAddressMwrR, byteSize, ReceiverResultReg, TempReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction6 = genoperandoperand(MoveRAw, TempReg, freeStartAddress()); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction7 = genoperandoperand(CmpCqR, getScavengeThreshold(), TempReg); - /* begin JumpBelow: */ - skip = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceScheduleScavengeTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperandoperand(MoveRMwr, ClassReg, (ClosureOuterContextIndex * BytesPerOop) + BaseHeaderSize, ReceiverResultReg); - if (shouldAnnotateObjectReference(compiledBlock)) { - annotateobjRef(gMoveCwR(compiledBlock, TempReg), compiledBlock); - } - else { - /* begin MoveCq:R: */ - anInstruction = genoperandoperand(MoveCqR, compiledBlock, TempReg); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperandoperand(MoveRMwr, TempReg, (ClosureStartPCIndex * BytesPerOop) + BaseHeaderSize, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)numArgs << 1) | 1); - anInstruction10 = genoperandoperand(MoveCqR, (((usqInt)numArgs << 1) | 1), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveRMwr, TempReg, (ClosureNumArgsIndex * BytesPerOop) + BaseHeaderSize, ReceiverResultReg); - return 0; -} - - -/* Make sure that the object in reg is not forwarded. This routine assumes - the object will - never be forwarded to an immediate, as it is used to unforward literal - variables (associations). - Use the fact that isForwardedObjectClassIndexPun is a power of two to save - an instruction. */ - - /* CogObjectRepresentationForSpur>>#genEnsureObjInRegNotForwarded:scratchReg: */ -static sqInt NoDbgRegParms -genEnsureObjInRegNotForwardedscratchReg(sqInt reg, sqInt scratch) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *loop; - AbstractInstruction *ok; - sqInt quickConstant; - - assert(reg != scratch); - /* begin Label */ - loop = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, reg, scratch); - /* begin AndCq:R: */ - quickConstant = (classIndexMask()) - (isForwardedObjectClassIndexPun()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, quickConstant, scratch); - /* begin JumpNonZero: */ - ok = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(0, reg, reg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)loop)); - jmpTarget(ok, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - /* CogObjectRepresentationForSpur>>#genEnsureOopInRegNotForwarded:scratchReg: */ -static sqInt NoDbgRegParms -genEnsureOopInRegNotForwardedscratchReg(sqInt reg, sqInt scratch) -{ - AbstractInstruction *instruction; - - /* begin genEnsureOopInRegNotForwarded:scratchReg:jumpBackTo: */ - instruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - return genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(reg, scratch, instruction, 0); -} - - -/* Make sure that the oop in reg is not forwarded. - Use the fact that isForwardedObjectClassIndexPun is a power of two to save - an instruction. */ -/* maybe a fixup or an instruction */ -/* maybe a fixup or an instruction */ - - /* CogObjectRepresentationForSpur>>#genEnsureOopInRegNotForwarded:scratchReg:ifForwarder:ifNotForwarder: */ -static sqInt NoDbgRegParms -genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(sqInt reg, sqInt scratch, void *fwdJumpTarget, void *nonFwdJumpTargetOrZero) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction * finished; - AbstractInstruction * imm; - AbstractInstruction * ok; - sqInt quickConstant; - - assert(reg != scratch); - - /* notionally - self genGetClassIndexOfNonImm: reg into: scratch. - cogit CmpCq: objectMemory isForwardedObjectClassIndexPun R: TempReg. - but the following is an instruction shorter: */ - imm = genJumpImmediate(reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, reg, scratch); - /* begin AndCq:R: */ - quickConstant = (classIndexMask()) - (isForwardedObjectClassIndexPun()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, quickConstant, scratch); - /* begin JumpNonZero: */ - ok = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(0, reg, reg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)fwdJumpTarget)); - if ((((usqInt)nonFwdJumpTargetOrZero)) == 0) { - /* begin Label */ - finished = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - else { - finished = nonFwdJumpTargetOrZero; - } - jmpTarget(imm, jmpTarget(ok, finished)); - return 0; -} - - -/* Make sure that the oop in reg is not forwarded, updating the slot in - objReg with the value. - */ - - /* CogObjectRepresentationForSpur>>#genEnsureOopInRegNotForwarded:scratchReg:updatingSlot:in: */ -static sqInt NoDbgRegParms -genEnsureOopInRegNotForwardedscratchRegupdatingSlotin(sqInt reg, sqInt scratch, sqInt index, sqInt objReg) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *imm; - AbstractInstruction *loop; - AbstractInstruction *ok; - sqInt quickConstant; - - - /* Open-code - self genEnsureOopInRegNotForwarded: reg - scratchReg: scratch - updatingMw: index * objectMemory wordSize + objectMemory baseHeaderSize - r: objReg. - to avoid calling the store check unless the receiver is forwarded. */ - assert((reg != scratch) - && (objReg != scratch)); - /* begin Label */ - loop = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - - /* notionally - self genGetClassIndexOfNonImm: reg into: scratch. - cogit CmpCq: objectMemory isForwardedObjectClassIndexPun R: TempReg. - but the following is an instruction shorter: */ - imm = genJumpImmediate(reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, reg, scratch); - /* begin AndCq:R: */ - quickConstant = (classIndexMask()) - (isForwardedObjectClassIndexPun()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, quickConstant, scratch); - /* begin JumpNonZero: */ - ok = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(0, reg, reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveRMwr, reg, (index * BytesPerWord) + BaseHeaderSize, objReg); - assert((reg == Arg0Reg) - && ((scratch == TempReg) - && (objReg == ReceiverResultReg))); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceStoreCheckContextReceiverTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin Jump: */ - genoperand(Jump, ((sqInt)loop)); - jmpTarget(ok, jmpTarget(imm, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return 0; -} - - -/* Do the store check. Answer the argument for the benefit of the code - generator; ReceiverResultReg may be caller-saved and hence smashed by this - call. Answering - it allows the code generator to reload ReceiverResultReg cheaply. - In Spur the only thing we leave to the run-time is adding the receiver to - the remembered set and setting its isRemembered bit. */ - - /* CogObjectRepresentationForSpur>>#generateObjectRepresentationTrampolines */ -static void -generateObjectRepresentationTrampolines(void) -{ - sqInt instVarIndex; - AbstractInstruction *jumpSC; - - -# if IMMUTABILITY - for (instVarIndex = 0; instVarIndex < NumStoreTrampolines; instVarIndex += 1) { - ceStoreTrampolines[instVarIndex] = (genStoreTrampolineCalledinstVarIndex(trampolineNamenumArgslimit("ceStoreTrampoline", instVarIndex, NumStoreTrampolines - 2), instVarIndex)); - } -# endif // IMMUTABILITY - ceNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceNewHash", 1, ReceiverResultReg, null, null, null, /* begin emptyRegisterMask */ 0, 1, ReceiverResultReg, 0); - ceInlineNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceInlineNewHash", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, ReceiverResultReg, 0); - /* begin genStoreCheckTrampoline */ - if (CheckRememberedInTrampoline) { - zeroOpcodeIndex(); - jumpSC = genCheckRememberedBitOfscratch(ReceiverResultReg, ABIResultReg); - assert(((jumpSC->opcode)) == JumpNonZero); - (jumpSC->opcode = JumpZero); - /* begin RetN: */ - genoperand(RetN, 0); - jmpTarget(jumpSC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) - ? ReceiverResultReg - : ABIResultReg), CheckRememberedInTrampoline); - ceStoreCheckContextReceiverTrampoline = genStoreCheckContextReceiverTrampoline(); - /* begin genTrampolineFor:called:regsToSave: */ - ceScheduleScavengeTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceScheduleScavenge, "ceScheduleScavengeTrampoline", 0, null, null, null, null, CallerSavedRegisterMask, 1, NoReg, 0); - ceSmallActiveContextInMethodTrampoline = genActiveContextTrampolineLargeinBlockcalled(0, 0, "ceSmallMethodContext"); - ceSmallActiveContextInBlockTrampoline = genActiveContextTrampolineLargeinBlockcalled(0, InVanillaBlock, "ceSmallBlockContext"); - ceSmallActiveContextInFullBlockTrampoline = genActiveContextTrampolineLargeinBlockcalled(0, InFullBlock, "ceSmallFullBlockContext"); - ceLargeActiveContextInMethodTrampoline = genActiveContextTrampolineLargeinBlockcalled(1, 0, "ceLargeMethodContext"); - ceLargeActiveContextInBlockTrampoline = genActiveContextTrampolineLargeinBlockcalled(1, InVanillaBlock, "ceLargeBlockContext"); - ceLargeActiveContextInFullBlockTrampoline = genActiveContextTrampolineLargeinBlockcalled(1, InFullBlock, "ceLargeFullBlockContext"); - } - - -/* Create a trampoline to answer the active context that will - answer it if a frame is already married, and create it otherwise. - Assume numArgs is in SendNumArgsReg and ClassReg is free. */ - - /* CogObjectRepresentationForSpur>>#genGetActiveContextLarge:inBlock: */ -static sqInt NoDbgRegParms -genGetActiveContextLargeinBlock(sqInt isLarge, sqInt isInBlock) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction22; - AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction24; - AbstractInstruction *anInstruction25; - AbstractInstruction *anInstruction26; - AbstractInstruction *anInstruction27; - AbstractInstruction *anInstruction28; - AbstractInstruction *anInstruction29; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction30; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction32; - AbstractInstruction *anInstruction33; - AbstractInstruction *anInstruction34; - AbstractInstruction *anInstruction35; - AbstractInstruction *anInstruction36; - AbstractInstruction *anInstruction37; - AbstractInstruction *anInstruction38; - AbstractInstruction *anInstruction39; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction40; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt constant; - AbstractInstruction * continuation; - AbstractInstruction * exit; - usqLong header; - AbstractInstruction * inst; - AbstractInstruction * jumpNeedScavenge; - AbstractInstruction * jumpSingle; - AbstractInstruction * loopHead; - sqInt offset; - sqInt offset1; - sqInt quickConstant; - sqInt quickConstant1; - sqInt slotSize; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, FoxMethod, FPReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(TstCqR, MFMethodFlagHasContextFlag, ClassReg); - /* begin JumpZero: */ - jumpSingle = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperandoperand(MoveMwrR, FoxThisContext, FPReg, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, 0); - jmpTarget(jumpSingle, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperand(OrCqR, MFMethodFlagHasContextFlag, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperandoperand(MoveRMwr, ClassReg, FoxMethod, FPReg); - switch (isInBlock) { - case InFullBlock: - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, 3, ClassReg); - break; - case InVanillaBlock: - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(SubCqR, 3, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveM16rR, 0, ClassReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, ClassReg); - break; - case 0: - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(SubCqR, 1, ClassReg); - break; - default: - error("Case not found and no otherwise clause"); - } - slotSize = (isLarge - ? LargeContextSlots - : SmallContextSlots); - header = headerForSlotsformatclassIndex(slotSize, indexablePointersFormat(), ClassMethodContextCompactIndex); - flag("endianness"); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction12 = genoperandoperand(MoveAwR, freeStartAddress(), ReceiverResultReg); - /* begin genStoreHeader:intoNewInstance:using: */ - anInstruction13 = genoperandoperand(MoveCqR, ((usqInt) header), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperandoperand(MoveRMwr, TempReg, 0, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperand(MoveCqR, (header) >> 32, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction31 = genoperandoperandoperand(MoveRMwr, TempReg, 4, ReceiverResultReg); - /* begin LoadEffectiveAddressMw:r:R: */ - offset = smallObjectBytesForSlots(slotSize); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperandoperand(LoadEffectiveAddressMwrR, offset, ReceiverResultReg, TempReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction16 = genoperandoperand(MoveRAw, TempReg, freeStartAddress()); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction17 = genoperandoperand(CmpCqR, getScavengeThreshold(), TempReg); - /* begin JumpAboveOrEqual: */ - jumpNeedScavenge = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin LoadEffectiveAddressMw:r:R: */ - anInstruction18 = genoperandoperandoperand(LoadEffectiveAddressMwrR, 1, FPReg, TempReg); - continuation = anInstruction18; - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperandoperand(MoveRMwr, TempReg, BaseHeaderSize + (SenderIndex * BytesPerOop), ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperandoperand(MoveMwrR, FoxSavedFP, FPReg, TempReg); - genSetSmallIntegerTagsIn(TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperandoperand(MoveRMwr, TempReg, BaseHeaderSize + (InstructionPointerIndex * BytesPerOop), ReceiverResultReg); - /* begin MoveMw:r:R: */ - offset1 = offsetof(CogMethod, methodObject); - /* begin checkQuickConstant:forInstruction: */ - anInstruction23 = genoperandoperandoperand(MoveMwrR, offset1, ClassReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction24 = genoperandoperandoperand(MoveRMwr, TempReg, BaseHeaderSize + (MethodIndex * BytesPerWord), ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction25 = genoperandoperandoperand(MoveRMwr, ReceiverResultReg, FoxThisContext, FPReg); - gSubRRR(SPReg, FPReg, TempReg); - /* begin LogicalShiftRightCq:R: */ - quickConstant = 2 /* log2BytesPerWord */; - genoperandoperand(LogicalShiftRightCqR, quickConstant, TempReg); - /* begin SubCq:R: */ - quickConstant1 = 3; - /* begin checkQuickConstant:forInstruction: */ - anInstruction26 = genoperandoperand(SubCqR, quickConstant1, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, SendNumArgsReg, TempReg); - genConvertIntegerToSmallIntegerInReg(TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction27 = genoperandoperandoperand(MoveRMwr, TempReg, BaseHeaderSize + (StackPointerIndex * BytesPerOop), ReceiverResultReg); - if (isInBlock > 0) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperandoperand(LoadEffectiveAddressMwrR, 2, SendNumArgsReg, TempReg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, TempReg, FPReg, TempReg); - } - else { - /* begin genMoveConstant:R: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, TempReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction40 = genoperandoperand(MoveCqR, constant, TempReg); - } - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction28 = genoperandoperandoperand(MoveRMwr, TempReg, BaseHeaderSize + (ClosureIndex * BytesPerOop), ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction29 = genoperandoperandoperand(MoveMwrR, FoxMFReceiver, FPReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction30 = genoperandoperandoperand(MoveRMwr, TempReg, BaseHeaderSize + (ReceiverIndex * BytesPerOop), ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction32 = genoperandoperand(MoveCqR, 1, ClassReg); - /* begin CmpR:R: */ - assert(!((SendNumArgsReg == SPReg))); - loopHead = genoperandoperand(CmpRR, SendNumArgsReg, ClassReg); - /* begin JumpGreater: */ - exit = genConditionalBranchoperand(JumpGreater, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SendNumArgsReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, ClassReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction33 = genoperandoperand(AddCqR, 2, TempReg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, TempReg, FPReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction34 = genoperandoperand(AddCqR, ReceiverIndex + (BaseHeaderSize / BytesPerWord), ClassReg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, TempReg, ClassReg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction35 = genoperandoperand(SubCqR, (ReceiverIndex + (BaseHeaderSize / BytesPerWord)) - 1, ClassReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)loopHead)); - jmpTarget(exit, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - nilObject(); - anInstruction5 = genoperandoperand(MoveCqR, nilObject(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction36 = genoperandoperandoperand(LoadEffectiveAddressMwrR, FoxMFReceiver, FPReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction37 = genoperandoperand(AddCqR, (ReceiverIndex + 1) + (BaseHeaderSize / BytesPerWord), SendNumArgsReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction38 = genoperandoperand(SubCqR, BytesPerWord, ClassReg); - loopHead = anInstruction38; - /* begin CmpR:R: */ - assert(!((ClassReg == SPReg))); - genoperandoperand(CmpRR, ClassReg, SPReg); - /* begin JumpAbove: */ - exit = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, TempReg, SendNumArgsReg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction39 = genoperandoperand(AddCqR, 1, SendNumArgsReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)loopHead)); - jmpTarget(exit, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin RetN: */ - genoperand(RetN, 0); - jmpTarget(jumpNeedScavenge, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - CallRTregistersToBeSavedMask(ceScheduleScavengeTrampoline, ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)) | (1U << ClassReg)); - /* begin PopR: */ - genoperand(PopR, LinkReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuation)); - return 0; -} - - -/* Get the active context into ReceiverResultReg, creating it if necessary. */ - - /* CogObjectRepresentationForSpur>>#genGetActiveContextNumArgs:large:inBlock: */ -static sqInt NoDbgRegParms -genGetActiveContextNumArgslargeinBlock(sqInt numArgs, sqInt isLargeContext, sqInt isInBlock) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - sqInt routine; - - if (isLargeContext) { - switch (isInBlock) { - case 0: - routine = ceLargeActiveContextInMethodTrampoline; - break; - - case InVanillaBlock: - routine = ceLargeActiveContextInBlockTrampoline; - break; - - case InFullBlock: - routine = ceLargeActiveContextInFullBlockTrampoline; - break; - - default: - error("Case not found and no otherwise clause"); - routine = -1; - } - } - else { - switch (isInBlock) { - case 0: - routine = ceSmallActiveContextInMethodTrampoline; - break; - - case InVanillaBlock: - routine = ceSmallActiveContextInBlockTrampoline; - break; - - case InFullBlock: - routine = ceSmallActiveContextInFullBlockTrampoline; - break; - - default: - error("Case not found and no otherwise clause"); - routine = -1; - } - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, numArgs, SendNumArgsReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, routine); - (abstractInstruction->annotation = IsRelativeCall); - return 0; -} - - /* CogObjectRepresentationForSpur>>#genGetBits:ofFormatByteOf:into: */ -static sqInt NoDbgRegParms -genGetBitsofFormatByteOfinto(sqInt mask, sqInt sourceReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - flag("endianness"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMbrR, 3, sourceReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, mask, destReg); - return 0; -} - - -/* Fetch the instance's class index into destReg. */ - - /* CogObjectRepresentationForSpur>>#genGetClassIndexOfNonImm:into: */ -static sqInt NoDbgRegParms -genGetClassIndexOfNonImminto(sqInt sourceReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, sourceReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - classIndexMask(); - anInstruction1 = genoperandoperand(AndCqR, classIndexMask(), destReg); - return 0; -} - - -/* Fetch the class object whose index is in instReg into destReg. - It is non-obvious, but the Cogit assumes loading a class does not involve - a runtime call, so do not call classAtIndex: */ - - /* CogObjectRepresentationForSpur>>#genGetClassObjectOfClassIndex:into:scratchReg: */ -static sqInt NoDbgRegParms -genGetClassObjectOfClassIndexintoscratchReg(sqInt instReg, sqInt destReg, sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - sqInt offset; - sqInt quickConstant; - - assert(instReg != destReg); - assert(instReg != scratchReg); - assert(destReg != scratchReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instReg, scratchReg); - /* begin LogicalShiftRightCq:R: */ - quickConstant = classTableMajorIndexShift(); - genoperandoperand(LogicalShiftRightCqR, quickConstant, scratchReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), scratchReg); - assert(!(shouldAnnotateObjectReference(classTableRootObj()))); - /* begin MoveMw:r:R: */ - offset = (classTableRootObj()) + BaseHeaderSize; - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, scratchReg, destReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instReg, scratchReg); - /* begin checkQuickConstant:forInstruction: */ - classTableMinorIndexMask(); - anInstruction3 = genoperandoperand(AndCqR, classTableMinorIndexMask(), scratchReg); - /* begin AddCq:R: */ - anInstruction4 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), scratchReg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, scratchReg, destReg, destReg); - return 0; -} - - -/* Fetch the instance's class into destReg. If the instance is not the - receiver and is forwarded, follow forwarding. */ - - /* CogObjectRepresentationForSpur>>#genGetClassObjectOf:into:scratchReg:mayBeAForwarder: */ -static sqInt NoDbgRegParms -genGetClassObjectOfintoscratchRegmayBeAForwarder(sqInt instReg, sqInt destReg, sqInt scratchReg, sqInt mayBeForwarder) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *jumpIsImm; - AbstractInstruction *jumpNotForwarded; - AbstractInstruction *loop; - - if ((instReg == destReg) - || ((instReg == scratchReg) - || (destReg == scratchReg))) { - return BadRegisterSet; - } - /* begin MoveR:R: */ - loop = genoperandoperand(MoveRR, instReg, scratchReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AndCqR, tagMask(), scratchReg); - /* begin JumpNonZero: */ - jumpIsImm = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - flag("endianness"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperandoperand(MoveMwrR, 0, instReg, scratchReg); - /* begin checkQuickConstant:forInstruction: */ - classIndexMask(); - anInstruction4 = genoperandoperand(AndCqR, classIndexMask(), scratchReg); - if (mayBeForwarder) { - - /* if it is forwarded... */ - /* begin checkQuickConstant:forInstruction: */ - isForwardedObjectClassIndexPun(); - anInstruction = genoperandoperand(CmpCqR, isForwardedObjectClassIndexPun(), scratchReg); - /* begin JumpNonZero: */ - jumpNotForwarded = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, BaseHeaderSize, instReg, instReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)loop)); - jmpTarget(jumpNotForwarded, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - jmpTarget(jumpIsImm, genoperandoperand(MoveRR, scratchReg, destReg)); - if (scratchReg == TempReg) { - /* begin PushR: */ - genoperand(PushR, instReg); - genGetClassObjectOfClassIndexintoscratchReg(destReg, instReg, TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instReg, destReg); - /* begin PopR: */ - genoperand(PopR, instReg); - } - else { - genGetClassObjectOfClassIndexintoscratchReg(destReg, scratchReg, TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, scratchReg, destReg); - } - return 0; -} - - /* CogObjectRepresentationForSpur>>#genGetClassTagOf:into:scratchReg: */ -static AbstractInstruction * NoDbgRegParms -genGetClassTagOfintoscratchReg(sqInt instReg, sqInt destReg, sqInt scratchReg) -{ - return genGetInlineCacheClassTagFromintoforEntry(instReg, destReg, 1); -} - - -/* Fetch the instance's class index into destReg. */ - - /* CogObjectRepresentationForSpur>>#genGetCompactClassIndexNonImmOf:into: */ -static sqInt NoDbgRegParms -genGetCompactClassIndexNonImmOfinto(sqInt instReg, sqInt destReg) -{ - return genGetClassIndexOfNonImminto(instReg, destReg); -} - - /* CogObjectRepresentationForSpur>>#genGetDoubleValueOf:into: */ -static sqInt NoDbgRegParms -genGetDoubleValueOfinto(sqInt srcReg, sqInt destFPReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveM64rRd, BaseHeaderSize, srcReg, destFPReg); - return 0; -} - - -/* Get the format field of the object in srcReg into destReg. - srcReg may equal destReg. */ - - /* CogObjectRepresentationForSpur>>#genGetFormatOf:into: */ -static sqInt NoDbgRegParms -genGetFormatOfinto(sqInt srcReg, sqInt destReg) -{ - return genGetBitsofFormatByteOfinto(formatMask(), srcReg, destReg); -} - - -/* Get the format of the object in sourceReg into destReg. If - scratchRegOrNone is not NoReg, load at least the least significant 32-bits - (64-bits in 64-bits) of the - header word, which contains the format, into scratchRegOrNone. */ - - /* CogObjectRepresentationForSpur>>#genGetFormatOf:into:leastSignificantHalfOfBaseHeaderIntoScratch: */ -static sqInt NoDbgRegParms -genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(sqInt sourceReg, sqInt destReg, sqInt scratchRegOrNone) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - - if (scratchRegOrNone == NoReg) { - flag("endianness"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMbrR, 3, sourceReg, destReg); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, 0, sourceReg, scratchRegOrNone); - gLogicalShiftRightCqRR(formatShift(), scratchRegOrNone, destReg); - } - /* begin checkQuickConstant:forInstruction: */ - formatMask(); - anInstruction2 = genoperandoperand(AndCqR, formatMask(), destReg); - return 0; -} - - -/* ReceiverResultReg is required for the trampoline. We force the allocation, - and we have two path to avoid conflicts in ReceiverResultReg. */ - - /* CogObjectRepresentationForSpur>>#genGetIdentityHash:resultReg: */ -static void NoDbgRegParms -genGetIdentityHashresultReg(sqInt rcvrReg, sqInt resultReg) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *jumpSet; - - voidReceiverResultRegContainsSelf(); - if (resultReg == ReceiverResultReg) { - popToReg(ssTop(), rcvrReg); - genGetHashFieldNonImmOfasSmallIntegerInto(rcvrReg, resultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, ConstZero, resultReg); - /* begin JumpNonZero: */ - jumpSet = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, rcvrReg, resultReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceInlineNewHashTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - } - else { - popToReg(ssTop(), ReceiverResultReg); - genGetHashFieldNonImmOfasSmallIntegerInto(ReceiverResultReg, resultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, ConstZero, resultReg); - /* begin JumpNonZero: */ - jumpSet = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin CallRT: */ - abstractInstruction1 = genoperand(Call, ceInlineNewHashTrampoline); - (abstractInstruction1->annotation = IsRelativeCall); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, resultReg); - } - jmpTarget(jumpSet, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); -} - - -/* Create an instance of classObj and assign it to destReg, initializing the - instance if initializeInstance is true with 0 This is for inline - primitives. Assume there is sufficient space in new space to complete the - operation. */ - - /* CogObjectRepresentationForSpur>>#genGetInstanceOfByteClass:into:initializingIf:numBytes: */ -static sqInt NoDbgRegParms -genGetInstanceOfByteClassintoinitializingIfnumBytes(sqInt classObj, sqInt destReg, sqInt initializeInstance, sqInt numBytes) -{ - sqInt byteFormat; - sqInt classIndex; - sqInt numSlots; - - classIndex = rawHashBitsOf(classObj); - flag("duplication"); - numSlots = (numBytes + (BytesPerWord - 1)) / BytesPerWord; - byteFormat = (firstByteFormat()) + ((8 - numBytes) & (BytesPerWord - 1)); - assert(classIndex != 0); - genGetUninitializedInstanceWithClassIndexnumSlotsformatinto(classIndex, numSlots, byteFormat, destReg); - if (initializeInstance - && (numBytes > 0)) { - genStoreValueinstancenumSlots(0, destReg, numSlots); - } - return 0; -} - - -/* Create an instance of classObj and assign it to destReg, initializing the - instance if initializeInstance is true with nil This is for inline - primitives. Assume there is sufficient space in new space to complete the - operation. */ - - /* CogObjectRepresentationForSpur>>#genGetInstanceOfPointerClass:into:initializingIf:numVariableSlots: */ -static sqInt NoDbgRegParms -genGetInstanceOfPointerClassintoinitializingIfnumVariableSlots(sqInt classObj, sqInt destReg, sqInt initializeInstance, sqInt varSlots) -{ - sqInt classFormat; - sqInt classIndex; - sqInt fixedSlots; - sqInt totalNumSlots; - - classIndex = rawHashBitsOf(classObj); - classFormat = formatOfClass(classObj); - fixedSlots = fixedFieldsOfClassFormat(classFormat); - totalNumSlots = varSlots + fixedSlots; - assert(classIndex != 0); - genGetUninitializedInstanceWithClassIndexnumSlotsformatinto(classIndex, totalNumSlots, instSpecOfClassFormat(classFormat), destReg); - if (initializeInstance - && (totalNumSlots > 0)) { - genStoreValueinstancenumSlots(nilObject(), destReg, totalNumSlots); - } - return 0; -} - - -/* Get the size in word-sized slots of the object in srcReg into destReg. - srcReg may equal destReg. */ - - /* CogObjectRepresentationForSpur>>#genGetNumSlotsOf:into: */ -static sqInt NoDbgRegParms -genGetNumSlotsOfinto(sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *jmp; - - assert(srcReg != destReg); - genGetRawSlotSizeOfNonImminto(srcReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - numSlotsMask(); - anInstruction = genoperandoperand(CmpCqR, numSlotsMask(), destReg); - /* begin JumpLess: */ - jmp = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - genGetOverflowSlotsOfinto(srcReg, destReg); - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - -/* The raw numSlots field is the most significant byte of the 64-bit header - word. MoveMbrR zero-extends. */ - - /* CogObjectRepresentationForSpur>>#genGetRawSlotSizeOfNonImm:into: */ -static sqInt NoDbgRegParms -genGetRawSlotSizeOfNonImminto(sqInt sourceReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin MoveCq:R: */ - anInstruction = genoperandoperand(MoveCqR, 0, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMbrR, 7, sourceReg, destReg); - return 0; -} - - -/* Write in destReg the pointer to the object (adjusted based on header size) - Can deal with large header but not with with old space allocation (max - allocation size) - */ - - /* CogObjectRepresentationForSpur>>#genGetUninitializedInstanceWithClassIndex:numSlots:format:into: */ -static sqInt NoDbgRegParms -genGetUninitializedInstanceWithClassIndexnumSlotsformatinto(sqInt classIndex, sqInt numSlots, sqInt format, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - usqLong header; - sqInt lowNumSlots; - sqInt offset; - usqLong overflowHeader; - - if (numSlots >= (fixedFieldsOfClassFormatMask())) { - return UnimplementedOperation; - } - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction5 = genoperandoperand(MoveAwR, freeStartAddress(), destReg); - if (numSlots >= (numSlotsMask())) { - overflowHeader = numSlots + (((sqLong)((usqLong)((numSlotsMask())) << (numSlotsFullShift())))); - /* begin genStoreHeader:intoNewInstance:using: */ - anInstruction = genoperandoperand(MoveCqR, ((usqInt) overflowHeader), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveRMwr, TempReg, 0, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, (overflowHeader) >> 32, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperandoperand(MoveRMwr, TempReg, 4, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(AddCqR, BaseHeaderSize, destReg); - lowNumSlots = numSlotsMask(); - } - else { - lowNumSlots = numSlots; - } - header = headerForSlotsformatclassIndex(lowNumSlots, format, classIndex); - /* begin genStoreHeader:intoNewInstance:using: */ - anInstruction6 = genoperandoperand(MoveCqR, ((usqInt) header), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperandoperand(MoveRMwr, TempReg, 0, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperand(MoveCqR, (header) >> 32, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction31 = genoperandoperandoperand(MoveRMwr, TempReg, 4, destReg); - /* begin LoadEffectiveAddressMw:r:R: */ - offset = objectBytesForSlots(numSlots); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(LoadEffectiveAddressMwrR, offset, destReg, TempReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction8 = genoperandoperand(MoveRAw, TempReg, freeStartAddress()); - return 0; -} - - /* CogObjectRepresentationForSpur>>#genIfRequiredCheckRememberedBitOf:scratch: */ -static AbstractInstruction * NoDbgRegParms -genIfRequiredCheckRememberedBitOfscratch(sqInt rr, sqInt scratchReg) -{ - if (!CheckRememberedInTrampoline) { - return genCheckRememberedBitOfscratch(rr, scratchReg); - } - return 0; -} - - /* CogObjectRepresentationForSpur>>#genJumpCharacterInScratchReg: */ -static AbstractInstruction * NoDbgRegParms -genJumpCharacterInScratchReg(sqInt reg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, tagMask(), reg); - /* begin checkQuickConstant:forInstruction: */ - characterTag(); - anInstruction1 = genoperandoperand(CmpCqR, characterTag(), reg); - /* begin JumpZero: */ - return genConditionalBranchoperand(JumpZero, ((sqInt)0)); -} - - /* CogObjectRepresentationForSpur>>#genJumpImmediate: */ -static AbstractInstruction * NoDbgRegParms -genJumpImmediate(sqInt aRegister) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(TstCqR, tagMask(), aRegister); - /* begin JumpNonZero: */ - return genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -} - - /* CogObjectRepresentationForSpur>>#genJumpImmutable:scratchReg: */ -#if IMMUTABILITY -static AbstractInstruction * NoDbgRegParms -genJumpImmutablescratchReg(sqInt sourceReg, sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, sourceReg, scratchReg); - /* begin genJumpBaseHeaderImmutable: */ - immutableBitMask(); - anInstruction1 = genoperandoperand(TstCqR, immutableBitMask(), scratchReg); - /* begin JumpNonZero: */ - return genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -} -#endif /* IMMUTABILITY */ - - /* CogObjectRepresentationForSpur>>#genJumpMutable:scratchReg: */ -#if IMMUTABILITY -static AbstractInstruction * NoDbgRegParms -genJumpMutablescratchReg(sqInt sourceReg, sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, sourceReg, scratchReg); - /* begin genJumpBaseHeaderMutable: */ - immutableBitMask(); - anInstruction1 = genoperandoperand(TstCqR, immutableBitMask(), scratchReg); - /* begin JumpZero: */ - return genConditionalBranchoperand(JumpZero, ((sqInt)0)); -} -#endif /* IMMUTABILITY */ - - /* CogObjectRepresentationForSpur>>#genJumpNotCharacterInScratchReg: */ -static AbstractInstruction * NoDbgRegParms -genJumpNotCharacterInScratchReg(sqInt reg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, tagMask(), reg); - /* begin checkQuickConstant:forInstruction: */ - characterTag(); - anInstruction1 = genoperandoperand(CmpCqR, characterTag(), reg); - /* begin JumpNonZero: */ - return genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -} - - /* CogObjectRepresentationForSpur>>#genJumpNotImmediate: */ -static AbstractInstruction * NoDbgRegParms -genJumpNotImmediate(sqInt aRegister) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(TstCqR, tagMask(), aRegister); - /* begin JumpZero: */ - return genConditionalBranchoperand(JumpZero, ((sqInt)0)); -} - - -/* Generate a call to code that allocates a new Array of size. - The Array should be initialized with nils iff initialize is true. - The size arg is passed in SendNumArgsReg, the result - must come back in ReceiverResultReg. */ - - /* CogObjectRepresentationForSpur>>#genNewArrayOfSize:initialized: */ -static sqInt NoDbgRegParms -genNewArrayOfSizeinitialized(sqInt size, sqInt initialize) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - usqLong header; - sqInt i; - sqInt offset; - sqInt quickConstant; - AbstractInstruction *skip; - - assert(size < (numSlotsMask())); - header = headerForSlotsformatclassIndex(size, arrayFormat(), ClassArrayCompactIndex); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction2 = genoperandoperand(MoveAwR, freeStartAddress(), ReceiverResultReg); - /* begin genStoreHeader:intoNewInstance:using: */ - anInstruction4 = genoperandoperand(MoveCqR, ((usqInt) header), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperandoperand(MoveRMwr, TempReg, 0, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperand(MoveCqR, (header) >> 32, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperandoperand(MoveRMwr, TempReg, 4, ReceiverResultReg); - if (initialize - && (size > 0)) { - if (shouldAnnotateObjectReference(nilObject())) { - annotateobjRef(gMoveCwR(nilObject(), TempReg), nilObject()); - } - else { - /* begin MoveCq:R: */ - quickConstant = nilObject(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, TempReg); - } - for (i = 0; i < size; i += 1) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveRMwr, TempReg, (i * BytesPerWord) + BaseHeaderSize, ReceiverResultReg); - } - } - /* begin LoadEffectiveAddressMw:r:R: */ - offset = smallObjectBytesForSlots(size); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(LoadEffectiveAddressMwrR, offset, ReceiverResultReg, TempReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction6 = genoperandoperand(MoveRAw, TempReg, freeStartAddress()); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction7 = genoperandoperand(CmpCqR, getScavengeThreshold(), TempReg); - /* begin JumpBelow: */ - skip = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceScheduleScavengeTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - -/* Create a closure with the given startpc, numArgs and numCopied - within a context with ctxtNumArgs, large if isLargeCtxt that is in a - block if isInBlock. Do /not/ initialize the copied values. */ - - /* CogObjectRepresentationForSpur>>#genNoPopCreateClosureAt:numArgs:numCopied:contextNumArgs:large:inBlock: */ -static sqInt NoDbgRegParms -genNoPopCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(sqInt bcpc, sqInt numArgs, sqInt numCopied, sqInt ctxtNumArgs, sqInt isLargeCtxt, sqInt isInBlock) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - usqInt byteSize; - usqLong header; - sqInt numSlots; - AbstractInstruction *skip; - - - /* First get thisContext into ReceiverResultRega and thence in ClassReg. */ - genGetActiveContextNumArgslargeinBlock(ctxtNumArgs, isLargeCtxt, isInBlock); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, ClassReg); - numSlots = ClosureFirstCopiedValueIndex + numCopied; - byteSize = smallObjectBytesForSlots(numSlots); - header = headerForSlotsformatclassIndex(numSlots, indexablePointersFormat(), ClassBlockClosureCompactIndex); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction = genoperandoperand(MoveAwR, freeStartAddress(), ReceiverResultReg); - /* begin genStoreHeader:intoNewInstance:using: */ - anInstruction4 = genoperandoperand(MoveCqR, ((usqInt) header), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveRMwr, TempReg, 0, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, (header) >> 32, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperandoperand(MoveRMwr, TempReg, 4, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(LoadEffectiveAddressMwrR, byteSize, ReceiverResultReg, TempReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction6 = genoperandoperand(MoveRAw, TempReg, freeStartAddress()); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction7 = genoperandoperand(CmpCqR, getScavengeThreshold(), TempReg); - /* begin JumpBelow: */ - skip = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceScheduleScavengeTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperandoperand(MoveRMwr, ClassReg, (ClosureOuterContextIndex * BytesPerOop) + BaseHeaderSize, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)bcpc << 1) | 1); - anInstruction9 = genoperandoperand(MoveCqR, (((usqInt)bcpc << 1) | 1), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveRMwr, TempReg, (ClosureStartPCIndex * BytesPerOop) + BaseHeaderSize, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)numArgs << 1) | 1); - anInstruction11 = genoperandoperand(MoveCqR, (((usqInt)numArgs << 1) | 1), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveRMwr, TempReg, (ClosureNumArgsIndex * BytesPerOop) + BaseHeaderSize, ReceiverResultReg); - return 0; -} - - /* CogObjectRepresentationForSpur>>#genPrimitiveAsCharacter */ -static sqInt -genPrimitiveAsCharacter(void) -{ - AbstractInstruction *jumpNotInt; - AbstractInstruction *jumpOutOfRange; - sqInt reg; - - jumpNotInt = ((AbstractInstruction *) 0); - if (methodOrBlockNumArgs == 0) { - reg = ReceiverResultReg; - } - else { - if (methodOrBlockNumArgs > 1) { - return UnimplementedPrimitive; - } - reg = Arg0Reg; - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotInt = genJumpNotSmallInteger(reg); - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - jumpOutOfRange = jumpNotCharacterUnsignedValueInRegister(TempReg); - genConvertSmallIntegerToCharacterInReg(reg); - if (reg != ReceiverResultReg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, reg, ReceiverResultReg); - } - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpOutOfRange, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (reg != ReceiverResultReg) { - jmpTarget(jumpNotInt, ((AbstractInstruction *) (((jumpOutOfRange->operands))[0]))); - } - return CompletePrimitive; -} - - -/* Generate primitive 60, at: with unsigned access for pure bits classes. */ - - /* CogObjectRepresentationForSpur>>#genPrimitiveAt */ -static sqInt -genPrimitiveAt(void) -{ - return genPrimitiveAtSigned(0); -} - - /* CogObjectRepresentationForSpur>>#genPrimitiveIdenticalOrNotIf: */ -static sqInt NoDbgRegParms -genPrimitiveIdenticalOrNotIf(sqInt orNot) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *comp; - sqInt constant; - sqInt constant1; - AbstractInstruction *jumpCmp; - - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - comp = genoperandoperand(CmpRR, Arg0Reg, ReceiverResultReg); - if (orNot) { - /* begin JumpZero: */ - jumpCmp = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin genEnsureOopInRegNotForwarded:scratchReg:jumpBackTo: */ - genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(Arg0Reg, TempReg, comp, 0); - } - else { - /* begin JumpNonZero: */ - jumpCmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - } - /* begin genMoveConstant:R: */ - constant = trueObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpCmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (!orNot) { - /* begin genEnsureOopInRegNotForwarded:scratchReg:jumpBackTo: */ - genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(Arg0Reg, TempReg, comp, 0); - } - /* begin genMoveConstant:R: */ - constant1 = falseObject(); - if (shouldAnnotateObjectReference(constant1)) { - annotateobjRef(checkLiteralforInstruction(constant1, genoperandoperand(MoveCwR, constant1, ReceiverResultReg)), constant1); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, constant1, ReceiverResultReg); - } - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - return UnfailingPrimitive; -} - - -/* Generate primitive 164, at: with signed access for pure bits classes. */ - - /* CogObjectRepresentationForSpur>>#genPrimitiveIntegerAt */ -static sqInt -genPrimitiveIntegerAt(void) -{ - return genPrimitiveAtSigned(1); -} - - -/* Generate primitive 165, at:put: with signed access for pure bits classes. */ - - /* CogObjectRepresentationForSpur>>#genPrimitiveIntegerAtPut */ -static sqInt -genPrimitiveIntegerAtPut(void) -{ - return genPrimitiveAtPutSigned(1); -} - - -/* */ - - /* CogObjectRepresentationForSpur>>#genPrimitiveMakePoint */ -static sqInt -genPrimitiveMakePoint(void) -{ - sqInt allocSize; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction * jumpFail; - usqLong newPointHeader; - sqInt resultReg; - sqInt scratchReg; - - resultReg = ClassReg; - - /* */ - scratchReg = SendNumArgsReg; - allocSize = BaseHeaderSize + (BytesPerWord * 2); - newPointHeader = headerForSlotsformatclassIndex(2, nonIndexablePointerFormat(), ClassPointCompactIndex); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction = genoperandoperand(MoveAwR, freeStartAddress(), resultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(LoadEffectiveAddressMwrR, allocSize, resultReg, scratchReg); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction2 = genoperandoperand(CmpCqR, getScavengeThreshold(), scratchReg); - /* begin JumpAboveOrEqual: */ - jumpFail = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction3 = genoperandoperand(MoveRAw, scratchReg, freeStartAddress()); - /* begin genStoreHeader:intoNewInstance:using: */ - anInstruction4 = genoperandoperand(MoveCqR, ((usqInt) newPointHeader), scratchReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperandoperand(MoveRMwr, scratchReg, 0, resultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperand(MoveCqR, (newPointHeader) >> 32, scratchReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction31 = genoperandoperandoperand(MoveRMwr, scratchReg, 4, resultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(MoveRMwr, ReceiverResultReg, BaseHeaderSize, resultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperandoperand(MoveRMwr, Arg0Reg, BaseHeaderSize + BytesPerWord, resultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, resultReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpFail, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - /* CogObjectRepresentationForSpur>>#genPrimitiveObjectAt */ -static sqInt -genPrimitiveObjectAt(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - sqInt headerReg; - AbstractInstruction *jumpBadIndex; - AbstractInstruction *jumpBounds; - AbstractInstruction *jumpNotHeaderIndex; - sqInt quickConstant; - - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpBadIndex = genJumpNotSmallInteger(Arg0Reg); - genGetMethodHeaderOfintoscratch(ReceiverResultReg, (headerReg = Arg1Reg), TempReg); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)1 << 1) | 1); - anInstruction = genoperandoperand(CmpCqR, (((usqInt)1 << 1) | 1), Arg0Reg); - /* begin JumpNonZero: */ - jumpNotHeaderIndex = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, headerReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotHeaderIndex, gAndCqR((((usqInt)(alternateHeaderNumLiteralsMask()) << 1) | 1), headerReg)); - /* begin SubCq:R: */ - quickConstant = ((((usqInt)1 << 1) | 1)) - (smallIntegerTag()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(SubCqR, quickConstant, Arg0Reg); - /* begin CmpR:R: */ - assert(!((headerReg == SPReg))); - genoperandoperand(CmpRR, headerReg, Arg0Reg); - /* begin JumpAbove: */ - jumpBounds = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - genConvertSmallIntegerToIntegerInReg(Arg0Reg); - /* begin AddCq:R: */ - anInstruction2 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg0Reg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, Arg0Reg, ReceiverResultReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpBounds, gAddCqR(((((usqInt)1 << 1) | 1)) - (smallIntegerTag()), Arg0Reg)); - jmpTarget(jumpBadIndex, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - -/* c.f. StackInterpreter>>stSizeOf: lengthOf:baseHeader:format: - fixedFieldsOf:format:length: - */ - - /* CogObjectRepresentationForSpur>>#genPrimitiveSize */ -static sqInt -genPrimitiveSize(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - AbstractInstruction * jump32BitLongsDone; - AbstractInstruction * jump64BitLongsDone; - AbstractInstruction * jumpArrayDone; - AbstractInstruction * jumpBytesDone; - AbstractInstruction * jumpHasFixedFields; - AbstractInstruction *jumpImm; - AbstractInstruction * jumpIs64BitLongs; - AbstractInstruction * jumpIsBytes; - AbstractInstruction *jumpIsContext; - AbstractInstruction * jumpIsContext1; - AbstractInstruction * jumpIsShorts; - AbstractInstruction *jumpNotIndexable; - AbstractInstruction * jumpNotIndexable1; - AbstractInstruction * jumpShortsDone; - - jumpImm = genJumpImmediate(ReceiverResultReg); - /* begin genGetSizeOf:into:formatReg:scratchReg:abortJumpsInto: */ - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, SendNumArgsReg, TempReg); - genGetNumSlotsOfinto(ReceiverResultReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction = genoperandoperand(CmpCqR, firstByteFormat(), SendNumArgsReg); - /* begin JumpGreaterOrEqual: */ - jumpIsBytes = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction1 = genoperandoperand(CmpCqR, arrayFormat(), SendNumArgsReg); - /* begin JumpZero: */ - jumpArrayDone = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin JumpLess: */ - jumpNotIndexable1 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - weakArrayFormat(); - anInstruction2 = genoperandoperand(CmpCqR, weakArrayFormat(), SendNumArgsReg); - /* begin JumpLessOrEqual: */ - jumpHasFixedFields = genConditionalBranchoperand(JumpLessOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstShortFormat(); - anInstruction3 = genoperandoperand(CmpCqR, firstShortFormat(), SendNumArgsReg); - /* begin JumpGreaterOrEqual: */ - jumpIsShorts = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction4 = genoperandoperand(CmpCqR, firstLongFormat(), SendNumArgsReg); - /* begin JumpGreaterOrEqual: */ - jump32BitLongsDone = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - sixtyFourBitIndexableFormat(); - anInstruction5 = genoperandoperand(CmpCqR, sixtyFourBitIndexableFormat(), SendNumArgsReg); - /* begin JumpZero: */ - jumpIs64BitLongs = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - jmpTarget(jumpNotIndexable1, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin Jump: */ - jumpNotIndexable1 = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpIsBytes, genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), ClassReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(AndCqR, BytesPerWord - 1, SendNumArgsReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, SendNumArgsReg, ClassReg); - /* begin Jump: */ - jumpBytesDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpIsShorts, gLogicalShiftLeftCqR((shiftForWord()) - 1, ClassReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(AndCqR, 1, SendNumArgsReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, SendNumArgsReg, ClassReg); - /* begin Jump: */ - jumpShortsDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpIs64BitLongs, genoperandoperand(LogicalShiftRightCqR, 1, ClassReg)); - /* begin Jump: */ - jump64BitLongsDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpHasFixedFields, checkQuickConstantforInstruction(classIndexMask(), genoperandoperand(AndCqR, classIndexMask(), TempReg))); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, SendNumArgsReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, TempReg); - /* begin JumpZero: */ - jumpIsContext1 = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin PushR: */ - genoperand(PushR, ClassReg); - genGetClassObjectOfClassIndexintoscratchReg(SendNumArgsReg, ClassReg, TempReg); - genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, ClassReg, SendNumArgsReg); - genConvertSmallIntegerToIntegerInReg(SendNumArgsReg); - /* begin PopR: */ - genoperand(PopR, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - fixedFieldsOfClassFormatMask(); - anInstruction9 = genoperandoperand(AndCqR, fixedFieldsOfClassFormatMask(), SendNumArgsReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, SendNumArgsReg, ClassReg); - jmpTarget(jumpArrayDone, jmpTarget(jump64BitLongsDone, jmpTarget(jump32BitLongsDone, jmpTarget(jumpShortsDone, jmpTarget(jumpBytesDone, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))))); - jumpNotIndexable = jumpNotIndexable1; - jumpIsContext = jumpIsContext1; - genConvertIntegerInRegtoSmallIntegerInReg(ClassReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpImm, jmpTarget(jumpNotIndexable, jmpTarget(jumpIsContext, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))); - return CompletePrimitive; -} - - -/* primitiveCompareWith: */ - - /* CogObjectRepresentationForSpur>>#genPrimitiveStringCompareWith */ -static sqInt -genPrimitiveStringCompareWith(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction * instr; - AbstractInstruction *jump; - AbstractInstruction *jumpAbove; - AbstractInstruction *jumpIncorrectFormat1; - AbstractInstruction *jumpIncorrectFormat2; - AbstractInstruction *jumpIncorrectFormat3; - AbstractInstruction *jumpIncorrectFormat4; - AbstractInstruction *jumpMidFailure; - AbstractInstruction *jumpSuccess; - sqInt minSizeReg; - sqInt string1CharOrByteSizeReg; - sqInt string1Reg; - sqInt string2CharOrByteSizeReg; - sqInt string2Reg; - - - /* I redefine those name to ease program comprehension */ - string1Reg = ReceiverResultReg; - string2Reg = Arg0Reg; - string1CharOrByteSizeReg = Arg1Reg; - string2CharOrByteSizeReg = ClassReg; - - /* Load arguments in reg */ - minSizeReg = SendNumArgsReg; - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - genGetFormatOfinto(string1Reg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction = genoperandoperand(CmpCqR, firstByteFormat(), TempReg); - /* begin JumpLess: */ - jumpIncorrectFormat1 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction1 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), TempReg); - /* begin JumpAboveOrEqual: */ - jumpIncorrectFormat2 = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - genGetNumSlotsOfinto(string1Reg, string1CharOrByteSizeReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), string1CharOrByteSizeReg); - gAndCqRR(BytesPerWord - 1, TempReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, string1CharOrByteSizeReg); - genGetFormatOfinto(string2Reg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction2 = genoperandoperand(CmpCqR, firstByteFormat(), TempReg); - /* begin JumpLess: */ - jumpIncorrectFormat3 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction3 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), TempReg); - /* begin JumpAboveOrEqual: */ - jumpIncorrectFormat4 = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - genGetNumSlotsOfinto(string2Reg, string2CharOrByteSizeReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), string2CharOrByteSizeReg); - gAndCqRR(BytesPerWord - 1, TempReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, string2CharOrByteSizeReg); - /* begin CmpR:R: */ - assert(!((string1CharOrByteSizeReg == SPReg))); - genoperandoperand(CmpRR, string1CharOrByteSizeReg, string2CharOrByteSizeReg); - /* begin JumpBelow: */ - jumpAbove = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, string1CharOrByteSizeReg, minSizeReg); - /* begin Jump: */ - jump = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpAbove, genoperandoperand(MoveRR, string2CharOrByteSizeReg, minSizeReg)); - jmpTarget(jump, checkQuickConstantforInstruction(0, genoperandoperand(CmpCqR, 0, minSizeReg))); - /* begin JumpZero: */ - jumpSuccess = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(MoveCqR, BaseHeaderSize, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(AddCqR, BaseHeaderSize, minSizeReg); - /* begin MoveXbr:R:R: */ - instr = genoperandoperandoperand(MoveXbrRR, TempReg, string1Reg, string1CharOrByteSizeReg); - /* begin MoveXbr:R:R: */ - genoperandoperandoperand(MoveXbrRR, TempReg, string2Reg, string2CharOrByteSizeReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, string2CharOrByteSizeReg, string1CharOrByteSizeReg); - /* begin JumpNonZero: */ - jumpMidFailure = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(AddCqR, 1, TempReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, minSizeReg); - /* begin JumpNonZero: */ - genConditionalBranchoperand(JumpNonZero, ((sqInt)instr)); - genGetNumBytesOfinto(string1Reg, string1CharOrByteSizeReg); - genGetNumBytesOfinto(string2Reg, string2CharOrByteSizeReg); - jmpTarget(jumpSuccess, genoperandoperand(SubRR, string2CharOrByteSizeReg, string1CharOrByteSizeReg)); - jmpTarget(jumpMidFailure, genoperandoperand(MoveRR, string1CharOrByteSizeReg, ReceiverResultReg)); - genConvertIntegerToSmallIntegerInReg(ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIncorrectFormat4, jmpTarget(jumpIncorrectFormat3, jmpTarget(jumpIncorrectFormat2, jmpTarget(jumpIncorrectFormat1, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))); - return CompletePrimitive; -} - - -/* replaceFrom: start to: stop with: replacement startingAt: repStart. - - The primitive in the JIT tries to deal with two pathological cases, copy - of arrays and byteStrings, - which often copies only a dozen of fields and where switching to the C - runtime cost a lot. - - Based on heuristics on the method class, I generate a quick array path - (typically for Array), - a quick byteString path (typically for ByteString, ByteArray and - LargeInteger) or no quick - path at all (Typically for Bitmap). - - The many tests to ensure that the primitive won't fail are not super - optimised (multiple reloading - or stack arguments in registers) but this is still good enough and worth - it since we're avoiding - the Smalltalk to C stack switch. The tight copying loops are optimised. - - It is possible to build a bigger version with the 2 different paths but I - (Clement) believe this - is too big machine code wise to be worth it. - */ - - /* CogObjectRepresentationForSpur>>#genPrimitiveStringReplace */ -static sqInt -genPrimitiveStringReplace(void) -{ - sqInt adjust; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction22; - AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction24; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt arrayReg; - AbstractInstruction * inst; - AbstractInstruction * instr; - AbstractInstruction *jmpAlreadyRemembered; - AbstractInstruction *jmpDestYoung; - AbstractInstruction *jumpEmpty; - AbstractInstruction *jumpImm; - AbstractInstruction *jumpImmutable; - AbstractInstruction *jumpIncorrectFormat1; - AbstractInstruction *jumpIncorrectFormat2; - AbstractInstruction *jumpIncorrectFormat3; - AbstractInstruction *jumpIncorrectFormat4; - AbstractInstruction *jumpNotSmi1; - AbstractInstruction *jumpNotSmi2; - AbstractInstruction *jumpNotSmi3; - AbstractInstruction *jumpOutOfBounds1; - AbstractInstruction *jumpOutOfBounds2; - AbstractInstruction *jumpOutOfBounds3; - AbstractInstruction *jumpOutOfBounds4; - sqInt offset; - sqInt offset1; - sqInt offset2; - sqInt offset3; - sqInt offset4; - sqInt offset5; - sqInt offset6; - sqInt offset7; - sqInt offset8; - sqInt offset9; - sqInt replReg; - sqInt repStartReg; - sqInt result; - sqInt startReg; - sqInt stopReg; - - - /* Can I generate a quick path for this method ? */ - jmpAlreadyRemembered = ((AbstractInstruction *) 0); - jumpImmutable = ((AbstractInstruction *) 0); - jumpOutOfBounds3 = ((AbstractInstruction *) 0); - jumpOutOfBounds4 = ((AbstractInstruction *) 0); - if (!((maybeMethodClassOfseemsToBeInstantiating(methodObj, arrayFormat())) - || (maybeMethodClassOfseemsToBeInstantiating(methodObj, firstByteFormat())))) { - return UnimplementedPrimitive; - } - arrayReg = ReceiverResultReg; - startReg = Arg0Reg; - stopReg = Arg1Reg; - replReg = ClassReg; - - /* Load arguments in reg */ - repStartReg = SendNumArgsReg; - /* begin genStackArgAt:into: */ - offset6 = (0) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperandoperand(MoveMwrR, offset6, SPReg, repStartReg); - /* begin genStackArgAt:into: */ - offset7 = (1) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperandoperand(MoveMwrR, offset7, SPReg, replReg); - /* begin genStackArgAt:into: */ - offset8 = (2) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction23 = genoperandoperandoperand(MoveMwrR, offset8, SPReg, stopReg); - /* begin genStackArgAt:into: */ - offset9 = (3) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction24 = genoperandoperandoperand(MoveMwrR, offset9, SPReg, startReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSmi1 = genJumpNotSmallInteger(repStartReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSmi2 = genJumpNotSmallInteger(stopReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSmi3 = genJumpNotSmallInteger(startReg); - - /* if start>stop primitive success */ - jumpImm = genJumpImmediate(replReg); - /* begin CmpR:R: */ - assert(!((startReg == SPReg))); - genoperandoperand(CmpRR, startReg, stopReg); - /* begin JumpLess: */ - jumpEmpty = genConditionalBranchoperand(JumpLess, ((sqInt)0)); -# if IMMUTABILITY - jumpImmutable = genJumpImmutablescratchReg(ReceiverResultReg, TempReg); -# endif - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)0 << 1) | 1); - anInstruction13 = genoperandoperand(CmpCqR, (((usqInt)0 << 1) | 1), startReg); - /* begin JumpLessOrEqual: */ - jumpOutOfBounds1 = genConditionalBranchoperand(JumpLessOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)0 << 1) | 1); - anInstruction14 = genoperandoperand(CmpCqR, (((usqInt)0 << 1) | 1), repStartReg); - /* begin JumpLessOrEqual: */ - jumpOutOfBounds2 = genConditionalBranchoperand(JumpLessOrEqual, ((sqInt)0)); - if (maybeMethodClassOfseemsToBeInstantiating(methodObj, arrayFormat())) { - - /* Are they both array format ? */ - genGetFormatOfinto(arrayReg, TempReg); - genGetFormatOfinto(replReg, startReg); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction2 = genoperandoperand(CmpCqR, arrayFormat(), startReg); - /* begin JumpNonZero: */ - jumpIncorrectFormat1 = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction3 = genoperandoperand(CmpCqR, arrayFormat(), TempReg); - /* begin JumpNonZero: */ - jumpIncorrectFormat2 = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genGetNumSlotsOfinto(arrayReg, TempReg); - genConvertSmallIntegerToIntegerInReg(stopReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, stopReg); - /* begin JumpGreater: */ - jumpOutOfBounds3 = genConditionalBranchoperand(JumpGreater, ((sqInt)0)); - genGetNumSlotsOfinto(replReg, TempReg); - /* begin genStackArgAt:into: */ - offset = (3) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperandoperand(MoveMwrR, offset, SPReg, startReg); - genConvertSmallIntegerToIntegerInReg(startReg); - genConvertSmallIntegerToIntegerInReg(repStartReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, startReg, stopReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, repStartReg, stopReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, stopReg); - /* begin JumpGreater: */ - jumpOutOfBounds4 = genConditionalBranchoperand(JumpGreater, ((sqInt)0)); - /* begin checkLiteral:forInstruction: */ - storeCheckBoundary(); - anInstruction4 = genoperandoperand(MoveCwR, storeCheckBoundary(), TempReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, arrayReg); - /* begin JumpBelow: */ - jmpDestYoung = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - if (!CheckRememberedInTrampoline) { - jmpAlreadyRemembered = genCheckRememberedBitOfscratch(arrayReg, TempReg); - } - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - callStoreCheckTrampoline(); - /* begin PopR: */ - genoperand(PopR, LinkReg); - jmpTarget(jmpDestYoung, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (!CheckRememberedInTrampoline) { - jmpTarget(jmpAlreadyRemembered, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - /* begin genStackArgAt:into: */ - offset1 = (2) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction16 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, stopReg); - genConvertSmallIntegerToIntegerInReg(stopReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, startReg, repStartReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), repStartReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, repStartReg, replReg); - adjust = (((usqInt)(BaseHeaderSize)) >> (shiftForWord())) - 1; - if (adjust != 0) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, adjust, startReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AddCqR, adjust, stopReg); - } - /* begin MoveXwr:R:R: */ - instr = genoperandoperandoperand(MoveXwrRR, startReg, replReg, TempReg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, TempReg, startReg, arrayReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(AddCqR, 1, startReg); - /* begin CmpR:R: */ - assert(!((startReg == SPReg))); - genoperandoperand(CmpRR, startReg, stopReg); - /* begin JumpAboveOrEqual: */ - genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)instr)); - jmpTarget(jumpEmpty, (methodOrBlockNumArgs <= 2 /* numRegArgs */ - ? (/* begin RetN: */ - genoperand(RetN, 0)) - : (/* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord)))); - jmpTarget(jumpIncorrectFormat1, jmpTarget(jumpIncorrectFormat2, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - } - if (maybeMethodClassOfseemsToBeInstantiating(methodObj, firstByteFormat())) { - - /* Are they both byte array format ? CompiledMethod excluded */ - genGetFormatOfinto(arrayReg, TempReg); - genGetFormatOfinto(replReg, repStartReg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction8 = genoperandoperand(CmpCqR, firstByteFormat(), repStartReg); - /* begin JumpLess: */ - jumpIncorrectFormat1 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction9 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), repStartReg); - /* begin JumpGreaterOrEqual: */ - jumpIncorrectFormat2 = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction10 = genoperandoperand(CmpCqR, firstByteFormat(), TempReg); - /* begin JumpLess: */ - jumpIncorrectFormat3 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction11 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), TempReg); - /* begin JumpGreaterOrEqual: */ - jumpIncorrectFormat4 = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - genGetNumSlotsOfinto(arrayReg, startReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), startReg); - gAndCqRR(BytesPerWord - 1, TempReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, startReg); - genConvertSmallIntegerToIntegerInReg(stopReg); - /* begin CmpR:R: */ - assert(!((startReg == SPReg))); - genoperandoperand(CmpRR, startReg, stopReg); - /* begin JumpGreater: */ - jumpOutOfBounds3 = genConditionalBranchoperand(JumpGreater, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, repStartReg, TempReg); - /* begin genStackArgAt:into: */ - offset2 = (0) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, repStartReg); - /* begin genStackArgAt:into: */ - offset3 = (3) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction18 = genoperandoperandoperand(MoveMwrR, offset3, SPReg, startReg); - genConvertSmallIntegerToIntegerInReg(startReg); - genConvertSmallIntegerToIntegerInReg(repStartReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, startReg, stopReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, repStartReg, stopReg); - genGetNumSlotsOfinto(replReg, startReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), startReg); - gAndCqRR(BytesPerWord - 1, TempReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, startReg); - /* begin CmpR:R: */ - assert(!((startReg == SPReg))); - genoperandoperand(CmpRR, startReg, stopReg); - /* begin JumpGreater: */ - jumpOutOfBounds4 = genConditionalBranchoperand(JumpGreater, ((sqInt)0)); - /* begin genStackArgAt:into: */ - offset4 = (3) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperandoperand(MoveMwrR, offset4, SPReg, startReg); - genConvertSmallIntegerToIntegerInReg(startReg); - /* begin genStackArgAt:into: */ - offset5 = (2) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperandoperand(MoveMwrR, offset5, SPReg, stopReg); - genConvertSmallIntegerToIntegerInReg(stopReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, startReg, repStartReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, repStartReg, replReg); - adjust = BaseHeaderSize - 1; - if (adjust != 0) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(AddCqR, adjust, startReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(AddCqR, adjust, stopReg); - } - /* begin MoveXbr:R:R: */ - instr = genoperandoperandoperand(MoveXbrRR, startReg, replReg, TempReg); - /* begin MoveR:Xbr:R: */ - genoperandoperandoperand(MoveRXbrR, TempReg, startReg, arrayReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperand(AddCqR, 1, startReg); - /* begin CmpR:R: */ - assert(!((startReg == SPReg))); - genoperandoperand(CmpRR, startReg, stopReg); - /* begin JumpAboveOrEqual: */ - genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)instr)); - jmpTarget(jumpEmpty, (methodOrBlockNumArgs <= 2 /* numRegArgs */ - ? (/* begin RetN: */ - genoperand(RetN, 0)) - : (/* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord)))); - jmpTarget(jumpIncorrectFormat4, jmpTarget(jumpIncorrectFormat3, jmpTarget(jumpIncorrectFormat2, jmpTarget(jumpIncorrectFormat1, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))); - } - if (((result = compileInterpreterPrimitive())) < 0) { - return result; - } - jmpTarget(jumpImm, jmpTarget(jumpNotSmi1, jmpTarget(jumpNotSmi2, jmpTarget(jumpNotSmi3, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))); - jmpTarget(jumpOutOfBounds1, jmpTarget(jumpOutOfBounds2, jmpTarget(jumpOutOfBounds3, jmpTarget(jumpOutOfBounds4, ((AbstractInstruction *) (((jumpImm->operands))[0])))))); -# if IMMUTABILITY - jmpTarget(jumpImmutable, ((AbstractInstruction *) (((jumpImm->operands))[0]))); -# endif - return CompletePrimitive; -} - - /* CogObjectRepresentationForSpur>>#genSetSmallIntegerTagsIn: */ -static sqInt NoDbgRegParms -genSetSmallIntegerTagsIn(sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(OrCqR, 1, scratchReg); - return 0; -} - - -/* Create a trampoline to store-check the update of the receiver in a - closure's outerContext in compileBlockFrameBuild:. */ - - /* CogObjectRepresentationForSpur>>#genStoreCheckContextReceiverTrampoline */ -static usqInt -genStoreCheckContextReceiverTrampoline(void) -{ - usqInt startAddress; - - startAddress = methodZoneBase(); - zeroOpcodeIndex(); - genStoreCheckReceiverRegvalueRegscratchReginFrame(ReceiverResultReg, Arg0Reg, TempReg, 0); - /* begin RetN: */ - genoperand(RetN, 0); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress("ceStoreCheckContextReceiver", startAddress); - recordRunTimeObjectReferences(); - return startAddress; -} - - -/* Generate the code for a store check of valueReg into destReg. */ - - /* CogObjectRepresentationForSpur>>#genStoreCheckReceiverReg:valueReg:scratchReg:inFrame: */ -static sqInt NoDbgRegParms -genStoreCheckReceiverRegvalueRegscratchReginFrame(sqInt destReg, sqInt valueReg, sqInt scratchReg, sqInt inFrame) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction * inst; - AbstractInstruction *jmpAlreadyRemembered; - AbstractInstruction *jmpDestYoung; - AbstractInstruction *jmpImmediate; - AbstractInstruction *jmpSourceOld; - - - /* Is value stored an immediate? If so we're done */ - jmpAlreadyRemembered = ((AbstractInstruction *) 0); - - /* Get the old/new boundary in scratchReg */ - jmpImmediate = genJumpImmediate(valueReg); - /* begin checkLiteral:forInstruction: */ - storeCheckBoundary(); - anInstruction = genoperandoperand(MoveCwR, storeCheckBoundary(), scratchReg); - /* begin CmpR:R: */ - assert(!((scratchReg == SPReg))); - genoperandoperand(CmpRR, scratchReg, destReg); - /* begin JumpBelow: */ - jmpDestYoung = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((scratchReg == SPReg))); - genoperandoperand(CmpRR, scratchReg, valueReg); - /* begin JumpAboveOrEqual: */ - jmpSourceOld = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - if (!CheckRememberedInTrampoline) { - jmpAlreadyRemembered = genCheckRememberedBitOfscratch(destReg, scratchReg); - } - assert(destReg == ReceiverResultReg); - /* begin evaluateTrampolineCallBlock:protectLinkRegIfNot: */ - if (inFrame) { - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceStoreCheckTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - } - else { - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceStoreCheckTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin PopR: */ - genoperand(PopR, LinkReg); - } - jmpTarget(jmpImmediate, jmpTarget(jmpDestYoung, jmpTarget(jmpSourceOld, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))); - if (!CheckRememberedInTrampoline) { - jmpTarget(jmpAlreadyRemembered, ((AbstractInstruction *) (((jmpSourceOld->operands))[0]))); - } - return 0; -} - - /* CogObjectRepresentationForSpur>>#genStoreSourceReg:slotIndex:destReg:scratchReg:inFrame:needsStoreCheck: */ -static sqInt NoDbgRegParms -genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt inFrame, sqInt needsStoreCheck) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - - /* begin genTraceStores */ - if (traceStores > 0) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, TempReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceTraceStoreTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveRMwr, sourceReg, (index * BytesPerWord) + BaseHeaderSize, destReg); - if (needsStoreCheck) { - return genStoreCheckReceiverRegvalueRegscratchReginFrame(destReg, sourceReg, scratchReg, inFrame); - } - return 0; -} - - -/* This method is used for unchecked stores in objects after their creation - (typically, inlined creation of Array, closures and some temp vectors). - Currently there is no need to do the immutability check here - */ - - /* CogObjectRepresentationForSpur>>#genStoreSourceReg:slotIndex:intoNewObjectInDestReg: */ -static sqInt NoDbgRegParms -genStoreSourceRegslotIndexintoNewObjectInDestReg(sqInt sourceReg, sqInt index, sqInt destReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveRMwr, sourceReg, (index * BytesPerWord) + BaseHeaderSize, destReg); - return 0; -} - - -/* Convention: - - RcvrResultReg holds the object mutated. - If immutability failure: - - TempReg holds the instance variable index mutated - if instVarIndex > numDedicatedStoreTrampoline - - ClassReg holds the value to store - Registers are not lived across this trampoline as the - immutability failure may need new stack frames. */ - - /* CogObjectRepresentationForSpur>>#genStoreTrampolineCalled:instVarIndex: */ -#if IMMUTABILITY -static usqInt NoDbgRegParms -genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) -{ - AbstractInstruction * jumpImmutable; - AbstractInstruction * jumpImmutable1; - AbstractInstruction * jumpRC; - sqInt pushLinkReg; - usqInt startAddress; - - startAddress = methodZoneBase(); - zeroOpcodeIndex(); - if (CheckRememberedInTrampoline) { - /* begin genStoreTrampolineCheckingRememberedCalled:instVarIndex: */ - - /* Store check */ - /* If on 64-bits and doing the remembered bit test here, we can combine the tests to fetch the header once. */ - jumpImmutable = genJumpImmutablescratchReg(ReceiverResultReg, SendNumArgsReg); - jumpRC = genCheckRememberedBitOfscratch(ReceiverResultReg, SendNumArgsReg); - assert(((jumpRC->opcode)) == JumpNonZero); - (jumpRC->opcode = JumpZero); - /* begin RetN: */ - genoperand(RetN, 0); - jmpTarget(jumpRC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) - ? ReceiverResultReg - : ABIResultReg)); - jmpTarget(jumpImmutable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(ceCannotAssignTowithIndexvalueToAssign, 3, ReceiverResultReg, (instVarIndex < (NumStoreTrampolines - 1) - ? (/* begin trampolineArgConstant: */ - assert(instVarIndex >= 0), - -2 - instVarIndex) - : TempReg), ClassReg, null, 0 /* emptyRegisterMask */, 1, NoReg); - } - else { - /* begin genStoreTrampolineNotCheckingRememberedCalled:instVarIndex: */ - genSmalltalkToCStackSwitch((pushLinkReg = 1)); - - /* Store check */ - jumpImmutable1 = genJumpImmutablescratchReg(ReceiverResultReg, SendNumArgsReg); - compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) - ? ReceiverResultReg - : ABIResultReg), 0 /* emptyRegisterMask */); - genLoadStackPointers(backEnd()); - genTrampolineReturn(pushLinkReg); - jmpTarget(jumpImmutable1, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileCallFornumArgsargargargargresultRegregsToSave(ceCannotAssignTowithIndexvalueToAssign, 3, ReceiverResultReg, (instVarIndex < (NumStoreTrampolines - 1) - ? (/* begin trampolineArgConstant: */ - assert(instVarIndex >= 0), - -2 - instVarIndex) - : TempReg), ClassReg, null, NoReg, 0 /* emptyRegisterMask */); - genLoadStackPointers(backEnd()); - genTrampolineReturn(pushLinkReg); - } - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress(trampolineName, startAddress); - recordRunTimeObjectReferences(); - return startAddress; -} -#endif /* IMMUTABILITY */ - - -/* Store the value in the instance from field 1 to numSlots - Typically used for for inlined allocations, initializing objects with 0 or - nil. destReg is referencing the object (oop) and is restored at the end of - this code. - If less than 8 fields, use a full unrolled initialization (up to 8 stores) - If more than 8 fields, use a duff device to initialize with a 8-vectorized - loop. */ - - /* CogObjectRepresentationForSpur>>#genStoreValue:instance:numSlots: */ -static sqInt NoDbgRegParms -genStoreValueinstancenumSlots(sqInt value, sqInt destReg, sqInt numSlots) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - AbstractInstruction * branch; - sqInt constReg; - sqInt delta; - sqInt i; - AbstractInstruction * inst; - AbstractInstruction * loop; - sqInt loopCount; - sqInt slotsPerIteration; - - branch = ((AbstractInstruction *) 0); - if (numSlots <= ((slotsPerIteration = 8))) { - - /* slotsPerIteration must be even; see cogit SubCq: objectMemory bytesPerOop R: TempReg below */ - if (shouldAnnotateObjectReference(value)) { - annotateobjRef(gMoveCwR(value, TempReg), value); - } - else { - /* begin MoveCq:R: */ - anInstruction = genoperandoperand(MoveCqR, value, TempReg); - } - for (i = 0; i < numSlots; i += 1) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveRMwr, TempReg, (i * BytesPerWord) + BaseHeaderSize, destReg); - } - return 0; - } - constReg = allocateRegNotConflictingWith(1U << destReg); - if (shouldAnnotateObjectReference(value)) { - annotateobjRef(gMoveCwR(value, constReg), value); - } - else { - /* begin MoveCq:R: */ - anInstruction2 = genoperandoperand(MoveCqR, value, constReg); - } - if ((numSlots % slotsPerIteration) != 0) { - - /* delta maps the offset at the loop entryPoint onto destReg + objectMemory baseHeaderSize */ - delta = ((slotsPerIteration - (numSlots % slotsPerIteration)) * BytesPerOop) - BaseHeaderSize; - if (delta > 0) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(SubCqR, delta, destReg); - } - if (delta < 0) { - /* begin checkQuickConstant:forInstruction: */ - -delta; - anInstruction4 = genoperandoperand(AddCqR, -delta, destReg); - } - delta += BaseHeaderSize; - if ((numSlots % 2) == 1) { - - /* if end of loop is not at start of next object, adjust loop limit in TempReg to point to last field filled. */ - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(SubCqR, BytesPerOop, TempReg); - } - /* begin Jump: */ - branch = genoperand(Jump, ((sqInt)0)); - } - else { - delta = 0; - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(AddCqR, BaseHeaderSize, destReg); - } - loopCount = ((numSlots + slotsPerIteration) - 1) / slotsPerIteration; - assert(loopCount > 1); - /* begin Label */ - loop = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - for (i = 0; i <= 7; i += 1) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveRMwr, constReg, i * BytesPerOop, destReg); - inst = anInstruction7; - if ((slotsPerIteration - (numSlots % slotsPerIteration)) == i) { - jmpTarget(branch, inst); - } - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(AddCqR, slotsPerIteration * BytesPerOop, destReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, destReg); - /* begin JumpBelow: */ - genConditionalBranchoperand(JumpBelow, ((sqInt)loop)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(SubCqR, (((loopCount * slotsPerIteration) * BytesPerOop) + BaseHeaderSize) - delta, destReg); - return 0; -} - - -/* Store check code is duplicated to use a single trampoline */ - - /* CogObjectRepresentationForSpur>>#genStoreWithImmutabilityAndStoreCheckSourceReg:slotIndex:destReg:scratchReg:needRestoreRcvr: */ -#if IMMUTABILITY -static sqInt NoDbgRegParms -genStoreWithImmutabilityAndStoreCheckSourceRegslotIndexdestRegscratchRegneedRestoreRcvr(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt needRestoreRcvr) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *abstractInstruction2; - AbstractInstruction *abstractInstruction3; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *immutableJump; - AbstractInstruction *jmpAlreadyRemembered; - AbstractInstruction *jmpDestYoung; - AbstractInstruction *jmpImmediate; - AbstractInstruction *jmpSourceOld; - - jmpAlreadyRemembered = ((AbstractInstruction *) 0); - immutableJump = genJumpImmutablescratchReg(destReg, scratchReg); - /* begin genTraceStores */ - if (traceStores > 0) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, TempReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceTraceStoreTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveRMwr, sourceReg, (index * BytesPerWord) + BaseHeaderSize, destReg); - - /* Get the old/new boundary in scratchReg */ - jmpImmediate = genJumpImmediate(sourceReg); - /* begin checkLiteral:forInstruction: */ - storeCheckBoundary(); - anInstruction1 = genoperandoperand(MoveCwR, storeCheckBoundary(), scratchReg); - /* begin CmpR:R: */ - assert(!((scratchReg == SPReg))); - genoperandoperand(CmpRR, scratchReg, destReg); - /* begin JumpBelow: */ - jmpDestYoung = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((scratchReg == SPReg))); - genoperandoperand(CmpRR, scratchReg, sourceReg); - /* begin JumpAboveOrEqual: */ - jmpSourceOld = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - if (!CheckRememberedInTrampoline) { - jmpAlreadyRemembered = genCheckRememberedBitOfscratch(destReg, scratchReg); - } - jmpTarget(immutableJump, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin genStoreTrampolineCall: */ - assert(IMMUTABILITY); - if (index >= (NumStoreTrampolines - 1)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, index, TempReg); - /* begin CallRT: */ - abstractInstruction3 = genoperand(Call, ceStoreTrampolines[NumStoreTrampolines - 1]); - (abstractInstruction3->annotation = IsRelativeCall); - } - else { - /* begin CallRT: */ - abstractInstruction1 = genoperand(Call, ceStoreTrampolines[index]); - (abstractInstruction1->annotation = IsRelativeCall); - } - /* begin annotateBytecode: */ - abstractInstruction2 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction2->annotation = HasBytecodePC); - /* begin voidReceiverOptStatus */ - ((simSelf())->liveRegister = NoReg); - if (needRestoreRcvr) { - /* begin putSelfInReceiverResultReg */ - storeToReg(simSelf(), ReceiverResultReg); - } - jmpTarget(jmpImmediate, jmpTarget(jmpDestYoung, jmpTarget(jmpSourceOld, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))); - if (!CheckRememberedInTrampoline) { - jmpTarget(jmpAlreadyRemembered, ((AbstractInstruction *) (((jmpSourceOld->operands))[0]))); - } - return 0; -} -#endif /* IMMUTABILITY */ - - -/* Gen an immutability check with no store check (e.g. assigning an immediate - literal) - */ -/* imm check has its own trampoline */ - - /* CogObjectRepresentationForSpur>>#genStoreWithImmutabilityButNoStoreCheckSourceReg:slotIndex:destReg:scratchReg:needRestoreRcvr: */ -#if IMMUTABILITY -static sqInt NoDbgRegParms -genStoreWithImmutabilityButNoStoreCheckSourceRegslotIndexdestRegscratchRegneedRestoreRcvr(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt needRestoreRcvr) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *abstractInstruction2; - AbstractInstruction *abstractInstruction3; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *immutabilityFailure; - AbstractInstruction *mutableJump; - - mutableJump = genJumpMutablescratchReg(destReg, scratchReg); - /* begin genStoreTrampolineCall: */ - assert(IMMUTABILITY); - if (index >= (NumStoreTrampolines - 1)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, index, TempReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceStoreTrampolines[NumStoreTrampolines - 1]); - (abstractInstruction->annotation = IsRelativeCall); - } - else { - /* begin CallRT: */ - abstractInstruction1 = genoperand(Call, ceStoreTrampolines[index]); - (abstractInstruction1->annotation = IsRelativeCall); - } - /* begin annotateBytecode: */ - abstractInstruction2 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction2->annotation = HasBytecodePC); - /* begin voidReceiverOptStatus */ - ((simSelf())->liveRegister = NoReg); - if (needRestoreRcvr) { - /* begin putSelfInReceiverResultReg */ - storeToReg(simSelf(), ReceiverResultReg); - } - /* begin Jump: */ - immutabilityFailure = genoperand(Jump, ((sqInt)0)); - jmpTarget(mutableJump, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin genTraceStores */ - if (traceStores > 0) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, TempReg); - /* begin CallRT: */ - abstractInstruction3 = genoperand(Call, ceTraceStoreTrampoline); - (abstractInstruction3->annotation = IsRelativeCall); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveRMwr, sourceReg, (index * BytesPerWord) + BaseHeaderSize, destReg); - jmpTarget(immutabilityFailure, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} -#endif /* IMMUTABILITY */ - - -/* We know there is a frame as immutability check requires a frame */ -/* needRestoreRcvr has to be true to keep RcvrResultReg live with the - receiver in it across the trampoline - */ -/* Trampoline convention... */ - - /* CogObjectRepresentationForSpur>>#genStoreWithImmutabilityCheckSourceReg:slotIndex:destReg:scratchReg:needsStoreCheck:needRestoreRcvr: */ -#if IMMUTABILITY -static sqInt NoDbgRegParms -genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt needsStoreCheck, sqInt needRestoreRcvr) -{ - assert(destReg == ReceiverResultReg); - assert(scratchReg == TempReg); - assert(sourceReg == ClassReg); - if (needsStoreCheck) { - genStoreWithImmutabilityAndStoreCheckSourceRegslotIndexdestRegscratchRegneedRestoreRcvr(sourceReg, index, destReg, scratchReg, needRestoreRcvr); - } - else { - genStoreWithImmutabilityButNoStoreCheckSourceRegslotIndexdestRegscratchRegneedRestoreRcvr(sourceReg, index, destReg, scratchReg, needRestoreRcvr); - } - return 0; -} -#endif /* IMMUTABILITY */ - - /* CogObjectRepresentationForSpur>>#genVarIndexCallStoreTrampoline */ -static void -genVarIndexCallStoreTrampoline(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - - assert(IMMUTABILITY); -# if IMMUTABILITY - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceStoreTrampolines[NumStoreTrampolines - 1]); - (abstractInstruction->annotation = IsRelativeCall); - /* begin annotateBytecode: */ - abstractInstruction1 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction1->annotation = HasBytecodePC); -# endif // IMMUTABILITY -} - - -/* Make sure SendNumArgsReg and ClassReg are available in addition to - ReceiverResultReg and TempReg in - genGetActiveContextNumArgs:large:inBlock:. - */ - - /* CogObjectRepresentationForSpur>>#getActiveContextAllocatesInMachineCode */ -static sqInt -getActiveContextAllocatesInMachineCode(void) -{ - return 1; -} - - -/* Since all cache tags in Spur are class indices none of - them are young or have to be updated in a scavenge. */ - - /* CogObjectRepresentationForSpur>>#inlineCacheTagIsYoung: */ -static sqInt NoDbgRegParms -inlineCacheTagIsYoung(sqInt cacheTag) -{ - return 0; -} - - /* CogObjectRepresentationForSpur>>#jumpNotCharacterUnsignedValueInRegister: */ -static AbstractInstruction * NoDbgRegParms -jumpNotCharacterUnsignedValueInRegister(sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin CmpCq:R: */ - anInstruction = genoperandoperand(CmpCqR, 0x3FFFFFFF, reg); - /* begin JumpAbove: */ - return genConditionalBranchoperand(JumpAbove, ((sqInt)0)); -} - - -/* Mark and trace a literal in a machine code instruction preceding address - in cogMethodOrNil. - Answer if code was modified. */ - - /* CogObjectRepresentationForSpur>>#markAndTraceLiteral:in:atpc: */ -static sqInt NoDbgRegParms -markAndTraceLiteralinatpc(sqInt literal, CogMethod *cogMethodOrNil, usqInt address) -{ - sqInt objOop; - - if (!(couldBeObject(literal))) { - return 0; - } - assert(addressCouldBeObj(literal)); - if (!(isForwarded(literal))) { - markAndTrace(literal); - return 0; - } - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - objOop = followForwarded(literal); - storeLiteralbeforeFollowingAddress(backEnd(), objOop, address); - markAndTraceUpdatedLiteralin(objOop, cogMethodOrNil); - return 1; -} - - -/* Mark and trace a literal in a sqInt variable of cogMethod. */ - - /* CogObjectRepresentationForSpur>>#markAndTraceLiteral:in:at: */ -static void NoDbgRegParms -markAndTraceLiteralinat(sqInt literal, CogMethod *cogMethod, sqInt *address) -{ - sqInt objOop; - - if (!(couldBeObject(literal))) { - return; - } - assert(addressCouldBeObj(literal)); - if (!(isForwarded(literal))) { - markAndTrace(literal); - return; - } - objOop = followForwarded(literal); - address[0] = objOop; - markAndTraceUpdatedLiteralin(objOop, cogMethod); -} - - -/* Common code to mark a literal in cogMethod and add - the cogMethod to youngReferrers if the literal is young. */ - - /* CogObjectRepresentationForSpur>>#markAndTraceUpdatedLiteral:in: */ -static void NoDbgRegParms -markAndTraceUpdatedLiteralin(sqInt objOop, CogMethod *cogMethodOrNil) -{ - if (isNonImmediate(objOop)) { - if ((cogMethodOrNil != null) - && (isYoungObject(objOop))) { - ensureInYoungReferrers(cogMethodOrNil); - } - markAndTrace(objOop); - } -} - - -/* If primIndex has an accessorDepth and fails, or it is external and fails - with PrimErrNoMemory, - call ceCheckAndMaybeRetryPrimitive if so If ceCheck.... answers true, - retry the primitive. */ - - /* CogObjectRepresentationForSpur>>#maybeCompileRetryOnPrimitiveFail: */ -static sqInt NoDbgRegParms -maybeCompileRetryOnPrimitiveFail(sqInt primIndex) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *jmp; - - if ((accessorDepthForPrimitiveIndex(primIndex)) >= 0) { - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpZero: */ - jmp = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - } - else { - if ((primNumberExternalCall()) != primIndex) { - return 0; - } - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction2 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(CmpCqR, PrimErrNoMemory, TempReg); - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - } - compileCallFornumArgsargargargargresultRegregsToSave(ceCheckAndMaybeRetryPrimitive, 1, trampolineArgConstant(primIndex), null, null, null, TempReg, 0 /* emptyRegisterMask */); - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - -/* Generate a shift of the register containing the class tag in a method - cache probe. - c.f. SpurMemoryManager>>methodCacheHashOf:with: */ - - /* CogObjectRepresentationForSpur>>#maybeShiftClassTagRegisterForMethodCacheProbe: */ -static sqInt NoDbgRegParms -maybeShiftClassTagRegisterForMethodCacheProbe(sqInt classTagReg) -{ - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, 2, classTagReg); - return 0; -} - - /* CogObjectRepresentationForSpur>>#mixed:branchIf:instanceOfBehaviors:target: */ -static sqInt NoDbgRegParms -mixedbranchIfinstanceOfBehaviorstarget(sqInt numNonImmediates, sqInt reg, sqInt arrayObj, AbstractInstruction *targetFixUp) -{ - sqInt classIndex; - sqInt classObj; - sqInt i; - sqInt index; - sqInt j; - AbstractInstruction *jmp; - AbstractInstruction *jmpImmediate; - AbstractInstruction * jmpImmediate1; - usqInt numCases; - - jmpImmediate1 = ((AbstractInstruction *) 0); - numCases = numSlotsOf(arrayObj); - - /* Rcvr is non immediate */ - jmpImmediate = genJumpImmediate(reg); - genGetClassIndexOfNonImminto(reg, TempReg); - index = 0; - for (i = 0; i < numCases; i += 1) { - classObj = fetchPointerofObject(i, arrayObj); - if (!(isImmediateClass(classObj))) { - genCmpClassIndexR(classTagForClass(classObj), TempReg); - /* begin JumpZero: */ - genConditionalBranchoperand(JumpZero, ((sqInt)targetFixUp)); - index += 1; - } - } - /* begin Jump: */ - jmp = genoperand(Jump, ((sqInt)0)); - jmpTarget(jmpImmediate, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - switch (numCases - numNonImmediates) { - case 1: - - /* 1 immediate needs to jump. Find it and jump. */ - for (j = 0; j < numCases; j += 1) { - classObj = fetchPointerofObject(j, arrayObj); - if (isImmediateClass(classObj)) { - /* begin branchIf:hasImmediateTag:target: */ - classIndex = classTagForClass(classObj); - if (classIndex == (smallIntegerTag())) { - jmpImmediate1 = genJumpSmallInteger(reg); - } - if (classIndex == (characterTag())) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, reg, TempReg); - jmpImmediate1 = genJumpCharacterInScratchReg(reg); - } - jmpTarget(jmpImmediate1, targetFixUp); - } - } - break; - case 2: - - /* 2 immediates needs to jump */ - /* begin branch2CasesIf:instanceOfBehaviors:target: */ - genoperand(Jump, ((sqInt)(((void *) targetFixUp)))); - break; - case 3: - - /* all 3 needs to jump */ - /* begin Jump: */ - genoperand(Jump, ((sqInt)targetFixUp)); - break; - default: - error("Case not found and no otherwise clause"); - } - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - /* CogObjectRepresentationForSpur>>#mixed:branchIf:notInstanceOfBehaviors:target: */ -static sqInt NoDbgRegParms -mixedbranchIfnotInstanceOfBehaviorstarget(sqInt numNonImmediates, sqInt reg, sqInt arrayObj, AbstractInstruction *targetFixUp) -{ - sqInt classIndex; - sqInt classObj; - sqInt i; - sqInt index; - sqInt j; - AbstractInstruction *jmpImmediate; - AbstractInstruction * jmpImmediate1; - AbstractInstruction **jumps; - AbstractInstruction *label; - usqInt numCases; - - jmpImmediate1 = ((AbstractInstruction *) 0); - numCases = numSlotsOf(arrayObj); - - /* Rcvr is non immediate */ - jmpImmediate = genJumpImmediate(reg); - jumps = allocatype(numNonImmediates, AbstractInstruction *); - genGetClassIndexOfNonImminto(reg, TempReg); - index = 0; - for (i = 0; i < numCases; i += 1) { - classObj = fetchPointerofObject(i, arrayObj); - if (!(isImmediateClass(classObj))) { - genCmpClassIndexR(classTagForClass(classObj), TempReg); - jumps[index] = (genConditionalBranchoperand(JumpZero, ((sqInt)0))); - index += 1; - } - } - /* begin Jump: */ - genoperand(Jump, ((sqInt)targetFixUp)); - jmpTarget(jmpImmediate, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - switch (numCases - numNonImmediates) { - case 1: - - /* 1 immediate allowed. jump to targetFixUp if the rcvr is not this immediate */ - for (j = 0; j < numCases; j += 1) { - classObj = fetchPointerofObject(j, arrayObj); - if (isImmediateClass(classObj)) { - /* begin branchIf:hasNotImmediateTag:target: */ - classIndex = classTagForClass(classObj); - if (classIndex == (smallIntegerTag())) { - jmpImmediate1 = genJumpNotSmallInteger(reg); - } - if (classIndex == (characterTag())) { - - /* Character test destroy register value in Spur */ - /* begin MoveR:R: */ - genoperandoperand(MoveRR, reg, TempReg); - jmpImmediate1 = genJumpNotCharacterInScratchReg(TempReg); - } - jmpTarget(jmpImmediate1, targetFixUp); - } - } - break; - case 2: - - /* 2 immediates allowed. On 32 bits nothing to do, all immediate are allowed, on 64 bits generates the jump to fixup for the third tag */ - break; - case 3: - - /* nothing to do, all immediates are allowed. */ - break; - default: - error("Case not found and no otherwise clause"); - } - /* begin Label */ - label = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - for (i = 0; i < numNonImmediates; i += 1) { - jmpTarget(jumps[i], label); - } - return 0; -} - - -/* All classes in arrayObj are not immediate */ - - /* CogObjectRepresentationForSpur>>#noneImmediateBranchIf:instanceOfBehaviors:target: */ -static sqInt NoDbgRegParms -noneImmediateBranchIfinstanceOfBehaviorstarget(sqInt reg, sqInt arrayObj, AbstractInstruction *targetFixUp) -{ - sqInt classObj; - sqInt i; - sqInt iLimiT; - AbstractInstruction *jmp; - - jmp = genJumpImmediate(reg); - genGetClassIndexOfNonImminto(reg, TempReg); - for (i = 0, iLimiT = ((numSlotsOf(arrayObj)) - 1); i <= iLimiT; i += 1) { - classObj = fetchPointerofObject(i, arrayObj); - genCmpClassIndexR(classTagForClass(classObj), TempReg); - /* begin JumpZero: */ - genConditionalBranchoperand(JumpZero, ((sqInt)targetFixUp)); - } - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - -/* All classes in arrayObj are not immediate */ - - /* CogObjectRepresentationForSpur>>#noneImmediateBranchIf:notInstanceOfBehaviors:target: */ -static sqInt NoDbgRegParms -noneImmediateBranchIfnotInstanceOfBehaviorstarget(sqInt reg, sqInt arrayObj, AbstractInstruction *targetFixUp) -{ - sqInt classObj; - sqInt i; - sqInt iLimiT; - AbstractInstruction **jumps; - AbstractInstruction *label; - usqInt numJumps; - - jumps = allocatype(numSlotsOf(arrayObj), AbstractInstruction *); - jmpTarget(genJumpImmediate(reg), targetFixUp); - genGetClassIndexOfNonImminto(reg, TempReg); - for (i = 0, iLimiT = (((numJumps = numSlotsOf(arrayObj))) - 1); i <= iLimiT; i += 1) { - classObj = fetchPointerofObject(i, arrayObj); - genCmpClassIndexR(classTagForClass(classObj), TempReg); - jumps[i] = (genConditionalBranchoperand(JumpZero, ((sqInt)0))); - } - /* begin Jump: */ - genoperand(Jump, ((sqInt)targetFixUp)); - /* begin Label */ - label = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - for (i = 0; i < numJumps; i += 1) { - jmpTarget(jumps[i], label); - } - return 0; -} - - /* CogObjectRepresentationForSpur>>#numCharacterBits */ -static sqInt -numCharacterBits(void) -{ - return 30; -} - - -/* Define how many register arguments a StackToRegisterMappingCogit can - and should use with the receiver. The value must be 0, 1 or 2. Note that a - SimpleStackBasedCogit always has 0 register args (although the receiver is - passed in a register). The Spur object representation is simple enough - that implementing at:put: is straight-forward and hence 2 register args - are worth - while. The method must be inlined in CoInterpreter, and dead code - eliminated so that the register-popping enilopmarts such as - enterRegisterArgCogMethod:- at:receiver: do not have to be implemented in - SimpleStackBasedCogit. */ - - /* CogObjectRepresentationForSpur>>#numRegArgs */ -sqInt -numRegArgs(void) -{ - return 2; -} - - /* CogObjectRepresentationForSpur>>#remapObject: */ -static sqInt NoDbgRegParms -remapObject(sqInt objOop) -{ - assert(addressCouldBeObj(objOop)); - return (shouldRemapObj(objOop) - ? remapObj(objOop) - : objOop); -} - - /* CogObjectRepresentationForSpur>>#remapOop: */ -static sqInt NoDbgRegParms -remapOop(sqInt objOop) -{ - return (shouldRemapOop(objOop) - ? remapObj(objOop) - : objOop); -} - - /* CogObjectRepresentationForSpur>>#resetCountersIn: */ -void -resetCountersIn(CogMethod *cogMethod) -{ - fillInCountersatStartAddress(numCountersFor((cogMethod->counters)), (cogMethod->counters)); -} - - -/* Objects in newSpace or oldSpace except nil, true, false & - classTableRootObj need to be annotated. - */ - - /* CogObjectRepresentationForSpur>>#shouldAnnotateObjectReference: */ -static sqInt NoDbgRegParms -shouldAnnotateObjectReference(sqInt anOop) -{ - return (isNonImmediate(anOop)) - && ((oopisGreaterThan(anOop, classTableRootObj())) - || (oopisLessThan(anOop, nilObject()))); -} - - /* CogObjectRepresentationForSpur>>#slotOffsetOfInstVarIndex: */ -static sqInt NoDbgRegParms -slotOffsetOfInstVarIndex(sqInt index) -{ - return (index * BytesPerWord) + BaseHeaderSize; -} - - /* CogObjectRepresentationForSpur>>#valueOfAssociation: */ -static sqInt NoDbgRegParms -valueOfAssociation(sqInt associationOop) -{ - sqInt association; - - association = associationOop; - if (isForwarded(association)) { - association = followForwarded(association); - } - return fetchPointerofObject(ValueIndex, association); -} - - /* CogSimStackEntry>>#ensureSpilledAt:from: */ -static SimStackEntry * NoDbgRegParms -ensureSpilledAtfrom(SimStackEntry * self_in_ensureSpilledAtfrom, sqInt baseOffset, sqInt baseRegister) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *inst; - sqInt reg; - sqInt wordConstant; - - if ((self_in_ensureSpilledAtfrom->spilled)) { - if (((self_in_ensureSpilledAtfrom->type)) == SSSpill) { - assert(((((self_in_ensureSpilledAtfrom->offset)) == baseOffset) - && (((self_in_ensureSpilledAtfrom->registerr)) == baseRegister)) - || (violatesEnsureSpilledSpillAssert())); - return self_in_ensureSpilledAtfrom; - } - } - assert(((self_in_ensureSpilledAtfrom->type)) != SSSpill); - traceSpill(self_in_ensureSpilledAtfrom); - if (((self_in_ensureSpilledAtfrom->type)) == SSConstant) { - if (shouldAnnotateObjectReference((self_in_ensureSpilledAtfrom->constant))) { - inst = annotateobjRef(gPushCw((self_in_ensureSpilledAtfrom->constant)), (self_in_ensureSpilledAtfrom->constant)); - } - else { - /* begin PushCq: */ - wordConstant = (self_in_ensureSpilledAtfrom->constant); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperand(PushCq, wordConstant); - inst = anInstruction; - } - } - else { - if (((self_in_ensureSpilledAtfrom->type)) == SSBaseOffset) { - /* begin checkQuickConstant:forInstruction: */ - (self_in_ensureSpilledAtfrom->offset); - anInstruction1 = genoperandoperandoperand(MoveMwrR, (self_in_ensureSpilledAtfrom->offset), (self_in_ensureSpilledAtfrom->registerr), TempReg); - /* begin PushR: */ - inst = genoperand(PushR, TempReg); - } - else { - assert(((self_in_ensureSpilledAtfrom->type)) == SSRegister); - /* begin PushR: */ - reg = (self_in_ensureSpilledAtfrom->registerr); - inst = genoperand(PushR, reg); - } - (self_in_ensureSpilledAtfrom->type) = SSSpill; - (self_in_ensureSpilledAtfrom->offset) = baseOffset; - (self_in_ensureSpilledAtfrom->registerr) = baseRegister; - } - (self_in_ensureSpilledAtfrom->spilled) = 1; - return 0; -} - - /* CogSimStackEntry>>#isSameEntryAs: */ -static sqInt NoDbgRegParms -isSameEntryAs(SimStackEntry * self_in_isSameEntryAs, CogSimStackEntry *ssEntry) -{ - return (((self_in_isSameEntryAs->type)) == ((ssEntry->type))) - && ((((((self_in_isSameEntryAs->type)) == SSBaseOffset) - || (((self_in_isSameEntryAs->type)) == SSSpill)) - && ((((self_in_isSameEntryAs->offset)) == ((ssEntry->offset))) - && (((self_in_isSameEntryAs->registerr)) == ((ssEntry->registerr))))) - || (((((self_in_isSameEntryAs->type)) == SSRegister) - && (((self_in_isSameEntryAs->registerr)) == ((ssEntry->registerr)))) - || ((((self_in_isSameEntryAs->type)) == SSConstant) - && (((self_in_isSameEntryAs->constant)) == ((ssEntry->constant)))))); -} - - -/* Receiver is not a forwarder, except in blocks with no inst var access. - For now we optimize only the case where receiver is accessed in a method. */ - - /* CogSimStackEntry>>#mayBeAForwarder */ -static sqInt NoDbgRegParms -mayBeAForwarder(SimStackEntry * self_in_mayBeAForwarder) -{ - if ((((self_in_mayBeAForwarder->type)) == SSRegister) - && (isNonForwarderReceiver((self_in_mayBeAForwarder->registerr)))) { - return 0; - } - return ((self_in_mayBeAForwarder->type)) != SSConstant; -} - - /* CogSimStackEntry>>#popToReg: */ -static void NoDbgRegParms -popToReg(SimStackEntry * self_in_popToReg, sqInt reg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt quickConstant; - sqInt reg1; - - if ((self_in_popToReg->spilled)) { - /* begin PopR: */ - genoperand(PopR, reg); - } - else { - switch ((self_in_popToReg->type)) { - case SSBaseOffset: - /* begin checkQuickConstant:forInstruction: */ - (self_in_popToReg->offset); - anInstruction = genoperandoperandoperand(MoveMwrR, (self_in_popToReg->offset), (self_in_popToReg->registerr), reg); - break; - case SSConstant: - if (shouldAnnotateObjectReference((self_in_popToReg->constant))) { - annotateobjRef(gMoveCwR((self_in_popToReg->constant), reg), (self_in_popToReg->constant)); - } - else { - /* begin MoveCq:R: */ - quickConstant = (self_in_popToReg->constant); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, quickConstant, reg); - } - break; - case SSRegister: - if (reg != ((self_in_popToReg->registerr))) { - /* begin MoveR:R: */ - reg1 = (self_in_popToReg->registerr); - genoperandoperand(MoveRR, reg1, reg); - } - else { - /* begin Label */ - genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - break; - default: - error("Case not found and no otherwise clause"); - } - } -} - - -/* Answer a bit mask for the receiver's register, if any. */ - - /* CogSimStackEntry>>#registerMask */ -static sqInt NoDbgRegParms -registerMask(SimStackEntry * self_in_registerMask) -{ - sqInt reg; - - return ((((self_in_registerMask->type)) == SSBaseOffset) - || (((self_in_registerMask->type)) == SSRegister) - ? (/* begin registerMaskFor: */ - (reg = (self_in_registerMask->registerr)), - 1U << reg) - : 0); -} - - /* CogSimStackEntry>>#registerMaskOrNone */ -static sqInt NoDbgRegParms -registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone) -{ - sqInt reg; - - return (((self_in_registerMaskOrNone->type)) == SSRegister - ? (/* begin registerMaskFor: */ - (reg = (self_in_registerMaskOrNone->registerr)), - 1U << reg) - : 0); -} - - /* CogSimStackEntry>>#registerOrNone */ -static sqInt NoDbgRegParms -registerOrNone(SimStackEntry * self_in_registerOrNone) -{ - return (((self_in_registerOrNone->type)) == SSRegister - ? (self_in_registerOrNone->registerr) - : NoReg); -} - - /* CogSimStackEntry>>#storeToReg: */ -static void NoDbgRegParms -storeToReg(SimStackEntry * self_in_storeToReg, sqInt reg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt quickConstant; - sqInt reg1; - - switch ((self_in_storeToReg->type)) { - case SSBaseOffset: - case SSSpill: - /* begin checkQuickConstant:forInstruction: */ - (self_in_storeToReg->offset); - anInstruction = genoperandoperandoperand(MoveMwrR, (self_in_storeToReg->offset), (self_in_storeToReg->registerr), reg); - break; - case SSConstant: - if (shouldAnnotateObjectReference((self_in_storeToReg->constant))) { - annotateobjRef(gMoveCwR((self_in_storeToReg->constant), reg), (self_in_storeToReg->constant)); - } - else { - /* begin MoveCq:R: */ - quickConstant = (self_in_storeToReg->constant); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, quickConstant, reg); - } - break; - case SSRegister: - if (reg != ((self_in_storeToReg->registerr))) { - /* begin MoveR:R: */ - reg1 = (self_in_storeToReg->registerr); - genoperandoperand(MoveRR, reg1, reg); - } - else { - /* begin Label */ - genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - break; - default: - error("Case not found and no otherwise clause"); - } -} - - /* CogSSBytecodeFixup>>#isMergeFixup */ -static sqInt NoDbgRegParms -isMergeFixup(BytecodeFixup * self_in_isMergeFixup) -{ - return (((usqInt)((self_in_isMergeFixup->targetInstruction)))) == NeedsMergeFixupFlag; -} - - /* InLineLiteralsManager>>#checkLiteral:forInstruction: */ -static AbstractInstruction * NoDbgRegParms -checkLiteralforInstruction(sqInt literal, AbstractInstruction *anInstruction) -{ - return anInstruction; -} - - /* InLineLiteralsManager>>#checkQuickConstant:forInstruction: */ -static AbstractInstruction * NoDbgRegParms -checkQuickConstantforInstruction(sqInt literal, AbstractInstruction *anInstruction) -{ - return anInstruction; -} - - /* SimpleStackBasedCogit>>#cogMethodHasExternalPrim: */ -sqInt -cogMethodHasExternalPrim(CogMethod *aCogMethod) -{ - sqInt primIndex; - - primIndex = primitiveIndexOfMethodheader((aCogMethod->methodObject), (aCogMethod->methodHeader)); - return (primIndex == PrimNumberExternalCall) - || (primIndex == PrimNumberFFICall); -} - - /* SimpleStackBasedCogit>>#cogMethodHasMachineCodePrim: */ -sqInt -cogMethodHasMachineCodePrim(CogMethod *aCogMethod) -{ - sqInt primIndex; - - primIndex = primitiveIndexOfMethodheader((aCogMethod->methodObject), (aCogMethod->objectHeader)); - return (((primIndex >= 1) && (primIndex <= MaxCompiledPrimitiveIndex))) - && ((((primitiveGeneratorTable[primIndex]).primitiveGenerator)) != null); -} - - -/* Compile the jump instruction(s) at the end of the method that dispatch to - each block body. - */ - - /* SimpleStackBasedCogit>>#compileBlockDispatch */ -static sqInt -compileBlockDispatch(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *jumpSkip; - - assert(blockCount > 0); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 0, SendNumArgsReg); - blockEntryNoContextSwitch = anInstruction; - /* begin Jump: */ - jumpSkip = genoperand(Jump, ((sqInt)0)); - /* begin MoveR:R: */ - blockEntryLabel = genoperandoperand(MoveRR, ReceiverResultReg, SendNumArgsReg); - jmpTarget(jumpSkip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (blockCount > 1) { - genLoadSlotsourceRegdestReg(ClosureStartPCIndex, ReceiverResultReg, TempReg); - } - compileBlockDispatchFromto(0, blockCount - 1); - return 0; -} - - -/* After pushing the temporaries but before the stack limit check a primitive - method needs to fetch the error code, if any. If the primitive has failed, - call the trampoline - that will assign it to the last temp. */ - - /* SimpleStackBasedCogit>>#compileGetErrorCode */ -static void -compileGetErrorCode(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *jmpNoError; - - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpZero: */ - jmpNoError = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceReapAndResetErrorCodeTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - jmpTarget(jmpNoError, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); -} - - /* SimpleStackBasedCogit>>#compileInterpreterPrimitive */ -static sqInt -compileInterpreterPrimitive(void) -{ - sqInt flags; - void (*primitiveRoutine)(void); - - flags = 0; - primitiveRoutine = functionPointerForCompiledMethodprimitiveIndexprimitivePropertyFlagsInto(methodObj, primitiveIndex, (&flags)); - assert(!((((flags & PrimCallOnSmalltalkStack) != 0)))); - return compileInterpreterPrimitiveflags(primitiveRoutine, flags); -} - - -/* Compile a call to an interpreter primitive. Call the C routine with the - usual stack-switching dance, test the primFailCode and then either - return on success or continue to the method body. */ - - /* SimpleStackBasedCogit>>#compileInterpreterPrimitive:flags: */ -static sqInt NoDbgRegParms -compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) -{ - sqInt address; - sqInt address1; - sqInt address2; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction24; - AbstractInstruction *anInstruction25; - AbstractInstruction *anInstruction26; - AbstractInstruction *anInstruction28; - AbstractInstruction *anInstruction30; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction33; - AbstractInstruction *anInstruction34; - AbstractInstruction *anInstruction35; - AbstractInstruction *anInstruction36; - AbstractInstruction *anInstruction37; - AbstractInstruction *anInstruction38; - AbstractInstruction *anInstruction39; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction * continuePostSampleNonPrim; - AbstractInstruction * continuePostSamplePrim; - AbstractInstruction * jmp; - AbstractInstruction * jmpSampleNonPrim; - AbstractInstruction * jmpSamplePrim; - sqInt offset; - sqInt offset1; - sqInt offset2; - sqInt operand1; - sqInt operand3; - sqInt reg; - sqInt retpc; - - continuePostSampleNonPrim = ((AbstractInstruction *) 0); - continuePostSamplePrim = ((AbstractInstruction *) 0); - jmpSampleNonPrim = ((AbstractInstruction *) 0); - jmpSamplePrim = ((AbstractInstruction *) 0); - assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); - genExternalizePointersForPrimitiveCall(); - /* begin genLoadCStackPointersForPrimCall */ - if (cFramePointerInUse) { - genLoadCStackPointers(backEnd); - } - else { - genLoadCStackPointer(backEnd); - } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick if so */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin MoveAw:R: */ - address = (nextProfileTickAddress()) + BytesPerWord; - /* begin checkLiteral:forInstruction: */ - anInstruction1 = genoperandoperand(MoveAwR, address, ClassReg); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSampleNonPrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSampleNonPrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - if (recordPrimTraceForMethod(methodObj)) { - genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction36 = genoperandoperand(MoveCqR, 0, TempReg); - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction37 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); - if (methodOrBlockNumArgs != 0) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); - } - /* begin checkLiteral:forInstruction: */ - argumentCountAddress(); - anInstruction38 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); - if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { - /* begin checkLiteral:forInstruction: */ - ((sqInt)primitiveRoutine); - anInstruction5 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); - /* begin checkLiteral:forInstruction: */ - primitiveFunctionPointerAddress(); - anInstruction6 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); - } - if (((flags & (PrimCallNeedsNewMethod + PrimCallMayEndureCodeCompaction)) != 0)) { - - /* The ceActivateFailingPrimitiveMethod: machinery can't handle framelessness. */ - if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - needsFrame = 1; - } - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); - /* begin MoveMw:r:R: */ - offset = offsetof(CogMethod, methodObject); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - /* begin checkLiteral:forInstruction: */ - newMethodAddress(); - anInstruction8 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); - } - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction39 = genoperand(PrefetchAw, primFailCodeAddress()); - if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - - /* Sideways call the C primitive routine so that we return through cePrimReturnEnterCogCode. */ - /* On Spur ceActivateFailingPrimitiveMethod: would like to retry if forwarders - are found. So insist on PrimCallNeedsPrimitiveFunction being set too. */ - assert(((flags & PrimCallNeedsPrimitiveFunction) != 0)); - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l32; - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction11 = genoperandoperand(MoveCqR, -2 - null, A0); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A0); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction12 = genoperandoperand(MoveCqR, -2 - null, A1); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A1); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction21 = genoperandoperand(MoveCqR, -2 - null, A2); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A2); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction31 = genoperandoperand(MoveCqR, -2 - null, A3); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A3); - } - l32: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin genSubstituteReturnAddress: */ - retpc = (((flags & PrimCallCollectsProfileSamples) != 0) - ? cePrimReturnEnterCogCodeProfiling - : cePrimReturnEnterCogCode); - /* begin checkLiteral:forInstruction: */ - anInstruction13 = genoperandoperand(MoveCwR, retpc, RA); - /* begin gen:literal: */ - anInstruction10 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); - jmp = (jmpSamplePrim = (continuePostSamplePrim = null)); - } - else { - - /* Call the C primitive routine. */ - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l48; - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, A0); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, A1); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, A2); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, A3); - l48: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin gen:literal: */ - anInstruction15 = genoperand(CallFull, ((sqInt)primitiveRoutine)); - /* begin genRemoveNArgsFromStack: */ - assert(0 <= 4); - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction16 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin MoveAw:R: */ - address1 = (nextProfileTickAddress()) + BytesPerWord; - /* begin checkLiteral:forInstruction: */ - anInstruction17 = genoperandoperand(MoveAwR, address1, ClassReg); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSamplePrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSamplePrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - maybeCompileRetryOnPrimitiveFail(primitiveIndex); - /* begin MoveAw:R: */ - address2 = instructionPointerAddress(); - reg = LinkReg; - /* begin checkLiteral:forInstruction: */ - anInstruction23 = genoperandoperand(MoveAwR, address2, reg); - genLoadStackPointers(backEnd); - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction24 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction25 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset1 = 0; - /* begin checkQuickConstant:forInstruction: */ - anInstruction26 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, BytesPerWord); - } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* The sample is collected by cePrimReturnEnterCogCode for external calls */ - if (!(jmpSamplePrim == null)) { - - /* Call ceCheckProfileTick: to record sample and then continue. */ - jmpTarget(jmpSamplePrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin gen:literal: */ - operand1 = ((usqIntptr_t)ceCheckProfileTick); - /* begin checkLiteral:forInstruction: */ - anInstruction28 = genoperand(CallFull, operand1); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSamplePrim)); - } - jmpTarget(jmpSampleNonPrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction33 = genoperandoperand(MoveCqR, 0, TempReg); - /* begin checkLiteral:forInstruction: */ - newMethodAddress(); - anInstruction34 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); - /* begin gen:literal: */ - operand3 = ((usqIntptr_t)ceCheckProfileTick); - /* begin checkLiteral:forInstruction: */ - anInstruction30 = genoperand(CallFull, operand3); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSampleNonPrim)); - } - if (!(jmp == null)) { - - /* Jump to restore of receiver reg and proceed to frame build for failure. */ - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin MoveMw:r:R: */ - offset2 = BytesPerWord * (methodOrBlockNumArgs + (0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction35 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); - } - return 0; -} - - -/* Compile a call to a machine-code convention interpreter primitive. Call - the C routine - on the Smalltalk stack, assuming it consumes little or no stack space. */ -/* for now handle functions with less than 4 arguments; our C call - marshalling machinery - extends up to 4 arguments only, and the first argument of an mcprim is the - receiver. - */ - - /* SimpleStackBasedCogit>>#compileMachineCodeInterpreterPrimitive: */ -static sqInt NoDbgRegParms -compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)) -{ - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction5; - AbstractInstruction * jmpFail; - sqInt liveRegsMask; - sqInt n; - sqInt offset; - - assert(methodOrBlockNumArgs <= 3); - if ((methodOrBlockNumArgs > 2 /* numRegArgs */) - || (methodOrBlockNumArgs == 0)) { - /* begin registerMaskFor: */ - liveRegsMask = 1U << ReceiverResultReg; - } - else { - if (methodOrBlockNumArgs > 1) { - /* begin registerMaskFor:and:and: */ - liveRegsMask = ((1U << ReceiverResultReg) | (1U << Arg0Reg)) | (1U << Arg1Reg); - } - else { - /* begin registerMaskFor:and: */ - liveRegsMask = (1U << ReceiverResultReg) | (1U << Arg0Reg); - } - } - genSaveRegs(backEnd, liveRegsMask & CallerSavedRegisterMask); - if (methodOrBlockNumArgs > 2 /* numRegArgs */) { - - /* Wrangle args into Arg0Reg, Arg1Reg, SendNumArgsReg & ClassReg */ - /* offset := self bitCountOf: (liveRegsMask bitAnd: CallerSavedRegisterMask). */ - error("shouldBeImplemented"); - } - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - if ((methodOrBlockNumArgs + 1) == 0) { - goto l18; - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, A0); - if ((methodOrBlockNumArgs + 1) == 1) { - goto l18; - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, A1); - if ((methodOrBlockNumArgs + 1) == 2) { - goto l18; - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, A2); - if ((methodOrBlockNumArgs + 1) == 3) { - goto l18; - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SendNumArgsReg, A3); - l18: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin saveAndRestoreLinkRegUsingCalleeSavedRegNotLiveAtPointOfSendAround: */ - /* begin gen:literal: */ - anInstruction1 = genoperand(CallFull, ((sqInt)primitiveRoutine)); - /* begin genRemoveNArgsFromStack: */ - n = methodOrBlockNumArgs + 1; - assert(n <= 4); - genRestoreRegs(backEnd, liveRegsMask & CallerSavedRegisterMask); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(CmpCqR, 0, ABIResultReg); - /* begin JumpZero: */ - jmpFail = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - genWriteCResultIntoReg(backEnd, ReceiverResultReg); - /* begin RetN: */ - offset = (methodOrBlockNumArgs > 2 /* numRegArgs */ - ? (methodOrBlockNumArgs + 1) * BytesPerWord - : 0); - genoperand(RetN, offset); - jmpTarget(jmpFail, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - -/* Compile a fast call of a C primitive using the current stack page, - avoiding the stack switch except on failure. - This convention still uses stackPointer and argumentCount to access - operands. Push all operands to the stack, - assign stackPointer, argumentCount, and zero primFailCode. Make the call - (saving a LinkReg if required). - Test for failure and return. On failure on Spur, if there is an accessor - depth, assign framePointer and newMethod, - do the stack switch, call checkForAndFollowForwardedPrimitiveState, and - loop back if forwarders are found. - Fall through to frame build. */ - - /* SimpleStackBasedCogit>>#compileOnStackExternalPrimitive:flags: */ -static sqInt NoDbgRegParms -compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction22; - AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt calleeSavedRegisterMask; - AbstractInstruction * jmp; - sqInt linkRegSaveRegister; - sqInt offset; - sqInt offset1; - sqInt operand1; - AbstractInstruction * retry; - AbstractInstruction * skip; - sqInt spRegSaveRegister; - - linkRegSaveRegister = 0; - assert(((flags & PrimCallOnSmalltalkStack) != 0)); - assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); - if (recordFastCCallPrimTraceForMethod(methodObj)) { - genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction18 = genoperandoperand(MoveCqR, 0, TempReg); - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction19 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); - if (methodOrBlockNumArgs != 0) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); - } - /* begin checkLiteral:forInstruction: */ - argumentCountAddress(); - anInstruction20 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); - genExternalizeStackPointerForFastPrimitiveCall(); - calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | (1U << ClassReg)) - (1U << ClassReg)); - linkRegSaveRegister = availableRegisterOrNoneIn(calleeSavedRegisterMask); - assert(!((linkRegSaveRegister == NoReg))); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, LinkReg, linkRegSaveRegister); - calleeSavedRegisterMask = ((calleeSavedRegisterMask | (1U << linkRegSaveRegister)) - (1U << linkRegSaveRegister)); - spRegSaveRegister = NoReg; - /* begin Label */ - retry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - if (((flags & PrimCallOnSmalltalkStackAlign2x) != 0)) { - gAndCqRR((-1 - (((BytesPerWord * 2) - 1))), SPReg, NativeSPReg); - } - else { - } - /* begin gen:literal: */ - anInstruction2 = genoperand(CallFull, primitiveRoutine); - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction21 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - if (spRegSaveRegister != NoReg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, spRegSaveRegister, SPReg); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkLiteral:forInstruction: */ - stackPointerAddress(); - anInstruction23 = genoperandoperand(MoveAwR, stackPointerAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperandoperand(MoveMwrR, 0, TempReg, ReceiverResultReg); - gAddCqRR(BytesPerWord, TempReg, SPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, linkRegSaveRegister, LinkReg); - /* begin RetN: */ - genoperand(RetN, 0); - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if ((accessorDepthForExternalPrimitiveMethod(methodObj)) >= 0) { - - /* Given that following primitive state to the accessor depth is recursive, we're asking for - trouble if we run the fixup on the Smalltalk stack page. Run it on the full C stack instead. - This won't be a performance issue since primitive failure should be very rare. */ - /* begin checkLiteral:forInstruction: */ - framePointerAddress(); - anInstruction9 = genoperandoperand(MoveRAw, FPReg, framePointerAddress()); - /* begin checkLiteral:forInstruction: */ - ((sqInt)primitiveRoutine); - anInstruction10 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); - /* begin checkLiteral:forInstruction: */ - primitiveFunctionPointerAddress(); - anInstruction11 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); - /* begin MoveMw:r:R: */ - offset = offsetof(CogMethod, methodObject); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - /* begin checkLiteral:forInstruction: */ - newMethodAddress(); - anInstruction13 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); - /* begin genLoadCStackPointersForPrimCall */ - if (cFramePointerInUse) { - genLoadCStackPointers(backEnd); - } - else { - genLoadCStackPointer(backEnd); - } - /* begin gen:literal: */ - operand1 = ((usqIntptr_t)checkForAndFollowForwardedPrimitiveState); - /* begin checkLiteral:forInstruction: */ - anInstruction8 = genoperand(CallFull, operand1); - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(CmpCqR, 0, ABIResultReg); - /* begin JumpZero: */ - skip = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperand(MoveCqR, 0, TempReg); - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction16 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); - /* begin Jump: */ - genoperand(Jump, ((sqInt)retry)); - jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - else { - - /* must reload SPReg to undo any alignment change, */ - if (((flags & PrimCallOnSmalltalkStackAlign2x) != 0)) { - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); - } - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, linkRegSaveRegister, LinkReg); - if (((ABICallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { - /* begin MoveMw:r:R: */ - offset1 = (methodOrBlockNumArgs + (0)) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); - } - return 0; -} - - -/* Compile one method cache probe in an OpenPIC's lookup of selector. - Answer the jump taken if the selector probe fails. - The class tag of the receiver must be in SendNumArgsReg. ClassReg and - TempReg are used as scratch registers. - On a hit, the offset of the entry is in ClassReg. */ - - /* SimpleStackBasedCogit>>#compileOpenPICMethodCacheProbeFor:withShift:baseRegOrNone: */ -static AbstractInstruction * NoDbgRegParms -compileOpenPICMethodCacheProbeForwithShiftbaseRegOrNone(sqInt selector, sqInt shift, sqInt baseRegOrNone) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *jumpSelectorMiss; - sqInt offset; - sqInt offset1; - - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SendNumArgsReg, ClassReg); - maybeShiftClassTagRegisterForMethodCacheProbe(ClassReg); - annotateobjRef(checkLiteralforInstruction(selector, genoperandoperand(XorCwR, selector, ClassReg)), selector); - assert(shift <= (shiftForWord())); - if (shift < (shiftForWord())) { - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (shiftForWord()) - shift, ClassReg); - } - /* begin AndCq:R: */ - anInstruction4 = genoperandoperand(AndCqR, ((int)((usqInt)(MethodCacheMask) << (shiftForWord()))), ClassReg); - if (baseRegOrNone == NoReg) { - /* begin MoveMw:r:R: */ - offset = (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheSelector) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - } - else { - /* begin AddR:R: */ - genoperandoperand(AddRR, baseRegOrNone, ClassReg); - /* begin MoveMw:r:R: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, ((int)((usqInt)(MethodCacheSelector) << (shiftForWord()))), ClassReg, TempReg); - } - annotateobjRef(checkLiteralforInstruction(selector, genoperandoperand(CmpCwR, selector, TempReg)), selector); - /* begin JumpNonZero: */ - jumpSelectorMiss = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - if (baseRegOrNone == NoReg) { - /* begin MoveMw:r:R: */ - offset1 = (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheClass) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveMwrR, offset1, ClassReg, TempReg); - } - else { - /* begin MoveMw:r:R: */ - anInstruction3 = genoperandoperandoperand(MoveMwrR, ((int)((usqInt)(MethodCacheClass) << (shiftForWord()))), ClassReg, TempReg); - } - /* begin CmpR:R: */ - assert(!((SendNumArgsReg == SPReg))); - genoperandoperand(CmpRR, SendNumArgsReg, TempReg); - return jumpSelectorMiss; -} - - -/* Compile the code for an open PIC. Perform a probe of the first-level - method lookup cache followed by a call of ceSendFromInLineCacheMiss: if - the probe fails. */ - - /* SimpleStackBasedCogit>>#compileOpenPIC:numArgs: */ -static void NoDbgRegParms -compileOpenPICnumArgs(sqInt selector, sqInt numArgs) -{ - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - sqInt cacheBaseReg; - AbstractInstruction *itsAHit; - AbstractInstruction *jumpBCMethod; - AbstractInstruction *jumpClassMiss; - AbstractInstruction *jumpSelectorMiss; - sqInt offset; - - /* begin preenMethodLabel */ - (((((AbstractInstruction *) methodLabel))->operands))[1] = 0; - compilePICAbort(numArgs); - entry = genGetClassTagOfintoscratchReg(ReceiverResultReg, SendNumArgsReg, TempReg); - flag("lookupInMethodCacheSel:classTag:"); - cacheBaseReg = NoReg; - jumpSelectorMiss = compileOpenPICMethodCacheProbeForwithShiftbaseRegOrNone(selector, 0, cacheBaseReg); - /* begin JumpNonZero: */ - jumpClassMiss = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset = (cacheBaseReg == NoReg - ? (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheMethod) << (shiftForWord())))) - : ((int)((usqInt)(MethodCacheMethod) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, SendNumArgsReg); - itsAHit = anInstruction1; - genLoadSlotsourceRegdestReg(HeaderIndex, SendNumArgsReg, ClassReg); - jumpBCMethod = genJumpImmediate(ClassReg); - jmpTarget(jumpBCMethod, picInterpretAbort); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AddCqR, cmNoCheckEntryOffset, ClassReg); - /* begin JumpR: */ - genoperand(JumpR, ClassReg); - jmpTarget(jumpSelectorMiss, jmpTarget(jumpClassMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - jumpSelectorMiss = compileOpenPICMethodCacheProbeForwithShiftbaseRegOrNone(selector, 1, cacheBaseReg); - /* begin JumpZero: */ - genConditionalBranchoperand(JumpZero, ((sqInt)itsAHit)); - jmpTarget(jumpSelectorMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - jumpSelectorMiss = compileOpenPICMethodCacheProbeForwithShiftbaseRegOrNone(selector, 2, cacheBaseReg); - /* begin JumpZero: */ - genConditionalBranchoperand(JumpZero, ((sqInt)itsAHit)); - jmpTarget(jumpSelectorMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genPushRegisterArgsForNumArgsscratchReg(backEnd, numArgs, SendNumArgsReg); - genSmalltalkToCStackSwitch(1); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), SendNumArgsReg)))); - compileCallFornumArgsargargargargresultRegregsToSave(ceSendFromInLineCacheMiss, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); -} - - -/* Compile one method cache probe in a perform: primitive's lookup of - selector. Answer the jump taken if the selector probe fails. */ - - /* SimpleStackBasedCogit>>#compilePerformMethodCacheProbeFor:withShift:baseRegOrNone: */ -static AbstractInstruction * NoDbgRegParms -compilePerformMethodCacheProbeForwithShiftbaseRegOrNone(sqInt selectorReg, sqInt shift, sqInt baseRegOrNone) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *jumpSelectorMiss; - sqInt offset; - sqInt offset1; - - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SendNumArgsReg, ClassReg); - maybeShiftClassTagRegisterForMethodCacheProbe(ClassReg); - /* begin XorR:R: */ - genoperandoperand(XorRR, selectorReg, ClassReg); - assert(shift <= (shiftForWord())); - if (shift < (shiftForWord())) { - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (shiftForWord()) - shift, ClassReg); - } - /* begin AndCq:R: */ - anInstruction4 = genoperandoperand(AndCqR, ((int)((usqInt)(MethodCacheMask) << (shiftForWord()))), ClassReg); - if (baseRegOrNone == NoReg) { - /* begin MoveMw:r:R: */ - offset = (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheSelector) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - } - else { - /* begin AddR:R: */ - genoperandoperand(AddRR, baseRegOrNone, ClassReg); - /* begin MoveMw:r:R: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, ((int)((usqInt)(MethodCacheSelector) << (shiftForWord()))), ClassReg, TempReg); - } - /* begin CmpR:R: */ - assert(!((selectorReg == SPReg))); - genoperandoperand(CmpRR, selectorReg, TempReg); - /* begin JumpNonZero: */ - jumpSelectorMiss = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - if (baseRegOrNone == NoReg) { - /* begin MoveMw:r:R: */ - offset1 = (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheClass) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveMwrR, offset1, ClassReg, TempReg); - } - else { - /* begin MoveMw:r:R: */ - anInstruction3 = genoperandoperandoperand(MoveMwrR, ((int)((usqInt)(MethodCacheClass) << (shiftForWord()))), ClassReg, TempReg); - } - /* begin CmpR:R: */ - assert(!((SendNumArgsReg == SPReg))); - genoperandoperand(CmpRR, SendNumArgsReg, TempReg); - return jumpSelectorMiss; -} - - -/* Compile a primitive. If possible, performance-critical primitives will - be generated by their own routines (primitiveGenerator). Otherwise, - if there is a primitive at all, we call the C routine with the usual - stack-switching dance, test the primFailCode and then either return - on success or continue to the method body. */ - - /* SimpleStackBasedCogit>>#compilePrimitive */ -static sqInt -compilePrimitive(void) -{ - sqInt code; - sqInt flags; - sqInt opcodeIndexAtPrimitive; - PrimitiveDescriptor *primitiveDescriptor; - void (*primitiveRoutine)(void); - - flags = 0; - if (primitiveIndex == 0) { - return 0; - } - if ((((primitiveDescriptor = primitiveGeneratorOrNil())) != null) - && ((((primitiveDescriptor->primitiveGenerator)) != null) - && ((((primitiveDescriptor->primNumArgs)) < 0) - || (((primitiveDescriptor->primNumArgs)) == (argumentCountOf(methodObj)))))) { - - /* Note opcodeIndex so that any arg load instructions - for unimplemented primitives can be discarded. */ - opcodeIndexAtPrimitive = opcodeIndex; - code = ((primitiveDescriptor->primitiveGenerator))(); - if ((code < 0) - && (code != UnimplementedPrimitive)) { - - /* Generator failed, so no point continuing... */ - return code; - } - if (code == UnfailingPrimitive) { - return 0; - } - if ((code == CompletePrimitive) - && (!(((primitiveIndexOfMethodheader(methodObj, methodHeader)) > 0) - && ((longStoreBytecodeForHeader(methodHeader)) == (fetchByteofObject((startPCOfMethod(methodObj)) + (sizeOfCallPrimitiveBytecode(methodHeader)), methodObj)))))) { - return 0; - } - if (code == UnimplementedPrimitive) { - opcodeIndex = opcodeIndexAtPrimitive; - } - } - primitiveRoutine = functionPointerForCompiledMethodprimitiveIndexprimitivePropertyFlagsInto(methodObj, primitiveIndex, (&flags)); - if (((flags & PrimCallDoNotJIT) != 0)) { - return ShouldNotJIT; - } - if ((primitiveRoutine == 0) - || (primitiveRoutine == (((void (*)(void)) primitiveFail)))) { - return genFastPrimFail(); - } - if (((flags & PrimCallOnSmalltalkStack) != 0)) { - assert(!(((((flags & FastCPrimitiveUseCABIFlag) != 0)) - && (((flags & PrimCallOnSmalltalkStackAlign2x) != 0))))); - if (((flags & FastCPrimitiveUseCABIFlag) != 0)) { - return compileMachineCodeInterpreterPrimitive(((void (*)(void)) (mcprimFunctionForPrimitiveIndex(primitiveIndex)))); - } - return compileOnStackExternalPrimitiveflags(primitiveRoutine, flags); - } - minValidCallAddress = ((minValidCallAddress < (((usqInt)primitiveRoutine))) ? minValidCallAddress : (((usqInt)primitiveRoutine))); - return compileInterpreterPrimitiveflags(primitiveRoutine, flags); -} - - /* SimpleStackBasedCogit>>#extendedPushBytecode */ -static sqInt -extendedPushBytecode(void) -{ - sqInt variableIndex; - sqInt variableType; - - variableType = (((usqInt)(byte1)) >> 6) & 3; - variableIndex = byte1 & 0x3F; - if (variableType == 0) { - return genPushReceiverVariable(variableIndex); - } - if (variableType == 1) { - return genPushTemporaryVariable(variableIndex); - } - if (variableType == 2) { - return genPushLiteralIndex(variableIndex); - } - return genPushLiteralVariable(variableIndex); -} - - /* SimpleStackBasedCogit>>#extendedStoreAndPopBytecode */ -static sqInt -extendedStoreAndPopBytecode(void) -{ - AbstractInstruction *abstractInstruction; - sqInt variableIndex; - sqInt variableType; - - variableType = (((usqInt)(byte1)) >> 6) & 3; - variableIndex = byte1 & 0x3F; - if (variableType == 0) { - return genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(1, variableIndex, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } - if (variableType == 1) { - genStorePopTemporaryVariable(1, variableIndex); -# if IMMUTABILITY - /* begin annotateBytecode: */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction->annotation = HasBytecodePC); -# endif // IMMUTABILITY - return 0; - } - if (variableType == 3) { - return genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(1, variableIndex, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } - return EncounteredUnknownBytecode; -} - - /* SimpleStackBasedCogit>>#extendedStoreBytecode */ -static sqInt -extendedStoreBytecode(void) -{ - AbstractInstruction *abstractInstruction; - sqInt variableIndex; - sqInt variableType; - - variableType = (((usqInt)(byte1)) >> 6) & 3; - variableIndex = byte1 & 0x3F; - if (variableType == 0) { - return genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(0, variableIndex, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } - if (variableType == 1) { - genStorePopTemporaryVariable(0, variableIndex); -# if IMMUTABILITY - /* begin annotateBytecode: */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction->annotation = HasBytecodePC); -# endif // IMMUTABILITY - return 0; - } - if (variableType == 3) { - return genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(0, variableIndex, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } - return EncounteredUnknownBytecode; -} - - /* SimpleStackBasedCogit>>#frameOffsetOfTemporary: */ -static sqInt NoDbgRegParms -frameOffsetOfTemporary(sqInt index) -{ - return (index < methodOrBlockNumArgs - ? FoxCallerSavedIP + ((methodOrBlockNumArgs - index) * BytesPerWord) - : (FoxMFReceiver - BytesPerWord) + ((methodOrBlockNumArgs - index) * BytesPerWord)); -} - - -/* Can use any of the first 32 literals for the selector and pass up to 7 - arguments. - */ - - /* SimpleStackBasedCogit>>#genExtendedSendBytecode */ -static sqInt -genExtendedSendBytecode(void) -{ - return genSendnumArgs(byte1 & 0x1F, ((usqInt)(byte1)) >> 5); -} - - /* SimpleStackBasedCogit>>#genExtendedSuperBytecode */ -static sqInt -genExtendedSuperBytecode(void) -{ - return genSendSupernumArgs(byte1 & 0x1F, ((usqInt)(byte1)) >> 5); -} - - -/* 244 11110100 i i i i i i i i Pop and Jump 0n False i i i i i i i i (+ - Extend B * 256, where Extend B >= 0) - */ - - /* SimpleStackBasedCogit>>#genExtJumpIfFalse */ -static sqInt -genExtJumpIfFalse(void) -{ - sqInt distance; - sqInt target; - - distance = byte1 + (((sqInt)((usqInt)(extB) << 8))); - assert(distance == (v4LongForwardBranchDistance(generatorAt(byte0), bytecodePC, ((extA != 0 - ? 1 - : 0)) + ((extB != 0 - ? 1 - : 0)), methodObj))); - extB = 0; - numExtB = 0; - target = (distance + 2) + bytecodePC; - return genJumpIfto(falseObject(), target); -} - - -/* 243 11110011 i i i i i i i i Pop and Jump 0n True i i i i i i i i (+ - Extend B * 256, where Extend B >= 0) - */ - - /* SimpleStackBasedCogit>>#genExtJumpIfTrue */ -static sqInt -genExtJumpIfTrue(void) -{ - sqInt distance; - sqInt target; - - distance = byte1 + (((sqInt)((usqInt)(extB) << 8))); - assert(distance == (v4LongForwardBranchDistance(generatorAt(byte0), bytecodePC, ((extA != 0 - ? 1 - : 0)) + ((extB != 0 - ? 1 - : 0)), methodObj))); - extB = 0; - numExtB = 0; - target = (distance + 2) + bytecodePC; - return genJumpIfto(trueObject(), target); -} - - -/* NewspeakV4: 221 11011101 Nop */ -/* SistaV1: 91 01011011' Nop */ - - /* SimpleStackBasedCogit>>#genExtNopBytecode */ -static sqInt -genExtNopBytecode(void) -{ - extA = (numExtB = (extB = 0)); - return 0; -} - - -/* SistaV1: 233 11101001 iiiiiiii Push Character #iiiiiiii (+ Extend B * - 256) - */ - - /* SimpleStackBasedCogit>>#genExtPushCharacterBytecode */ -static sqInt -genExtPushCharacterBytecode(void) -{ - sqInt value; - - value = byte1 + (((sqInt)((usqInt)(extB) << 8))); - extB = 0; - numExtB = 0; - return genPushLiteral(characterObjectOf(value)); -} - - -/* NewsqueakV4: 229 11100101 iiiiiiii Push Integer #iiiiiiii (+ Extend B * - 256, where bbbbbbbb = sddddddd, e.g. -32768 = i=0, a=0, s=1) - SistaV1: 232 11101000 iiiiiiii Push Integer #iiiiiiii (+ Extend B * 256, - where bbbbbbbb = sddddddd, e.g. -32768 = i=0, a=0, s=1) - */ - - /* SimpleStackBasedCogit>>#genExtPushIntegerBytecode */ -static sqInt -genExtPushIntegerBytecode(void) -{ - sqInt value; - - value = byte1 + (((sqInt)((usqInt)(extB) << 8))); - extB = 0; - numExtB = 0; - return genPushLiteral((((usqInt)value << 1) | 1)); -} - - -/* 228 11100100 i i i i i i i i Push Literal #iiiiiiii (+ Extend A * 256) */ - - /* SimpleStackBasedCogit>>#genExtPushLiteralBytecode */ -static sqInt -genExtPushLiteralBytecode(void) -{ - sqInt index; - - index = byte1 + (((sqInt)((usqInt)(extA) << 8))); - extA = 0; - return genPushLiteralIndex(index); -} - - -/* 227 11100011 i i i i i i i i Push Literal Variable #iiiiiiii (+ Extend A - * 256) - */ - - /* SimpleStackBasedCogit>>#genExtPushLiteralVariableBytecode */ -static sqInt -genExtPushLiteralVariableBytecode(void) -{ - sqInt index; - - index = byte1 + (((sqInt)((usqInt)(extA) << 8))); - extA = 0; - return genPushLiteralVariable(index); -} - - -/* SistaV1: * 82 01010010 Push thisContext, (then Extend B = 1 => push - thisProcess) - */ - - /* SimpleStackBasedCogit>>#genExtPushPseudoVariable */ -static sqInt -genExtPushPseudoVariable(void) -{ - sqInt ext; - - ext = extB; - extB = 0; - numExtB = 0; - switch (ext) { - case 0: - return genPushActiveContextBytecode(); - - default: - /* begin unknownBytecode */ - return EncounteredUnknownBytecode; - - } - return 0; -} - - -/* 226 11100010 i i i i i i i i Push Receiver Variable #iiiiiiii (+ Extend A - * 256) - */ - - /* SimpleStackBasedCogit>>#genExtPushReceiverVariableBytecode */ -static sqInt -genExtPushReceiverVariableBytecode(void) -{ - sqInt index; - - index = byte1 + (((sqInt)((usqInt)(extA) << 8))); - extA = 0; - return (isReadMediatedContextInstVarIndex(index) - ? genPushMaybeContextReceiverVariable(index) - : genPushReceiverVariable(index)); -} - - -/* 238 11101110 i i i i i j j j Send Literal Selector #iiiii (+ Extend A * - 32) with jjj (+ Extend B * 8) Arguments - */ - - /* SimpleStackBasedCogit>>#genExtSendBytecode */ -static sqInt -genExtSendBytecode(void) -{ - sqInt litIndex; - sqInt nArgs; - - litIndex = (((usqInt)(byte1)) >> 3) + (((sqInt)((usqInt)(extA) << 5))); - extA = 0; - nArgs = (byte1 & 7) + (((sqInt)((usqInt)(extB) << 3))); - extB = 0; - numExtB = 0; - return genSendnumArgs(litIndex, nArgs); -} - - -/* 239 11101111 i i i i i j j j Send To Superclass Literal Selector #iiiii - (+ Extend A * 32) with jjj (+ Extend B * 8) Arguments - */ - - /* SimpleStackBasedCogit>>#genExtSendSuperBytecode */ -static sqInt -genExtSendSuperBytecode(void) -{ - int isDirected; - sqInt litIndex; - sqInt nArgs; - - if ((isDirected = extB >= 64)) { - extB = extB & 0x3F; - } - litIndex = (((usqInt)(byte1)) >> 3) + (((sqInt)((usqInt)(extA) << 5))); - extA = 0; - nArgs = (byte1 & 7) + (((sqInt)((usqInt)(extB) << 3))); - extB = 0; - numExtB = 0; - return (isDirected - ? genSendDirectedSupernumArgs(litIndex, nArgs) - : genSendSupernumArgs(litIndex, nArgs)); -} - - -/* 236 11101100 i i i i i i i i Pop and Store Literal Variable #iiiiiiii (+ - Extend A * 256) - */ - - /* SimpleStackBasedCogit>>#genExtStoreAndPopLiteralVariableBytecode */ -static sqInt -genExtStoreAndPopLiteralVariableBytecode(void) -{ - sqInt index; - - index = byte1 + (((sqInt)((usqInt)(extA) << 8))); - extA = 0; - return genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(1, index, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); -} - - -/* 235 11101011 i i i i i i i i Pop and Store Receiver Variable #iiiiiii (+ - Extend A * 256) - */ - - /* SimpleStackBasedCogit>>#genExtStoreAndPopReceiverVariableBytecode */ -static sqInt -genExtStoreAndPopReceiverVariableBytecode(void) -{ - sqInt index; - - index = byte1 + (((sqInt)((usqInt)(extA) << 8))); - extA = 0; - return (isWriteMediatedContextInstVarIndex(index) - ? genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(1, index, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1) - : genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(1, index, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1)); -} - - -/* 233 11101001 i i i i i i i i Store Literal Variable #iiiiiiii (+ Extend A - * 256) - */ - - /* SimpleStackBasedCogit>>#genExtStoreLiteralVariableBytecode */ -static sqInt -genExtStoreLiteralVariableBytecode(void) -{ - sqInt index; - - index = byte1 + (((sqInt)((usqInt)(extA) << 8))); - extA = 0; - return genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(0, index, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); -} - - -/* 232 11101000 i i i i i i i i Store Receiver Variable #iiiiiii (+ Extend A - * 256) - */ - - /* SimpleStackBasedCogit>>#genExtStoreReceiverVariableBytecode */ -static sqInt -genExtStoreReceiverVariableBytecode(void) -{ - sqInt index; - - index = byte1 + (((sqInt)((usqInt)(extA) << 8))); - extA = 0; - return (isWriteMediatedContextInstVarIndex(index) - ? genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(0, index, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1) - : genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(0, index, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1)); -} - - -/* 242 11110010 i i i i i i i i Jump i i i i i i i i (+ Extend B * 256, - where bbbbbbbb = sddddddd, e.g. -32768 = i=0, a=0, s=1) - */ - - /* SimpleStackBasedCogit>>#genExtUnconditionalJump */ -static sqInt -genExtUnconditionalJump(void) -{ - AbstractInstruction *abstractInstruction; - sqInt distance; - sqInt target; - - distance = byte1 + (((sqInt)((usqInt)(extB) << 8))); - assert(distance == (v4LongBranchDistance(generatorAt(byte0), bytecodePC, ((extA != 0 - ? 1 - : 0)) + ((extB != 0 - ? 1 - : 0)), methodObj))); - extB = 0; - numExtB = 0; - target = (distance + 2) + bytecodePC; - if (distance < 0) { - return genJumpBackTo(target); - } - genJumpTo(target); - /* begin annotateBytecode: */ - abstractInstruction = lastOpcode(); - (abstractInstruction->annotation = HasBytecodePC); - return 0; -} - - /* SimpleStackBasedCogit>>#genFastPrimFail */ -static sqInt -genFastPrimFail(void) -{ - primitiveIndex = 0; - return UnfailingPrimitive; -} - - -/* Suport for compileInterpreterPrimitive. Generate inline code so as to - record the primitive - trace as fast as possible. */ - - /* SimpleStackBasedCogit>>#genFastPrimTraceUsing:and: */ -static void NoDbgRegParms -genFastPrimTraceUsingand(sqInt r1, sqInt r2) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - sqInt offset; - - /* begin MoveCq:R: */ - anInstruction = genoperandoperand(MoveCqR, 0, r2); - /* begin checkLiteral:forInstruction: */ - primTraceLogIndexAddress(); - anInstruction1 = genoperandoperand(MoveAbR, primTraceLogIndexAddress(), r2); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(LoadEffectiveAddressMwrR, 1, r2, r1); - /* begin checkLiteral:forInstruction: */ - primTraceLogIndexAddress(); - anInstruction3 = genoperandoperand(MoveRAb, r1, primTraceLogIndexAddress()); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), r1)))); - /* begin MoveMw:r:R: */ - offset = offsetof(CogMethod, selector); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperandoperand(MoveMwrR, offset, r1, TempReg); - /* begin checkLiteral:forInstruction: */ - ((sqInt)(primTraceLogAddress())); - anInstruction5 = genoperandoperand(MoveCwR, ((sqInt)(primTraceLogAddress())), r1); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, TempReg, r2, r1); -} - - /* SimpleStackBasedCogit>>#genLongJumpIfFalse */ -static sqInt -genLongJumpIfFalse(void) -{ - sqInt distance; - sqInt target; - - distance = v3LongForwardBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - target = (distance + 2) + bytecodePC; - return genJumpIfto(falseObject(), target); -} - - /* SimpleStackBasedCogit>>#genLongJumpIfTrue */ -static sqInt -genLongJumpIfTrue(void) -{ - sqInt distance; - sqInt target; - - distance = v3LongForwardBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - target = (distance + 2) + bytecodePC; - return genJumpIfto(trueObject(), target); -} - - -/* 230 11100110 i i i i i i i i Push Temporary Variable #iiiiiiii */ - - /* SimpleStackBasedCogit>>#genLongPushTemporaryVariableBytecode */ -static sqInt -genLongPushTemporaryVariableBytecode(void) -{ - return genPushTemporaryVariable(byte1); -} - - -/* 237 11101101 i i i i i i i i Pop and Store Temporary Variable #iiiiiiii */ - - /* SimpleStackBasedCogit>>#genLongStoreAndPopTemporaryVariableBytecode */ -static sqInt -genLongStoreAndPopTemporaryVariableBytecode(void) -{ - return genStorePopTemporaryVariable(1, byte1); -} - - -/* 234 11101010 i i i i i i i i Store Temporary Variable #iiiiiiii */ - - /* SimpleStackBasedCogit>>#genLongStoreTemporaryVariableBytecode */ -static sqInt -genLongStoreTemporaryVariableBytecode(void) -{ - return genStorePopTemporaryVariable(0, byte1); -} - - /* SimpleStackBasedCogit>>#genLongUnconditionalBackwardJump */ -static sqInt -genLongUnconditionalBackwardJump(void) -{ - sqInt distance; - - distance = v3LongBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - assert(distance < 0); - return genJumpBackTo((distance + 2) + bytecodePC); -} - - /* SimpleStackBasedCogit>>#genLongUnconditionalForwardJump */ -static sqInt -genLongUnconditionalForwardJump(void) -{ - sqInt distance; - sqInt targetpc; - - distance = v3LongBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - assert(distance >= 0); - targetpc = (distance + 2) + bytecodePC; - return genJumpTo(targetpc); -} - - -/* Compile the code for a probe of the first-level method cache for a perform - primitive. The selector is assumed to be in Arg0Reg. Defer to - adjustArgumentsForPerform: to - adjust the arguments before the jump to the method. */ - - /* SimpleStackBasedCogit>>#genLookupForPerformNumArgs: */ -static sqInt NoDbgRegParms -genLookupForPerformNumArgs(sqInt numArgs) -{ - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - sqInt cacheBaseReg; - AbstractInstruction *itsAHit; - AbstractInstruction *jumpClassMiss; - AbstractInstruction *jumpInterpret; - AbstractInstruction *jumpSelectorMiss; - sqInt offset; - - - /* N.B. Can't assume TempReg already contains the tag because a method can - of course be invoked via the unchecked entry-point, e.g. as does perform:. */ - genGetInlineCacheClassTagFromintoforEntry(ReceiverResultReg, SendNumArgsReg, 0); - flag("lookupInMethodCacheSel:classTag:"); - cacheBaseReg = NoReg; - jumpSelectorMiss = compilePerformMethodCacheProbeForwithShiftbaseRegOrNone(Arg0Reg, 0, cacheBaseReg); - /* begin JumpNonZero: */ - jumpClassMiss = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset = (cacheBaseReg == NoReg - ? (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheMethod) << (shiftForWord())))) - : ((int)((usqInt)(MethodCacheMethod) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, SendNumArgsReg); - itsAHit = anInstruction1; - genLoadSlotsourceRegdestReg(HeaderIndex, SendNumArgsReg, ClassReg); - - /* Adjust arguments and jump to the method's unchecked entry-point. */ - jumpInterpret = genJumpImmediate(ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AddCqR, cmNoCheckEntryOffset, ClassReg); - adjustArgumentsForPerform(numArgs); - /* begin JumpR: */ - genoperand(JumpR, ClassReg); - jmpTarget(jumpSelectorMiss, jmpTarget(jumpClassMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - jumpSelectorMiss = compilePerformMethodCacheProbeForwithShiftbaseRegOrNone(Arg0Reg, 1, cacheBaseReg); - /* begin JumpZero: */ - genConditionalBranchoperand(JumpZero, ((sqInt)itsAHit)); - jmpTarget(jumpSelectorMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - jumpSelectorMiss = compilePerformMethodCacheProbeForwithShiftbaseRegOrNone(Arg0Reg, 2, cacheBaseReg); - /* begin JumpZero: */ - genConditionalBranchoperand(JumpZero, ((sqInt)itsAHit)); - jmpTarget(jumpSelectorMiss, jmpTarget(jumpInterpret, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return 0; -} - - /* SimpleStackBasedCogit>>#genMoveFalseR: */ -static AbstractInstruction * NoDbgRegParms -genMoveFalseR(sqInt reg) -{ - AbstractInstruction *anInstruction; - sqInt constant; - - /* begin genMoveConstant:R: */ - constant = falseObject(); - return (shouldAnnotateObjectReference(constant) - ? annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, reg)), constant) - : (/* begin checkQuickConstant:forInstruction: */ - (anInstruction = genoperandoperand(MoveCqR, constant, reg)), - anInstruction)); -} - - /* SimpleStackBasedCogit>>#genMoveTrueR: */ -static AbstractInstruction * NoDbgRegParms -genMoveTrueR(sqInt reg) -{ - AbstractInstruction *anInstruction; - sqInt constant; - - /* begin genMoveConstant:R: */ - constant = trueObject(); - return (shouldAnnotateObjectReference(constant) - ? annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, reg)), constant) - : (/* begin checkQuickConstant:forInstruction: */ - (anInstruction = genoperandoperand(MoveCqR, constant, reg)), - anInstruction)); -} - - -/* Implement 28-bit hashMultiply for SmallInteger and LargePositiveInteger - receivers. - */ - - /* SimpleStackBasedCogit>>#genPrimitiveHashMultiply */ -static sqInt -genPrimitiveHashMultiply(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction * jmpFailImm; - AbstractInstruction * jmpFailNotPositiveLargeInt; - - return UnimplementedPrimitive; - if (mclassIsSmallInteger()) { - genConvertSmallIntegerToIntegerInReg(ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, HashMultiplyConstant, TempReg); - /* begin MulR:R: */ - genMulRR(backEnd, TempReg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, HashMultiplyMask, ReceiverResultReg); - genConvertIntegerToSmallIntegerInReg(ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, 0); - return CompletePrimitive; - } - jmpFailImm = genJumpImmediate(ReceiverResultReg); - genGetCompactClassIndexNonImmOfinto(ReceiverResultReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(CmpCqR, ClassLargePositiveIntegerCompactIndex, ClassReg); - /* begin JumpNonZero: */ - jmpFailNotPositiveLargeInt = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(0, ReceiverResultReg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(MoveCqR, HashMultiplyConstant, TempReg); - /* begin MulR:R: */ - genMulRR(backEnd, TempReg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(AndCqR, HashMultiplyMask, ReceiverResultReg); - genConvertIntegerToSmallIntegerInReg(ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, 0); - jmpTarget(jmpFailImm, jmpTarget(jmpFailNotPositiveLargeInt, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - -/* Generate the substitute return code for an external or FFI primitive call. - On success simply return, extracting numArgs from newMethod. - On primitive failure call ceActivateFailingPrimitiveMethod: newMethod. */ - - /* SimpleStackBasedCogit>>#genPrimReturnEnterCogCodeEnilopmart: */ -static void NoDbgRegParms -genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) -{ - sqInt address; - sqInt address1; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - sqInt callTarget; - AbstractInstruction *continuePostSample; - AbstractInstruction * inst; - AbstractInstruction *jmpFail; - AbstractInstruction *jmpSample; - sqInt quickConstant; - sqInt reg; - - continuePostSample = ((AbstractInstruction *) 0); - jmpSample = ((AbstractInstruction *) 0); - zeroOpcodeIndex(); - /* begin MoveCq:R: */ - quickConstant = varBaseAddress(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - if (profiling) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick: if so. - N.B. nextProfileTick is 64-bits so 32-bit systems need to test both halves. */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction1 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin MoveAw:R: */ - address = (nextProfileTickAddress()) + BytesPerWord; - /* begin checkLiteral:forInstruction: */ - anInstruction2 = genoperandoperand(MoveAwR, address, ClassReg); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSample = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction13 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadStackPointers(backEnd); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); - /* begin checkLiteral:forInstruction: */ - instructionPointerAddress(); - anInstruction7 = genoperandoperand(MoveAwR, instructionPointerAddress(), LinkReg); - /* begin RetN: */ - genoperand(RetN, BytesPerWord); - jmpTarget(jmpFail, checkLiteralforInstruction(newMethodAddress(), genoperandoperand(MoveAwR, newMethodAddress(), SendNumArgsReg))); - /* begin checkLiteral:forInstruction: */ - cStackPointerAddress(); - anInstruction15 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); - compileCallFornumArgsargargargargresultRegregsToSave(ceActivateFailingPrimitiveMethod, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); - /* begin MoveAw:R: */ - address1 = instructionPointerAddress(); - reg = LinkReg; - /* begin checkLiteral:forInstruction: */ - anInstruction16 = genoperandoperand(MoveAwR, address1, reg); - genLoadStackPointers(backEnd); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, BytesPerWord); - if (profiling) { - - /* Call ceCheckProfileTick: to record sample and then continue. newMethod - should be up-to-date. Need to save and restore the link reg around this call. */ - jmpTarget(jmpSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - /* begin CallFullRT: */ - callTarget = (usqIntptr_t)ceCheckProfileTick; - /* begin checkLiteral:forInstruction: */ - anInstruction18 = genoperand(CallFull, callTarget); - /* begin PopR: */ - genoperand(PopR, LinkReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSample)); - } -} - - /* SimpleStackBasedCogit>>#genPushConstantFalseBytecode */ -static sqInt -genPushConstantFalseBytecode(void) -{ - return genPushLiteral(falseObject()); -} - - /* SimpleStackBasedCogit>>#genPushConstantNilBytecode */ -static sqInt -genPushConstantNilBytecode(void) -{ - return genPushLiteral(nilObject()); -} - - -/* 79 01001111 Push 1 */ - - /* SimpleStackBasedCogit>>#genPushConstantOneBytecode */ -static sqInt -genPushConstantOneBytecode(void) -{ - return genPushLiteral((((usqInt)1 << 1) | 1)); -} - - /* SimpleStackBasedCogit>>#genPushConstantTrueBytecode */ -static sqInt -genPushConstantTrueBytecode(void) -{ - return genPushLiteral(trueObject()); -} - - -/* 78 01001110 Push 0 */ - - /* SimpleStackBasedCogit>>#genPushConstantZeroBytecode */ -static sqInt -genPushConstantZeroBytecode(void) -{ - return genPushLiteral((((usqInt)0 << 1) | 1)); -} - - /* SimpleStackBasedCogit>>#genPushLiteralConstantBytecode */ -static sqInt -genPushLiteralConstantBytecode(void) -{ - return genPushLiteralIndex(byte0 & 0x1F); -} - - -/* 16-31 0001 i i i i Push Literal Variable #iiii */ - - /* SimpleStackBasedCogit>>#genPushLiteralVariable16CasesBytecode */ -static sqInt -genPushLiteralVariable16CasesBytecode(void) -{ - return genPushLiteralVariable(byte0 & 15); -} - - /* SimpleStackBasedCogit>>#genPushLiteralVariableBytecode */ -static sqInt -genPushLiteralVariableBytecode(void) -{ - return genPushLiteralVariable(byte0 & 0x1F); -} - - /* SimpleStackBasedCogit>>#genPushQuickIntegerConstantBytecode */ -static sqInt -genPushQuickIntegerConstantBytecode(void) -{ - return genPushLiteral((((usqInt)(byte0 - 117) << 1) | 1)); -} - - /* SimpleStackBasedCogit>>#genPushReceiverVariableBytecode */ -static sqInt -genPushReceiverVariableBytecode(void) -{ - return genPushReceiverVariable(byte0 & 15); -} - - /* SimpleStackBasedCogit>>#genPushTemporaryVariableBytecode */ -static sqInt -genPushTemporaryVariableBytecode(void) -{ - return genPushTemporaryVariable(byte0 & 15); -} - - -/* because selected by CoInterpreter>>quickPrimitiveGeneratorFor: */ - - /* SimpleStackBasedCogit>>#genQuickReturnConst */ -sqInt -genQuickReturnConst(void) -{ - AbstractInstruction *anInstruction; - sqInt constant; - - constant = quickPrimitiveConstantFor(primitiveIndex); - /* begin genMoveConstant:R: */ - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - genUpArrowReturn(); - return UnfailingPrimitive; -} - - -/* because selected by CoInterpreter>>quickPrimitiveGeneratorFor: */ - - /* SimpleStackBasedCogit>>#genQuickReturnInstVar */ -sqInt -genQuickReturnInstVar(void) -{ - sqInt index; - - index = quickPrimitiveInstVarIndexFor(primitiveIndex); - genLoadSlotsourceRegdestReg(index, ReceiverResultReg, ReceiverResultReg); - genUpArrowReturn(); - return UnfailingPrimitive; -} - - -/* because selected by CoInterpreter>>quickPrimitiveGeneratorFor: */ - - /* SimpleStackBasedCogit>>#genQuickReturnSelf */ -sqInt -genQuickReturnSelf(void) -{ - genUpArrowReturn(); - return UnfailingPrimitive; -} - - /* SimpleStackBasedCogit>>#genReturnFalse */ -static sqInt -genReturnFalse(void) -{ - AbstractInstruction *anInstruction; - sqInt constant; - - /* begin genMoveFalseR: */ - constant = falseObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - return genUpArrowReturn(); -} - - /* SimpleStackBasedCogit>>#genReturnNil */ -static sqInt -genReturnNil(void) -{ - AbstractInstruction *anInstruction; - sqInt constant; - - /* begin genMoveNilR: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - return genUpArrowReturn(); -} - - /* SimpleStackBasedCogit>>#genReturnNilFromBlock */ -static sqInt -genReturnNilFromBlock(void) -{ - AbstractInstruction *anInstruction; - sqInt constant; - - assert(inBlock > 0); - /* begin genMoveNilR: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - return genBlockReturn(); -} - - /* SimpleStackBasedCogit>>#genReturnTrue */ -static sqInt -genReturnTrue(void) -{ - AbstractInstruction *anInstruction; - sqInt constant; - - /* begin genMoveTrueR: */ - constant = trueObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - return genUpArrowReturn(); -} - - -/* Can use any of the first 64 literals for the selector and pass up to 3 - arguments. - */ - - /* SimpleStackBasedCogit>>#genSecondExtendedSendBytecode */ -static sqInt -genSecondExtendedSendBytecode(void) -{ - return genSendnumArgs(byte1 & 0x3F, ((usqInt)(byte1)) >> 6); -} - - /* SimpleStackBasedCogit>>#genSendLiteralSelector0ArgsBytecode */ -static sqInt -genSendLiteralSelector0ArgsBytecode(void) -{ - return genSendnumArgs(byte0 & 15, 0); -} - - /* SimpleStackBasedCogit>>#genSendLiteralSelector1ArgBytecode */ -static sqInt -genSendLiteralSelector1ArgBytecode(void) -{ - return genSendnumArgs(byte0 & 15, 1); -} - - /* SimpleStackBasedCogit>>#genSendLiteralSelector2ArgsBytecode */ -static sqInt -genSendLiteralSelector2ArgsBytecode(void) -{ - return genSendnumArgs(byte0 & 15, 2); -} - - /* SimpleStackBasedCogit>>#genShortJumpIfFalse */ -static sqInt -genShortJumpIfFalse(void) -{ - sqInt distance; - sqInt target; - - distance = v3ShortForwardBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - target = (distance + 1) + bytecodePC; - return genJumpIfto(falseObject(), target); -} - - /* SimpleStackBasedCogit>>#genShortJumpIfTrue */ -static sqInt -genShortJumpIfTrue(void) -{ - sqInt distance; - sqInt target; - - distance = v3ShortForwardBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - target = (distance + 1) + bytecodePC; - return genJumpIfto(trueObject(), target); -} - - /* SimpleStackBasedCogit>>#genShortUnconditionalJump */ -static sqInt -genShortUnconditionalJump(void) -{ - sqInt distance; - sqInt target; - - distance = v3ShortForwardBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - target = (distance + 1) + bytecodePC; - return genJumpTo(target); -} - - /* SimpleStackBasedCogit>>#genSpecialSelectorEqualsEquals */ -static sqInt -genSpecialSelectorEqualsEquals(void) -{ - return genInlinedIdenticalOrNotIf(0); -} - - /* SimpleStackBasedCogit>>#genSpecialSelectorNotEqualsEquals */ -static sqInt -genSpecialSelectorNotEqualsEquals(void) -{ - return genInlinedIdenticalOrNotIf(1); -} - - /* SimpleStackBasedCogit>>#genSpecialSelectorSend */ -static sqInt -genSpecialSelectorSend(void) -{ - sqInt index; - sqInt numArgs; - - index = byte0 - ( -#if MULTIPLEBYTECODESETS - (bytecodeSetOffset == 0x100 - ? AltFirstSpecialSelector + 0x100 - : FirstSpecialSelector) -#else - FirstSpecialSelector -#endif - ); - numArgs = specialSelectorNumArgs(index); - return genSendnumArgs((-index) - 1, numArgs); -} - - /* SimpleStackBasedCogit>>#genStoreAndPopReceiverVariableBytecode */ -static sqInt -genStoreAndPopReceiverVariableBytecode(void) -{ - return genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(1, byte0 & 7, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); -} - - /* SimpleStackBasedCogit>>#genStoreAndPopRemoteTempLongBytecode */ -static sqInt -genStoreAndPopRemoteTempLongBytecode(void) -{ - return genStorePopRemoteTempAtneedsStoreCheck(1, byte1, byte2, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant))))); -} - - /* SimpleStackBasedCogit>>#genStoreAndPopTemporaryVariableBytecode */ -static sqInt -genStoreAndPopTemporaryVariableBytecode(void) -{ - return genStorePopTemporaryVariable(1, byte0 & 7); -} - - /* SimpleStackBasedCogit>>#genStoreRemoteTempLongBytecode */ -static sqInt -genStoreRemoteTempLongBytecode(void) -{ - return genStorePopRemoteTempAtneedsStoreCheck(0, byte1, byte2, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant))))); -} - - -/* Collect the branch and send data for cogMethod, storing it into arrayObj. */ - - /* SimpleStackBasedCogit>>#mapPCDataFor:into: */ -sqInt -mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj) -{ - sqInt aMethodHeader; - sqInt aMethodHeader1; - sqInt aMethodObj; - sqInt annotation; - sqInt bcpc; - sqInt bsOffset; - sqInt byte; - sqInt byte01; - sqInt byte02; - BytecodeDescriptor *descriptor; - sqInt distance; - sqInt distance1; - sqInt distance2; - sqInt endbcpc; - sqInt errCode; - CogMethod *homeMethod; - sqInt isBackwardBranch; - sqInt isInBlock; - sqInt latestContinuation; - usqInt map; - sqInt mapByte; - usqInt mcpc; - sqInt nExts; - sqInt newContinuation; - sqInt nextBcpc; - sqInt prim; - sqInt result; - sqInt startbcpc; - sqInt targetPC; - sqInt targetPC1; - sqInt upperByte; - - latestContinuation = 0; - introspectionDataIndex = 0; - introspectionData = arrayObj; - if (((cogMethod->stackCheckOffset)) == 0) { - assert(introspectionDataIndex == 0); - if ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock)) { - storePointerUncheckedofObjectwithValue(0, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(1, introspectionData, (((usqInt)cbNoSwitchEntryOffset << 1) | 1)); - storePointerUncheckedofObjectwithValue(2, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(3, introspectionData, (((usqInt)cbEntryOffset << 1) | 1)); - } - else { - storePointerUncheckedofObjectwithValue(0, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(1, introspectionData, (((usqInt)cmEntryOffset << 1) | 1)); - storePointerUncheckedofObjectwithValue(2, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(3, introspectionData, (((usqInt)cmNoCheckEntryOffset << 1) | 1)); - } - return 4; - } - /* begin mapFor:bcpc:performUntil:arg: */ - startbcpc = startPCOfMethod((cogMethod->methodObject)); - assert((((((CogBlockMethod *) cogMethod))->stackCheckOffset)) > 0); - - /* The stack check maps to the start of the first bytecode, - the first bytecode being effectively after frame build. */ - mcpc = (((usqInt)(((CogBlockMethod *) cogMethod)))) + (((((CogBlockMethod *) cogMethod))->stackCheckOffset)); - result = pcDataForAnnotationMcpcBcpcMethod(null, (0 + (((int)((usqInt)(HasBytecodePC) << 1)))), (((char *) mcpc)), startbcpc, (((void *)cogMethod))); - if (result != 0) { - errCode = result; - goto l9; - } - - /* In both CMMethod and CMBlock cases find the start of the map and - skip forward to the bytecode pc map entry for the stack check. */ - bcpc = startbcpc; - if ((((((CogBlockMethod *) cogMethod))->cmType)) == CMMethod) { - /* begin cmIsFullBlock */ - isInBlock = ((((CogBlockMethod *) cogMethod))->cpicHasMNUCaseOrCMIsFullBlock); - homeMethod = ((CogMethod *) (((CogBlockMethod *) cogMethod))); - assert(startbcpc == (startPCOfMethodHeader((homeMethod->methodHeader)))); - map = ((((usqInt)homeMethod)) + ((homeMethod->blockSize))) - 1; - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert((annotation == IsAbsPCReference) - || ((annotation == IsObjectReference) - || ((annotation == IsRelativeCall) - || (annotation == IsDisplacementX2N)))); - latestContinuation = startbcpc; - aMethodObj = (homeMethod->methodObject); - endbcpc = (numBytesOf(aMethodObj)) - 1; - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader) - ? 0x100 - : 0) -# else - 0 -# endif - ; - bcpc += deltaToSkipPrimAndErrorStoreInheader(aMethodObj, (homeMethod->methodHeader)); - } - else { - isInBlock = 1; - assert(bcpc == (((((CogBlockMethod *) cogMethod))->startpc))); - homeMethod = cmHomeMethod(((CogBlockMethod *) cogMethod)); - map = findMapLocationForMcpcinMethod((((usqInt)(((CogBlockMethod *) cogMethod)))) + (sizeof(CogBlockMethod)), homeMethod); - assert(map != 0); - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert(((((usqInt)(annotation)) >> AnnotationShift) == HasBytecodePC) - || ((((usqInt)(annotation)) >> AnnotationShift) == IsDisplacementX2N)); - while (((annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift)) != HasBytecodePC) { - map -= 1; - } - - /* skip fiducial; i.e. the map entry for the pc immediately following the method header. */ - map -= 1; - aMethodObj = (homeMethod->methodObject); - bcpc = startbcpc - ( -#if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet((homeMethod->methodHeader)) - ? AltBlockCreationBytecodeSize - : BlockCreationBytecodeSize) -#else // MULTIPLEBYTECODESETS - BlockCreationBytecodeSize -#endif - ); - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader1 = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader1) - ? 0x100 - : 0) -# else - 0 -# endif - ; - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - endbcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, -1, aMethodObj)) - : 0)); - bcpc = startbcpc; - } - nExts = 0; - while ((((usqInt)((byteAt(map)))) >> AnnotationShift) != HasBytecodePC) { - map -= 1; - } - map -= 1; - while (((mapByte = byteAt(map))) != MapEnd) { - - /* defensive; we exit on bcpc */ - if (mapByte >= FirstAnnotation) { - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if (annotation >= HasBytecodePC) { - if ((annotation == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - while (1) { - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - if (isInBlock) { - if (bcpc >= endbcpc) { - errCode = 0; - goto l9; - } - } - else { - if (((descriptor->isReturn)) - && (bcpc >= latestContinuation)) { - errCode = 0; - goto l9; - } - if ((isBranch(descriptor)) - || ((descriptor->isBlockCreation))) { - /* begin latestContinuationPCFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj); - targetPC = (bcpc + ((descriptor->numBytes))) + (((distance < 0) ? 0 : distance)); - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - /* begin maybeUnsafeJumpContinuation:at:for:in: */ - newContinuation = latestContinuation; - if ((descriptor->hasUnsafeJump)) { - byte01 = fetchByteofObject(bcpc + 1, aMethodObj); - - /* pushIntegerLong */ - byte02 = fetchByteofObject(bcpc + 2, aMethodObj); - /* begin decodePushIntegerLongBefore:in: */ - distance1 = fetchByteofObject(bcpc - 1, methodObj); - upperByte = fetchByteofObject(bcpc - 3, methodObj); - if (upperByte > 0x7F) { - upperByte -= 0x100; - } - distance2 = (((sqInt)((usqInt)(upperByte) << 8))) + distance1; - targetPC1 = (bcpc + ((descriptor->numBytes))) + distance2; - if (!((descriptor->isMapped))) { - if ((((usqInt)(byte02)) >> 5) == 4) { - - /* inlined sista primitive */ - prim = (((sqInt)((usqInt)((byte02 & 0x1F)) << 8))) + byte01; - if (prim >= 7000) { - - /* branch forward */ - newContinuation = ((latestContinuation < targetPC1) ? targetPC1 : latestContinuation); - } - } - } - } - latestContinuation = newContinuation; - } - nextBcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) - : 0)); - if (((descriptor->isMapped)) - || (isInBlock - && ((descriptor->isMappedInBlock)))) break; - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - isBackwardBranch = (isBranch(descriptor)) - && ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) < 0)); - result = pcDataForAnnotationMcpcBcpcMethod(descriptor, ((isBackwardBranch - ? (((sqInt)((usqInt)(annotation) << 1))) + 1 - : ((sqInt)((usqInt)(annotation) << 1)))), (((char *) mcpc)), ((isBackwardBranch - ? bcpc - (2 * nExts) - : bcpc)), (((void *)cogMethod))); - if (result != 0) { - errCode = result; - goto l9; - } - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - } - else { - assert(((((usqInt)(mapByte)) >> AnnotationShift) == IsDisplacementX2N) - || ((((usqInt)(mapByte)) >> AnnotationShift) == IsAnnotationExtension)); - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - errCode = 0; - l9: /* end mapFor:bcpc:performUntil:arg: */; - if (errCode != 0) { - assert(errCode == PrimErrNoMemory); - return -1; - } - if (((cogMethod->blockEntryOffset)) != 0) { - errCode = blockDispatchTargetsForperformarg(cogMethod, pcDataForBlockEntryMethod, ((sqInt)cogMethod)); - if (errCode != 0) { - assert(errCode == PrimErrNoMemory); - return -1; - } - } - return introspectionDataIndex; -} - - /* SimpleStackBasedCogit>>#numSpecialSelectors */ -static sqInt -numSpecialSelectors(void) -{ - return -# if MULTIPLEBYTECODESETS - (bytecodeSetOffset == 0x100 - ? AltNumSpecialSelectors - : NumSpecialSelectors) -# else - NumSpecialSelectors -# endif - ; -} - - -/* Collect the branch and send data for the block method starting at - blockEntryMcpc, storing it into picData. - */ - - /* SimpleStackBasedCogit>>#pcDataForBlockEntry:Method: */ -static usqInt NoDbgRegParms -pcDataForBlockEntryMethod(sqInt blockEntryMcpc, sqInt cogMethod) -{ - storePointerUncheckedofObjectwithValue(introspectionDataIndex, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 1, introspectionData, (((usqInt)(blockEntryMcpc - blockNoContextSwitchOffset) << 1) | 1)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 2, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 3, introspectionData, (((usqInt)blockEntryMcpc << 1) | 1)); - introspectionDataIndex += 4; - return 0; -} - - /* SimpleStackBasedCogit>>#pcDataFor:Annotation:Mcpc:Bcpc:Method: */ -static sqInt NoDbgRegParms -pcDataForAnnotationMcpcBcpcMethod(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *cogMethodArg) -{ - sqInt actualBcpc; - sqInt actualMcpc; - - if (!descriptor) { - - /* this is the stackCheck offset */ - assert(introspectionDataIndex == 0); - if (((((CogMethod *) cogMethodArg))->cpicHasMNUCaseOrCMIsFullBlock)) { - storePointerUncheckedofObjectwithValue(introspectionDataIndex, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 1, introspectionData, (((usqInt)cbNoSwitchEntryOffset << 1) | 1)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 2, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 3, introspectionData, (((usqInt)cbEntryOffset << 1) | 1)); - } - else { - storePointerUncheckedofObjectwithValue(introspectionDataIndex, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 1, introspectionData, (((usqInt)cmEntryOffset << 1) | 1)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 2, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 3, introspectionData, (((usqInt)cmNoCheckEntryOffset << 1) | 1)); - } - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 4, introspectionData, (((usqInt)(bcpc + 1) << 1) | 1)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 5, introspectionData, (((((((CogMethod *) cogMethodArg))->stackCheckOffset)) << 1) | 1)); - introspectionDataIndex += 6; - return 0; - } - if ((((usqInt)(isBackwardBranchAndAnnotation)) >> 1) >= HasBytecodePC) { - actualBcpc = (((isBackwardBranchAndAnnotation & 1) != 0) - ? bcpc + 1 - : (bcpc + ((descriptor->numBytes))) + 1); - actualMcpc = (((usqInt)mcpc)) - (((usqInt)cogMethodArg)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex, introspectionData, (((usqInt)actualBcpc << 1) | 1)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 1, introspectionData, (((usqInt)actualMcpc << 1) | 1)); - introspectionDataIndex += 2; - } - return 0; -} - - -/* If there is a generator for the current primitive then answer it; - otherwise answer nil. */ - - /* SimpleStackBasedCogit>>#primitiveGeneratorOrNil */ -static PrimitiveDescriptor * -primitiveGeneratorOrNil(void) -{ - PrimitiveDescriptor *primitiveDescriptor; - - if (isQuickPrimitiveIndex(primitiveIndex)) { - - /* an unused one */ - primitiveDescriptor = (&(primitiveGeneratorTable[0])); - (primitiveDescriptor->primitiveGenerator = quickPrimitiveGeneratorFor(primitiveIndex)); - return primitiveDescriptor; - } - if (((primitiveIndex >= 1) && (primitiveIndex <= MaxCompiledPrimitiveIndex))) { - return (&(primitiveGeneratorTable[primitiveIndex])); - } - return null; -} - - /* SimpleStackBasedCogit>>#register:isInMask: */ -static sqInt NoDbgRegParms -registerisInMask(sqInt reg, sqInt mask) -{ - return ((mask & (1U << reg)) != 0); -} - - /* SimpleStackBasedCogit>>#v3:Block:Code:Size: */ -static sqInt NoDbgRegParms -v3BlockCodeSize(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - assert(nExts <= 0); - return (((sqInt)((usqInt)((fetchByteofObject(pc + 2, aMethodObj))) << 8))) + (fetchByteofObject(pc + 3, aMethodObj)); -} - - -/* Answer the distance of a two byte forward long jump. */ - - /* SimpleStackBasedCogit>>#v3:LongForward:Branch:Distance: */ -static sqInt NoDbgRegParms -v3LongForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - assert(nExts == 0); - return (((sqInt)((usqInt)(((fetchByteofObject(pc, aMethodObj)) & 3)) << 8))) + (fetchByteofObject(pc + 1, aMethodObj)); -} - - -/* Answer the distance of a two byte forward long jump. */ - - /* SimpleStackBasedCogit>>#v3:Long:Branch:Distance: */ -static sqInt NoDbgRegParms -v3LongBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - assert(nExts == 0); - return (((sqInt)((usqInt)((((fetchByteofObject(pc, aMethodObj)) & 7) - 4)) << 8))) + (fetchByteofObject(pc + 1, aMethodObj)); -} - - -/* N.B. This serves for both BlueBook/V3 and V4 short jumps. */ - - /* SimpleStackBasedCogit>>#v3:ShortForward:Branch:Distance: */ -static sqInt NoDbgRegParms -v3ShortForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - assert(nExts == 0); - return ((fetchByteofObject(pc, aMethodObj)) & 7) + 1; -} - - -/* 253 11111101 eei i i kkk jjjjjjjj Push Closure Num Copied iii (+ Ext A - // 16 * 8) Num Args kkk (+ Ext A \\ 16 * 8) BlockSize jjjjjjjj (+ Ext B * - 256). ee = num extensions - */ - - /* SimpleStackBasedCogit>>#v4:Block:Code:Size: */ -static sqInt NoDbgRegParms -v4BlockCodeSize(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - sqInt byte; - sqInt byteOne; - sqInt extAValue; - sqInt extBValue; - sqInt extBValue1; - sqInt extByte; - sqInt pc1; - - - /* If nExts < 0 it isn't known and we rely on the number of extensions encoded in the eeiiikkk byte. */ - byteOne = fetchByteofObject(pc + 1, aMethodObj); - assert((nExts < 0) - || (nExts == (((usqInt)(byteOne)) >> 6))); - /* begin parseV4Exts:priorTo:in:into: */ - extAValue = (extBValue1 = 0); - pc1 = (pc - (((usqInt)(byteOne)) >> 6)) - (((usqInt)(byteOne)) >> 6); - while (pc1 < pc) { - byte = fetchByteofObject(pc1, aMethodObj); - pc1 += 1; - extByte = fetchByteofObject(pc1, aMethodObj); - pc1 += 1; - assert((byte == 224) - || (byte == 225)); - if (byte == 224) { - extAValue = ((((sqInt)((usqInt)(extAValue) << 8)))) + extByte; - } - else { - extBValue1 = ((extBValue1 == 0) - && (extByte > 0x7F) - ? extByte - 0x100 - : ((((sqInt)((usqInt)(extBValue1) << 8)))) + extByte); - } - } - extBValue = extBValue1; - return (fetchByteofObject(pc + 2, aMethodObj)) + (((sqInt)((usqInt)(extBValue) << 8))); -} - - -/* 242 11110010 i i i i i i i i Jump i i i i i i i i (+ Extend B * 256, - where bbbbbbbb = sddddddd, e.g. -32768 = i=0, a=0, s=1) - */ -/* 243 11110011 i i i i i i i i Pop and Jump 0n True i i i i i i i i (+ - Extend A * 256) - */ -/* 244 11110100 i i i i i i i i Pop and Jump 0n False i i i i i i i i (+ - Extend A * 256) - */ - - /* SimpleStackBasedCogit>>#v4:LongForward:Branch:Distance: */ -static sqInt NoDbgRegParms -v4LongForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - sqInt byte; - sqInt extAValue; - sqInt extBValue; - sqInt extBValue1; - sqInt extByte; - sqInt pc1; - - assert(nExts >= 0); - /* begin parseV4Exts:priorTo:in:into: */ - extAValue = (extBValue1 = 0); - pc1 = (pc - nExts) - nExts; - while (pc1 < pc) { - byte = fetchByteofObject(pc1, aMethodObj); - pc1 += 1; - extByte = fetchByteofObject(pc1, aMethodObj); - pc1 += 1; - assert((byte == 224) - || (byte == 225)); - if (byte == 224) { - extAValue = ((((sqInt)((usqInt)(extAValue) << 8)))) + extByte; - } - else { - extBValue1 = ((extBValue1 == 0) - && (extByte > 0x7F) - ? extByte - 0x100 - : ((((sqInt)((usqInt)(extBValue1) << 8)))) + extByte); - } - } - extBValue = extBValue1; - return (fetchByteofObject(pc + 1, aMethodObj)) + (((sqInt)((usqInt)(extBValue) << 8))); -} - - -/* 242 11110010 i i i i i i i i Jump i i i i i i i i (+ Extend B * 256, - where bbbbbbbb = sddddddd, e.g. -32768 = i=0, a=0, s=1) - */ - - /* SimpleStackBasedCogit>>#v4:Long:Branch:Distance: */ -static sqInt NoDbgRegParms -v4LongBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - sqInt byte; - sqInt extAValue; - sqInt extBValue; - sqInt extBValue1; - sqInt extByte; - sqInt pc1; - - assert(nExts >= 0); - /* begin parseV4Exts:priorTo:in:into: */ - extAValue = (extBValue1 = 0); - pc1 = (pc - nExts) - nExts; - while (pc1 < pc) { - byte = fetchByteofObject(pc1, aMethodObj); - pc1 += 1; - extByte = fetchByteofObject(pc1, aMethodObj); - pc1 += 1; - assert((byte == 224) - || (byte == 225)); - if (byte == 224) { - extAValue = ((((sqInt)((usqInt)(extAValue) << 8)))) + extByte; - } - else { - extBValue1 = ((extBValue1 == 0) - && (extByte > 0x7F) - ? extByte - 0x100 - : ((((sqInt)((usqInt)(extBValue1) << 8)))) + extByte); - } - } - extBValue = extBValue1; - return (fetchByteofObject(pc + 1, aMethodObj)) + (((sqInt)((usqInt)(extBValue) << 8))); -} - - /* SistaCogit>>#compileCogFullBlockMethod: */ -static CogMethod * NoDbgRegParms -compileCogFullBlockMethod(sqInt numCopied) -{ - sqInt allocBytes; - sqInt fixupBytes; - sqInt numBlocks; - sqInt numBytecodes; - sqInt numberOfAbstractOpcodes; - sqInt numCleanBlocks; - sqInt opcodeBytes; - sqInt result; - - counters = 0; - methodOrBlockNumTemps = tempCountOf(methodObj); - setHasMovableLiteral(0); - setHasYoungReferent(isYoungObject(methodObj)); - methodOrBlockNumArgs = argumentCountOf(methodObj); - inBlock = InFullBlock; - maxLitIndex = -1; - assert((primitiveIndexOf(methodObj)) == 0); - - /* initial estimate. Actual endPC is determined in scanMethod. */ - initialPC = startPCOfMethod(methodObj); - endPC = numBytesOf(methodObj); - numBytecodes = (endPC - initialPC) + 1; - primitiveIndex = 0; - /* begin allocateOpcodes:bytecodes:ifFail: */ - numberOfAbstractOpcodes = (numBytecodes + 10) * 11 /* estimateOfAbstractOpcodesPerBytecodes */; - numAbstractOpcodes = numberOfAbstractOpcodes; - opcodeBytes = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupBytes = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - - /* Document the fact that the MaxStackAllocSize ensures that the number of abstract - opcodes fits in a 16 bit integer (e.g. CogBytecodeFixup's instructionIndex). */ - allocBytes = opcodeBytes + fixupBytes; - assert((((sizeof(CogAbstractInstruction)) + (sizeof(CogBytecodeFixup))) * 0xC000) > MaxStackAllocSize); - if (allocBytes > MaxStackAllocSize) { - return ((CogMethod *) MethodTooBig); - goto l1; - } - abstractOpcodes = alloca(allocBytes); - bzero(abstractOpcodes, allocBytes); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeBytes)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - l1: /* end allocateOpcodes:bytecodes:ifFail: */; - flag("TODO"); - if (((numBlocks = scanMethod())) < 0) { - return ((CogMethod *) numBlocks); - } - assert(numBlocks == 0); - numCleanBlocks = scanForCleanBlocks(); - assert(numCleanBlocks == 0); - allocateBlockStarts(numBlocks + numCleanBlocks); - blockCount = 0; - if (numCleanBlocks > 0) { - addCleanBlockStarts(); - } - if (!((maybeAllocAndInitCounters()) - && (maybeAllocAndInitIRCs()))) { - - /* Inaccurate error code, but it'll do. This will likely never fail. */ - return ((CogMethod *) InsufficientCodeSpace); - } - blockEntryLabel = null; - (methodLabel->dependent = null); - if (((result = compileEntireFullBlockMethod(numCopied))) < 0) { - return ((CogMethod *) result); - } - return generateCogFullBlock(); -} - - /* SistaCogit>>#compileCogMethod: */ -static CogMethod * NoDbgRegParms -compileCogMethod(sqInt selector) -{ - sqInt allocBytes; - int extra; - sqInt fixupBytes; - sqInt numBlocks; - sqInt numBytecodes; - sqInt numberOfAbstractOpcodes; - sqInt numCleanBlocks; - sqInt opcodeBytes; - sqInt result; - - counters = 0; - methodOrBlockNumTemps = tempCountOf(methodObj); - setHasMovableLiteral(0); - setHasYoungReferent((isYoungObject(methodObj)) - || (isYoung(selector))); - methodOrBlockNumArgs = argumentCountOf(methodObj); - inBlock = 0; - maxLitIndex = -1; - extra = ((((primitiveIndex = primitiveIndexOf(methodObj))) > 0) - && (!(isQuickPrimitiveIndex(primitiveIndex))) - ? 30 - : 10); - - /* initial estimate. Actual endPC is determined in scanMethod. */ - initialPC = startPCOfMethod(methodObj); - endPC = (isQuickPrimitiveIndex(primitiveIndex) - ? initialPC - 1 - : numBytesOf(methodObj)); - numBytecodes = (endPC - initialPC) + 1; - /* begin allocateOpcodes:bytecodes:ifFail: */ - numberOfAbstractOpcodes = (numBytecodes + extra) * 11 /* estimateOfAbstractOpcodesPerBytecodes */; - numAbstractOpcodes = numberOfAbstractOpcodes; - opcodeBytes = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupBytes = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - - /* Document the fact that the MaxStackAllocSize ensures that the number of abstract - opcodes fits in a 16 bit integer (e.g. CogBytecodeFixup's instructionIndex). */ - allocBytes = opcodeBytes + fixupBytes; - assert((((sizeof(CogAbstractInstruction)) + (sizeof(CogBytecodeFixup))) * 0xC000) > MaxStackAllocSize); - if (allocBytes > MaxStackAllocSize) { - return ((CogMethod *) MethodTooBig); - goto l1; - } - abstractOpcodes = alloca(allocBytes); - bzero(abstractOpcodes, allocBytes); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeBytes)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - l1: /* end allocateOpcodes:bytecodes:ifFail: */; - if (((numBlocks = scanMethod())) < 0) { - return ((CogMethod *) numBlocks); - } - numCleanBlocks = scanForCleanBlocks(); - if (methodFoundInvalidPostScan()) { - return ((CogMethod *) ShouldNotJIT); - } - allocateBlockStarts(numBlocks + numCleanBlocks); - blockCount = 0; - if (numCleanBlocks > 0) { - addCleanBlockStarts(); - } - if (!((maybeAllocAndInitCounters()) - && (maybeAllocAndInitIRCs()))) { - - /* Inaccurate error code, but it'll do. This will likely never fail. */ - return ((CogMethod *) InsufficientCodeSpace); - } - blockEntryLabel = null; - (methodLabel->dependent = null); - if (((result = compileEntireMethod())) < 0) { - return ((CogMethod *) result); - } - return generateCogMethod(selector); -} - - -/* Build a frame for a CogMethod activation. See CoInterpreter - class>>initializeFrameIndices. receiver (in ReceiverResultReg) - arg0 - ... - argN - caller's saved ip/this stackPage (for a base frame) - fp-> saved fp - method - context (uninitialized?) - receiver - first temp - ... - sp-> Nth temp - If there is a primitive and an error code the Nth temp is the error code. - Ensure SendNumArgsReg is set early on (incidentally to nilObj) because - it is the flag determining whether context switch is allowed on - stack-overflow. */ -/* Build a frame for a CogMethod activation. See CoInterpreter - class>>initializeFrameIndices. Override to push the register receiver and - register arguments, if any. */ -/* Override to prefetch counters, if any. */ - - /* SistaCogit>>#compileFrameBuild */ -static void -compileFrameBuild(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction2; - sqInt constant; - sqInt i; - sqInt iLimiT; - - -# if IMMUTABILITY - if (useTwoPaths) { - compileTwoPathFrameBuild(); - return; - } -# endif - if (!needsFrame) { - if (useTwoPaths) { - compileTwoPathFramelessInit(); - } - initSimStackForFramelessMethod(initialPC); - return; - } - assert(!(useTwoPaths)); - genPushRegisterArgs(); - if (!needsFrame) { - return; - } - /* begin PushR: */ - genoperand(PushR, LinkReg); - /* begin PushR: */ - genoperand(PushR, FPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SPReg, FPReg); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperand(PushCw, ((sqInt)methodLabel))))); - /* begin genMoveNilR: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, SendNumArgsReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, SendNumArgsReg); - } - /* begin PushR: */ - genoperand(PushR, SendNumArgsReg); - /* begin PushR: */ - genoperand(PushR, ReceiverResultReg); - for (i = (methodOrBlockNumArgs + 1), iLimiT = (temporaryCountOfMethodHeader(methodHeader)); i <= iLimiT; i += 1) { - /* begin PushR: */ - genoperand(PushR, SendNumArgsReg); - } - if (((primitiveIndexOfMethodheader(methodObj, methodHeader)) > 0) - && ((longStoreBytecodeForHeader(methodHeader)) == (fetchByteofObject((startPCOfMethod(methodObj)) + (sizeOfCallPrimitiveBytecode(methodHeader)), methodObj)))) { - compileGetErrorCode(); - } - stackCheckLabel = compileStackOverflowCheck(canContextSwitchIfActivatingheader(methodObj, methodHeader)); - initSimStackForFramefulMethod(initialPC); - if (counters != 0) { - /* begin checkLiteral:forInstruction: */ - anInstruction2 = genoperand(PrefetchAw, counters); - } -} - - -/* Build a frame for a block activation. See CoInterpreter - class>>initializeFrameIndices. closure (in ReceiverResultReg) - arg0 - ... - argN - caller's saved ip/this stackPage (for a base frame) - fp-> saved fp - method - context (uninitialized?) - receiver - first temp - ... - sp-> Nth temp - Avoid use of SendNumArgsReg which is the flag determining whether - context switch is allowed on stack-overflow. */ -/* Override to prefetch counters if any */ - - /* SistaCogit>>#compileFullBlockMethodFrameBuild: */ -static void NoDbgRegParms -compileFullBlockMethodFrameBuild(sqInt numCopied) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt constant; - sqInt i; - sqInt iLimiT; - - if (useTwoPaths) { - - /* method with only inst var store, we compile only slow path for now */ - useTwoPaths = 0; -# if IMMUTABILITY - needsFrame = 1; -# endif - } - if (!needsFrame) { - - /* it is OK for numCopied to be non-zero provided that the block does not actually use the copied values. - There are some blocks like this, e.g. that simply reference copied values to mark them as used for Slang. - See e.g. CroquetPlugin>>#primitiveGatherEntropy which contains the block [bufPtr. bufSize. false], - which the bytecode compiler optimizes to [false]. */ - compileFullBlockFramelessEntry(numCopied); - initSimStackForFramelessBlock(initialPC); - return; - } - if (!needsFrame) { - return; - } - /* begin PushR: */ - genoperand(PushR, LinkReg); - /* begin PushR: */ - genoperand(PushR, FPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SPReg, FPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, ClassReg); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperand(PushCw, ((sqInt)methodLabel))))); - /* begin setLabelOffset: */ - (((((AbstractInstruction *) methodLabel))->operands))[1] = MFMethodFlagIsBlockFlag; - /* begin genMoveNilR: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, SendNumArgsReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, SendNumArgsReg); - } - /* begin PushR: */ - genoperand(PushR, SendNumArgsReg); - flag("TODO"); - genLoadSlotsourceRegdestReg(FullClosureReceiverIndex, ClassReg, Arg0Reg); - genEnsureOopInRegNotForwardedscratchRegupdatingSlotin(Arg0Reg, TempReg, FullClosureReceiverIndex, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ReceiverResultReg); - /* begin PushR: */ - genoperand(PushR, ReceiverResultReg); - for (i = 0; i < numCopied; i += 1) { - genLoadSlotsourceRegdestReg(i + FullClosureFirstCopiedValueIndex, ClassReg, TempReg); - /* begin PushR: */ - genoperand(PushR, TempReg); - } - for (i = ((methodOrBlockNumArgs + numCopied) + 1), iLimiT = (temporaryCountOfMethodHeader(methodHeader)); i <= iLimiT; i += 1) { - /* begin PushR: */ - genoperand(PushR, SendNumArgsReg); - } - stackCheckLabel = compileStackOverflowCheck(1); - initSimStackForFramefulMethod(initialPC); - if (counters != 0) { - /* begin checkLiteral:forInstruction: */ - anInstruction1 = genoperand(PrefetchAw, counters); - } -} - - -/* Return the default number of bytes to allocate for native code at startup. - The actual value can be set via vmParameterAt: and/or a preference in the - ini file. */ - - /* SistaCogit>>#defaultCogCodeSize */ -sqInt -defaultCogCodeSize(void) -{ - return 0x300000; -} - - /* SistaCogit>>#fillInCounters:atStartAddress: */ -static void NoDbgRegParms -fillInCountersatStartAddress(sqInt nCounters, sqInt startAddress) -{ - sqInt address; - - for (address = startAddress; address <= (startAddress + ((nCounters - 1) * CounterBytes)); address += CounterBytes) { - long32Atput(address, (((sqInt)((usqInt)(initialCounterValue) << 16))) + initialCounterValue); - } -} - - -/* Fill in the header for theCogMehtod method. This may be located at the - writable mapping. */ - - /* SistaCogit>>#fillInMethodHeader:size:selector: */ -static void NoDbgRegParms -fillInMethodHeadersizeselector(CogMethod *method, sqInt size, sqInt selector) -{ - sqInt actualMethodLocation; - CogMethod *originalMethod; - sqInt rawHeader; - - actualMethodLocation = (((usqInt)method)) - codeToDataDelta; - (method->cmType = CMMethod); - (method->objectHeader = nullHeaderForMachineCodeMethod()); - (method->blockSize = size); - (method->methodObject = methodObj); - - /* If the method has already been cogged (e.g. Newspeak accessors) then - leave the original method attached to its cog method, but get the right header. */ - rawHeader = rawHeaderOf(methodObj); - if (isCogMethodReference(rawHeader)) { - originalMethod = ((CogMethod *) rawHeader); - assert(((originalMethod->blockSize)) == size); - assert(methodHeader == ((originalMethod->methodHeader))); - } - else { - rawHeaderOfput(methodObj, actualMethodLocation); - } - (method->methodHeader = methodHeader); - (method->selector = selector); - (method->cmNumArgs = argumentCountOfMethodHeader(methodHeader)); - (method->cmHasMovableLiteral = hasMovableLiteral); - if ((method->cmRefersToYoung = hasYoungReferent)) { - addToYoungReferrers(method); - } - (method->cmUsageCount = initialMethodUsageCount()); - /* begin cpicHasMNUCase: */ - ((((CogBlockMethod *) method))->cpicHasMNUCaseOrCMIsFullBlock) = 0; - (method->cmUsesPenultimateLit = maxLitIndex >= ((literalCountOfMethodHeader(methodHeader)) - 2)); - (method->blockEntryOffset = (blockEntryLabel != null - ? ((blockEntryLabel->address)) - actualMethodLocation - : 0)); - if (needsFrame) { - if (!((((stackCheckLabel->address)) - actualMethodLocation) <= MaxStackCheckOffset)) { - error("too much code for stack check offset"); - } - } - (method->stackCheckOffset = (needsFrame - ? ((stackCheckLabel->address)) - actualMethodLocation - : 0)); - assert((callTargetFromReturnAddress(backEnd, actualMethodLocation + missOffset)) == (methodAbortTrampolineFor((method->cmNumArgs)))); - assert(size == (roundUpLength(size))); - /* begin assertValidDualZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, actualMethodLocation + cmNoCheckEntryOffset, codeToDataDelta); -# endif - /* begin maybeEnableSingleStep */ - fillInCountersatStartAddress(numCounters, counters); - (method->counters = counters); -} - - -/* The store check requires rr to be ReceiverResultReg */ - - /* SistaCogit>>#genAtPutInlinePrimitive: */ -static sqInt NoDbgRegParms -genAtPutInlinePrimitive(sqInt prim) -{ - switch (prim) { - case 0: - genPointerAtPutMaybeContextstoreCheckimmutabilityCheck(0, 0, 0); - break; - case 1: - genPointerAtPutMaybeContextstoreCheckimmutabilityCheck(0, 1, 0); - break; - case 2: - genPointerAtPutMaybeContextstoreCheckimmutabilityCheck(1, 0, 0); - break; - case 3: - genPointerAtPutMaybeContextstoreCheckimmutabilityCheck(1, 1, 0); - break; - case 4: - genByteAtPut(); - break; - default: - return EncounteredUnknownBytecode; - - } - return 0; -} - - -/* 2064 pointerAt: - Pointer object (Fixed sized or not) and not a context, Smi => (1-based, - optimised if arg1 is a constant) - 2065 maybeContextPointerAt: - Pointer object (Fixed sized or not), Smi => (1-based, optimised if arg1 is - a constant) - 2066 byteAt: - byte object, Smi => 8 bits unsigned Smi (1-based, optimised if arg1 is a - constant) 2067 shortAt: - short object, Smi => 16 bits unsigned Smi (1-based, optimised if arg1 is a - constant) 2068 wordAt: - word object, Smi => 32 bits unsigned Smi (1-based, optimised if arg1 is a - constant) 2069 doubleWordAt: - double word object, Smi => 64 bits unsigned Smi or LargePositiveInteger - (1-based, optimised if arg1 is a constant) - */ - - /* SistaCogit>>#genBinaryAtConstInlinePrimitive: */ -static sqInt NoDbgRegParms -genBinaryAtConstInlinePrimitive(sqInt primIndex) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *jmpDone; - AbstractInstruction *jmpSingle; - sqInt rr; - sqInt val; - sqInt zeroBasedIndex; - - val = ((ssTop())->constant); - if (primIndex == 65) { - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); - voidReceiverResultRegContainsSelf(); - rr = ReceiverResultReg; - } - else { - rr = allocateRegForStackEntryAtnotConflictingWith(1, 0); - } - popToReg(ssValue(1), rr); - ssPop(2); - zeroBasedIndex = ((val >> 1)) - 1; - switch (primIndex) { - case 64: - genLoadSlotsourceRegdestReg(zeroBasedIndex, rr, rr); - break; - case 65: - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << SendNumArgsReg, simStackPtr, simNativeStackPtr); - /* begin genPushMaybeContextSlotIndex: */ - assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { - - /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ - voidReceiverResultRegContainsSelf(); - } - if (zeroBasedIndex == InstructionPointerIndex) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, zeroBasedIndex, SendNumArgsReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceFetchContextInstVarTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - return ssPushRegister(SendNumArgsReg); - } - genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); - jmpSingle = genJumpNotSmallIntegerInScratchReg(TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, zeroBasedIndex, SendNumArgsReg); - /* begin CallRT: */ - abstractInstruction1 = genoperand(Call, ceFetchContextInstVarTrampoline); - (abstractInstruction1->annotation = IsRelativeCall); - /* begin Jump: */ - jmpDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jmpSingle, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genLoadSlotsourceRegdestReg(zeroBasedIndex, ReceiverResultReg, SendNumArgsReg); - jmpTarget(jmpDone, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return ssPushRegister(SendNumArgsReg); - - case 66: - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMbrR, zeroBasedIndex + BaseHeaderSize, rr, rr); - genConvertIntegerToSmallIntegerInReg(rr); - break; - default: - return EncounteredUnknownBytecode; - - } - return ssPushRegister(rr); -} - - -/* 2064 pointerAt: - Pointer object (Fixed sized or not) and not a context, Smi => (1-based, - optimised if arg1 is a constant) - 2065 maybeContextPointerAt: - Pointer object (Fixed sized or not), Smi => (1-based, optimised if arg1 is - a constant) - 2066 byteAt: - byte object, Smi => 8 bits unsigned Smi (1-based, optimised if arg1 is a - constant) 2067 shortAt: - short object, Smi => 16 bits unsigned Smi (1-based, optimised if arg1 is a - constant) 2068 wordAt: - word object, Smi => 32 bits unsigned Smi (1-based, optimised if arg1 is a - constant) 2069 doubleWordAt: - double word object, Smi => 64 bits unsigned Smi or LargePositiveInteger - (1-based, optimised if arg1 is a constant) - */ - - /* SistaCogit>>#genBinaryAtInlinePrimitive: */ -static sqInt NoDbgRegParms -genBinaryAtInlinePrimitive(sqInt primIndex) -{ - sqInt adjust; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt ra; - sqInt reg; - sqInt rNext1; - sqInt rr; - sqInt rTop1; - sqInt topRegistersMask; - - /* begin allocateRegForStackTopTwoEntriesInto: */ - topRegistersMask = 0; - rTop1 = (rNext1 = NoReg); - if ((registerOrNone(ssTop())) != NoReg) { - rTop1 = registerOrNone(ssTop()); - } - if ((registerOrNone(ssValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; - } - if (rTop1 == NoReg) { - rTop1 = allocateRegNotConflictingWith(topRegistersMask); - } - if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); - } - assert(!(((rTop1 == NoReg) - || (rNext1 == NoReg)))); - ra = rTop1; - rr = rNext1; - popToReg(ssTop(), ra); - ssPop(1); - popToReg(ssTop(), rr); - ssPop(1); - switch (primIndex) { - case 64: - genConvertSmallIntegerToIntegerInReg(ra); - adjust = (((usqInt)(BaseHeaderSize)) >> (shiftForWord())) - 1; - if (adjust != 0) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, adjust, ra); - } - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, ra, rr, rr); - break; - case 66: - genConvertSmallIntegerToIntegerInReg(ra); - adjust = BaseHeaderSize - 1; - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AddCqR, adjust, ra); - /* begin MoveXbr:R:R: */ - genoperandoperandoperand(MoveXbrRR, ra, rr, rr); - genConvertIntegerToSmallIntegerInReg(rr); - break; - default: - return EncounteredUnknownBytecode; - - } - return ssPushRegister(rr); -} - - -/* 2032 > - Smi, Smi => Boolean (optimised if one operand is a constant, Pipelined - with ifTrue:ifFalse:) - 2033 < - Smi, Smi => Boolean (optimised if one operand is a constant, Pipelined - with ifTrue:ifFalse:) - 2034 >= - Smi, Smi => Boolean (optimised if one operand is a constant, Pipelined - with ifTrue:ifFalse:) - 2035 <= - Smi, Smi => Boolean (optimised if one operand is a constant, Pipelined - with ifTrue:ifFalse:) - 2036 = - Smi, Smi => Boolean (optimised if one operand is a constant, Pipelined - with ifTrue:ifFalse:) - 2037 ~= - Smi, Smi => Boolean (optimised if one operand is a constant, Pipelined - with ifTrue:ifFalse:) - 2038 rawEqualsEquals: - not a forwarder, not a forwarder => Boolean (optimised if one operand is a - constant, Pipelined with ifTrue:ifFalse:) - 2039 rawNotEqualsEquals: - not a forwarder, not a forwarder => Boolean (optimised if one operand is a - constant, Pipelined with ifTrue:ifFalse:) - */ - - /* SistaCogit>>#genBinaryCompInlinePrimitive: */ -static sqInt NoDbgRegParms -genBinaryCompInlinePrimitive(sqInt primIndex) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt constant; - sqInt constant1; - sqInt invertedOpFalse; - sqInt invertedOpTrue; - sqInt opFalse; - sqInt opTrue; - sqInt otherReg; - sqInt resultReg; - - assert(((primIndex >= 32) && (primIndex <= 39))); - switch (primIndex) { - case 32: - opTrue = JumpGreater; - opFalse = JumpLessOrEqual; - invertedOpTrue = JumpLess; - invertedOpFalse = JumpGreaterOrEqual; - break; - case 33: - opTrue = JumpLess; - opFalse = JumpGreaterOrEqual; - invertedOpTrue = JumpGreater; - invertedOpFalse = JumpLessOrEqual; - break; - case 34: - opTrue = JumpGreaterOrEqual; - opFalse = JumpLess; - invertedOpTrue = JumpLessOrEqual; - invertedOpFalse = JumpGreater; - break; - case 35: - opTrue = JumpLessOrEqual; - opFalse = JumpGreater; - invertedOpTrue = JumpGreaterOrEqual; - invertedOpFalse = JumpLess; - break; - case 36: - case 38: - opTrue = JumpZero; - opFalse = JumpNonZero; - invertedOpTrue = JumpZero; - invertedOpFalse = JumpNonZero; - break; - case 37: - case 39: - opTrue = JumpNonZero; - opFalse = JumpZero; - invertedOpTrue = JumpNonZero; - invertedOpFalse = JumpZero; - break; - default: - error("Case not found and no otherwise clause"); - } - if ((((ssTop())->type)) == SSConstant) { - resultReg = allocateRegForStackEntryAtnotConflictingWith(1, 0); - popToReg(ssValue(1), resultReg); - /* begin genCmpConstant:R: */ - constant = ((ssTop())->constant); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(CmpCwR, constant, resultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, constant, resultReg); - } - ssPop(2); - genBinaryInlineComparisonopFalsedestReg(opTrue, opFalse, resultReg); - return ssPushRegister(resultReg); - } - if ((((ssValue(1))->type)) == SSConstant) { - resultReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - popToReg(ssTop(), resultReg); - /* begin genCmpConstant:R: */ - constant1 = ((ssValue(1))->constant); - if (shouldAnnotateObjectReference(constant1)) { - annotateobjRef(checkLiteralforInstruction(constant1, genoperandoperand(CmpCwR, constant1, resultReg)), constant1); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, constant1, resultReg); - } - ssPop(2); - genBinaryInlineComparisonopFalsedestReg(invertedOpTrue, invertedOpFalse, resultReg); - return ssPushRegister(resultReg); - } - otherReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - popToReg(ssTop(), otherReg); - resultReg = allocateRegForStackEntryAtnotConflictingWith(1, 1U << otherReg); - popToReg(ssValue(1), resultReg); - /* begin CmpR:R: */ - assert(!((otherReg == SPReg))); - genoperandoperand(CmpRR, otherReg, resultReg); - ssPop(2); - genBinaryInlineComparisonopFalsedestReg(opTrue, opFalse, resultReg); - return ssPushRegister(resultReg); -} - - /* SistaCogit>>#genBinaryConstOpVarSmiInlinePrimitive: */ -static sqInt NoDbgRegParms -genBinaryConstOpVarSmiInlinePrimitive(sqInt primIndex) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - sqInt ra; - sqInt untaggedVal; - sqInt val; - - ra = allocateRegForStackEntryAtnotConflictingWith(0, 0); - popToReg(ssTop(), ra); - ssPop(1); - val = ((ssTop())->constant); - ssPop(1); - untaggedVal = val - (smallIntegerTag()); - switch (primIndex) { - case 0: - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, untaggedVal, ra); - break; - case 1: - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, val, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, ra, TempReg); - genAddSmallIntegerTagsTo(TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ra); - break; - case 2: - genShiftAwaySmallIntegerTagsInScratchReg(ra); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, untaggedVal, TempReg); - /* begin MulR:R: */ - genMulRR(backEnd, TempReg, ra); - genSetSmallIntegerTagsIn(ra); - break; - case 16: - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(AndCqR, val, ra); - break; - case 17: - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(OrCqR, val, ra); - break; - case 18: - /* begin checkLiteral:forInstruction: */ - anInstruction5 = genoperandoperand(XorCwR, untaggedVal, ra); - break; - default: - return EncounteredUnknownBytecode; - - } - ssPushRegister(ra); - return 0; -} - - -/* Inlined comparison. opTrue = jump for true and opFalse = jump for false */ - - /* SistaCogit>>#genBinaryInlineComparison:opFalse:destReg: */ -static sqInt NoDbgRegParms -genBinaryInlineComparisonopFalsedestReg(sqInt opTrue, sqInt opFalse, sqInt destReg) -{ - AbstractInstruction *anInstruction; - sqInt bcpc; - BytecodeDescriptor *branchDescriptor; - BytecodeDescriptor *branchDescriptor1; - AbstractInstruction * condJump; - sqInt constant; - BytecodeDescriptor *descriptor; - sqInt eA; - sqInt eB; - AbstractInstruction * jump; - void *jumpTarget; - sqInt nExts; - sqInt nextPC; - sqInt nextPC1; - sqInt postBranchPC; - sqInt postBranchPC1; - BytecodeDescriptor *primDescriptor; - sqInt savedB0; - sqInt savedB1; - sqInt savedB2; - sqInt savedB3; - sqInt savedEA; - sqInt savedEB; - sqInt savedNEB; - sqInt targetBytecodePC; - sqInt targetBytecodePC1; - - /* begin extractMaybeBranchDescriptorInto: */ - primDescriptor = generatorAt(byte0); - nextPC1 = bytecodePC + ((primDescriptor->numBytes)); - nExts = 0; - while (1) { - while (1) { - /* begin generatorForPC: */ - branchDescriptor1 = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC1, methodObj))); - if (!((branchDescriptor1->isExtension))) break; - nExts += 1; - nextPC1 += (branchDescriptor1->numBytes); - } - /* begin isUnconditionalBranch */ - if (!((isBranch(branchDescriptor1)) - && (!(((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse)))))) break; - nextPC1 = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - } - targetBytecodePC1 = (postBranchPC1 = 0); - if (((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse))) { - targetBytecodePC1 = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - postBranchPC1 = eventualTargetOf(nextPC1 + ((branchDescriptor1->numBytes))); - } - else { - nextPC1 = bytecodePC + ((primDescriptor->numBytes)); - } - branchDescriptor = branchDescriptor1; - nextPC = nextPC1; - postBranchPC = postBranchPC1; - targetBytecodePC = targetBytecodePC1; - if (((branchDescriptor->isBranchTrue)) - || ((branchDescriptor->isBranchFalse))) { - - /* This is the path where the inlined comparison is followed immediately by a branch */ - if ((((fixupAt(nextPC))->targetInstruction)) == 0) { - - /* The next instruction is dead. we can skip it. */ - deadCode = 1; - ensureFixupAt(targetBytecodePC); - ensureFixupAt(postBranchPC); - } - else { - ssPushConstant(trueObject()); - } - genConditionalBranchoperand(((branchDescriptor->isBranchTrue) - ? opTrue - : opFalse), ((usqInt)(ensureNonMergeFixupAt(targetBytecodePC)))); - /* begin nextDescriptorExtensionsAndNextPCInto: */ - descriptor = generatorAt(byte0); - savedB0 = byte0; - savedB1 = byte1; - savedB2 = byte2; - savedB3 = byte3; - savedEA = extA; - savedEB = extB; - savedNEB = numExtB; - bcpc = bytecodePC + ((descriptor->numBytes)); - do { - if (bcpc > endPC) { - nextPC = 0; - goto l2; - } - byte0 = (fetchByteofObject(bcpc, methodObj)) + bytecodeSetOffset; - descriptor = generatorAt(byte0); - loadSubsequentBytesForDescriptorat(descriptor, bcpc); - if (!((descriptor->isExtension))) { - eA = extA; - eB = extB; - extA = savedEA; - extB = savedEB; - numExtB = savedNEB; - byte0 = savedB0; - byte1 = savedB1; - byte2 = savedB2; - byte3 = savedB3; - nextPC = bcpc; - goto l2; - } - ((descriptor->generator))(); - bcpc += (descriptor->numBytes); - } while(1); - l2: /* end nextDescriptorExtensionsAndNextPCInto: */; - if (!(deadCode - && (nextPC == postBranchPC))) { - /* begin Jump: */ - jumpTarget = ensureNonMergeFixupAt(postBranchPC); - genoperand(Jump, ((sqInt)jumpTarget)); - } - } - else { - - /* This is the path where the inlined comparison is *not* followed immediately by a branch */ - condJump = genConditionalBranchoperand(opTrue, 0); - /* begin genMoveFalseR: */ - constant = falseObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, destReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, destReg); - } - /* begin Jump: */ - jump = genoperand(Jump, ((sqInt)0)); - jmpTarget(condJump, genMoveTrueR(destReg)); - jmpTarget(jump, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - return 0; -} - - -/* Bulk comments: each sub-method has its own comment with the specific case. - 2000 + - Smi, Smi => Smi (no overflow, optimised if one operand is a constant) - 2001 - - Smi, Smi => Smi (no overflow, optimised if one operand is a constant) - 2002 * - Smi, Smi => Smi (no overflow, optimised if one operand is a constant) - 2003 / - Smi, Smi => Smi (no overflow, optimised if one operand is a constant) - 2004 // - Smi, Smi => Smi (no overflow, optimised if one operand is a constant) - 2005 \ - Smi, Smi => Smi (no overflow, optimised if one operand is a constant) - 2006 quo: - Smi, Smi => Smi (no overflow, optimised if one operand is a constant) - 2016 bitAnd: - Smi, Smi => Smi (optimised if one operand is a constant) - 2017 bitOr: - Smi, Smi => Smi (optimised if one operand is a constant) - 2018 bitXor: - Smi, Smi => Smi (optimised if one operand is a constant) - 2019 bitShiftLeft: - Smi greater or equal to 0, Smi greater or equal to 0 => Smi (no overflow, - optimised if arg1 is a constant) - 2020 bitShiftRight: - Smi, Smi greater or equal to 0 => Smi (optimised if arg1 is a constant) - 2032 > - Smi, Smi => Boolean (optimised if one operand is a constant, Pipelined - with ifTrue:ifFalse:) - 2033 < - Smi, Smi => Boolean (optimised if one operand is a constant, Pipelined - with ifTrue:ifFalse:) - 2034 >= - Smi, Smi => Boolean (optimised if one operand is a constant, Pipelined - with ifTrue:ifFalse:) - 2035 <= - Smi, Smi => Boolean (optimised if one operand is a constant, Pipelined - with ifTrue:ifFalse:) - 2036 = - Smi, Smi => Boolean (optimised if one operand is a constant, Pipelined - with ifTrue:ifFalse:) - 2037 ~= - Smi, Smi => Boolean (optimised if one operand is a constant, Pipelined - with ifTrue:ifFalse:) - 2038 rawEqualsEquals: - not a forwarder, not a forwarder => Boolean (optimised if one operand is a - constant, Pipelined with ifTrue:ifFalse:) - 2039 rawNotEqualsEquals: - not a forwarder, not a forwarder => Boolean (optimised if one operand is a - constant, Pipelined with ifTrue:ifFalse:) - 2048 rawNew: - literal which is a fixed-sized behavior, Smi => instance of receiver, - fields nilled out (optimised if arg1 is a constant) - 2049 rawNewNoInit: - literal which is a fixed-sized behavior, Smi => instance of receiver - (Fields of returned value contain undefined data, optimised if arg1 is a - constant) 2064 pointerAt: - Pointer object (Fixed sized or not) and not a context, Smi => (1-based, - optimised if arg1 is a constant) - 2065 maybeContextPointerAt: - Pointer object (Fixed sized or not), Smi => (1-based, optimised if arg1 is - a constant) - 2066 byteAt: - byte object, Smi => 8 bits unsigned Smi (1-based, optimised if arg1 is a - constant) 2067 shortAt: - short object, Smi => 16 bits unsigned Smi (1-based, optimised if arg1 is a - constant) 2068 wordAt: - word object, Smi => 32 bits unsigned Smi (1-based, optimised if arg1 is a - constant) 2069 doubleWordAt: - double word object, Smi => 64 bits unsigned Smi or LargePositiveInteger - (1-based, optimised if arg1 is a constant) - */ - - /* SistaCogit>>#genBinaryInlinePrimitive: */ -static sqInt NoDbgRegParms -genBinaryInlinePrimitive(sqInt primIndex) -{ - if ((primIndex <= 18) - && ((primIndex <= 2) - || (primIndex > 6))) { - if ((((ssTop())->type)) == SSConstant) { - return genBinaryVarOpConstSmiInlinePrimitive(primIndex); - } - if ((((ssValue(1))->type)) == SSConstant) { - return genBinaryConstOpVarSmiInlinePrimitive(primIndex); - } - return genBinaryVarOpVarSmiInlinePrimitive(primIndex); - } - if (primIndex <= 6) { - return genDivInlinePrimitive(primIndex); - } - if (primIndex == 19) { - return genBinarySmiBitShiftLeftInlinePrimitive(); - } - if (primIndex == 20) { - return genBinarySmiBitShiftRightInlinePrimitive(); - } - if (primIndex < 32) { - return EncounteredUnknownBytecode; - } - if (primIndex <= 39) { - return genBinaryCompInlinePrimitive(primIndex); - } - if (primIndex < 48) { - return EncounteredUnknownBytecode; - } - if (primIndex <= 49) { - return genBinaryNewInlinePrimitive(primIndex); - } - if (primIndex < 64) { - return EncounteredUnknownBytecode; - } - if (primIndex <= 69) { - if ((((ssTop())->type)) == SSConstant) { - return genBinaryAtConstInlinePrimitive(primIndex); - } - return genBinaryAtInlinePrimitive(primIndex); - } - return EncounteredUnknownBytecode; -} - - -/* 2048 rawNew: - literal which is a variable-sized behavior, Smi => instance of receiver, - fields nilled/zeroed out (optimised if arg1 is a constant) - 2049 rawNewNoInit: - literal which is a variable-sized behavior, Smi => instance of receiver - (Fields of returned value contain undefined data, optimised if arg1 is a - constant) - */ -/* Assertion */ - - /* SistaCogit>>#genBinaryNewInlinePrimitive: */ -static sqInt NoDbgRegParms -genBinaryNewInlinePrimitive(sqInt primIndex) -{ - sqInt argInt; - sqInt classFormat; - sqInt classObj; - sqInt resultReg; - - if (!((((ssValue(1))->type)) == SSConstant)) { - return UnimplementedOperation; - } - if (!((((ssTop())->type)) == SSConstant)) { - return UnimplementedOperation; - } - classObj = ((ssValue(1))->constant); - assert(isNonImmediate(classObj)); - assert(objCouldBeClassObj(classObj)); - assert(!((isFixedSizePointerFormat(instSpecOfClassFormat(formatOfClass(classObj)))))); - classTagForClass(classObj); - resultReg = allocateRegNotConflictingWith(0); - classFormat = instSpecOfClassFormat(formatOfClass(classObj)); - argInt = ((((ssTop())->constant)) >> 1); - ssPop(2); - ssPushRegister(resultReg); - if ((classFormat == (arrayFormat())) - || (classFormat == (indexablePointersFormat()))) { - return genGetInstanceOfPointerClassintoinitializingIfnumVariableSlots(classObj, resultReg, primIndex == 48, argInt); - } - if (classFormat == (firstByteFormat())) { - return genGetInstanceOfByteClassintoinitializingIfnumBytes(classObj, resultReg, primIndex == 48, argInt); - } - return UnimplementedOperation; -} - - -/* 2019 bitShiftLeft: - Smi greater or equal to 0, Smi greater or equal to 0 => Smi (no overflow, - optimised if arg1 is a constant) - */ - - /* SistaCogit>>#genBinarySmiBitShiftLeftInlinePrimitive */ -static sqInt -genBinarySmiBitShiftLeftInlinePrimitive(void) -{ - sqInt quickConstant; - sqInt ra; - sqInt rr; - - rr = allocateRegForStackEntryAtnotConflictingWith(1, 0); - popToReg(ssValue(1), rr); - genRemoveSmallIntegerTagsInScratchReg(rr); - if ((((ssTop())->type)) == SSConstant) { - /* begin LogicalShiftLeftCq:R: */ - quickConstant = ((((ssTop())->constant)) >> 1); - genoperandoperand(LogicalShiftLeftCqR, quickConstant, rr); - } - else { - ra = allocateRegForStackEntryAtnotConflictingWith(0, 1U << rr); - popToReg(ssTop(), ra); - genConvertSmallIntegerToIntegerInReg(ra); - /* begin LogicalShiftLeftR:R: */ - genoperandoperand(LogicalShiftLeftRR, ra, rr); - } - genAddSmallIntegerTagsTo(rr); - ssPop(2); - return ssPushRegister(rr); -} - - -/* 2019 bitShiftLeft: - Smi greater or equal to 0, Smi greater or equal to 0 => Smi (no overflow, - optimised if arg1 is a constant) - */ - - /* SistaCogit>>#genBinarySmiBitShiftRightInlinePrimitive */ -static sqInt -genBinarySmiBitShiftRightInlinePrimitive(void) -{ - sqInt quickConstant; - sqInt ra; - sqInt rr; - - rr = allocateRegForStackEntryAtnotConflictingWith(1, 0); - popToReg(ssValue(1), rr); - if ((((ssTop())->type)) == SSConstant) { - /* begin ArithmeticShiftRightCq:R: */ - quickConstant = ((((ssTop())->constant)) >> 1); - genoperandoperand(ArithmeticShiftRightCqR, quickConstant, rr); - } - else { - ra = allocateRegForStackEntryAtnotConflictingWith(0, 1U << rr); - popToReg(ssTop(), ra); - genConvertSmallIntegerToIntegerInReg(ra); - /* begin ArithmeticShiftRightR:R: */ - genoperandoperand(ArithmeticShiftRightRR, ra, rr); - } - genClearAndSetSmallIntegerTagsIn(rr); - ssPop(2); - return ssPushRegister(rr); -} - - /* SistaCogit>>#genBinaryVarOpConstSmiInlinePrimitive: */ -static sqInt NoDbgRegParms -genBinaryVarOpConstSmiInlinePrimitive(sqInt primIndex) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - sqInt rr; - sqInt untaggedVal; - sqInt val; - - assert(primIndex <= 18); - val = ((ssTop())->constant); - ssPop(1); - rr = allocateRegForStackEntryAtnotConflictingWith(0, 0); - popToReg(ssTop(), rr); - ssPop(1); - untaggedVal = val - (smallIntegerTag()); - switch (primIndex) { - case 0: - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, untaggedVal, rr); - break; - case 1: - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(SubCqR, untaggedVal, rr); - break; - case 2: - flag("could use MulCq:R"); - genShiftAwaySmallIntegerTagsInScratchReg(rr); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, untaggedVal, TempReg); - /* begin MulR:R: */ - genMulRR(backEnd, TempReg, rr); - genSetSmallIntegerTagsIn(rr); - break; - case 16: - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(AndCqR, val, rr); - break; - case 17: - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(OrCqR, val, rr); - break; - case 18: - flag("could use XorCq:"); - /* begin checkLiteral:forInstruction: */ - anInstruction5 = genoperandoperand(XorCwR, untaggedVal, rr); - break; - default: - return EncounteredUnknownBytecode; - - } - ssPushRegister(rr); - return 0; -} - - /* SistaCogit>>#genBinaryVarOpVarSmiInlinePrimitive: */ -static sqInt NoDbgRegParms -genBinaryVarOpVarSmiInlinePrimitive(sqInt primIndex) -{ - sqInt ra; - sqInt reg; - sqInt rNext1; - sqInt rr; - sqInt rTop1; - sqInt topRegistersMask; - - /* begin allocateRegForStackTopTwoEntriesInto: */ - topRegistersMask = 0; - rTop1 = (rNext1 = NoReg); - if ((registerOrNone(ssTop())) != NoReg) { - rTop1 = registerOrNone(ssTop()); - } - if ((registerOrNone(ssValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; - } - if (rTop1 == NoReg) { - rTop1 = allocateRegNotConflictingWith(topRegistersMask); - } - if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); - } - assert(!(((rTop1 == NoReg) - || (rNext1 == NoReg)))); - ra = rTop1; - rr = rNext1; - popToReg(ssTop(), ra); - ssPop(1); - popToReg(ssTop(), rr); - ssPop(1); - switch (primIndex) { - case 0: - genRemoveSmallIntegerTagsInScratchReg(ra); - /* begin AddR:R: */ - genoperandoperand(AddRR, ra, rr); - break; - case 1: - /* begin SubR:R: */ - genoperandoperand(SubRR, ra, rr); - genAddSmallIntegerTagsTo(rr); - break; - case 2: - genShiftAwaySmallIntegerTagsInScratchReg(rr); - genRemoveSmallIntegerTagsInScratchReg(ra); - /* begin MulR:R: */ - genMulRR(backEnd, ra, rr); - genSetSmallIntegerTagsIn(rr); - break; - case 16: - /* begin AndR:R: */ - genoperandoperand(AndRR, ra, rr); - break; - case 17: - /* begin OrR:R: */ - genoperandoperand(OrRR, ra, rr); - break; - case 18: - genRemoveSmallIntegerTagsInScratchReg(ra); - /* begin XorR:R: */ - genoperandoperand(XorRR, ra, rr); - break; - default: - return EncounteredUnknownBytecode; - - } - ssPushRegister(rr); - return 0; -} - - /* SistaCogit>>#genByteAtPut */ -static sqInt -genByteAtPut(void) -{ - sqInt adjust; - AbstractInstruction *anInstruction; - sqInt ra1; - sqInt ra2; - sqInt reg; - sqInt rNext1; - sqInt rr; - sqInt rThird1; - sqInt rTop1; - sqInt topRegistersMask; - - /* begin allocateRegForStackTopThreeEntriesInto:thirdIsReceiver: */ - topRegistersMask = 0; - rTop1 = (rNext1 = (rThird1 = NoReg)); - if (((registerOrNone(ssTop())) != NoReg) - && (1)) { - /* begin registerMaskFor: */ - reg = (rTop1 = registerOrNone(ssTop())); - topRegistersMask = 1U << reg; - } - if (((registerOrNone(ssValue(1))) != NoReg) - && (1)) { - topRegistersMask = topRegistersMask | (registerMaskFor((rNext1 = registerOrNone(ssValue(1))))); - } - if (((registerOrNone(ssValue(2))) != NoReg) - && (1)) { - topRegistersMask = topRegistersMask | (registerMaskFor((rThird1 = registerOrNone(ssValue(2))))); - } - if (rThird1 == NoReg) { - rThird1 = allocateRegNotConflictingWith(topRegistersMask); - topRegistersMask = topRegistersMask | (1U << rThird1); - } - if (rTop1 == NoReg) { - rTop1 = allocateRegNotConflictingWith(topRegistersMask); - topRegistersMask = topRegistersMask | (1U << rTop1); - } - if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(topRegistersMask); - } - assert(!(((rTop1 == NoReg) - || ((rNext1 == NoReg) - || (rThird1 == NoReg))))); - ra2 = rTop1; - ra1 = rNext1; - rr = rThird1; - assert((rr != ra1) - && ((rr != ra2) - && (ra1 != ra2))); - popToReg(ssTop(), ra2); - ssPop(1); - popToReg(ssTop(), ra1); - ssPop(1); - popToReg(ssTop(), rr); - ssPop(1); - - /* shift by baseHeaderSize and then move from 1 relative to zero relative */ - adjust = BaseHeaderSize - 1; - genConvertSmallIntegerToIntegerInReg(ra1); - genConvertSmallIntegerToIntegerInReg(ra2); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, adjust, ra1); - /* begin MoveR:Xbr:R: */ - genoperandoperandoperand(MoveRXbrR, ra2, ra1, rr); - genConvertIntegerToSmallIntegerInReg(ra2); - return ssPushRegister(ra2); -} - - /* SistaCogit>>#genByteAtPutImmutabilityCheck */ -static sqInt -genByteAtPutImmutabilityCheck(void) -{ - sqInt adjust; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - sqInt i; - AbstractInstruction *immutabilityFailure; - int indexIsCst; - AbstractInstruction *mutableJump; - sqInt quickConstant; - sqInt ra1; - sqInt ra2; - sqInt rr; - - - /* Assumes rr is not a context and no store check is needed */ - indexIsCst = (((ssValue(1))->type)) == SSConstant; - rr = ReceiverResultReg; - ra1 = TempReg; - ra2 = ClassReg; - voidReceiverResultRegContainsSelf(); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 1)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 1)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 1))); i < simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 1) + 1; - } - popToReg(ssTop(), ra2); - - /* shift by baseHeaderSize and then move from 1 relative to zero relative */ - adjust = BaseHeaderSize - 1; - if (indexIsCst) { - /* begin MoveCq:R: */ - quickConstant = (((((ssValue(1))->constant)) >> 1)) + adjust; - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, ra1); - } - else { - popToReg(ssValue(1), ra1); - genConvertSmallIntegerToIntegerInReg(ra1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AddCqR, adjust, ra1); - } - popToReg(ssValue(2), rr); - ssPop(3); - ssPushRegister(ra2); - mutableJump = genJumpMutablescratchReg(rr, Arg0Reg); - /* begin PushR: */ - genoperand(PushR, ra2); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(SubCqR, 1 + adjust, ra1); - genVarIndexCallStoreTrampoline(); - /* begin PopR: */ - genoperand(PopR, ra2); - /* begin Jump: */ - immutabilityFailure = genoperand(Jump, ((sqInt)0)); - jmpTarget(mutableJump, genoperandoperand(MoveRR, ra2, Arg0Reg)); - genConvertSmallIntegerToIntegerInReg(Arg0Reg); - /* begin MoveR:Xbr:R: */ - genoperandoperandoperand(MoveRXbrR, Arg0Reg, ra1, rr); - jmpTarget(immutabilityFailure, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - -/* Byte equal is falling through if the result is true, or jumping using jmp - if the result is false. - The method is required to set the jump target of jmp. - We look ahead for a branch and pipeline the jumps if possible.. - ReturnReg is used only if not followed immediately by a branch. */ - - /* SistaCogit>>#genByteEqualsInlinePrimitiveResult:returnReg: */ -static sqInt NoDbgRegParms -genByteEqualsInlinePrimitiveResultreturnReg(sqInt jmp, sqInt reg) -{ - AbstractInstruction *anInstruction; - sqInt bcpc; - BytecodeDescriptor *branchDescriptor; - BytecodeDescriptor *branchDescriptor1; - sqInt canElide; - sqInt constant; - BytecodeDescriptor *descriptor; - sqInt eA; - sqInt eB; - void *jumpTarget; - void *jumpTarget1; - AbstractInstruction *localJump; - sqInt nExts; - sqInt nextPC; - sqInt nextPC1; - sqInt postBranchPC; - sqInt postBranchPC1; - BytecodeDescriptor *primDescriptor; - sqInt savedB0; - sqInt savedB1; - sqInt savedB2; - sqInt savedB3; - sqInt savedEA; - sqInt savedEB; - sqInt savedNEB; - sqInt targetBytecodePC; - sqInt targetBytecodePC1; - - /* begin extractMaybeBranchDescriptorInto: */ - primDescriptor = generatorAt(byte0); - nextPC1 = bytecodePC + ((primDescriptor->numBytes)); - nExts = 0; - while (1) { - while (1) { - /* begin generatorForPC: */ - branchDescriptor1 = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC1, methodObj))); - if (!((branchDescriptor1->isExtension))) break; - nExts += 1; - nextPC1 += (branchDescriptor1->numBytes); - } - /* begin isUnconditionalBranch */ - if (!((isBranch(branchDescriptor1)) - && (!(((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse)))))) break; - nextPC1 = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - } - targetBytecodePC1 = (postBranchPC1 = 0); - if (((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse))) { - targetBytecodePC1 = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - postBranchPC1 = eventualTargetOf(nextPC1 + ((branchDescriptor1->numBytes))); - } - else { - nextPC1 = bytecodePC + ((primDescriptor->numBytes)); - } - branchDescriptor = branchDescriptor1; - nextPC = nextPC1; - postBranchPC = postBranchPC1; - targetBytecodePC = targetBytecodePC1; - if (!(((branchDescriptor->isBranchTrue)) - || ((branchDescriptor->isBranchFalse)))) { - /* begin genMoveTrueR: */ - constant = trueObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, reg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, reg); - } - /* begin Jump: */ - localJump = genoperand(Jump, ((sqInt)0)); - jmpTarget(jmp, genMoveFalseR(reg)); - jmpTarget(localJump, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushRegister(reg); - return 0; - } - if ((((fixupAt(nextPC))->targetInstruction)) == 0) { - - /* The next instruction is dead. we can skip it. */ - deadCode = 1; - ensureFixupAt(targetBytecodePC); - ensureFixupAt(postBranchPC); - } - else { - ssPushConstant(trueObject()); - } - /* begin nextDescriptorExtensionsAndNextPCInto: */ - descriptor = generatorAt(byte0); - savedB0 = byte0; - savedB1 = byte1; - savedB2 = byte2; - savedB3 = byte3; - savedEA = extA; - savedEB = extB; - savedNEB = numExtB; - bcpc = bytecodePC + ((descriptor->numBytes)); - do { - if (bcpc > endPC) { - nextPC = 0; - goto l5; - } - byte0 = (fetchByteofObject(bcpc, methodObj)) + bytecodeSetOffset; - descriptor = generatorAt(byte0); - loadSubsequentBytesForDescriptorat(descriptor, bcpc); - if (!((descriptor->isExtension))) { - eA = extA; - eB = extB; - extA = savedEA; - extB = savedEB; - numExtB = savedNEB; - byte0 = savedB0; - byte1 = savedB1; - byte2 = savedB2; - byte3 = savedB3; - nextPC = bcpc; - goto l5; - } - ((descriptor->generator))(); - bcpc += (descriptor->numBytes); - } while(1); - l5: /* end nextDescriptorExtensionsAndNextPCInto: */; - canElide = deadCode - && (nextPC == postBranchPC); - if ((branchDescriptor->isBranchTrue)) { - /* begin Jump: */ - jumpTarget = ensureNonMergeFixupAt(targetBytecodePC); - genoperand(Jump, ((sqInt)jumpTarget)); - if (canElide) { - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - else { - jmpTarget(jmp, ensureNonMergeFixupAt(postBranchPC)); - } - } - else { - if (!canElide) { - /* begin Jump: */ - jumpTarget1 = ensureNonMergeFixupAt(postBranchPC); - genoperand(Jump, ((sqInt)jumpTarget1)); - jmpTarget(jmp, ensureNonMergeFixupAt(targetBytecodePC)); - } - } - return 0; -} - - -/* 3021 Byte Object >> equals:length: - The receiver and the arguments are both byte objects and have both the - same size (length in bytes). - The length argument is a smallinteger. - Answers true if all fields are equal, false if not. - Comparison is bulked to word comparison. - */ -/* Overview: - 1. The primitive is called like that: [byteObj1 equals: byteObj2 length: - length]. In the worst case we use 5 registers including TempReg - and we produce a loop bulk comparing words. - 2. The common case is a comparison against a cst: [byteString = 'foo']. - which produces in Scorch [byteString equals: 'foo' length: 3]. - We try to generate fast code for this case with 3 heuristics: - - specific fast code if len is a constant - - unroll the loop if len < 2 * wordSize - - compile-time reads if str1 or str2 is a constant and loop is unrolled. - We use 3 registers including TempReg in the common case. - We could use 1 less reg if the loop is unrolled, the instr is followed by - a branch - AND one operand is a constant, but this is complicated enough. - 3. We ignore the case where all operands are constants - (We assume Scorch simplifies it, it works but it is not optimised) */ - - /* SistaCogit>>#genByteEqualsInlinePrimitive: */ -static sqInt NoDbgRegParms -genByteEqualsInlinePrimitive(sqInt prim) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction22; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction32; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - sqInt extraReg; - AbstractInstruction *instr; - AbstractInstruction *jmp; - AbstractInstruction *jmp2; - AbstractInstruction *jmpZeroSize; - sqInt lenCst; - sqInt lenReg; - sqInt mask; - sqInt needjmpZeroSize; - int needLoop; - sqInt quickConstant; - sqInt quickConstant1; - sqInt quickConstant11; - sqInt quickConstant2; - sqInt shift; - sqInt shift1; - sqInt str1Reg; - sqInt str2Reg; - sqInt unroll; - - - /* --- quick path for empty string--- */ - /* This path does not allocate registers and right shift on negative int later in the code. - Normally this is resolved by Scorch but we keep it for correctness and consistency */ - jmp2 = ((AbstractInstruction *) 0); - jmpZeroSize = ((AbstractInstruction *) 0); - lenCst = 0; - lenReg = 0; - str1Reg = 0; - str2Reg = 0; - if ((((ssTop())->type)) == SSConstant) { - lenCst = ((((ssTop())->constant)) >> 1); - if (lenCst == 0) { - ssPop(3); - ssPushConstant(trueObject()); - return 0; - } - } - needLoop = !(((((ssTop())->type)) == SSConstant) - && (lenCst <= (BytesPerWord * 2))); - unroll = (!needLoop) - && (lenCst > BytesPerWord); - if (needLoop) { - assert(!(((ssTop())->spilled))); - str1Reg = allocateRegForStackEntryAtnotConflictingWith(1, 0 /* emptyRegisterMask */); - str2Reg = allocateRegForStackEntryAtnotConflictingWith(2, 1U << str1Reg); - lenReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << str1Reg) | (1U << str2Reg)); - popToReg(ssValue(1), str1Reg); - popToReg(ssValue(2), str2Reg); - extraReg = allocateRegNotConflictingWith(((1U << str1Reg) | (1U << str2Reg)) | (1U << lenReg)); - } - else { - /* begin emptyRegisterMask */ - mask = 0; - if (!((((ssValue(1))->type)) == SSConstant)) { - str1Reg = allocateRegForStackEntryAtnotConflictingWith(1, mask); - popToReg(ssValue(1), str1Reg); - mask = mask | (1U << str1Reg); - } - if (!((((ssValue(2))->type)) == SSConstant)) { - str2Reg = allocateRegForStackEntryAtnotConflictingWith(2, mask); - popToReg(ssValue(2), str2Reg); - mask = mask | (1U << str2Reg); - } - extraReg = allocateRegNotConflictingWith(mask); - } - if ((((ssTop())->type)) == SSConstant) { - - /* common case, str = 'foo'. We can precompute lenReg. */ - lenCst = ((usqInt)(((lenCst + BaseHeaderSize) - 1))) >> (shiftForWord()); - if (needLoop) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, lenCst, lenReg); - } - needjmpZeroSize = 0; - } - else { - - /* uncommon case, str = str2. lenReg in word computed at runtime. */ - popToReg(ssTop(), lenReg); - genConvertSmallIntegerToIntegerInReg(lenReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, lenReg); - /* begin JumpZero: */ - jmpZeroSize = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - needjmpZeroSize = 1; - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AddCqR, BaseHeaderSize - 1, lenReg); - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, shiftForWord(), lenReg); - } - if (needLoop) { - /* begin MoveXwr:R:R: */ - instr = genoperandoperandoperand(MoveXwrRR, lenReg, str1Reg, extraReg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, lenReg, str2Reg, TempReg); - /* begin CmpR:R: */ - assert(!((extraReg == SPReg))); - genoperandoperand(CmpRR, extraReg, TempReg); - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(AddCqR, -1, lenReg); - /* begin CmpCq:R: */ - anInstruction4 = genoperandoperand(CmpCqR, (((usqInt)(BaseHeaderSize)) >> (shiftForWord())) - 1, lenReg); - /* begin JumpNonZero: */ - genConditionalBranchoperand(JumpNonZero, ((sqInt)instr)); - } - else { - - /* Common case, only 1 or 2 word to check: no lenReg allocation, cst micro optimisations */ - /* begin genByteEqualsInlinePrimitiveCmp:with:scratch1:scratch2:field: */ - shift1 = BaseHeaderSize + (0 * BytesPerWord); - if ((((ssValue(1))->type)) == SSConstant) { - /* begin MoveCq:R: */ - quickConstant2 = fetchPointerofObject(0, ((ssValue(1))->constant)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(MoveCqR, quickConstant2, extraReg); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveMwrR, shift1, str1Reg, extraReg); - } - if ((((ssValue(2))->type)) == SSConstant) { - /* begin MoveCq:R: */ - quickConstant11 = fetchPointerofObject(0, ((ssValue(2))->constant)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperand(MoveCqR, quickConstant11, TempReg); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction32 = genoperandoperandoperand(MoveMwrR, shift1, str2Reg, TempReg); - } - /* begin CmpR:R: */ - assert(!((extraReg == SPReg))); - genoperandoperand(CmpRR, extraReg, TempReg); - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - if (unroll) { - - /* unrolling more than twice generate more instructions than the loop so we don't do it */ - /* begin genByteEqualsInlinePrimitiveCmp:with:scratch1:scratch2:field: */ - shift = BaseHeaderSize + (1 * BytesPerWord); - if ((((ssValue(1))->type)) == SSConstant) { - /* begin MoveCq:R: */ - quickConstant = fetchPointerofObject(1, ((ssValue(1))->constant)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(MoveCqR, quickConstant, extraReg); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperandoperand(MoveMwrR, shift, str1Reg, extraReg); - } - if ((((ssValue(2))->type)) == SSConstant) { - /* begin MoveCq:R: */ - quickConstant1 = fetchPointerofObject(1, ((ssValue(2))->constant)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperand(MoveCqR, quickConstant1, TempReg); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction31 = genoperandoperandoperand(MoveMwrR, shift, str2Reg, TempReg); - } - /* begin CmpR:R: */ - assert(!((extraReg == SPReg))); - genoperandoperand(CmpRR, extraReg, TempReg); - /* begin JumpNonZero: */ - jmp2 = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - } - } - if (needjmpZeroSize) { - jmpTarget(jmpZeroSize, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - ssPop(3); - genByteEqualsInlinePrimitiveResultreturnReg(jmp, extraReg); - if (unroll) { - jmpTarget(jmp2, ((AbstractInstruction *) (((jmp->operands))[0]))); - } - return 0; -} - - -/* SistaV1: 236 11101100 iiiiiiii callMappedInlinedPrimitive */ - - /* SistaCogit>>#genCallMappedInlinedPrimitive */ -static sqInt -genCallMappedInlinedPrimitive(void) -{ - return genMappedInlinePrimitive(byte1); -} - - -/* SistaV1: 248 11111000 iiiiiiii mjjjjjjj Call Primitive #iiiiiiii + - (jjjjjjj * 256) m=1 means inlined primitive, no hard return after - execution. See EncoderForSistaV1's class comment and - StackInterpreter>>#inlinePrimitiveBytecode: - */ - - /* SistaCogit>>#genCallPrimitiveBytecode */ -static sqInt -genCallPrimitiveBytecode(void) -{ - sqInt prim; - sqInt primSet; - - if (byte2 < 128) { - return (bytecodePC == initialPC - ? 0 - : EncounteredUnknownBytecode); - } - prim = (((sqInt)((usqInt)((byte2 - 128)) << 8))) + byte1; - primSet = (((usqInt)(prim)) >> 13) & 3; - prim = prim & 0x1FFF; - assert(primSet == 0); - return genSistaInlinePrimitive(prim); -} - - -/* Specific version if the branch is only reached while falling through if - the counter trips after an inlined #== branch. We do not regenerate the - counter logic in this case to avoid 24 bytes instructions. - */ - - /* SistaCogit>>#genCounterTripOnlyJumpIf:to: */ -static sqInt NoDbgRegParms -genCounterTripOnlyJumpIfto(sqInt boolean, sqInt targetBytecodePC) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - sqInt i; - void *jumpTarget; - AbstractInstruction *mustBeBooleanTrampoline; - AbstractInstruction *ok; - sqInt quickConstant; - - extA = 0; - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 1)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 1)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 1))); i < simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 1) + 1; - } - popToReg(ssTop(), TempReg); - ssPop(1); - - /* counters are increased / decreased in the inlined branch */ - /* We need SendNumArgsReg because of the mustBeBooleanTrampoline */ - counterIndex += 1; - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << SendNumArgsReg, simStackPtr, simNativeStackPtr); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, 1, SendNumArgsReg); - mustBeBooleanTrampoline = genCallMustBeBooleanFor(boolean); - /* begin annotateBytecode: */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction->annotation = HasBytecodePC); - assert((objectAfter(falseObject())) == (trueObject())); - /* begin genSubConstant:R: */ - if (shouldAnnotateObjectReference(boolean)) { - annotateobjRef(checkLiteralforInstruction(boolean, genoperandoperand(SubCwR, boolean, TempReg)), TempReg); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, boolean, TempReg); - } - /* begin JumpZero: */ - jumpTarget = ensureFixupAt(targetBytecodePC); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget)); - /* begin CmpCq:R: */ - quickConstant = (boolean == (falseObject()) - ? (trueObject()) - (falseObject()) - : (falseObject()) - (trueObject())); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(CmpCqR, quickConstant, TempReg); - /* begin JumpZero: */ - ok = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(MoveCqR, 0, SendNumArgsReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)mustBeBooleanTrampoline)); - jmpTarget(ok, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - -/* 250 directCall - literal index of the method to call on top of stack => (variable number of - parameters) - */ - - /* SistaCogit>>#genDirectCall */ -static sqInt -genDirectCall(void) -{ - sqInt annotation; - sqInt litIndex; - sqInt newMethod; - sqInt newMethodArgCount; - sqInt newMethodHeader; - sqInt sendTable; - - assert(((((ssTop())->type)) == SSConstant) - && (isCompiledMethod(((ssTop())->constant)))); - litIndex = ((((ssTop())->constant)) >> 1); - newMethod = getLiteral(litIndex); - ssPop(1); - flag("TODO"); - - /* directCallSendTable */ - sendTable = 1; - - /* directCallAnnotation */ - annotation = 1; - newMethodHeader = rawHeaderOf(newMethod); - - /* The receiver cannot be a forwader */ - /* numArgs >= (NumSendTrampolines - 1) ifTrue: - [self MoveCq: newMethodArgCount R: SendNumArgsReg]. */ - /* Load inline cache with method index */ - /* self MoveUniqueC32: litIndex R: ClassReg. - (self Call: (sendTable at: (newMethodArgCount min: NumSendTrampolines - 1))) annotation: annotation. - self voidReceiverOptStatus. - self ssPushRegister: ReceiverResultReg. */ - newMethodArgCount = argumentCountOfMethodHeader(methodHeader); - return EncounteredUnknownBytecode; -} - - -/* 2003 / - Smi, Smi => Smi (no overflow, optimised if one operand is a constant) */ -/* 2004 // - Smi, Smi => Smi (no overflow, optimised if one operand is a constant) */ -/* 2005 \\ - Smi, Smi => Smi (no overflow, optimised if one operand is a constant) */ -/* 2006 quo: - Smi, Smi => Smi (no overflow, optimised if one operand is a constant) */ -/* We don't deal with constants here. Too complex and does nto bring much */ - - /* SistaCogit>>#genDivInlinePrimitive: */ -static sqInt NoDbgRegParms -genDivInlinePrimitive(sqInt primIndex) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *jumpExact; - AbstractInstruction *jumpSameSign; - sqInt ra; - sqInt reg; - sqInt rNext1; - sqInt rr; - sqInt rTop1; - sqInt topRegistersMask; - - /* begin allocateRegForStackTopTwoEntriesInto: */ - topRegistersMask = 0; - rTop1 = (rNext1 = NoReg); - if ((registerOrNone(ssTop())) != NoReg) { - rTop1 = registerOrNone(ssTop()); - } - if ((registerOrNone(ssValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; - } - if (rTop1 == NoReg) { - rTop1 = allocateRegNotConflictingWith(topRegistersMask); - } - if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); - } - assert(!(((rTop1 == NoReg) - || (rNext1 == NoReg)))); - ra = rTop1; - rr = rNext1; - popToReg(ssTop(), ra); - ssPop(1); - popToReg(ssTop(), rr); - ssPop(1); - assert(canDivQuoRem(backEnd)); - switch (primIndex) { - case 4: - genShiftAwaySmallIntegerTagsInScratchReg(ra); - genShiftAwaySmallIntegerTagsInScratchReg(rr); - gDivRRQuoRem(ra, rr, rr, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpZero: */ - jumpExact = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - genConvertIntegerToSmallIntegerInReg(ra); - /* begin XorR:R: */ - genoperandoperand(XorRR, TempReg, ra); - if (!(setsConditionCodesFor(lastOpcode(), JumpZero))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, ra); - } - /* begin JumpGreaterOrEqual: */ - jumpSameSign = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(SubCqR, 1, rr); - jmpTarget(jumpSameSign, jmpTarget(jumpExact, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - genConvertIntegerToSmallIntegerInReg(rr); - break; - case 5: - genRemoveSmallIntegerTagsInScratchReg(ra); - genRemoveSmallIntegerTagsInScratchReg(rr); - gDivRRQuoRem(ra, rr, TempReg, rr); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, 0, rr); - /* begin JumpZero: */ - jumpExact = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin XorR:R: */ - genoperandoperand(XorRR, rr, ra); - if (!(setsConditionCodesFor(lastOpcode(), JumpZero))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(CmpCqR, 0, ra); - } - /* begin JumpGreaterOrEqual: */ - jumpSameSign = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin XorR:R: */ - genoperandoperand(XorRR, rr, ra); - /* begin AddR:R: */ - genoperandoperand(AddRR, ra, rr); - jmpTarget(jumpSameSign, jmpTarget(jumpExact, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - genSetSmallIntegerTagsIn(rr); - break; - case 6: - genShiftAwaySmallIntegerTagsInScratchReg(ra); - genShiftAwaySmallIntegerTagsInScratchReg(rr); - gDivRRQuoRem(ra, rr, rr, ra); - genConvertIntegerToSmallIntegerInReg(rr); - break; - default: - return EncounteredUnknownBytecode; - - } - ssPushRegister(rr); - return 0; -} - - -/* 50 EnsureEnoughWords - literal which is a Smi => ret value is receiver */ - - /* SistaCogit>>#genEnsureEnoughSlots */ -static sqInt -genEnsureEnoughSlots(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction2; - sqInt i; - sqInt quickConstant; - AbstractInstruction *skip; - sqInt slots; - - assert(((((ssTop())->type)) == SSConstant) - && (((((ssTop())->constant)) & 1))); - slots = ((((ssTop())->constant)) >> 1); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 1)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 1)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 1))); i < simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 1) + 1; - } - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction = genoperandoperand(MoveAwR, freeStartAddress(), TempReg); - /* begin CmpCq:R: */ - quickConstant = (getScavengeThreshold()) - (BytesPerOop * slots); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, quickConstant, TempReg); - /* begin JumpBelow: */ - skip = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin genSetGCNeeded */ - anInstruction2 = genoperandoperand(MoveCqR, 1, TempReg); - /* begin checkLiteral:forInstruction: */ - needGCFlagAddress(); - anInstruction11 = genoperandoperand(MoveRAw, TempReg, needGCFlagAddress()); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceCheckForInterruptTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin annotateBytecode: */ - abstractInstruction1 = ((AbstractInstruction *) (((skip->operands))[0])); - (abstractInstruction1->annotation = HasBytecodePC); - return 0; -} - - -/* Trap sends Sista trap message to context with top of stack, so we don't - need any arguments... - */ - - /* SistaCogit>>#generateSistaRuntime */ -static void -generateSistaRuntime(void) -{ - /* begin genTrampolineFor:called: */ - ceTrapTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceSistaTrap, "ceSistaTrapTrampoline", 0, null, null, null, null, 0 /* emptyRegisterMask */, 1, NoReg, 0); -} - - -/* Override to count inlined branches if followed by a conditional branch. - We borrow the following conditional branch's counter and when about to - inline the comparison we decrement the counter (without writing it back) - and if it trips simply abort the inlining, falling back to the normal send - which will then continue to the conditional branch which will trip and - enter the abort. */ - - /* SistaCogit>>#genForwardersInlinedIdenticalOrNotIf: */ -static sqInt NoDbgRegParms -genForwardersInlinedIdenticalOrNotIf(sqInt orNot) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt argConstant; - sqInt argConstant1; - sqInt argNeedsReg; - sqInt argNeedsReg1; - sqInt argReg; - sqInt argReg1; - sqInt argReg2; - sqInt argReg3; - BytecodeDescriptor *branchDescriptor; - BytecodeDescriptor *branchDescriptor1; - BytecodeDescriptor *branchDescriptor2; - BytecodeDescriptor *branchDescriptor3; - sqInt constant; - sqInt constant1; - sqInt constant11; - sqInt constant12; - sqInt constant2; - sqInt constant3; - sqInt constant4; - sqInt counterAddress; - sqInt counterAddress1; - sqInt counterReg; - AbstractInstruction *countTripped; - AbstractInstruction *countTripped1; - BytecodeFixup *fixup; - BytecodeFixup * fixup1; - sqInt i; - sqInt i1; - AbstractInstruction *jumpEqual; - AbstractInstruction *jumpNotEqual; - void *jumpTarget; - void *jumpTarget1; - void *jumpTarget2; - void *jumpTarget3; - AbstractInstruction *label; - sqInt nExts; - sqInt nExts1; - sqInt nextPC; - sqInt nextPC1; - sqInt nextPC2; - sqInt nextPC3; - sqInt opcode; - sqInt opcode1; - sqInt opcode2; - sqInt postBranchPC; - sqInt postBranchPC1; - sqInt postBranchPC2; - sqInt postBranchPC3; - BytecodeDescriptor *primDescriptor; - BytecodeDescriptor *primDescriptor1; - sqInt rcvrConstant; - sqInt rcvrConstant1; - sqInt rcvrNeedsReg; - sqInt rcvrNeedsReg1; - sqInt rcvrReg; - sqInt rcvrReg1; - sqInt rcvrReg2; - sqInt rcvrReg3; - sqInt reg; - sqInt reg1; - sqInt regMask; - sqInt rNext1; - sqInt rNext11; - sqInt rTop1; - sqInt rTop11; - CogSimStackEntry *simStackEntry; - CogSimStackEntry *simStackEntry1; - CogSimStackEntry *simStackEntry2; - CogSimStackEntry *simStackEntry3; - sqInt targetBytecodePC; - sqInt targetBytecodePC1; - sqInt targetBytecodePC2; - sqInt targetBytecodePC3; - sqInt topRegistersMask; - sqInt topRegistersMask1; - sqInt unforwardArg; - sqInt unforwardArg1; - sqInt unforwardRcvr; - sqInt unforwardRcvr1; - - if ((isOptimizedMethod(methodObj)) - || (!needsFrame)) { - unforwardRcvr1 = mayBeAForwarder(ssValue(1)); - unforwardArg1 = mayBeAForwarder(ssTop()); - if ((!unforwardRcvr1) - && (!unforwardArg1)) { - return genVanillaInlinedIdenticalOrNotIf(orNot); - } - assert(unforwardArg1 - || (unforwardRcvr1)); - /* begin isUnannotatableConstant: */ - simStackEntry = ssValue(1); - rcvrConstant1 = (((simStackEntry->type)) == SSConstant) - && ((isImmediate((simStackEntry->constant))) - || (!(shouldAnnotateObjectReference((simStackEntry->constant))))); - /* begin isUnannotatableConstant: */ - simStackEntry1 = ssTop(); - argConstant1 = (((simStackEntry1->type)) == SSConstant) - && ((isImmediate((simStackEntry1->constant))) - || (!(shouldAnnotateObjectReference((simStackEntry1->constant))))); - /* begin extractMaybeBranchDescriptorInto: */ - primDescriptor = generatorAt(byte0); - nextPC2 = bytecodePC + ((primDescriptor->numBytes)); - nExts = 0; - while (1) { - while (1) { - /* begin generatorForPC: */ - branchDescriptor2 = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC2, methodObj))); - if (!((branchDescriptor2->isExtension))) break; - nExts += 1; - nextPC2 += (branchDescriptor2->numBytes); - } - /* begin isUnconditionalBranch */ - if (!((isBranch(branchDescriptor2)) - && (!(((branchDescriptor2->isBranchTrue)) - || ((branchDescriptor2->isBranchFalse)))))) break; - nextPC2 = eventualTargetOf((nextPC2 + ((branchDescriptor2->numBytes))) + (((branchDescriptor2->spanFunction))(branchDescriptor2, nextPC2, nExts, methodObj))); - } - targetBytecodePC2 = (postBranchPC2 = 0); - if (((branchDescriptor2->isBranchTrue)) - || ((branchDescriptor2->isBranchFalse))) { - targetBytecodePC2 = eventualTargetOf((nextPC2 + ((branchDescriptor2->numBytes))) + (((branchDescriptor2->spanFunction))(branchDescriptor2, nextPC2, nExts, methodObj))); - postBranchPC2 = eventualTargetOf(nextPC2 + ((branchDescriptor2->numBytes))); - } - else { - nextPC2 = bytecodePC + ((primDescriptor->numBytes)); - } - branchDescriptor1 = branchDescriptor2; - nextPC1 = nextPC2; - postBranchPC1 = postBranchPC2; - targetBytecodePC1 = targetBytecodePC2; - /* begin allocateEqualsEqualsRegistersArgNeedsReg:rcvrNeedsReg:into: */ - argNeedsReg = !argConstant1; - rcvrNeedsReg = !rcvrConstant1; - assert(argNeedsReg - || (rcvrNeedsReg)); - argReg2 = (rcvrReg2 = NoReg); - if (argNeedsReg) { - if (rcvrNeedsReg) { - /* begin allocateRegForStackTopTwoEntriesInto: */ - topRegistersMask = 0; - rTop1 = (rNext1 = NoReg); - if ((registerOrNone(ssTop())) != NoReg) { - rTop1 = registerOrNone(ssTop()); - } - if ((registerOrNone(ssValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; - } - if (rTop1 == NoReg) { - rTop1 = allocateRegNotConflictingWith(topRegistersMask); - } - if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); - } - assert(!(((rTop1 == NoReg) - || (rNext1 == NoReg)))); - argReg2 = rTop1; - rcvrReg2 = rNext1; - popToReg(ssTop(), argReg2); - popToReg(ssValue(1), rcvrReg2); - } - else { - argReg2 = allocateRegForStackEntryAtnotConflictingWith(0, 0); - popToReg(ssTop(), argReg2); - if (((ssValue(1))->spilled)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(AddCqR, BytesPerWord, SPReg); - } - } - } - else { - assert(rcvrNeedsReg); - assert(!((((ssTop())->spilled)))); - rcvrReg2 = allocateRegForStackEntryAtnotConflictingWith(1, 0); - popToReg(ssValue(1), rcvrReg2); - } - assert(!((argNeedsReg - && (argReg2 == NoReg)))); - assert(!((rcvrNeedsReg - && (rcvrReg2 == NoReg)))); - rcvrReg1 = rcvrReg2; - argReg1 = argReg2; - if (!(((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse)))) { - return genIdenticalNoBranchArgIsConstantrcvrIsConstantargRegrcvrRegorNotIf(argConstant1, rcvrConstant1, argReg1, rcvrReg1, orNot); - } - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 2)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 2)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 2))); i <= (simStackPtr - 2); i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 2) + 1; - } - /* begin Label */ - label = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - /* begin genCmpArgIsConstant:rcvrIsConstant:argReg:rcvrReg: */ - assert((argReg1 != NoReg) - || (rcvrReg1 != NoReg)); - if (argConstant1) { - /* begin genCmpConstant:R: */ - constant2 = ((ssTop())->constant); - if (shouldAnnotateObjectReference(constant2)) { - annotateobjRef(checkLiteralforInstruction(constant2, genoperandoperand(CmpCwR, constant2, rcvrReg1)), constant2); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(CmpCqR, constant2, rcvrReg1); - } - } - else { - if (rcvrConstant1) { - /* begin genCmpConstant:R: */ - constant1 = ((ssValue(1))->constant); - if (shouldAnnotateObjectReference(constant1)) { - annotateobjRef(checkLiteralforInstruction(constant1, genoperandoperand(CmpCwR, constant1, argReg1)), constant1); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(CmpCqR, constant1, argReg1); - } - } - else { - /* begin CmpR:R: */ - assert(!((argReg1 == SPReg))); - genoperandoperand(CmpRR, argReg1, rcvrReg1); - } - } - ssPop(2); - if ((((fixupAt(nextPC1))->targetInstruction)) == 0) { - - /* The next instruction is dead. we can skip it. */ - deadCode = 1; - ensureFixupAt(targetBytecodePC1); - ensureFixupAt(postBranchPC1); - } - else { - assert(!(deadCode)); - } - if (orNot == ((branchDescriptor1->isBranchTrue))) { - - /* a == b ifFalse: ... or a ~~ b ifTrue: ... jump on equal to post-branch pc */ - fixup1 = ensureNonMergeFixupAt(targetBytecodePC1); - /* begin JumpZero: */ - jumpTarget = ensureNonMergeFixupAt(postBranchPC1); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget)); - } - else { - - /* orNot is true for ~~ */ - /* a == b ifTrue: ... or a ~~ b ifFalse: ... jump on equal to target pc */ - fixup1 = ensureNonMergeFixupAt(postBranchPC1); - /* begin JumpZero: */ - jumpTarget1 = ensureNonMergeFixupAt(targetBytecodePC1); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget1)); - } - if (unforwardArg1 - && (unforwardRcvr1)) { - /* begin genEnsureOopInRegNotForwarded:scratchReg:jumpBackTo: */ - genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(argReg1, TempReg, label, 0); - } - genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder((unforwardRcvr1 - ? rcvrReg1 - : argReg1), TempReg, label, fixup1); - if (!deadCode) { - ssPushConstant(trueObject()); - } - return 0; - } - regMask = 0; - unforwardRcvr = mayBeAForwarder(ssValue(1)); - unforwardArg = mayBeAForwarder(ssTop()); - if ((!unforwardRcvr) - && (!unforwardArg)) { - unforwardRcvr = 1; - } - assert(unforwardArg - || (unforwardRcvr)); - /* begin isUnannotatableConstant: */ - simStackEntry2 = ssValue(1); - rcvrConstant = (((simStackEntry2->type)) == SSConstant) - && ((isImmediate((simStackEntry2->constant))) - || (!(shouldAnnotateObjectReference((simStackEntry2->constant))))); - /* begin isUnannotatableConstant: */ - simStackEntry3 = ssTop(); - argConstant = (((simStackEntry3->type)) == SSConstant) - && ((isImmediate((simStackEntry3->constant))) - || (!(shouldAnnotateObjectReference((simStackEntry3->constant))))); - /* begin extractMaybeBranchDescriptorInto: */ - primDescriptor1 = generatorAt(byte0); - nextPC3 = bytecodePC + ((primDescriptor1->numBytes)); - nExts1 = 0; - while (1) { - while (1) { - /* begin generatorForPC: */ - branchDescriptor3 = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC3, methodObj))); - if (!((branchDescriptor3->isExtension))) break; - nExts1 += 1; - nextPC3 += (branchDescriptor3->numBytes); - } - /* begin isUnconditionalBranch */ - if (!((isBranch(branchDescriptor3)) - && (!(((branchDescriptor3->isBranchTrue)) - || ((branchDescriptor3->isBranchFalse)))))) break; - nextPC3 = eventualTargetOf((nextPC3 + ((branchDescriptor3->numBytes))) + (((branchDescriptor3->spanFunction))(branchDescriptor3, nextPC3, nExts1, methodObj))); - } - targetBytecodePC3 = (postBranchPC3 = 0); - if (((branchDescriptor3->isBranchTrue)) - || ((branchDescriptor3->isBranchFalse))) { - targetBytecodePC3 = eventualTargetOf((nextPC3 + ((branchDescriptor3->numBytes))) + (((branchDescriptor3->spanFunction))(branchDescriptor3, nextPC3, nExts1, methodObj))); - postBranchPC3 = eventualTargetOf(nextPC3 + ((branchDescriptor3->numBytes))); - } - else { - nextPC3 = bytecodePC + ((primDescriptor1->numBytes)); - } - branchDescriptor = branchDescriptor3; - nextPC = nextPC3; - postBranchPC = postBranchPC3; - targetBytecodePC = targetBytecodePC3; - /* begin allocateEqualsEqualsRegistersArgNeedsReg:rcvrNeedsReg:into: */ - argNeedsReg1 = !argConstant; - rcvrNeedsReg1 = !rcvrConstant; - assert(argNeedsReg1 - || (rcvrNeedsReg1)); - argReg3 = (rcvrReg3 = NoReg); - if (argNeedsReg1) { - if (rcvrNeedsReg1) { - /* begin allocateRegForStackTopTwoEntriesInto: */ - topRegistersMask1 = 0; - rTop11 = (rNext11 = NoReg); - if ((registerOrNone(ssTop())) != NoReg) { - rTop11 = registerOrNone(ssTop()); - } - if ((registerOrNone(ssValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg1 = (rNext11 = registerOrNone(ssValue(1))); - topRegistersMask1 = 1U << reg1; - } - if (rTop11 == NoReg) { - rTop11 = allocateRegNotConflictingWith(topRegistersMask1); - } - if (rNext11 == NoReg) { - rNext11 = allocateRegNotConflictingWith(1U << rTop11); - } - assert(!(((rTop11 == NoReg) - || (rNext11 == NoReg)))); - argReg3 = rTop11; - rcvrReg3 = rNext11; - popToReg(ssTop(), argReg3); - popToReg(ssValue(1), rcvrReg3); - } - else { - argReg3 = allocateRegForStackEntryAtnotConflictingWith(0, 0); - popToReg(ssTop(), argReg3); - if (((ssValue(1))->spilled)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperand(AddCqR, BytesPerWord, SPReg); - } - } - } - else { - assert(rcvrNeedsReg1); - assert(!((((ssTop())->spilled)))); - rcvrReg3 = allocateRegForStackEntryAtnotConflictingWith(1, 0); - popToReg(ssValue(1), rcvrReg3); - } - assert(!((argNeedsReg1 - && (argReg3 == NoReg)))); - assert(!((rcvrNeedsReg1 - && (rcvrReg3 == NoReg)))); - rcvrReg = rcvrReg3; - argReg = argReg3; - if (!(((branchDescriptor->isBranchTrue)) - || ((branchDescriptor->isBranchFalse)))) { - return genIdenticalNoBranchArgIsConstantrcvrIsConstantargRegrcvrRegorNotIf(argConstant, rcvrConstant, argReg, rcvrReg, orNot); - } - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 2)) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 2)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 2))); i1 <= (simStackPtr - 2); i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = (simStackPtr - 2) + 1; - } - if (unforwardArg) { - genEnsureOopInRegNotForwardedscratchReg(argReg, TempReg); - } - if (unforwardRcvr) { - genEnsureOopInRegNotForwardedscratchReg(rcvrReg, TempReg); - } - if (argReg == NoReg) { - /* begin registerMaskFor: */ - regMask = 1U << rcvrReg; - } - else { - if (rcvrReg == NoReg) { - /* begin registerMaskFor: */ - regMask = 1U << argReg; - } - else { - /* begin registerMaskFor:and: */ - regMask = (1U << rcvrReg) | (1U << argReg); - } - } - counterReg = allocateRegNotConflictingWith(regMask); - /* begin genExecutionCountLogicInto:counterReg: */ - counterAddress1 = counters + (CounterBytes * counterIndex); - /* begin gen:literal:operand: */ - opcode = MoveAwR; - /* begin checkLiteral:forInstruction: */ - anInstruction3 = genoperandoperand(opcode, counterAddress1, counterReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(SubCqR, 0x10000, counterReg); - /* begin JumpCarry: */ - countTripped1 = genConditionalBranchoperand(JumpCarry, ((sqInt)0)); - /* begin gen:operand:literal: */ - opcode1 = MoveRAw; - /* begin checkLiteral:forInstruction: */ - anInstruction2 = genoperandoperand(opcode1, counterReg, counterAddress1); - counterAddress = counterAddress1; - countTripped = countTripped1; - /* begin genCmpArgIsConstant:rcvrIsConstant:argReg:rcvrReg: */ - assert((argReg != NoReg) - || (rcvrReg != NoReg)); - if (argConstant) { - /* begin genCmpConstant:R: */ - constant3 = ((ssTop())->constant); - if (shouldAnnotateObjectReference(constant3)) { - annotateobjRef(checkLiteralforInstruction(constant3, genoperandoperand(CmpCwR, constant3, rcvrReg)), constant3); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(CmpCqR, constant3, rcvrReg); - } - } - else { - if (rcvrConstant) { - /* begin genCmpConstant:R: */ - constant11 = ((ssValue(1))->constant); - if (shouldAnnotateObjectReference(constant11)) { - annotateobjRef(checkLiteralforInstruction(constant11, genoperandoperand(CmpCwR, constant11, argReg)), constant11); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(CmpCqR, constant11, argReg); - } - } - else { - /* begin CmpR:R: */ - assert(!((argReg == SPReg))); - genoperandoperand(CmpRR, argReg, rcvrReg); - } - } - ssPop(2); - if (orNot == ((branchDescriptor->isBranchTrue))) { - fixup = ((usqInt)(ensureNonMergeFixupAt(targetBytecodePC))); - /* begin JumpZero: */ - jumpTarget2 = ((void *) (((usqInt)(ensureNonMergeFixupAt(postBranchPC))))); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget2)); - } - else { - - /* orNot is true for ~~ */ - fixup = ((usqInt)(ensureNonMergeFixupAt(postBranchPC))); - /* begin JumpZero: */ - jumpTarget3 = ((void *) (((usqInt)(ensureNonMergeFixupAt(targetBytecodePC))))); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget3)); - } - /* begin genFallsThroughCountLogicCounterReg:counterAddress: */ - anInstruction4 = genoperandoperand(SubCqR, 1, counterReg); - /* begin gen:operand:literal: */ - opcode2 = MoveRAw; - /* begin checkLiteral:forInstruction: */ - anInstruction11 = genoperandoperand(opcode2, counterReg, counterAddress); - /* begin Jump: */ - genoperand(Jump, ((sqInt)fixup)); - jmpTarget(countTripped, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPop(-2); - /* begin genCmpArgIsConstant:rcvrIsConstant:argReg:rcvrReg: */ - assert((argReg != NoReg) - || (rcvrReg != NoReg)); - if (!unforwardArg) { - /* begin genCmpConstant:R: */ - constant4 = ((ssTop())->constant); - if (shouldAnnotateObjectReference(constant4)) { - annotateobjRef(checkLiteralforInstruction(constant4, genoperandoperand(CmpCwR, constant4, rcvrReg)), constant4); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperand(CmpCqR, constant4, rcvrReg); - } - } - else { - if (!unforwardRcvr) { - /* begin genCmpConstant:R: */ - constant12 = ((ssValue(1))->constant); - if (shouldAnnotateObjectReference(constant12)) { - annotateobjRef(checkLiteralforInstruction(constant12, genoperandoperand(CmpCwR, constant12, argReg)), constant12); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperand(CmpCqR, constant12, argReg); - } - } - else { - /* begin CmpR:R: */ - assert(!((argReg == SPReg))); - genoperandoperand(CmpRR, argReg, rcvrReg); - } - } - ssPop(2); - if (orNot) { - /* begin JumpNonZero: */ - jumpEqual = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - } - else { - /* begin JumpZero: */ - jumpEqual = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - } - /* begin genMoveFalseR: */ - constant = falseObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, TempReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, TempReg); - } - /* begin Jump: */ - jumpNotEqual = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpEqual, genMoveTrueR(TempReg)); - jmpTarget(jumpNotEqual, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushRegister(TempReg); - if ((((fixupAt(nextPC))->targetInstruction)) == 0) { - branchReachedOnlyForCounterTrip = 1; - } - return 0; -} - - /* SistaCogit>>#genJumpBinaryInlinePrimitive: */ -static sqInt NoDbgRegParms -genJumpBinaryInlinePrimitive(sqInt primIndex) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - void *jumpTarget; - void *jumpTarget1; - void *jumpTarget2; - sqInt target; - sqInt testReg; - - assert((((ssTop())->type)) == SSConstant); - target = eventualTargetOf(((((((ssTop())->constant)) >> 1)) + 3) + bytecodePC); - testReg = allocateRegForStackEntryAtnotConflictingWith(1, 0); - popToReg(ssValue(1), testReg); - ssPop(2); - switch (primIndex) { - case 16: - -# if IMMUTABILITY - jmpTarget(genJumpMutablescratchReg(testReg, TempReg), ensureFixupAt(target)); -# else - /* begin Jump: */ - jumpTarget = ensureFixupAt(target); - genoperand(Jump, ((sqInt)jumpTarget)); -# endif - return 0; - - case 17: - -# if IMMUTABILITY - jmpTarget(genJumpImmutablescratchReg(testReg, TempReg), ensureFixupAt(target)); -# else - - /* Do nothing - fall through */ -# endif - return 0; - - case 18: - /* begin checkLiteral:forInstruction: */ - storeCheckBoundary(); - anInstruction = genoperandoperand(CmpCwR, storeCheckBoundary(), testReg); - /* begin JumpBelow: */ - jumpTarget1 = ensureFixupAt(target); - genConditionalBranchoperand(JumpBelow, ((sqInt)jumpTarget1)); - return 0; - - case 19: - /* begin checkLiteral:forInstruction: */ - storeCheckBoundary(); - anInstruction1 = genoperandoperand(CmpCwR, storeCheckBoundary(), testReg); - /* begin JumpAboveOrEqual: */ - jumpTarget2 = ensureFixupAt(target); - genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)jumpTarget2)); - return 0; - - default: - error("Case not found and no otherwise clause"); - } - return EncounteredUnknownBytecode; -} - - -/* The heart of performance counting in Sista. Conditional branches are 6 - times less - frequent than sends and can provide basic block frequencies (send counters - can't). Each conditional has a 32-bit counter split into an upper 16 bits - counting executions - and a lower half counting untaken executions of the branch. Executing the - branch decrements the upper half, tripping if the count goes negative. Not - taking the branch - decrements the lower half. N.B. We *do not* eliminate dead branches (true - ifTrue:/true ifFalse:) - so that scanning for send and branch data is simplified and that branch - data is correct. */ - - /* SistaCogit>>#genJumpIf:to: */ -static sqInt NoDbgRegParms -genJumpIfto(sqInt boolean, sqInt targetBytecodePC) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *abstractInstruction2; - AbstractInstruction *abstractInstruction3; - AbstractInstruction *abstractInstruction4; - AbstractInstruction *abstractInstruction5; - AbstractInstruction *abstractInstruction6; - AbstractInstruction *abstractInstruction7; - AbstractInstruction *abstractInstruction8; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt counterAddress; - sqInt counterAddress1; - AbstractInstruction *countTripped; - AbstractInstruction *countTripped1; - CogSimStackEntry *desc; - CogSimStackEntry *desc1; - CogSimStackEntry *desc2; - CogSimStackEntry *desc3; - CogSimStackEntry *desc4; - sqInt eventualTarget; - sqInt eventualTarget1; - sqInt eventualTarget2; - sqInt eventualTarget3; - sqInt eventualTarget4; - BytecodeFixup *fixup; - BytecodeFixup *fixup1; - BytecodeFixup *fixup2; - BytecodeFixup *fixup3; - sqInt i; - sqInt i1; - sqInt i2; - sqInt i3; - sqInt i4; - void *jumpTarget; - void *jumpTarget1; - void *jumpTarget2; - void *jumpTarget3; - void *jumpTarget4; - BytecodeDescriptor *nextDescriptor; - sqInt nextPC; - AbstractInstruction *ok; - AbstractInstruction *ok1; - AbstractInstruction *ok2; - AbstractInstruction *ok3; - AbstractInstruction *ok4; - sqInt opcode; - sqInt opcode1; - sqInt opcode2; - sqInt quickConstant; - sqInt quickConstant1; - sqInt quickConstant2; - sqInt quickConstant3; - sqInt quickConstant4; - AbstractInstruction *retry; - - - /* In optimized code we don't generate counters to improve performance */ - if (isOptimizedMethod(methodObj)) { - eventualTarget1 = eventualTargetOf(targetBytecodePC); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 1)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 1)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 1))); i < simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 1) + 1; - } - desc1 = ssTop(); - ssPop(1); - if ((((desc1->type)) == SSConstant) - && ((((desc1->constant)) == (trueObject())) - || (((desc1->constant)) == (falseObject())))) { - - /* Must arrange there's a fixup at the target whether it is jumped to or - not so that the simStackPtr can be kept correct. */ - - /* Must annotate the bytecode for correct pc mapping. */ - fixup = ensureFixupAt(eventualTarget1); - /* begin annotateBytecode: */ - if (((desc1->constant)) == boolean) { - /* begin Jump: */ - abstractInstruction = genoperand(Jump, ((sqInt)fixup)); - } - else { - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - } - (abstractInstruction->annotation = HasBytecodePC); - extA = 0; - return 0; - } - popToReg(desc1, TempReg); - assert((objectAfter(falseObject())) == (trueObject())); - /* begin genSubConstant:R: */ - if (shouldAnnotateObjectReference(boolean)) { - annotateobjRef(checkLiteralforInstruction(boolean, genoperandoperand(SubCwR, boolean, TempReg)), TempReg); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, boolean, TempReg); - } - /* begin JumpZero: */ - jumpTarget = ensureFixupAt(eventualTarget1); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget)); - if (((extA & 1) != 0)) { - extA = 0; - /* begin annotateBytecode: */ - abstractInstruction1 = lastOpcode(); - (abstractInstruction1->annotation = HasBytecodePC); - return 0; - } - extA = 0; - /* begin CmpCq:R: */ - quickConstant = (boolean == (falseObject()) - ? (trueObject()) - (falseObject()) - : (falseObject()) - (trueObject())); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, quickConstant, TempReg); - /* begin JumpZero: */ - ok1 = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - genCallMustBeBooleanFor(boolean); - jmpTarget(ok1, annotateBytecode(genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return 0; - } - if (branchReachedOnlyForCounterTrip) { - branchReachedOnlyForCounterTrip = 0; - return genCounterTripOnlyJumpIfto(boolean, targetBytecodePC); - } - if (boolean == (falseObject())) { - nextPC = bytecodePC + (((generatorAt(byte0))->numBytes)); - /* begin generatorForPC: */ - nextDescriptor = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC, methodObj))); - if (((nextDescriptor->generator)) == genPushConstantTrueBytecode) { - eventualTarget2 = eventualTargetOf(targetBytecodePC); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 1)) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 1)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 1))); i1 < simStackPtr; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = (simStackPtr - 1) + 1; - } - desc2 = ssTop(); - ssPop(1); - if ((((desc2->type)) == SSConstant) - && ((((desc2->constant)) == (trueObject())) - || (((desc2->constant)) == (falseObject())))) { - - /* Must arrange there's a fixup at the target whether it is jumped to or - not so that the simStackPtr can be kept correct. */ - - /* Must annotate the bytecode for correct pc mapping. */ - fixup1 = ensureFixupAt(eventualTarget2); - /* begin annotateBytecode: */ - if (((desc2->constant)) == boolean) { - /* begin Jump: */ - abstractInstruction2 = genoperand(Jump, ((sqInt)fixup1)); - } - else { - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction2 = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction2 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - } - (abstractInstruction2->annotation = HasBytecodePC); - extA = 0; - return 0; - } - popToReg(desc2, TempReg); - assert((objectAfter(falseObject())) == (trueObject())); - /* begin genSubConstant:R: */ - if (shouldAnnotateObjectReference(boolean)) { - annotateobjRef(checkLiteralforInstruction(boolean, genoperandoperand(SubCwR, boolean, TempReg)), TempReg); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(SubCqR, boolean, TempReg); - } - /* begin JumpZero: */ - jumpTarget1 = ensureFixupAt(eventualTarget2); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget1)); - if (((extA & 1) != 0)) { - extA = 0; - /* begin annotateBytecode: */ - abstractInstruction3 = lastOpcode(); - (abstractInstruction3->annotation = HasBytecodePC); - return 0; - } - extA = 0; - /* begin CmpCq:R: */ - quickConstant1 = (boolean == (falseObject()) - ? (trueObject()) - (falseObject()) - : (falseObject()) - (trueObject())); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(CmpCqR, quickConstant1, TempReg); - /* begin JumpZero: */ - ok2 = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - genCallMustBeBooleanFor(boolean); - jmpTarget(ok2, annotateBytecode(genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return 0; - } - /* begin generatorForPC: */ - nextDescriptor = generatorAt(bytecodeSetOffset + (fetchByteofObject(targetBytecodePC, methodObj))); - if (((nextDescriptor->generator)) == genPushConstantFalseBytecode) { - eventualTarget3 = eventualTargetOf(targetBytecodePC); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 1)) { - for (i2 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 1)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 1))); i2 < simStackPtr; i2 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i2), frameOffsetOfTemporary(i2 - 1), FPReg); - } - simSpillBase = (simStackPtr - 1) + 1; - } - desc3 = ssTop(); - ssPop(1); - if ((((desc3->type)) == SSConstant) - && ((((desc3->constant)) == (trueObject())) - || (((desc3->constant)) == (falseObject())))) { - - /* Must arrange there's a fixup at the target whether it is jumped to or - not so that the simStackPtr can be kept correct. */ - - /* Must annotate the bytecode for correct pc mapping. */ - fixup2 = ensureFixupAt(eventualTarget3); - /* begin annotateBytecode: */ - if (((desc3->constant)) == boolean) { - /* begin Jump: */ - abstractInstruction4 = genoperand(Jump, ((sqInt)fixup2)); - } - else { - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction4 = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction4 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - } - (abstractInstruction4->annotation = HasBytecodePC); - extA = 0; - return 0; - } - popToReg(desc3, TempReg); - assert((objectAfter(falseObject())) == (trueObject())); - /* begin genSubConstant:R: */ - if (shouldAnnotateObjectReference(boolean)) { - annotateobjRef(checkLiteralforInstruction(boolean, genoperandoperand(SubCwR, boolean, TempReg)), TempReg); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(SubCqR, boolean, TempReg); - } - /* begin JumpZero: */ - jumpTarget2 = ensureFixupAt(eventualTarget3); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget2)); - if (((extA & 1) != 0)) { - extA = 0; - /* begin annotateBytecode: */ - abstractInstruction5 = lastOpcode(); - (abstractInstruction5->annotation = HasBytecodePC); - return 0; - } - extA = 0; - /* begin CmpCq:R: */ - quickConstant2 = (boolean == (falseObject()) - ? (trueObject()) - (falseObject()) - : (falseObject()) - (trueObject())); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(CmpCqR, quickConstant2, TempReg); - /* begin JumpZero: */ - ok3 = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - genCallMustBeBooleanFor(boolean); - jmpTarget(ok3, annotateBytecode(genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return 0; - } - } - - /* We ignore the noMustBeBoolean flag. It should not be present in methods with counters, and if it is we don't care. */ - /* We don't generate counters on branches on true/false, the basicblock usage can be inferred */ - extA = 0; - desc = ssTop(); - if ((((desc->type)) == SSConstant) - && ((((desc->constant)) == (trueObject())) - || (((desc->constant)) == (falseObject())))) { - eventualTarget4 = eventualTargetOf(targetBytecodePC); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 1)) { - for (i3 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 1)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 1))); i3 < simStackPtr; i3 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i3), frameOffsetOfTemporary(i3 - 1), FPReg); - } - simSpillBase = (simStackPtr - 1) + 1; - } - desc4 = ssTop(); - ssPop(1); - if ((((desc4->type)) == SSConstant) - && ((((desc4->constant)) == (trueObject())) - || (((desc4->constant)) == (falseObject())))) { - - /* Must arrange there's a fixup at the target whether it is jumped to or - not so that the simStackPtr can be kept correct. */ - - /* Must annotate the bytecode for correct pc mapping. */ - fixup3 = ensureFixupAt(eventualTarget4); - /* begin annotateBytecode: */ - if (((desc4->constant)) == boolean) { - /* begin Jump: */ - abstractInstruction6 = genoperand(Jump, ((sqInt)fixup3)); - } - else { - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction6 = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction6 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - } - (abstractInstruction6->annotation = HasBytecodePC); - extA = 0; - return 0; - } - popToReg(desc4, TempReg); - assert((objectAfter(falseObject())) == (trueObject())); - /* begin genSubConstant:R: */ - if (shouldAnnotateObjectReference(boolean)) { - annotateobjRef(checkLiteralforInstruction(boolean, genoperandoperand(SubCwR, boolean, TempReg)), TempReg); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(SubCqR, boolean, TempReg); - } - /* begin JumpZero: */ - jumpTarget3 = ensureFixupAt(eventualTarget4); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget3)); - if (((extA & 1) != 0)) { - extA = 0; - /* begin annotateBytecode: */ - abstractInstruction7 = lastOpcode(); - (abstractInstruction7->annotation = HasBytecodePC); - return 0; - } - extA = 0; - /* begin CmpCq:R: */ - quickConstant3 = (boolean == (falseObject()) - ? (trueObject()) - (falseObject()) - : (falseObject()) - (trueObject())); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(CmpCqR, quickConstant3, TempReg); - /* begin JumpZero: */ - ok4 = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - genCallMustBeBooleanFor(boolean); - jmpTarget(ok4, annotateBytecode(genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return 0; - } - eventualTarget = eventualTargetOf(targetBytecodePC); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 1)) { - for (i4 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 1)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 1))); i4 < simStackPtr; i4 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i4), frameOffsetOfTemporary(i4 - 1), FPReg); - } - simSpillBase = (simStackPtr - 1) + 1; - } - popToReg(desc, TempReg); - ssPop(1); - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << SendNumArgsReg, simStackPtr, simNativeStackPtr); - /* begin Label */ - retry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - /* begin genExecutionCountLogicInto:counterReg: */ - counterAddress1 = counters + (CounterBytes * counterIndex); - /* begin gen:literal:operand: */ - opcode = MoveAwR; - /* begin checkLiteral:forInstruction: */ - anInstruction9 = genoperandoperand(opcode, counterAddress1, SendNumArgsReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperand(SubCqR, 0x10000, SendNumArgsReg); - /* begin JumpCarry: */ - countTripped1 = genConditionalBranchoperand(JumpCarry, ((sqInt)0)); - /* begin gen:operand:literal: */ - opcode1 = MoveRAw; - /* begin checkLiteral:forInstruction: */ - anInstruction21 = genoperandoperand(opcode1, SendNumArgsReg, counterAddress1); - counterAddress = counterAddress1; - countTripped = countTripped1; - - /* Cunning trick by LPD. If true and false are contiguous subtract the smaller. - Correct result is either 0 or the distance between them. If result is not 0 or - their distance send mustBeBoolean. */ - counterIndex += 1; - assert((objectAfter(falseObject())) == (trueObject())); - /* begin genSubConstant:R: */ - if (shouldAnnotateObjectReference(boolean)) { - annotateobjRef(checkLiteralforInstruction(boolean, genoperandoperand(SubCwR, boolean, TempReg)), TempReg); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(SubCqR, boolean, TempReg); - } - /* begin JumpZero: */ - jumpTarget4 = ensureFixupAt(eventualTarget); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget4)); - /* begin genFallsThroughCountLogicCounterReg:counterAddress: */ - anInstruction10 = genoperandoperand(SubCqR, 1, SendNumArgsReg); - /* begin gen:operand:literal: */ - opcode2 = MoveRAw; - /* begin checkLiteral:forInstruction: */ - anInstruction12 = genoperandoperand(opcode2, SendNumArgsReg, counterAddress); - /* begin CmpCq:R: */ - quickConstant4 = (boolean == (falseObject()) - ? (trueObject()) - (falseObject()) - : (falseObject()) - (trueObject())); - /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperand(CmpCqR, quickConstant4, TempReg); - /* begin JumpZero: */ - ok = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(MoveCqR, 0, SendNumArgsReg); - jmpTarget(countTripped, genCallMustBeBooleanFor(boolean)); - /* begin annotateBytecode: */ - abstractInstruction8 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction8->annotation = HasBytecodePC); - /* begin Jump: */ - genoperand(Jump, ((sqInt)retry)); - jmpTarget(ok, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - -/* Note: those tests work with forwarders (wrong class index) */ - - /* SistaCogit>>#genJumpTrinaryInlinePrimitive: */ -static sqInt NoDbgRegParms -genJumpTrinaryInlinePrimitive(sqInt primIndex) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction3; - sqInt behavior; - sqInt classIndex; - sqInt classIndex1; - AbstractInstruction *jmp; - AbstractInstruction * jmpImmediate; - AbstractInstruction * jmpImmediate1; - sqInt oop; - sqInt oop1; - sqInt oop11; - sqInt oop2; - sqInt oop21; - sqInt oop3; - sqInt target; - BytecodeFixup *targetFixUp; - sqInt testReg; - - jmpImmediate = ((AbstractInstruction *) 0); - jmpImmediate1 = ((AbstractInstruction *) 0); - assert((((ssTop())->type)) == SSConstant); - assert((((ssValue(1))->type)) == SSConstant); - testReg = allocateRegForStackEntryAtnotConflictingWith(2, 0); - popToReg(ssValue(2), testReg); - behavior = ((ssValue(1))->constant); - target = eventualTargetOf(((((((ssTop())->constant)) >> 1)) + 3) + bytecodePC); - ssPop(3); - targetFixUp = ((AbstractInstruction *) (ensureFixupAt(target))); - switch (primIndex) { - case 0: - - /* 8000 jumpIfInstanceOf:distance: - Anything, literal which is a Behavior, literal which is a Smi */ - /* begin branchIf:instanceOfBehavior:target: */ - classIndex1 = classTagForClass(behavior); - if (classIndex1 == (fetchClassTagOf(falseObject()))) { - /* begin branchIf:isOop:target: */ - oop3 = falseObject(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(CmpCqR, oop3, testReg); - /* begin JumpZero: */ - genConditionalBranchoperand(JumpZero, ((sqInt)(((AbstractInstruction *) targetFixUp)))); - } - if (classIndex1 == (fetchClassTagOf(trueObject()))) { - /* begin branchIf:isOop:target: */ - oop11 = trueObject(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperand(CmpCqR, oop11, testReg); - /* begin JumpZero: */ - genConditionalBranchoperand(JumpZero, ((sqInt)(((AbstractInstruction *) targetFixUp)))); - } - if (classIndex1 == (fetchClassTagOf(nilObject()))) { - /* begin branchIf:isOop:target: */ - oop21 = nilObject(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperand(CmpCqR, oop21, testReg); - /* begin JumpZero: */ - genConditionalBranchoperand(JumpZero, ((sqInt)(((AbstractInstruction *) targetFixUp)))); - } - if (isImmediateClass(behavior)) { - /* begin branchIf:hasImmediateTag:target: */ - if (classIndex1 == (smallIntegerTag())) { - jmpImmediate1 = genJumpSmallInteger(testReg); - } - if (classIndex1 == (characterTag())) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, testReg, TempReg); - jmpImmediate1 = genJumpCharacterInScratchReg(testReg); - } - jmpTarget(jmpImmediate1, ((AbstractInstruction *) targetFixUp)); - } - else { - jmp = genJumpImmediate(testReg); - genGetClassIndexOfNonImminto(testReg, TempReg); - genCmpClassIndexR(classIndex1, TempReg); - /* begin JumpZero: */ - genConditionalBranchoperand(JumpZero, ((sqInt)(((AbstractInstruction *) targetFixUp)))); - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - return 0; - - case 1: - - /* 8001 jumpIfNotInstanceOf:distance: - Anything, literal which is a Behavior, literal which is a Smi */ - /* begin branchIf:notInstanceOfBehavior:target: */ - classIndex = classTagForClass(behavior); - if (classIndex == (fetchClassTagOf(falseObject()))) { - /* begin branchIf:isNotOop:target: */ - oop = falseObject(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, oop, testReg); - /* begin JumpNonZero: */ - genConditionalBranchoperand(JumpNonZero, ((sqInt)(((AbstractInstruction *) targetFixUp)))); - } - if (classIndex == (fetchClassTagOf(trueObject()))) { - /* begin branchIf:isNotOop:target: */ - oop1 = trueObject(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, oop1, testReg); - /* begin JumpNonZero: */ - genConditionalBranchoperand(JumpNonZero, ((sqInt)(((AbstractInstruction *) targetFixUp)))); - } - if (classIndex == (fetchClassTagOf(nilObject()))) { - /* begin branchIf:isNotOop:target: */ - oop2 = nilObject(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(CmpCqR, oop2, testReg); - /* begin JumpNonZero: */ - genConditionalBranchoperand(JumpNonZero, ((sqInt)(((AbstractInstruction *) targetFixUp)))); - } - if (isImmediateClass(behavior)) { - /* begin branchIf:hasNotImmediateTag:target: */ - if (classIndex == (smallIntegerTag())) { - jmpImmediate = genJumpNotSmallInteger(testReg); - } - if (classIndex == (characterTag())) { - - /* Character test destroy register value in Spur */ - /* begin MoveR:R: */ - genoperandoperand(MoveRR, testReg, TempReg); - jmpImmediate = genJumpNotCharacterInScratchReg(TempReg); - } - jmpTarget(jmpImmediate, ((AbstractInstruction *) targetFixUp)); - } - else { - jmpTarget(genJumpImmediate(testReg), ((AbstractInstruction *) targetFixUp)); - genGetClassIndexOfNonImminto(testReg, TempReg); - genCmpClassIndexR(classIndex, TempReg); - /* begin JumpNonZero: */ - genConditionalBranchoperand(JumpNonZero, ((sqInt)(((AbstractInstruction *) targetFixUp)))); - } - return 0; - - case 2: - - /* 8002 jumpIfInstanceOfOneOf:distance: - Anything, Array of behaviors, literal which is a Smi */ - branchIfinstanceOfBehaviorstarget(testReg, behavior, targetFixUp); - return 0; - - case 3: - - /* 8003 jumpIfNotInstanceOfOneOf:distance: - Anything, Array of behaviors, literal which is a Smi */ - branchIfnotInstanceOfBehaviorstarget(testReg, behavior, targetFixUp); - return 0; - - default: - error("Case not found and no otherwise clause"); - } - return EncounteredUnknownBytecode; -} - - -/* 6000 backjumpNoInterrupt - literal which is a Smi */ - - /* SistaCogit>>#genJumpUnaryInlinePrimitive: */ -static sqInt NoDbgRegParms -genJumpUnaryInlinePrimitive(sqInt primIndex) -{ - sqInt i; - void *jumpTarget; - sqInt targetBytecodePC; - - if (primIndex == 0) { - assert((((ssTop())->type)) == SSConstant); - targetBytecodePC = ((((((ssTop())->constant)) >> 1)) + 3) + bytecodePC; - ssPop(1); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - - /* can't fall through */ - deadCode = 1; - /* begin Jump: */ - jumpTarget = fixupAtIndex(targetBytecodePC - initialPC); - genoperand(Jump, ((sqInt)jumpTarget)); - return 0; - } - return EncounteredUnknownBytecode; -} - - -/* SistaV1: 236 11101100 iiiiiiii callMappedInlinedPrimitive */ -/* Number of arguments: - 0-49 nullary - 50-99 unary - 100-149 binary - 150-199 trinary - 200-255 variable */ -/* Specification: - 50 EnsureEnoughWords - literal which is a Smi => ret value is receiver - 150 immCheckPointerAt:put: - pointer object (Fixed sized or not) and not a context, Smi, Anything => - arg2 (1-based, optimised if arg1 is a constant) - 151 immCheckStoreCheckPointerAt:put: - pointer object (Fixed sized or not) and not a context, Smi, Anything => - arg2 (1-based, optimised if arg1 is a constant) - 152 immCheckMaybeContextPointerAt:put: - pointer object (Fixed sized or not), Smi, Anything => arg2 (1-based, - optimised if arg1 is a constant) - 153 immCheckMaybeContextStoreCheckPointerAt:put: - pointer object (Fixed sized or not), Smi, Anything => arg2 (1-based, - optimised if arg1 is a constant) - 154 immCheckByteAt:put: - byte object, Smi, 8 bits unsigned Smi => arg2 (1-based, optimised if arg1 - is a constant) - 155 immCheckShortAt:put: - short object, Smi, 16 bits unsigned Smi => arg2 (1-based, optimised if - arg1 is a constant) - 156 immCheckWordAt:put: - word object, Smi, 32 bits unsigned Smi => arg2 (1-based, optimised if arg1 - is a constant) - 157 immCheckDoubleWordAt:put: - double word object, Smi, 64 bits unsigned Smi or LargePositiveInteger => - arg2 (1-based, optimised if arg1 is a constant) - 250 directCall - method to call on top of stack => (variable number of parameters) - */ - - /* SistaCogit>>#genMappedInlinePrimitive: */ -static sqInt NoDbgRegParms -genMappedInlinePrimitive(sqInt primIndex) -{ - AbstractInstruction *abstractInstruction; - - switch (primIndex) { - case 50: - return genEnsureEnoughSlots(); - - case 150: - return genPointerAtPutMaybeContextstoreCheckimmutabilityCheck(0, 0, 1); - - case 151: - return genPointerAtPutMaybeContextstoreCheckimmutabilityCheck(0, 1, 1); - - case 152: - return genPointerAtPutMaybeContextstoreCheckimmutabilityCheck(1, 0, 1); - - case 153: - return genPointerAtPutMaybeContextstoreCheckimmutabilityCheck(1, 1, 1); - - case 154: - -# if IMMUTABILITY - return genByteAtPutImmutabilityCheck(); -# else - genByteAtPut(); - /* begin annotateBytecode: */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction->annotation = HasBytecodePC); - return 0; -# endif // IMMUTABILITY - - case 155: - case 156: - case 157: - return EncounteredUnknownBytecode; - - case 250: - return genDirectCall(); - - default: - return EncounteredUnknownBytecode; - - } - return 0; -} - - -/* This can be entered in one of two states, depending on SendNumArgsReg. See - e.g. genJumpIf:to:. If SendNumArgsReg is non-zero then this has been - entered via - the initial test of the counter in the jump executed count (i.e. the - counter has - tripped). In this case TempReg contains the boolean to be tested and - should not - be offset, and ceCounterTripped should be invoked with the unoffset - TempReg. If SendNumArgsReg is zero then this has been entered for - must-be-boolean processing. TempReg has been offset by boolean and must be - corrected and - ceSendMustBeBoolean: invoked with the corrected value. */ - - /* SistaCogit>>#genMustBeBooleanTrampolineFor:called: */ -static usqInt NoDbgRegParms -genMustBeBooleanTrampolineForcalled(sqInt boolean, char *trampolineName) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *jumpMBB; - - zeroOpcodeIndex(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, SendNumArgsReg); - /* begin JumpZero: */ - jumpMBB = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - genSmalltalkToCStackSwitch(1); - compileCallFornumArgsargargargargresultRegregsToSave(ceCounterTripped, 1, TempReg, null, null, null, TempReg, 0 /* emptyRegisterMask */); - genLoadStackPointers(backEnd); - /* begin PopR: */ - genoperand(PopR, LinkReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, FoxMFReceiver, FPReg, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, 0); - assert(!(shouldAnnotateObjectReference(boolean))); - jmpTarget(jumpMBB, checkQuickConstantforInstruction(boolean, genoperandoperand(AddCqR, boolean, TempReg))); - return genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceSendMustBeBoolean, trampolineName, 1, TempReg, null, null, null, 0 /* emptyRegisterMask */, 1, NoReg, 1); -} - - /* SistaCogit>>#genPointerAtPutConstantMaybeContext:storeCheck:immutabilityCheck: */ -static sqInt NoDbgRegParms -genPointerAtPutConstantMaybeContextstoreCheckimmutabilityCheck(sqInt maybeContext, sqInt needsStoreCheck, sqInt needsImmCheck) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *abstractInstruction2; - AbstractInstruction *abstractInstruction3; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - sqInt i; - sqInt i1; - AbstractInstruction *immutabilityFailure; - sqInt indexCst; - AbstractInstruction *mutableJump; - sqInt rcvrReg; - sqInt topReg; - sqInt valReg; - - immutabilityFailure = ((AbstractInstruction *) 0); - - /* we want to have on top of stack the value to write descriptor. */ - indexCst = (((((ssValue(1))->constant)) >> 1)) - 1; - if (maybeContext - || (needsImmCheck)) { - valReg = ClassReg; - voidReceiverResultRegContainsSelf(); - rcvrReg = ReceiverResultReg; - } - else { - valReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - if (needsStoreCheck) { - voidReceiverResultRegContainsSelf(); - rcvrReg = ReceiverResultReg; - } - else { - rcvrReg = allocateRegForStackEntryAtnotConflictingWith(2, 1U << valReg); - } - } - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << valReg, simStackPtr - 2, simNativeStackPtr); - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << rcvrReg, simStackPtr - 3, simNativeStackPtr); - popToReg(ssTop(), valReg); - ssPop(1); - if (((ssTop())->spilled)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, BytesPerWord, SPReg); - } - ssPop(1); - popToReg(ssTop(), rcvrReg); - ssPop(1); - ssPushRegister(valReg); - if (maybeContext) { - /* begin genGenericStorePop:MaybeContextSlotIndex:needsStoreCheck:needsRestoreRcvr:needsImmutabilityCheck: */ - assert(needsFrame); -# if IMMUTABILITY - if (needsImmCheck) { - mutableJump = genJumpMutablescratchReg(ReceiverResultReg, TempReg); - /* begin genStoreTrampolineCall: */ - assert(IMMUTABILITY); - if (indexCst >= (NumStoreTrampolines - 1)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, indexCst, TempReg); - /* begin CallRT: */ - abstractInstruction3 = genoperand(Call, ceStoreTrampolines[NumStoreTrampolines - 1]); - (abstractInstruction3->annotation = IsRelativeCall); - } - else { - /* begin CallRT: */ - abstractInstruction1 = genoperand(Call, ceStoreTrampolines[indexCst]); - (abstractInstruction1->annotation = IsRelativeCall); - } - /* begin annotateBytecode: */ - abstractInstruction2 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction2->annotation = HasBytecodePC); - /* begin Jump: */ - immutabilityFailure = genoperand(Jump, ((sqInt)0)); - jmpTarget(mutableJump, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } -# endif // IMMUTABILITY - ssPop(1); - /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); - ssPush(1); - genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); - ssStoreAndReplacePoptoReg(0, ClassReg); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, indexCst, SendNumArgsReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceStoreContextInstVarTrampoline); - (abstractInstruction->annotation = IsRelativeCall); -# if IMMUTABILITY - if (needsImmCheck) { - jmpTarget(immutabilityFailure, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } -# endif // IMMUTABILITY - return 0; - } - else { - /* begin genGenericStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr:needsImmutabilityCheck: */ -# if IMMUTABILITY - if (needsImmCheck) { - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); - ssStoreAndReplacePoptoReg(0, ClassReg); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i1 <= simStackPtr; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, indexCst, rcvrReg, TempReg, needsStoreCheck, 0); - } -# endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << rcvrReg); - ssStorePoptoReg(0, topReg); - return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, indexCst, rcvrReg, TempReg, needsFrame, needsStoreCheck); - } -} - - /* SistaCogit>>#genPointerAtPutImmCheckAndStoreCheck */ -static sqInt -genPointerAtPutImmCheckAndStoreCheck(void) -{ - sqInt adjust; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - sqInt i; - AbstractInstruction *immutableJump; - int indexIsCst; - AbstractInstruction *jmpDestYoung; - AbstractInstruction *jmpImmediate; - AbstractInstruction *jmpSourceOld; - AbstractInstruction *jumpRemembered; - sqInt quickConstant; - sqInt ra1; - sqInt ra2; - sqInt rr; - sqInt scratchReg; - - - /* Assumes rr is not a context and no store check is needed */ - indexIsCst = (((ssValue(1))->type)) == SSConstant; - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 3)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 3)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 3))); i <= (simStackPtr - 3); i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 3) + 1; - } - rr = ReceiverResultReg; - ra1 = TempReg; - ra2 = ClassReg; - scratchReg = Arg0Reg; - - /* shift by baseHeaderSize and then move from 1 relative to zero relative */ - adjust = (((usqInt)(BaseHeaderSize)) >> (shiftForWord())) - 1; - popToReg(ssValue(2), rr); - if (indexIsCst) { - /* begin MoveCq:R: */ - quickConstant = (((((ssValue(1))->constant)) >> 1)) + adjust; - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, ra1); - } - else { - popToReg(ssValue(1), ra1); - genConvertSmallIntegerToIntegerInReg(ra1); - if (adjust != 0) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AddCqR, adjust, ra1); - } - } - popToReg(ssTop(), ra2); - ssPop(3); - ssPushRegister(ra2); - voidReceiverResultRegContainsSelf(); - immutableJump = genJumpImmutablescratchReg(rr, scratchReg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, ra2, ra1, rr); - - /* Get the old/new boundary in scratchReg */ - jmpImmediate = genJumpImmediate(ra2); - /* begin checkLiteral:forInstruction: */ - storeCheckBoundary(); - anInstruction2 = genoperandoperand(MoveCwR, storeCheckBoundary(), scratchReg); - /* begin CmpR:R: */ - assert(!((scratchReg == SPReg))); - genoperandoperand(CmpRR, scratchReg, rr); - /* begin JumpBelow: */ - jmpDestYoung = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((scratchReg == SPReg))); - genoperandoperand(CmpRR, scratchReg, ra2); - /* begin JumpAboveOrEqual: */ - jmpSourceOld = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - - /* Set the inst var index for the benefit of the immutability check. The trampoline will - repeat the check to choose between the immutbality violation and the store check. */ - jumpRemembered = genIfRequiredCheckRememberedBitOfscratch(rr, scratchReg); - jmpTarget(immutableJump, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin PushR: */ - genoperand(PushR, ra2); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(SubCqR, 1 + adjust, ra1); - genVarIndexCallStoreTrampoline(); - /* begin PopR: */ - genoperand(PopR, ra2); - jmpTarget(jmpImmediate, jmpTarget(jmpDestYoung, jmpTarget(jmpSourceOld, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))); - /* begin setIfRequiredTargetOf:toTargetOf: */ - if (!CheckRememberedInTrampoline) { - jmpTarget(jumpRemembered, ((AbstractInstruction *) (((jmpImmediate->operands))[0]))); - } - return 0; -} - - /* SistaCogit>>#genPointerAtPutImmCheckButNoStoreCheck */ -static sqInt -genPointerAtPutImmCheckButNoStoreCheck(void) -{ - sqInt adjust; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - sqInt i; - AbstractInstruction *immutabilityFailure; - int indexIsCst; - AbstractInstruction *mutableJump; - sqInt quickConstant; - sqInt ra1; - sqInt ra2; - sqInt rr; - - - /* Assumes rr is not a context and no store check is needed */ - indexIsCst = (((ssValue(1))->type)) == SSConstant; - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 3)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 3)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 3))); i <= (simStackPtr - 3); i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 3) + 1; - } - rr = ReceiverResultReg; - ra1 = TempReg; - ra2 = ClassReg; - popToReg(ssValue(2), rr); - - /* shift by baseHeaderSize and then move from 1 relative to zero relative */ - adjust = (((usqInt)(BaseHeaderSize)) >> (shiftForWord())) - 1; - if (indexIsCst) { - /* begin MoveCq:R: */ - quickConstant = (((((ssValue(1))->constant)) >> 1)) + adjust; - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, ra1); - } - else { - popToReg(ssValue(1), ra1); - genConvertSmallIntegerToIntegerInReg(ra1); - if (adjust != 0) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AddCqR, adjust, ra1); - } - } - popToReg(ssTop(), ra2); - ssPop(3); - ssPushRegister(ra2); - voidReceiverResultRegContainsSelf(); - - /* simStack is flushed, but result is not */ - mutableJump = genJumpMutablescratchReg(rr, Arg0Reg); - /* begin PushR: */ - genoperand(PushR, ra2); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(SubCqR, 1 + adjust, ra1); - genVarIndexCallStoreTrampoline(); - /* begin PopR: */ - genoperand(PopR, ra2); - /* begin Jump: */ - immutabilityFailure = genoperand(Jump, ((sqInt)0)); - jmpTarget(mutableJump, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, ra2, ra1, rr); - jmpTarget(immutabilityFailure, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - -/* 150 immCheckPointerAt:put: - pointer object (Fixed sized or not) and not a context, Smi, Anything => - arg2 (1-based, optimised if arg1 is a constant) - 151 immCheckStoreCheckPointerAt:put: - pointer object (Fixed sized or not) and not a context, Smi, Anything => - arg2 (1-based, optimised if arg1 is a constant) - 152 immCheckMaybeContextPointerAt:put: - pointer object (Fixed sized or not), Smi, Anything => arg2 (1-based, - optimised if arg1 is a constant) - 153 immCheckMaybeContextStoreCheckPointerAt:put: - pointer object (Fixed sized or not), Smi, Anything => arg2 (1-based, - optimised if arg1 is a constant) - */ - - /* SistaCogit>>#genPointerAtPutMaybeContext:storeCheck:immutabilityCheck: */ -static sqInt NoDbgRegParms -genPointerAtPutMaybeContextstoreCheckimmutabilityCheck(sqInt maybeContext, sqInt needsStoreCheck, sqInt needsImmCheck) -{ - AbstractInstruction *abstractInstruction; - CogSimStackEntry * index; - - - /* Instruction always annoted - uncommon, IMMUTABILITY disabled. We need a Nop since previous instr can be annotated. */ - index = ssValue(1); -# if IMMUTABILITY -# else - if (needsImmCheck) { - /* begin annotateBytecode: */ - abstractInstruction = gen(Nop); - (abstractInstruction->annotation = HasBytecodePC); - } -# endif // IMMUTABILITY - if (((index->type)) == SSConstant) { - return genPointerAtPutConstantMaybeContextstoreCheckimmutabilityCheck(maybeContext, needsStoreCheck, needsImmCheck); - } - if (maybeContext) { - return EncounteredUnknownBytecode; - } -# if IMMUTABILITY - if (needsImmCheck) { - if (needsStoreCheck) { - return genPointerAtPutImmCheckAndStoreCheck(); - } - else { - return genPointerAtPutImmCheckButNoStoreCheck(); - } - } -# endif // IMMUTABILITY - return genPointerAtPutStoreCheck(needsStoreCheck); -} - - -/* Assumes rr is not a context and no immutability check is needed */ -/* The store check requires rr to be ReceiverResultReg */ - - /* SistaCogit>>#genPointerAtPutStoreCheck: */ -static sqInt NoDbgRegParms -genPointerAtPutStoreCheck(sqInt needsStoreCheck) -{ - sqInt adjust; - AbstractInstruction *anInstruction; - sqInt ra1; - sqInt ra2; - sqInt reg; - sqInt rNext1; - sqInt rr; - sqInt rThird1; - sqInt rTop1; - sqInt topRegistersMask; - - /* begin allocateRegForStackTopThreeEntriesInto:thirdIsReceiver: */ - topRegistersMask = 0; - rTop1 = (rNext1 = (rThird1 = NoReg)); - if (((registerOrNone(ssTop())) != NoReg) - && ((!needsStoreCheck) - || ((registerOrNone(ssTop())) != ReceiverResultReg))) { - /* begin registerMaskFor: */ - reg = (rTop1 = registerOrNone(ssTop())); - topRegistersMask = 1U << reg; - } - if (((registerOrNone(ssValue(1))) != NoReg) - && ((!needsStoreCheck) - || ((registerOrNone(ssValue(1))) != ReceiverResultReg))) { - topRegistersMask = topRegistersMask | (registerMaskFor((rNext1 = registerOrNone(ssValue(1))))); - } - if (((registerOrNone(ssValue(2))) != NoReg) - && ((!needsStoreCheck) - || ((registerOrNone(ssValue(2))) == ReceiverResultReg))) { - topRegistersMask = topRegistersMask | (registerMaskFor((rThird1 = registerOrNone(ssValue(2))))); - } - if (rThird1 == NoReg) { - if (needsStoreCheck) { - - /* Free ReceiverResultReg if it was not free */ - rThird1 = ReceiverResultReg; - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); - voidReceiverResultRegContainsSelf(); - } - else { - rThird1 = allocateRegNotConflictingWith(topRegistersMask); - } - topRegistersMask = topRegistersMask | (1U << rThird1); - } - if (rTop1 == NoReg) { - rTop1 = allocateRegNotConflictingWith(topRegistersMask); - topRegistersMask = topRegistersMask | (1U << rTop1); - } - if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(topRegistersMask); - } - assert(!(((rTop1 == NoReg) - || ((rNext1 == NoReg) - || (rThird1 == NoReg))))); - ra2 = rTop1; - ra1 = rNext1; - rr = rThird1; - assert((rr != ra1) - && ((rr != ra2) - && (ra1 != ra2))); - popToReg(ssTop(), ra2); - ssPop(1); - popToReg(ssTop(), ra1); - ssPop(1); - popToReg(ssTop(), rr); - ssPop(1); - genConvertSmallIntegerToIntegerInReg(ra1); - - /* shift by baseHeaderSize and then move from 1 relative to zero relative */ - adjust = (((usqInt)(BaseHeaderSize)) >> (shiftForWord())) - 1; - if (adjust != 0) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, adjust, ra1); - } - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, ra2, ra1, rr); - if (needsStoreCheck) { - assert(needsFrame); - genStoreCheckReceiverRegvalueRegscratchReginFrame(rr, ra2, TempReg, 1); - } - ssPushRegister(ra2); - return 0; -} - - -/* SistaV1: 248 11111000 iiiiiiii mjjjjjjj Call Primitive #iiiiiiii + - (jjjjjjj * 256) m=1 means inlined primitive, no hard return after - execution. This is the dispatch for unmapped sista inlined primitives. - */ - - /* SistaCogit>>#genSistaInlinePrimitive: */ -static sqInt NoDbgRegParms -genSistaInlinePrimitive(sqInt prim) -{ - if (prim < 1000) { - /* begin genNullaryInlinePrimitive: */ - return EncounteredUnknownBytecode; - } - if (prim < 2000) { - return genUnaryInlinePrimitive(prim - 1000); - } - if (prim < 3000) { - return genBinaryInlinePrimitive(prim - 2000); - } - if (prim < 4000) { - return genTrinaryInlinePrimitive(prim - 3000); - } - if (prim < 5000) { - /* begin genQuaternaryInlinePrimitive: */ - return EncounteredUnknownBytecode; - } - if (prim < 6000) { - /* begin genQuinaryInlinePrimitive: */ - return EncounteredUnknownBytecode; - } - if (prim < 7000) { - return genJumpUnaryInlinePrimitive(prim - 6000); - } - if (prim < 8000) { - return genJumpBinaryInlinePrimitive(prim - 7000); - } - return genJumpTrinaryInlinePrimitive(prim - 8000); -} - - -/* Override to count inlined branches if followed by a conditional branch. - We borrow the following conditional branch's counter and when about to - inline the comparison we decrement the counter (without writing it back) - and if it trips simply abort the inlining, falling back to the normal send - which will then continue to the conditional branch which will trip and - enter the abort. */ - - /* SistaCogit>>#genSpecialSelectorComparison */ -static sqInt -genSpecialSelectorComparison(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - sqInt argInt; - sqInt argIsIntConst; - BytecodeDescriptor *branchDescriptor; - BytecodeDescriptor *branchDescriptor1; - sqInt counterAddress; - sqInt counterAddress1; - sqInt counterReg; - AbstractInstruction *countTripped; - AbstractInstruction *countTripped1; - sqInt i; - sqInt index; - sqInt inlineCAB; - AbstractInstruction *jumpNotSmallInts; - void *jumpTarget; - sqInt nExts; - sqInt nextPC; - sqInt nextPC1; - sqInt opcode; - sqInt opcode1; - sqInt opcode2; - sqInt postBranchPC; - sqInt postBranchPC1; - BytecodeDescriptor *primDescriptor; - BytecodeDescriptor *primDescriptor1; - int rcvrIsConst; - sqInt rcvrIsInt; - sqInt targetBytecodePC; - sqInt targetPC; - - if (isOptimizedMethod(methodObj)) { - return genSpecialSelectorComparisonWithoutCounters(); - } - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 2)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 2)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 2))); i <= (simStackPtr - 2); i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 2) + 1; - } - primDescriptor = generatorAt(byte0); - argIsIntConst = ((((ssTop())->type)) == SSConstant) - && ((((argInt = ((ssTop())->constant))) & 1)); - - /* short-cut the jump if operands are SmallInteger constants. */ - rcvrIsInt = (((rcvrIsConst = (((ssValue(1))->type)) == SSConstant)) - && (((((ssValue(1))->constant)) & 1))) - || ((mclassIsSmallInteger()) - && (isSameEntryAs(ssValue(1), simSelf()))); - if (argIsIntConst - && (rcvrIsInt - && (rcvrIsConst))) { - return genStaticallyResolvedSpecialSelectorComparison(); - } - /* begin extractMaybeBranchDescriptorInto: */ - primDescriptor1 = generatorAt(byte0); - nextPC1 = bytecodePC + ((primDescriptor1->numBytes)); - nExts = 0; - while (1) { - while (1) { - /* begin generatorForPC: */ - branchDescriptor1 = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC1, methodObj))); - if (!((branchDescriptor1->isExtension))) break; - nExts += 1; - nextPC1 += (branchDescriptor1->numBytes); - } - /* begin isUnconditionalBranch */ - if (!((isBranch(branchDescriptor1)) - && (!(((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse)))))) break; - nextPC1 = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - } - targetBytecodePC = (postBranchPC1 = 0); - if (((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse))) { - targetBytecodePC = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - postBranchPC1 = eventualTargetOf(nextPC1 + ((branchDescriptor1->numBytes))); - } - else { - nextPC1 = bytecodePC + ((primDescriptor1->numBytes)); - } - branchDescriptor = branchDescriptor1; - nextPC = nextPC1; - postBranchPC = postBranchPC1; - targetPC = targetBytecodePC; - - /* Further, only interested in inlining = and ~= if there's a SmallInteger constant involved. - The relational operators successfully statically predict SmallIntegers; the equality operators do not. */ - inlineCAB = ((branchDescriptor->isBranchTrue)) - || ((branchDescriptor->isBranchFalse)); - if (inlineCAB - && ((((primDescriptor->opcode)) == JumpZero) - || (((primDescriptor->opcode)) == JumpNonZero))) { - inlineCAB = argIsIntConst - || (rcvrIsInt); - } - if (!inlineCAB) { - return genSpecialSelectorSend(); - } - if (argIsIntConst) { - popToReg(ssValue(1), ReceiverResultReg); - ssPop(2); - } - else { - marshallSendArguments(1); - } - jumpNotSmallInts = (!(rcvrIsInt - && (argIsIntConst)) - ? (argIsIntConst - ? genJumpNotSmallInteger(ReceiverResultReg) - : (rcvrIsInt - ? genJumpNotSmallInteger(Arg0Reg) - : (/* begin genJumpNotSmallIntegersIn:and:scratch: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg), - /* begin AndR:R: */ - genoperandoperand(AndRR, Arg0Reg, TempReg), - genJumpNotSmallIntegerInScratchReg(TempReg)))) - : 0); - counterReg = allocateRegNotConflictingWith((1U << ReceiverResultReg) | (1U << Arg0Reg)); - /* begin genExecutionCountLogicInto:counterReg: */ - counterAddress1 = counters + (CounterBytes * counterIndex); - /* begin gen:literal:operand: */ - opcode = MoveAwR; - /* begin checkLiteral:forInstruction: */ - anInstruction3 = genoperandoperand(opcode, counterAddress1, counterReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperand(SubCqR, 0x10000, counterReg); - /* begin JumpCarry: */ - countTripped1 = genConditionalBranchoperand(JumpCarry, ((sqInt)0)); - /* begin gen:operand:literal: */ - opcode1 = MoveRAw; - /* begin checkLiteral:forInstruction: */ - anInstruction2 = genoperandoperand(opcode1, counterReg, counterAddress1); - counterAddress = counterAddress1; - countTripped = countTripped1; - if (argIsIntConst) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, argInt, ReceiverResultReg); - } - else { - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, ReceiverResultReg); - } - genConditionalBranchoperand(((branchDescriptor->isBranchTrue) - ? (primDescriptor->opcode) - : inverseBranchFor((primDescriptor->opcode))), ((usqInt)(ensureNonMergeFixupAt(targetPC)))); - /* begin genFallsThroughCountLogicCounterReg:counterAddress: */ - anInstruction4 = genoperandoperand(SubCqR, 1, counterReg); - /* begin gen:operand:literal: */ - opcode2 = MoveRAw; - /* begin checkLiteral:forInstruction: */ - anInstruction12 = genoperandoperand(opcode2, counterReg, counterAddress); - /* begin Jump: */ - jumpTarget = ensureNonMergeFixupAt(postBranchPC); - genoperand(Jump, ((sqInt)jumpTarget)); - jmpTarget(countTripped, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (jumpNotSmallInts == null) { - if ((((fixupAt(nextPC))->targetInstruction)) == 0) { - branchReachedOnlyForCounterTrip = 1; - } - } - else { - jmpTarget(jumpNotSmallInts, ((AbstractInstruction *) (((countTripped->operands))[0]))); - } - if (argIsIntConst) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, argInt, Arg0Reg); - } - index = byte0 - ( -#if MULTIPLEBYTECODESETS - (bytecodeSetOffset == 0x100 - ? AltFirstSpecialSelector + 0x100 - : FirstSpecialSelector) -#else - FirstSpecialSelector -#endif - ); - return genMarshalledSendnumArgssendTable((-index) - 1, 1, ordinarySendTrampolines); -} - - -/* This method is there because if I put directly the super send in - genSpecialSelectorComparison Slang does not correctly translte the code to - C, it does not correctly type one of the branchDescriptor to - BytecodeDescriptor - */ - - /* SistaCogit>>#genSpecialSelectorComparisonWithoutCounters */ -static sqInt -genSpecialSelectorComparisonWithoutCounters(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt argInt; - sqInt argIsIntConst; - BytecodeDescriptor *branchDescriptor; - BytecodeDescriptor *branchDescriptor1; - sqInt i; - sqInt index; - sqInt inlineCAB; - AbstractInstruction *jumpNotSmallInts; - void *jumpTarget; - sqInt nExts; - sqInt nextPC; - sqInt nextPC1; - sqInt postBranchPC; - sqInt postBranchPC1; - BytecodeDescriptor *primDescriptor; - BytecodeDescriptor *primDescriptor1; - int rcvrIsConst; - sqInt rcvrIsInt; - sqInt targetBytecodePC; - sqInt targetPC; - - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 2)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 2)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 2))); i <= (simStackPtr - 2); i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 2) + 1; - } - primDescriptor = generatorAt(byte0); - argIsIntConst = ((((ssTop())->type)) == SSConstant) - && ((((argInt = ((ssTop())->constant))) & 1)); - rcvrIsInt = (((rcvrIsConst = (((ssValue(1))->type)) == SSConstant)) - && (((((ssValue(1))->constant)) & 1))) - || ((mclassIsSmallInteger()) - && (isSameEntryAs(ssValue(1), simSelf()))); - if (argIsIntConst - && (rcvrIsInt - && (rcvrIsConst))) { - return genStaticallyResolvedSpecialSelectorComparison(); - } - /* begin extractMaybeBranchDescriptorInto: */ - primDescriptor1 = generatorAt(byte0); - nextPC1 = bytecodePC + ((primDescriptor1->numBytes)); - nExts = 0; - while (1) { - while (1) { - /* begin generatorForPC: */ - branchDescriptor1 = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC1, methodObj))); - if (!((branchDescriptor1->isExtension))) break; - nExts += 1; - nextPC1 += (branchDescriptor1->numBytes); - } - /* begin isUnconditionalBranch */ - if (!((isBranch(branchDescriptor1)) - && (!(((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse)))))) break; - nextPC1 = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - } - targetBytecodePC = (postBranchPC1 = 0); - if (((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse))) { - targetBytecodePC = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - postBranchPC1 = eventualTargetOf(nextPC1 + ((branchDescriptor1->numBytes))); - } - else { - nextPC1 = bytecodePC + ((primDescriptor1->numBytes)); - } - branchDescriptor = branchDescriptor1; - nextPC = nextPC1; - postBranchPC = postBranchPC1; - targetPC = targetBytecodePC; - - /* Further, only interested in inlining = and ~= if there's a SmallInteger constant involved. - The relational operators successfully statically predict SmallIntegers; the equality operators do not. */ - inlineCAB = ((branchDescriptor->isBranchTrue)) - || ((branchDescriptor->isBranchFalse)); - if (inlineCAB - && ((((primDescriptor->opcode)) == JumpZero) - || (((primDescriptor->opcode)) == JumpNonZero))) { - inlineCAB = argIsIntConst - || (rcvrIsInt); - } - if (!inlineCAB) { - return genSpecialSelectorSend(); - } - if (argIsIntConst) { - popToReg(ssValue(1), ReceiverResultReg); - ssPop(2); - } - else { - marshallSendArguments(1); - } - jumpNotSmallInts = (!(rcvrIsInt - && (argIsIntConst)) - ? (argIsIntConst - ? genJumpNotSmallInteger(ReceiverResultReg) - : (rcvrIsInt - ? genJumpNotSmallInteger(Arg0Reg) - : (/* begin genJumpNotSmallIntegersIn:and:scratch: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg), - /* begin AndR:R: */ - genoperandoperand(AndRR, Arg0Reg, TempReg), - genJumpNotSmallIntegerInScratchReg(TempReg)))) - : 0); - if (argIsIntConst) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, argInt, ReceiverResultReg); - } - else { - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, ReceiverResultReg); - } - genConditionalBranchoperand(((branchDescriptor->isBranchTrue) - ? (primDescriptor->opcode) - : inverseBranchFor((primDescriptor->opcode))), ((usqInt)(ensureNonMergeFixupAt(targetPC)))); - /* begin Jump: */ - jumpTarget = ensureNonMergeFixupAt(postBranchPC); - genoperand(Jump, ((sqInt)jumpTarget)); - if (!jumpNotSmallInts) { - /* begin annotateInstructionForBytecode */ - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (abstractInstruction->annotation = HasBytecodePC); - ensureFixupAt(postBranchPC); - ensureFixupAt(targetPC); - deadCode = 1; - return 0; - } - jmpTarget(jumpNotSmallInts, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (argIsIntConst) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, argInt, Arg0Reg); - } - index = byte0 - ( -#if MULTIPLEBYTECODESETS - (bytecodeSetOffset == 0x100 - ? AltFirstSpecialSelector + 0x100 - : FirstSpecialSelector) -#else - FirstSpecialSelector -#endif - ); - return genMarshalledSendnumArgssendTable((-index) - 1, 1, ordinarySendTrampolines); -} - - -/* Bulk comment, each sub method has its own comment - 3000 pointerAt:put: - Mutable pointer object (Fixed sized or not) and not a context, Smi, - Anything => arg2 (1-based, optimised if arg1 is a constant) - 3001 storeCheckPointerAt:put: - Mutable pointer object (Fixed sized or not) and not a context, Smi, - Anything => arg2 (1-based, optimised if arg1 is a constant) - 3002 maybeContextPointerAt:put: - Mutable pointer object (Fixed sized or not), Smi, Anything => arg2 - (1-based, optimised if arg1 is a constant) - 3003 maybeContextStoreCheckPointerAt:put: - Mutable pointer object (Fixed sized or not), Smi, Anything => arg2 - (1-based, optimised if arg1 is a constant) - 3004 byteAt:put: - Mutable byte object, Smi, 8 bits unsigned Smi => arg2 (1-based, optimised - if arg1 is a constant) - 3005 shortAt:put: - Mutable short object, Smi, 16 bits unsigned Smi => arg2 (1-based, - optimised if arg1 is a constant) - 3006 wordAt:put: - Mutable word object, Smi, 32 bits unsigned Smi => arg2 (1-based, optimised - if arg1 is a constant) - 3007 doubleWordAt:put: - Mutable double word object, Smi, 64 bits unsigned Smi or - LargePositiveInteger => arg2 (1-based, optimised if arg1 is a constant) - 3021 is deprecated. - */ - - /* SistaCogit>>#genTrinaryInlinePrimitive: */ -static sqInt NoDbgRegParms -genTrinaryInlinePrimitive(sqInt prim) -{ - if (prim <= 7) { - return genAtPutInlinePrimitive(prim); - } - if (prim == 21) { - return genByteEqualsInlinePrimitive(prim); - } - return EncounteredUnknownBytecode; -} - - -/* 1000 rawClass - not a forwarder => Behavior (Same as class special send, but receiver is - not a forwarder) - */ -/* Important performance note: - In Scorch, typically a value is known as not being a forwarder if there is - a trap. - If the trap is due to a monomorphic send, the #class send leads to: - trapIf: X notInstanceOf: C - X rawClass - therefore X rawClass is simplified in Scorch to the cst:C - The rawClass is therefore used only for PICs. - trapIf: X notInstanceOf: C, C', C'' - X rawClass - This unsafe operation is important to avoid register flush, but the - performance - difference in differencing rawClass for immediate and rawClass for non - immediate - classes is not that relevant */ - - /* SistaCogit>>#genUnaryClassPrimitive */ -static sqInt -genUnaryClassPrimitive(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - sqInt destReg; - AbstractInstruction *jumpIsImm; - sqInt topReg; - - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - destReg = allocateRegNotConflictingWith(1U << topReg); - popToReg(ssTop(), topReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, topReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, tagMask(), TempReg); - /* begin JumpNonZero: */ - jumpIsImm = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - flag("endianness"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, 0, topReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - classIndexMask(); - anInstruction2 = genoperandoperand(AndCqR, classIndexMask(), TempReg); - jmpTarget(jumpIsImm, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genGetClassObjectOfClassIndexintoscratchReg(TempReg, destReg, topReg); - ssPop(1); - return ssPushRegister(destReg); -} - - /* SistaCogit>>#genUnaryConvertInlinePrimitive: */ -static sqInt NoDbgRegParms -genUnaryConvertInlinePrimitive(sqInt primIndex) -{ - sqInt resultReg; - - assert(((primIndex >= 30) && (primIndex <= 32))); - switch (primIndex) { - case 30: - resultReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - popToReg(ssTop(), resultReg); - genConvertCharacterToSmallIntegerInReg(resultReg); - break; - case 0x1F: - return EncounteredUnknownBytecode; - - case 32: - resultReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - popToReg(ssTop(), resultReg); - assert(processorHasDoublePrecisionFloatingPointSupport()); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, resultReg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - /* begin ConvertR:Rd: */ - genoperandoperand(ConvertRRd, TempReg, DPFPReg0); - flag("TODO"); - genAllocFloatValueintoscratchRegscratchReg(DPFPReg0, resultReg, TempReg, NoReg); - break; - default: - error("Case not found and no otherwise clause"); - } - ssPop(1); - return ssPushRegister(resultReg); -} - - /* SistaCogit>>#genUnaryHashInlinePrimitive: */ -static sqInt NoDbgRegParms -genUnaryHashInlinePrimitive(sqInt primIndex) -{ - sqInt rcvrReg; - sqInt resultReg; - - assert(((primIndex >= 20) && (primIndex <= 23))); - switch (primIndex) { - case 20: - rcvrReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - resultReg = allocateRegNotConflictingWith(1U << rcvrReg); - popToReg(ssTop(), rcvrReg); - genGetIdentityHashresultReg(rcvrReg, resultReg); - break; - case 21: - resultReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - popToReg(ssTop(), resultReg); - break; - case 22: - resultReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - popToReg(ssTop(), resultReg); - genConvertCharacterToSmallIntegerInReg(resultReg); - break; - case 23: - resultReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - /* begin genConvertSmallFloatToSmallFloatHashAsIntegerInReg:scratch: */ - break; - case 24: - return EncounteredUnknownBytecode; - - default: - error("Case not found and no otherwise clause"); - } - ssPop(1); - return ssPushRegister(resultReg); -} - - -/* Bulk comments: each sub-method has its own comment with the specific case. - 1000 rawClass - not a forwarder => Behavior (Same as class special send, but receiver is - not a forwarder) - 1001 numSlots - pointer object => Smi between 0 and SmallInteger maxVal // 4 - 1 (Answers - total size in pointer-sized slots) - 1002 numBytes - byte object => Smi between 0 and SmallInteger maxVal - 9 (Includes - compiled code) - 1003 numShorts - short object => Smi between 0 and SmallInteger maxVal - 9 - 1004 numWords - word object => Smi between 0 and SmallInteger maxVal - 9 - 1005 numDoubleWords - double word object => Smi between 0 and SmallInteger maxVal - 9 - 1011 RawNew - literal which is a fixed-sized behavior => instance of the receiver with - fields nilled out - 1012 RawNewNoInit - literal which is a fixed-sized behavior => instance of the receiver - (Fields of returned value contain undefined data) - 1020 objectIdentityHash - non-immediate and non-behavior => 22 bits strictly positive Smi - 1021 smiIdentityHash - Smi => Smi - 1022 charIdentityHash - Character => 22 bits strictly positive Smi - 1023 smallfloatIdentityHash - SmallFloat => Smi - 1024 behaviorIdentityHash - Behavior => 22 bits strictly positive Smi - 1030 characterAsInteger - Character => 22 bits strictly positive Smi (Unicode) - 1031 smallFloatAsInteger - SmallFloat => Smi - 1032 smiAsFloat - Smi => SmallFloat - 1040 unforward - Anything => Not a forwarder - 1041 possibleRoot - non-immediate, not a forwarder => receiver is returned (should be - effect-only) (If old, becomes gray and remembered to allow many unchecked - stores in a row afterwards) - */ - - /* SistaCogit>>#genUnaryInlinePrimitive: */ -static sqInt NoDbgRegParms -genUnaryInlinePrimitive(sqInt primIndex) -{ - if (primIndex == 0) { - return genUnaryClassPrimitive(); - } - if (primIndex <= 6) { - return genUnarySizeInlinePrimitive(primIndex); - } - if (primIndex < 11) { - return EncounteredUnknownBytecode; - } - if (primIndex <= 12) { - return genUnaryNewInlinePrimitive(primIndex); - } - if (primIndex < 20) { - return EncounteredUnknownBytecode; - } - if (primIndex <= 24) { - return genUnaryHashInlinePrimitive(primIndex); - } - if (primIndex < 30) { - return EncounteredUnknownBytecode; - } - if (primIndex <= 32) { - return genUnaryConvertInlinePrimitive(primIndex); - } - if (primIndex == 39) { - return genUnaryUnforwardNonImmediateInlinePrimitive(); - } - if (primIndex == 40) { - return genUnaryUnforwardInlinePrimitive(); - } - if (primIndex == 41) { - return genUnaryPossibleRootInlinePrimitive(); - } - return EncounteredUnknownBytecode; -} - - -/* 1011 RawNew - literal which is a fixed-sized behavior => instance of the receiver with - fields nilled out - 1012 RawNewNoInit - literal which is a fixed-sized behavior => instance of the receiver - (Fields of returned value contain undefined data) - */ - - /* SistaCogit>>#genUnaryNewInlinePrimitive: */ -static sqInt NoDbgRegParms -genUnaryNewInlinePrimitive(sqInt primIndex) -{ - sqInt classObj; - sqInt resultReg; - - assert((((ssTop())->type)) == SSConstant); - classObj = ((ssTop())->constant); - assert(isNonImmediate(classObj)); - assert(objCouldBeClassObj(classObj)); - assert(isFixedSizePointerFormat(instSpecOfClassFormat(formatOfClass(classObj)))); - classTagForClass(classObj); - resultReg = allocateRegNotConflictingWith(0); - genGetInstanceOfPointerClassintoinitializingIfnumVariableSlots(classObj, resultReg, primIndex == 11, 0); - ssPop(1); - return ssPushRegister(resultReg); -} - - -/* 1041 possibleRoot - non-immediate, not a forwarder => receiver is returned (should be - effect-only) (If old, becomes gray and remembered to allow many unchecked - stores in a row afterwards) - */ - - /* SistaCogit>>#genUnaryPossibleRootInlinePrimitive */ -static sqInt -genUnaryPossibleRootInlinePrimitive(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *jmpAlreadyRemembered; - AbstractInstruction *jmpDestYoung; - sqInt topReg; - - jmpAlreadyRemembered = ((AbstractInstruction *) 0); - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - popToReg(ssTop(), topReg); - /* begin checkLiteral:forInstruction: */ - storeCheckBoundary(); - anInstruction = genoperandoperand(MoveCwR, storeCheckBoundary(), TempReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, topReg); - /* begin JumpBelow: */ - jmpDestYoung = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - if (!CheckRememberedInTrampoline) { - jmpAlreadyRemembered = genCheckRememberedBitOfscratch(topReg, TempReg); - } - callStoreCheckTrampoline(); - jmpTarget(jmpDestYoung, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (!CheckRememberedInTrampoline) { - jmpTarget(jmpAlreadyRemembered, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - ssPop(1); - return ssPushRegister(topReg); -} - - /* SistaCogit>>#genUnarySizeInlinePrimitive: */ -static sqInt NoDbgRegParms -genUnarySizeInlinePrimitive(sqInt primIndex) -{ - sqInt rcvrReg; - sqInt resultReg; - - assert(((primIndex >= 1) && (primIndex <= 6))); - rcvrReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - resultReg = allocateRegNotConflictingWith(1U << rcvrReg); - popToReg(ssTop(), rcvrReg); - ssPop(1); - ssPushRegister(resultReg); - switch (primIndex) { - case 1: - genGetNumSlotsOfinto(rcvrReg, resultReg); - genConvertIntegerToSmallIntegerInReg(resultReg); - break; - case 2: - genGetNumBytesOfinto(rcvrReg, resultReg); - genConvertIntegerToSmallIntegerInReg(resultReg); - break; - case 3: - case 5: - case 6: - return EncounteredUnknownBytecode; - - default: - error("Case not found and no otherwise clause"); - } - return 0; -} - - -/* 1040 unforward - Anything => Not a forwarder */ - - /* SistaCogit>>#genUnaryUnforwardInlinePrimitive */ -static sqInt -genUnaryUnforwardInlinePrimitive(void) -{ - sqInt topReg; - - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - popToReg(ssTop(), topReg); - genEnsureOopInRegNotForwardedscratchReg(topReg, TempReg); - ssPop(1); - return ssPushRegister(topReg); -} - - -/* 1039 unforwardNonImmediate - non immediate => Not a forwarder */ -/* unforwardNonImmediate was used exclusively for literal variables, - which are now never forwarders because we scan the zone in postBecome, - so this is effectively a noop. */ - - /* SistaCogit>>#genUnaryUnforwardNonImmediateInlinePrimitive */ -static sqInt -genUnaryUnforwardNonImmediateInlinePrimitive(void) -{ - sqInt topReg; - - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 0); - popToReg(ssTop(), topReg); - ssPop(1); - return ssPushRegister(topReg); -} - - -/* SistaV1: * 217 Trap */ - - /* SistaCogit>>#genUnconditionalTrapBytecode */ -static sqInt -genUnconditionalTrapBytecode(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - sqInt i; - - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceTrapTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin annotateBytecode: */ - abstractInstruction1 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction1->annotation = HasBytecodePC); - deadCode = 1; - return 0; -} - - /* SistaCogit>>#getJumpTargetPCAt: */ -usqInt -getJumpTargetPCAt(sqInt pc) -{ - return jumpTargetPCAt(backEnd, pc); -} - - /* SistaCogit>>#initializeCodeZoneFrom:upTo: */ -void -initializeCodeZoneFromupTo(sqInt startAddress, sqInt endAddress) -{ - sqInt fixupSize2; - sqInt numberOfAbstractOpcodes2; - sqInt opcodeSize2; - usqInt startAddress2; - - initialCounterValue = MaxCounterValue; - initializeBackend(); - sqMakeMemoryExecutableFromToCodeToDataDelta(startAddress, endAddress, -# if DUAL_MAPPED_CODE_ZONE - (&codeToDataDelta) -# else - null -# endif - ); - stopsFromto(backEnd, startAddress, endAddress - 1); - codeBase = (methodZoneBase = startAddress); - minValidCallAddress = (((((codeBase < (interpretAddress())) ? codeBase : (interpretAddress()))) < (primitiveFailAddress())) ? (((codeBase < (interpretAddress())) ? codeBase : (interpretAddress()))) : (primitiveFailAddress())); - /* begin manageFrom:to: */ - mzFreeStart = (baseAddress = methodZoneBase); - youngReferrers = (limitAddress = endAddress); - openPICList = null; - methodBytesFreedSinceLastCompaction = 0; - methodCount = 0; - /* begin computeAllocationThreshold */ - allocationThreshold = ((((((usqInt)((limitAddress - baseAddress) * thresholdRatio))) + (7)) & ~7)) + baseAddress; - assertValidDualZone(); - /* begin maybeGenerateCacheFlush */ - /* begin generateVMOwnerLockFunctions */ -# if COGMTVM - /* begin allocateOpcodes:bytecodes: */ - numberOfAbstractOpcodes2 = numLowLevelLockOpcodes(backEnd); - numAbstractOpcodes = numberOfAbstractOpcodes2; - opcodeSize2 = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize2 = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize2 + fixupSize2); - bzero(abstractOpcodes, opcodeSize2 + fixupSize2); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize2)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - zeroOpcodeIndex(); - startAddress2 = methodZoneBase; - generateLowLevelTryLock(backEnd, vmOwnerAddress()); - outputInstructionsForGeneratedRuntimeAt(startAddress2); - recordGeneratedRunTimeaddress("ceTryLockVMOwner", startAddress2); - ceTryLockVMOwner = ((usqIntptr_t (*)(usqIntptr_t)) startAddress2); -# endif // COGMTVM - genGetLeafCallStackPointers(); - generateStackPointerCapture(); - generateTrampolines(); - computeEntryOffsets(); - computeFullBlockEntryOffsets(); - generateClosedPICPrototype(); - alignMethodZoneBase(); - flushICacheFromto(backEnd, startAddress, ((usqInt)methodZoneBase)); - /* begin maybeFlushWritableZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - if (codeToDataDelta > 0) { - flushDCacheFromto(backEnd, startAddress, ((usqInt)methodZoneBase)); - } -# endif - /* begin manageFrom:to: */ - mzFreeStart = (baseAddress = methodZoneBase); - youngReferrers = (limitAddress = endAddress); - openPICList = null; - methodBytesFreedSinceLastCompaction = 0; - methodCount = 0; - /* begin computeAllocationThreshold */ - allocationThreshold = ((((((usqInt)((limitAddress - baseAddress) * thresholdRatio))) + (7)) & ~7)) + baseAddress; - generateOpenPICPrototype(); -} - - /* SistaCogit>>#maybeAllocAndInitCounters */ -static sqInt -maybeAllocAndInitCounters(void) -{ - sqInt objOop; - - assert(counters == 0); - counterIndex = 0; - if (numCounters == 0) { - return 1; - } - /* begin allocateCounters: */ - objOop = allocatePinnedSlots(numCounters); - counters = ((sqInt) ((objOop == null - ? 0 - : objOop + BaseHeaderSize))); - return counters != 0; -} - - -/* Mapped: 250 backjumpAlwaysInterrupt - Unmapped: 6000 backjumpNoInterrupt - 7016-7020 jumpWritable/Young - 8000-8003 type branches - In all cases the distance is an integer pushed on stack just before with - pushIntegerLong: */ - - /* SistaCogit>>#maybeDealWithUnsafeJumpForDescriptor:pc:latestContinuation: */ -static sqInt NoDbgRegParms -maybeDealWithUnsafeJumpForDescriptorpclatestContinuation(BytecodeDescriptor *descriptor, sqInt pc, sqInt latestContinuation) -{ - sqInt byte01; - sqInt byte02; - sqInt distance; - sqInt distance1; - BytecodeFixup * fixup; - BytecodeFixup * fixup1; - sqInt newContinuation; - sqInt prim; - sqInt targetPC; - sqInt upperByte; - - newContinuation = latestContinuation; - if ((descriptor->hasUnsafeJump)) { - byte01 = fetchByteofObject(pc + 1, methodObj); - byte02 = fetchByteofObject(pc + 2, methodObj); - /* begin decodePushIntegerLongBefore:in: */ - distance1 = fetchByteofObject(pc - 1, methodObj); - upperByte = fetchByteofObject(pc - 3, methodObj); - if (upperByte > 0x7F) { - upperByte -= 0x100; - } - distance = (((sqInt)((usqInt)(upperByte) << 8))) + distance1; - targetPC = (pc + ((descriptor->numBytes))) + distance; - if ((descriptor->isMapped)) { - if (byte01 == 250) { - - /* mapped always interrupt backjump */ - /* begin initializeFixupAt: */ - fixup = fixupAtIndex(targetPC - initialPC); - /* begin initializeFixup: */ - (fixup->targetInstruction) = ((AbstractInstruction *) NeedsMergeFixupFlag); - /* begin setIsBackwardBranchFixup */ - (fixup->isTargetOfBackwardBranch) = 1; - } - } - else { - if ((((usqInt)(byte02)) >> 5) == 4) { - - /* inlined sista primitive */ - prim = (((sqInt)((usqInt)((byte02 & 0x1F)) << 8))) + byte01; - if (prim >= 7000) { - - /* branch forward */ - newContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - else { - if (prim >= 6000) { - - /* no interrupt back jump */ - /* begin initializeFixupAt: */ - fixup1 = fixupAtIndex(targetPC - initialPC); - /* begin initializeFixup: */ - (fixup1->targetInstruction) = ((AbstractInstruction *) NeedsMergeFixupFlag); - /* begin setIsBackwardBranchFixup */ - (fixup1->isTargetOfBackwardBranch) = 1; - } - } - } - } - } - return newContinuation; -} - - -/* Collect the branch and send data for the block method starting at - blockEntryMcpc, storing it into picData. - */ - - /* SistaCogit>>#picDataForBlockEntry:Method: */ -static usqInt NoDbgRegParms -picDataForBlockEntryMethod(sqInt blockEntryMcpc, sqInt cogMethod) -{ - sqInt aMethodHeader; - sqInt aMethodHeader1; - sqInt aMethodObj; - sqInt annotation; - sqInt bcpc; - sqInt bsOffset; - sqInt byte; - sqInt byte01; - sqInt byte02; - CogBlockMethod *cogBlockMethod; - BytecodeDescriptor *descriptor; - sqInt distance; - sqInt distance1; - sqInt distance2; - sqInt endbcpc; - CogMethod *homeMethod; - sqInt isBackwardBranch; - sqInt isInBlock; - sqInt latestContinuation; - usqInt map; - sqInt mapByte; - usqInt mcpc; - sqInt nExts; - sqInt newContinuation; - sqInt nextBcpc; - sqInt prim; - sqInt result; - sqInt startbcpc; - sqInt targetPC; - sqInt targetPC1; - sqInt upperByte; - - latestContinuation = 0; - cogBlockMethod = ((CogBlockMethod *) (blockEntryMcpc - (sizeof(CogBlockMethod)))); - if (((cogBlockMethod->stackCheckOffset)) == 0) { - return 0; - } - /* begin mapFor:bcpc:performUntil:arg: */ - startbcpc = (cogBlockMethod->startpc); - assert(((cogBlockMethod->stackCheckOffset)) > 0); - - /* The stack check maps to the start of the first bytecode, - the first bytecode being effectively after frame build. */ - mcpc = (((usqInt)cogBlockMethod)) + ((cogBlockMethod->stackCheckOffset)); - result = picDataForAnnotationMcpcBcpcMethod(null, (0 + (((int)((usqInt)(HasBytecodePC) << 1)))), (((char *) mcpc)), startbcpc, (((void *)cogMethod))); - if (result != 0) { - return result; - } - - /* In both CMMethod and CMBlock cases find the start of the map and - skip forward to the bytecode pc map entry for the stack check. */ - bcpc = startbcpc; - if (((cogBlockMethod->cmType)) == CMMethod) { - /* begin cmIsFullBlock */ - isInBlock = (cogBlockMethod->cpicHasMNUCaseOrCMIsFullBlock); - homeMethod = ((CogMethod *) cogBlockMethod); - assert(startbcpc == (startPCOfMethodHeader((homeMethod->methodHeader)))); - map = ((((usqInt)homeMethod)) + ((homeMethod->blockSize))) - 1; - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert((annotation == IsAbsPCReference) - || ((annotation == IsObjectReference) - || ((annotation == IsRelativeCall) - || (annotation == IsDisplacementX2N)))); - latestContinuation = startbcpc; - aMethodObj = (homeMethod->methodObject); - endbcpc = (numBytesOf(aMethodObj)) - 1; - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader) - ? 0x100 - : 0) -# else - 0 -# endif - ; - bcpc += deltaToSkipPrimAndErrorStoreInheader(aMethodObj, (homeMethod->methodHeader)); - } - else { - isInBlock = 1; - assert(bcpc == ((cogBlockMethod->startpc))); - homeMethod = cmHomeMethod(cogBlockMethod); - map = findMapLocationForMcpcinMethod((((usqInt)cogBlockMethod)) + (sizeof(CogBlockMethod)), homeMethod); - assert(map != 0); - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert(((((usqInt)(annotation)) >> AnnotationShift) == HasBytecodePC) - || ((((usqInt)(annotation)) >> AnnotationShift) == IsDisplacementX2N)); - while (((annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift)) != HasBytecodePC) { - map -= 1; - } - - /* skip fiducial; i.e. the map entry for the pc immediately following the method header. */ - map -= 1; - aMethodObj = (homeMethod->methodObject); - bcpc = startbcpc - ( -#if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet((homeMethod->methodHeader)) - ? AltBlockCreationBytecodeSize - : BlockCreationBytecodeSize) -#else // MULTIPLEBYTECODESETS - BlockCreationBytecodeSize -#endif - ); - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader1 = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader1) - ? 0x100 - : 0) -# else - 0 -# endif - ; - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - endbcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, -1, aMethodObj)) - : 0)); - bcpc = startbcpc; - } - nExts = 0; - while ((((usqInt)((byteAt(map)))) >> AnnotationShift) != HasBytecodePC) { - map -= 1; - } - map -= 1; - while (((mapByte = byteAt(map))) != MapEnd) { - - /* defensive; we exit on bcpc */ - if (mapByte >= FirstAnnotation) { - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if (annotation >= HasBytecodePC) { - if ((annotation == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - while (1) { - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - if (isInBlock) { - if (bcpc >= endbcpc) { - return 0; - } - } - else { - if (((descriptor->isReturn)) - && (bcpc >= latestContinuation)) { - return 0; - } - if ((isBranch(descriptor)) - || ((descriptor->isBlockCreation))) { - /* begin latestContinuationPCFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj); - targetPC = (bcpc + ((descriptor->numBytes))) + (((distance < 0) ? 0 : distance)); - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - /* begin maybeUnsafeJumpContinuation:at:for:in: */ - newContinuation = latestContinuation; - if ((descriptor->hasUnsafeJump)) { - byte01 = fetchByteofObject(bcpc + 1, aMethodObj); - - /* pushIntegerLong */ - byte02 = fetchByteofObject(bcpc + 2, aMethodObj); - /* begin decodePushIntegerLongBefore:in: */ - distance1 = fetchByteofObject(bcpc - 1, methodObj); - upperByte = fetchByteofObject(bcpc - 3, methodObj); - if (upperByte > 0x7F) { - upperByte -= 0x100; - } - distance2 = (((sqInt)((usqInt)(upperByte) << 8))) + distance1; - targetPC1 = (bcpc + ((descriptor->numBytes))) + distance2; - if (!((descriptor->isMapped))) { - if ((((usqInt)(byte02)) >> 5) == 4) { - - /* inlined sista primitive */ - prim = (((sqInt)((usqInt)((byte02 & 0x1F)) << 8))) + byte01; - if (prim >= 7000) { - - /* branch forward */ - newContinuation = ((latestContinuation < targetPC1) ? targetPC1 : latestContinuation); - } - } - } - } - latestContinuation = newContinuation; - } - nextBcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) - : 0)); - if (((descriptor->isMapped)) - || (isInBlock - && ((descriptor->isMappedInBlock)))) break; - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - isBackwardBranch = (isBranch(descriptor)) - && ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) < 0)); - result = picDataForAnnotationMcpcBcpcMethod(descriptor, ((isBackwardBranch - ? (((sqInt)((usqInt)(annotation) << 1))) + 1 - : ((sqInt)((usqInt)(annotation) << 1)))), (((char *) mcpc)), ((isBackwardBranch - ? bcpc - (2 * nExts) - : bcpc)), (((void *)cogMethod))); - if (result != 0) { - return result; - } - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - } - else { - assert(((((usqInt)(mapByte)) >> AnnotationShift) == IsDisplacementX2N) - || ((((usqInt)(mapByte)) >> AnnotationShift) == IsAnnotationExtension)); - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - return 0; -} - - -/* N.B. Counters are always 32-bits, having two 16-bit halves for the reached - and taken counts. - */ - - /* SistaCogit>>#picDataForCounter:at: */ -static sqInt NoDbgRegParms -picDataForCounterat(unsigned int counter, sqInt bcpc) -{ - sqInt executedCount; - sqInt tuple; - sqInt untakenCount; - - tuple = eeInstantiateClassIndexformatnumSlots(ClassArrayCompactIndex, arrayFormat(), 3); - if (tuple == 0) { - return 0; - } - assert(CounterBytes == 4); - executedCount = initialCounterValue - ((counter) >> 16); - untakenCount = initialCounterValue - (counter & 0xFFFF); - storePointerUncheckedofObjectwithValue(0, tuple, (((usqInt)bcpc << 1) | 1)); - storePointerUncheckedofObjectwithValue(1, tuple, (((usqInt)executedCount << 1) | 1)); - storePointerUncheckedofObjectwithValue(2, tuple, (((usqInt)untakenCount << 1) | 1)); - return tuple; -} - - -/* Answer a tuple with the send data for a linked send to cogMethod. - If the target is a CogMethod (monomorphic send) answer - { bytecode pc, inline cache class, target method } - If the target is an open PIC (megamorphic send) answer - { bytecode pc, nil, send selector } - If the target is a closed PIC (polymorphic send) answer - { bytecode pc, first class, target method, second class, second target - method, ... } */ - - /* SistaCogit>>#picDataForSendTo:methodClassIfSuper:at:bcpc: */ -static sqInt NoDbgRegParms -picDataForSendTomethodClassIfSuperatbcpc(CogMethod *cogMethod, sqInt methodClassOrNil, char *sendMcpc, sqInt sendBcpc) -{ - sqInt class; - sqInt tuple; - - tuple = eeInstantiateClassIndexformatnumSlots(ClassArrayCompactIndex, arrayFormat(), (((cogMethod->cmType)) == CMClosedPIC - ? (2 * ((cogMethod->cPICNumCases))) + 1 - : 3)); - if (tuple == 0) { - return 0; - } - storePointerUncheckedofObjectwithValue(0, tuple, (((usqInt)sendBcpc << 1) | 1)); - if (((cogMethod->cmType)) == CMMethod) { - class = (!(methodClassOrNil) - ? classForInlineCacheTag(inlineCacheTagAt(backEnd, ((usqInt)sendMcpc))) - : methodClassOrNil); - storePointerofObjectwithValue(1, tuple, class); - storePointerofObjectwithValue(2, tuple, (cogMethod->methodObject)); - return tuple; - } - if (((cogMethod->cmType)) == CMClosedPIC) { - populatewithPICInfoForfirstCacheTag(tuple, cogMethod, inlineCacheTagAt(backEnd, ((usqInt)sendMcpc))); - return tuple; - } - if (((cogMethod->cmType)) == CMOpenPIC) { - storePointerUncheckedofObjectwithValue(1, tuple, nilObject()); - storePointerofObjectwithValue(2, tuple, (cogMethod->selector)); - return tuple; - } - error("invalid method type"); - return 0; -} - - -/* N.B. Counters are always 32-bits, having two 16-bit halves for the reached - and taken counts. - */ - - /* SistaCogit>>#picDataFor:Annotation:Mcpc:Bcpc:Method: */ -static sqInt NoDbgRegParms -picDataForAnnotationMcpcBcpcMethod(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *cogMethodArg) -{ - sqInt annotation; - sqInt association; - unsigned int counter; - usqInt entryPoint; - sqInt methodClassIfSuper; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - sqInt tuple; - - if (!descriptor) { - return 0; - } - if (isBranch(descriptor)) { - - /* it's a branch; conditional? */ - if (((descriptor->isBranchTrue)) - || ((descriptor->isBranchFalse))) { - counter = (((usqInt *) (((((CogMethod *) cogMethodArg))->counters))))[counterIndex]; - tuple = picDataForCounterat(counter, bcpc + 1); - if (tuple == 0) { - return PrimErrNoMemory; - } - storePointerofObjectwithValue(introspectionDataIndex, introspectionData, tuple); - introspectionDataIndex += 1; - counterIndex += 1; - } - return 0; - } - annotation = ((usqInt)(isBackwardBranchAndAnnotation)) >> 1; - if (!((annotation >= IsSendCall) - && (((entryPoint = callTargetFromReturnAddress(backEnd, ((usqInt)mcpc))), - entryPoint > methodZoneBase)))) { - - /* send is not linked, or is not a send */ - return 0; - } - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - - /* It's a linked send; find which kind. */ - methodClassIfSuper = null; - if (sendTable1 == superSendTrampolines) { - methodClassIfSuper = methodClassOf(((((CogMethod *) cogMethodArg))->methodObject)); - } - if (sendTable1 == directedSuperSendTrampolines) { - association = literalBeforeInlineCacheTagAt(backEnd, ((usqInt)mcpc)); - methodClassIfSuper = valueOfAssociation(association); - } - tuple = picDataForSendTomethodClassIfSuperatbcpc(targetMethod1, methodClassIfSuper, mcpc, bcpc + 1); - if (tuple == 0) { - return PrimErrNoMemory; - } - storePointerofObjectwithValue(introspectionDataIndex, introspectionData, tuple); - introspectionDataIndex += 1; - return 0; -} - - -/* Collect the branch and send data for cogMethod, storing it into arrayObj. */ - - /* SistaCogit>>#picDataFor:into: */ -sqInt -picDataForinto(CogMethod *cogMethod, sqInt arrayObj) -{ - sqInt aMethodHeader; - sqInt aMethodHeader1; - sqInt aMethodObj; - sqInt annotation; - sqInt bcpc; - sqInt bsOffset; - sqInt byte; - sqInt byte01; - sqInt byte02; - BytecodeDescriptor *descriptor; - sqInt distance; - sqInt distance1; - sqInt distance2; - sqInt endbcpc; - sqInt errCode; - CogMethod *homeMethod; - sqInt isBackwardBranch; - sqInt isInBlock; - sqInt latestContinuation; - usqInt map; - sqInt mapByte; - usqInt mcpc; - sqInt nExts; - sqInt newContinuation; - sqInt nextBcpc; - sqInt prim; - sqInt result; - sqInt startbcpc; - sqInt targetPC; - sqInt targetPC1; - sqInt upperByte; - - latestContinuation = 0; - if (((cogMethod->stackCheckOffset)) == 0) { - return 0; - } - introspectionDataIndex = (counterIndex = 0); - introspectionData = arrayObj; - /* begin mapFor:bcpc:performUntil:arg: */ - startbcpc = startPCOfMethod((cogMethod->methodObject)); - assert((((((CogBlockMethod *) cogMethod))->stackCheckOffset)) > 0); - - /* The stack check maps to the start of the first bytecode, - the first bytecode being effectively after frame build. */ - mcpc = (((usqInt)(((CogBlockMethod *) cogMethod)))) + (((((CogBlockMethod *) cogMethod))->stackCheckOffset)); - result = picDataForAnnotationMcpcBcpcMethod(null, (0 + (((int)((usqInt)(HasBytecodePC) << 1)))), (((char *) mcpc)), startbcpc, (((void *)cogMethod))); - if (result != 0) { - errCode = result; - goto l9; - } - - /* In both CMMethod and CMBlock cases find the start of the map and - skip forward to the bytecode pc map entry for the stack check. */ - bcpc = startbcpc; - if ((((((CogBlockMethod *) cogMethod))->cmType)) == CMMethod) { - /* begin cmIsFullBlock */ - isInBlock = ((((CogBlockMethod *) cogMethod))->cpicHasMNUCaseOrCMIsFullBlock); - homeMethod = ((CogMethod *) (((CogBlockMethod *) cogMethod))); - assert(startbcpc == (startPCOfMethodHeader((homeMethod->methodHeader)))); - map = ((((usqInt)homeMethod)) + ((homeMethod->blockSize))) - 1; - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert((annotation == IsAbsPCReference) - || ((annotation == IsObjectReference) - || ((annotation == IsRelativeCall) - || (annotation == IsDisplacementX2N)))); - latestContinuation = startbcpc; - aMethodObj = (homeMethod->methodObject); - endbcpc = (numBytesOf(aMethodObj)) - 1; - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader) - ? 0x100 - : 0) -# else - 0 -# endif - ; - bcpc += deltaToSkipPrimAndErrorStoreInheader(aMethodObj, (homeMethod->methodHeader)); - } - else { - isInBlock = 1; - assert(bcpc == (((((CogBlockMethod *) cogMethod))->startpc))); - homeMethod = cmHomeMethod(((CogBlockMethod *) cogMethod)); - map = findMapLocationForMcpcinMethod((((usqInt)(((CogBlockMethod *) cogMethod)))) + (sizeof(CogBlockMethod)), homeMethod); - assert(map != 0); - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert(((((usqInt)(annotation)) >> AnnotationShift) == HasBytecodePC) - || ((((usqInt)(annotation)) >> AnnotationShift) == IsDisplacementX2N)); - while (((annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift)) != HasBytecodePC) { - map -= 1; - } - - /* skip fiducial; i.e. the map entry for the pc immediately following the method header. */ - map -= 1; - aMethodObj = (homeMethod->methodObject); - bcpc = startbcpc - ( -#if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet((homeMethod->methodHeader)) - ? AltBlockCreationBytecodeSize - : BlockCreationBytecodeSize) -#else // MULTIPLEBYTECODESETS - BlockCreationBytecodeSize -#endif - ); - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader1 = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader1) - ? 0x100 - : 0) -# else - 0 -# endif - ; - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - endbcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, -1, aMethodObj)) - : 0)); - bcpc = startbcpc; - } - nExts = 0; - while ((((usqInt)((byteAt(map)))) >> AnnotationShift) != HasBytecodePC) { - map -= 1; - } - map -= 1; - while (((mapByte = byteAt(map))) != MapEnd) { - - /* defensive; we exit on bcpc */ - if (mapByte >= FirstAnnotation) { - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if (annotation >= HasBytecodePC) { - if ((annotation == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - while (1) { - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - if (isInBlock) { - if (bcpc >= endbcpc) { - errCode = 0; - goto l9; - } - } - else { - if (((descriptor->isReturn)) - && (bcpc >= latestContinuation)) { - errCode = 0; - goto l9; - } - if ((isBranch(descriptor)) - || ((descriptor->isBlockCreation))) { - /* begin latestContinuationPCFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj); - targetPC = (bcpc + ((descriptor->numBytes))) + (((distance < 0) ? 0 : distance)); - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - /* begin maybeUnsafeJumpContinuation:at:for:in: */ - newContinuation = latestContinuation; - if ((descriptor->hasUnsafeJump)) { - byte01 = fetchByteofObject(bcpc + 1, aMethodObj); - - /* pushIntegerLong */ - byte02 = fetchByteofObject(bcpc + 2, aMethodObj); - /* begin decodePushIntegerLongBefore:in: */ - distance1 = fetchByteofObject(bcpc - 1, methodObj); - upperByte = fetchByteofObject(bcpc - 3, methodObj); - if (upperByte > 0x7F) { - upperByte -= 0x100; - } - distance2 = (((sqInt)((usqInt)(upperByte) << 8))) + distance1; - targetPC1 = (bcpc + ((descriptor->numBytes))) + distance2; - if (!((descriptor->isMapped))) { - if ((((usqInt)(byte02)) >> 5) == 4) { - - /* inlined sista primitive */ - prim = (((sqInt)((usqInt)((byte02 & 0x1F)) << 8))) + byte01; - if (prim >= 7000) { - - /* branch forward */ - newContinuation = ((latestContinuation < targetPC1) ? targetPC1 : latestContinuation); - } - } - } - } - latestContinuation = newContinuation; - } - nextBcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) - : 0)); - if (((descriptor->isMapped)) - || (isInBlock - && ((descriptor->isMappedInBlock)))) break; - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - isBackwardBranch = (isBranch(descriptor)) - && ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) < 0)); - result = picDataForAnnotationMcpcBcpcMethod(descriptor, ((isBackwardBranch - ? (((sqInt)((usqInt)(annotation) << 1))) + 1 - : ((sqInt)((usqInt)(annotation) << 1)))), (((char *) mcpc)), ((isBackwardBranch - ? bcpc - (2 * nExts) - : bcpc)), (((void *)cogMethod))); - if (result != 0) { - errCode = result; - goto l9; - } - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - } - else { - assert(((((usqInt)(mapByte)) >> AnnotationShift) == IsDisplacementX2N) - || ((((usqInt)(mapByte)) >> AnnotationShift) == IsAnnotationExtension)); - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - errCode = 0; - l9: /* end mapFor:bcpc:performUntil:arg: */; - if (errCode != 0) { - assert(errCode == PrimErrNoMemory); - return -1; - } - if (((cogMethod->blockEntryOffset)) != 0) { - errCode = blockDispatchTargetsForperformarg(cogMethod, picDataForBlockEntryMethod, ((sqInt)cogMethod)); - if (errCode != 0) { - assert(errCode == PrimErrNoMemory); - return -1; - } - } - return introspectionDataIndex; -} - - -/* Populate tuple (which must be large enough) with the ClosedPIC's target - method class pairs. - The first entry in tuple contains the bytecode pc for the send, so skip - the tuple's first field. - */ - - /* SistaCogit>>#populate:withPICInfoFor:firstCacheTag: */ -static void NoDbgRegParms -populatewithPICInfoForfirstCacheTag(sqInt tuple, CogMethod *cPIC, sqInt firstCacheTag) -{ - sqInt cacheTag; - sqInt classOop; - usqInt entryPoint; - sqInt i; - sqInt pc; - CogMethod *targetMethod; - sqInt value; - - for (i = 1; i <= ((cPIC->cPICNumCases)); i += 1) { - pc = addressOfEndOfCaseinCPIC(i, cPIC); - cacheTag = (i == 1 - ? firstCacheTag - : literalBeforeFollowingAddress(backEnd, pc - 16 /* jumpLongConditionalByteSize */)); - classOop = classForInlineCacheTag(cacheTag); - storePointerofObjectwithValue((i * 2) - 1, tuple, classOop); - - /* Find target from jump. A jump to the MNU entry-point should collect #doesNotUnderstand: */ - entryPoint = (i == 1 - ? jumpLongTargetBeforeFollowingAddress(backEnd, pc) - : jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc)); - if (((((usqInt)cPIC)) <= (((usqInt)entryPoint))) - && (((((usqInt)cPIC)) + ((cPIC->blockSize))) >= (((usqInt)entryPoint)))) { - value = splObj(SelectorDoesNotUnderstand); - } - else { - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - assert(((targetMethod->cmType)) == CMMethod); - value = (targetMethod->methodObject); - } - storePointerofObjectwithValue(i * 2, tuple, value); - } -} - - /* SistaMethodZone>>#getCogCodeZoneThreshold */ -double -getCogCodeZoneThreshold(void) -{ - return thresholdRatio; -} - - /* SistaMethodZone>>#setCogCodeZoneThreshold: */ -sqInt -setCogCodeZoneThreshold(double ratio) -{ - if (!((ratio >= 0.1) - && (ratio <= 1.0))) { - return PrimErrBadArgument; - } - thresholdRatio = ratio; - /* begin computeAllocationThreshold */ - allocationThreshold = ((((((usqInt)((limitAddress - baseAddress) * thresholdRatio))) + (7)) & ~7)) + baseAddress; - return 0; -} - - -/* Add a blockStart for an embedded block. For a binary tree walk block - dispatch blocks must be compiled in pc/depth-first order but are scanned - in breadth-first - order, so do an insertion sort (which of course is really a bubble sort - because we - have to move everything higher to make room). */ - - /* StackToRegisterMappingCogit>>#addBlockStartAt:numArgs:numCopied:span: */ -static BlockStart * NoDbgRegParms -addBlockStartAtnumArgsnumCopiedspan(sqInt bytecodepc, sqInt numArgs, sqInt numCopied, sqInt span) -{ - BlockStart *blockStart; - sqInt i; - sqInt j; - - - /* Transcript ensureCr; nextPutAll: 'addBlockStartAt: '; print: bytecodepc; cr; flush. */ - if (blockCount > 0) { - i = blockCount - 1; - while (1) { - - /* check for repeat addition during recompilation due to initialNil miscount. */ - blockStart = (&(blockStarts[i])); - if (((blockStart->startpc)) == bytecodepc) { - return blockStart; - } - if (!((((blockStart->startpc)) > bytecodepc) - && (i > 0))) break; - i -= 1; - } - for (j = blockCount; j >= (i + 1); j += -1) { - blockStarts[j] = (blockStarts[j - 1]); - } - blockStart = (&(blockStarts[i + 1])); - } - else { - blockStart = (&(blockStarts[blockCount])); - } - blockCount += 1; - (blockStart->startpc = bytecodepc); - (blockStart->numArgs = numArgs); - (blockStart->numCopied = numCopied); - (blockStart->numInitialNils = 0); - (blockStart->stackCheckLabel = null); - (blockStart->hasInstVarRef = 0); - (blockStart->span = span); - return blockStart; -} - - -/* e.g. Receiver Receiver or Receiver Receiver (RISC) - Selector/Arg0 => Arg1 Selector/Arg0 => Arg1 - Arg1 Arg2 Arg1 Arg2 - Arg2 Arg3 Arg2 sp-> Arg3 - Arg3 sp-> retpc sp-> Arg3 - sp-> retpc */ -/* Generate code to adjust the possibly stacked arguments immediately - before jumping to a method looked up by a perform primitive. */ - - /* StackToRegisterMappingCogit>>#adjustArgumentsForPerform: */ -static void NoDbgRegParms -adjustArgumentsForPerform(sqInt numArgs) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction3; - sqInt index; - - assert((numRegArgs()) <= 2); - assert(numArgs >= 1); - if (numArgs <= 2 /* numRegArgs */) { - if (numArgs == 2) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, Arg0Reg); - } - return; - } - if ((3) == numArgs) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, SPReg, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, BytesPerWord, SPReg, Arg0Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(AddCqR, (numArgs + 1) * BytesPerWord, SPReg); - return; - } - for (index = (numArgs - 2); index >= 0; index += -1) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveMwrR, index * BytesPerWord, SPReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperandoperand(MoveRMwr, TempReg, (index + 1) * BytesPerWord, SPReg); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperand(AddCqR, BytesPerWord, SPReg); -} - - -/* If the stack entry is already in a register not conflicting with regMask, - answers it, - else allocate a new register not conflicting with reg mask - */ - - /* StackToRegisterMappingCogit>>#allocateRegForStackEntryAt:notConflictingWith: */ -static sqInt NoDbgRegParms -allocateRegForStackEntryAtnotConflictingWith(sqInt index, sqInt regMask) -{ - sqInt mask; - CogSimStackEntry *stackEntry; - - stackEntry = ssValue(index); - mask = registerMaskOrNone(stackEntry); - if ((mask != 0) - && ((!(mask & regMask)))) { - flag("TODO"); - return registerOrNone(stackEntry); - } - return allocateRegNotConflictingWith(regMask); -} - - -/* if there's a free register, use it */ - - /* StackToRegisterMappingCogit>>#allocateRegNotConflictingWith: */ -static sqInt NoDbgRegParms -allocateRegNotConflictingWith(sqInt regMask) -{ - sqInt reg; - - reg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); - if (reg == NoReg) { - - /* No free register, choose one that does not conflict with regMask */ - reg = freeAnyRegNotConflictingWith(regMask); - } - if (reg == ReceiverResultReg) { - - /* If we've allocated RcvrResultReg, it's not live anymore */ - voidReceiverResultRegContainsSelf(); - } - return reg; -} - - /* StackToRegisterMappingCogit>>#anyReferencesToRegister:inTopNItems: */ -static sqInt NoDbgRegParms -anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n) -{ - sqInt i; - sqInt regMask; - - /* begin registerMaskFor: */ - regMask = 1U << reg; - for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { - if ((((registerMask(simStackAt(i))) & regMask) != 0)) { - return 1; - } - } - return 0; -} - - -/* This is a static version of ceCallCogCodePopReceiverArg0Regs - for break-pointing when debugging in C. */ -/* This exists only for break-pointing. */ - - /* StackToRegisterMappingCogit>>#callCogCodePopReceiverArg0Regs */ -void -callCogCodePopReceiverArg0Regs(void) -{ - realCECallCogCodePopReceiverArg0Regs(); -} - - -/* This is a static version of ceCallCogCodePopReceiverArg1Arg0Regs - for break-pointing when debugging in C. */ -/* This exists only for break-pointing. */ - - /* StackToRegisterMappingCogit>>#callCogCodePopReceiverArg1Arg0Regs */ -void -callCogCodePopReceiverArg1Arg0Regs(void) -{ - realCECallCogCodePopReceiverArg1Arg0Regs(); -} - - -/* Loop over bytecodes, dispatching to the generator for each bytecode, - handling fixups in due course. - */ - - /* StackToRegisterMappingCogit>>#compileAbstractInstructionsFrom:through: */ -static sqInt NoDbgRegParms -compileAbstractInstructionsFromthrough(sqInt start, sqInt end) -{ - BytecodeDescriptor *descriptor; - BytecodeFixup *fixup; - sqInt nExts; - sqInt nextOpcodeIndex; - sqInt result; - - traceSimStack(); - bytecodePC = start; - nExts = (result = 0); - descriptor = null; - deadCode = 0; - while (1) { - maybeHaltIfDebugPC(); - mergeWithFixupIfRequired((fixup = fixupAt(bytecodePC))); - descriptor = loadBytesAndGetDescriptor(); - nextOpcodeIndex = opcodeIndex; - result = (deadCode - ? mapDeadDescriptorIfNeeded(descriptor) - : ((descriptor->generator))()); - if (result == 0) { - /* begin assertExtsAreConsumed: */ - if (!((descriptor->isExtension))) { - assert((extA == 0) - && ((extB == 0) - && (numExtB == 0))); - } - } - traceDescriptor(descriptor); - traceSimStack(); - /* begin patchFixupTargetIfNeeded:nextOpcodeIndex: */ - if ((((((usqInt)((fixup->targetInstruction)))) >= NeedsNonMergeFixupFlag) && ((((usqInt)((fixup->targetInstruction)))) <= NeedsMergeFixupFlag))) { - - /* There is a fixup for this bytecode. It must point to the first generated - instruction for this bytecode. If there isn't one we need to add a label. */ - if (opcodeIndex == nextOpcodeIndex) { - /* begin Label */ - genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (fixup->targetInstruction = abstractInstructionAt(nextOpcodeIndex)); - } - /* begin maybeDumpLiterals: */ - if (((isBranch(descriptor)) - && (!(((descriptor->isBranchTrue)) - || ((descriptor->isBranchFalse))))) - || ((descriptor->isReturn))) { - /* begin dumpLiterals: */ - !(((isBranch(descriptor)) - && (!(((descriptor->isBranchTrue)) - || ((descriptor->isBranchFalse))))) - || ((descriptor->isReturn))); - } - /* begin nextBytecodePCFor:exts: */ - bytecodePC = (bytecodePC + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? ((descriptor->spanFunction))(descriptor, bytecodePC, nExts, methodObj) - : 0)); - if (!((result == 0) - && (bytecodePC <= end))) break; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - /* begin checkEnoughOpcodes */ - if (opcodeIndex > numAbstractOpcodes) { - error("Cog JIT internal error. Too many abstract opcodes. Num opcodes heuristic is too optimistic."); - } - return result; -} - - /* StackToRegisterMappingCogit>>#compileBlockBodies */ -static sqInt -compileBlockBodies(void) -{ - BlockStart *blockStart; - sqInt compiledBlocksCount; - sqInt initialCounterIndex; - sqInt initialOpcodeIndex; - sqInt initialStackPtr; - sqInt (* const pushNilSizeFunction)(sqInt,sqInt) = squeakV3orSistaV1PushNilSizenumInitialNils; - sqInt result; - sqInt savedNeedsFrame; - sqInt savedNumArgs; - sqInt savedNumTemps; - - assert(blockCount > 0); - savedNeedsFrame = needsFrame; - savedNumArgs = methodOrBlockNumArgs; - savedNumTemps = methodOrBlockNumTemps; - inBlock = InVanillaBlock; - compiledBlocksCount = 0; - while (compiledBlocksCount < blockCount) { - compilationPass = 1; - blockStart = blockStartAt(compiledBlocksCount); - if (((result = scanBlock(blockStart))) < 0) { - return result; - } - initialOpcodeIndex = opcodeIndex; - /* begin maybeCounterIndex */ - initialCounterIndex = counterIndex; - while (1) { - compileBlockEntry(blockStart); - initialStackPtr = simStackPtr; - if (((result = compileAbstractInstructionsFromthrough(((blockStart->startpc)) + (pushNilSizeFunction(methodObj, ((blockStart->numInitialNils)))), (((blockStart->startpc)) + ((blockStart->span))) - 1))) < 0) { - return result; - } - if (initialStackPtr == simStackPtr) break; - assert((initialStackPtr > simStackPtr) - || (deadCode)); - - /* for asserts */ - compilationPass += 1; - (blockStart->numInitialNils = (((blockStart->numInitialNils)) + simStackPtr) - initialStackPtr); - (((blockStart->fakeHeader))->dependent = null); - reinitializeFixupsFromthrough(((blockStart->startpc)) + ((blockStart->numInitialNils)), (((blockStart->startpc)) + ((blockStart->span))) - 1); - bzero(abstractOpcodes + initialOpcodeIndex, - (opcodeIndex - initialOpcodeIndex) * sizeof(AbstractInstruction)); - opcodeIndex = initialOpcodeIndex; - /* begin maybeSetCounterIndex: */ - counterIndex = initialCounterIndex; - } - compiledBlocksCount += 1; - } - needsFrame = savedNeedsFrame; - methodOrBlockNumArgs = savedNumArgs; - methodOrBlockNumTemps = savedNumTemps; - return 0; -} - - -/* Build a frame for a block activation. See CoInterpreter - class>>initializeFrameIndices. closure (in ReceiverResultReg) - arg0 - ... - argN - caller's saved ip/this stackPage (for a base frame) - fp-> saved fp - method - context (uninitialized?) - receiver - first temp - ... - sp-> Nth temp - Avoid use of SendNumArgsReg which is the flag determining whether - context switch is allowed on stack-overflow. */ -/* Build a frame for a block activation. See CoInterpreter - class>>initializeFrameIndices. Override to push the register receiver and - register arguments, if any, and to correctly - initialize the explicitly nilled/pushed temp entries (they are /not/ of - type constant nil). */ - - /* StackToRegisterMappingCogit>>#compileBlockFrameBuild: */ -static void NoDbgRegParms -compileBlockFrameBuild(BlockStart *blockStart) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction * cascade0; - sqInt constant; - sqInt constant1; - sqInt i; - sqInt ign; - - /* begin annotateBytecode: */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction->annotation = HasBytecodePC); - /* begin PushR: */ - genoperand(PushR, LinkReg); - /* begin PushR: */ - genoperand(PushR, FPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SPReg, FPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, ClassReg); - cascade0 = (blockStart->fakeHeader); - addDependent(cascade0, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)((blockStart->fakeHeader))), genoperand(PushCw, ((sqInt)((blockStart->fakeHeader))))))); - /* begin setLabelOffset: */ - ((cascade0->operands))[1] = MFMethodFlagIsBlockFlag; - annotateobjRef(checkLiteralforInstruction(nilObject(), genoperand(PushCw, nilObject())), nilObject()); - if ((blockStart->hasInstVarRef)) { - - /* Use ReceiverResultReg for Context to agree with store check trampoline */ - genLoadSlotsourceRegdestReg(ClosureOuterContextIndex, ClassReg, ReceiverResultReg); - genLoadSlotsourceRegdestReg(ReceiverIndex, ReceiverResultReg, Arg0Reg); - genEnsureOopInRegNotForwardedscratchRegupdatingSlotin(Arg0Reg, TempReg, ReceiverIndex, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ReceiverResultReg); - } - else { - genLoadSlotsourceRegdestReg(ClosureOuterContextIndex, ClassReg, Arg0Reg); - genLoadSlotsourceRegdestReg(ReceiverIndex, Arg0Reg, ReceiverResultReg); - } - /* begin PushR: */ - genoperand(PushR, ReceiverResultReg); - for (i = 0; i < ((blockStart->numCopied)); i += 1) { - genLoadSlotsourceRegdestReg(i + ClosureFirstCopiedValueIndex, ClassReg, TempReg); - /* begin PushR: */ - genoperand(PushR, TempReg); - } - (blockStart->stackCheckLabel = compileStackOverflowCheck(1)); - methodOrBlockNumTemps = (((blockStart->numArgs)) + ((blockStart->numCopied))) + ((blockStart->numInitialNils)); - initSimStackForFramefulMethod((blockStart->startpc)); - if (((blockStart->numInitialNils)) > 0) { - if (((blockStart->numInitialNils)) > 1) { - /* begin genMoveNilR: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, TempReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, TempReg); - } - for (ign = 1; ign <= ((blockStart->numInitialNils)); ign += 1) { - /* begin PushR: */ - genoperand(PushR, TempReg); - } - } - else { - /* begin genPushConstant: */ - constant1 = nilObject(); - if (shouldAnnotateObjectReference(constant1)) { - annotateobjRef(checkLiteralforInstruction(constant1, genoperand(PushCw, constant1)), constant1); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperand(PushCq, constant1); - } - } - } -} - - -/* Make sure ReceiverResultReg holds the receiver, loaded from the closure, - which is what is initially in ReceiverResultReg. We must annotate the - first instruction in vanilla blocks so that - findMethodForStartBcpc:inHomeMethod: can function. We need two annotations - because the first is a fiducial. */ -/* Make sure ReceiverResultReg holds the receiver, loaded from - the closure, which is what is initially in ReceiverResultReg */ - - /* StackToRegisterMappingCogit>>#compileBlockFramelessEntry: */ -static void NoDbgRegParms -compileBlockFramelessEntry(BlockStart *blockStart) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - - methodOrBlockNumTemps = (((blockStart->numArgs)) + ((blockStart->numCopied))) + ((blockStart->numInitialNils)); - initSimStackForFramelessBlock((blockStart->startpc)); - if (!(((blockStart->entryLabel)) == null)) { - /* begin annotateBytecode: */ - abstractInstruction = (blockStart->entryLabel); - (abstractInstruction->annotation = HasBytecodePC); - /* begin annotateBytecode: */ - abstractInstruction1 = (blockStart->entryLabel); - (abstractInstruction1->annotation = HasBytecodePC); - } - if ((blockStart->hasInstVarRef)) { - - /* Use ReceiverResultReg for Context to agree with store check trampoline */ - genLoadSlotsourceRegdestReg(ClosureOuterContextIndex, ReceiverResultReg, ReceiverResultReg); - genLoadSlotsourceRegdestReg(ReceiverIndex, ReceiverResultReg, Arg0Reg); - genEnsureOopInRegNotForwardedscratchRegupdatingSlotin(Arg0Reg, TempReg, ReceiverIndex, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ReceiverResultReg); - } - else { - genLoadSlotsourceRegdestReg(ClosureOuterContextIndex, ReceiverResultReg, TempReg); - genLoadSlotsourceRegdestReg(ReceiverIndex, TempReg, ReceiverResultReg); - } -} - - -/* Compile the abstract instructions for the entire method, including blocks. */ -/* Compile the abstract instructions for the entire method, including blocks. */ - - /* StackToRegisterMappingCogit>>#compileEntireMethod */ -static sqInt -compileEntireMethod(void) -{ - sqInt result; - - regArgsHaveBeenPushed = 0; - /* begin preenMethodLabel */ - (((((AbstractInstruction *) methodLabel))->operands))[1] = 0; - compileAbort(); - compileEntry(); - if (((result = compilePrimitive())) < 0) { - return result; - } - compileFrameBuild(); - if (((result = compileMethodBody())) < 0) { - return result; - } - if (blockCount == 0) { - return 0; - } - if (((result = compileBlockBodies())) < 0) { - return result; - } - return compileBlockDispatch(); -} - - -/* Make sure ReceiverResultReg holds the receiver, loaded from the closure, - which is what is initially in ReceiverResultReg. */ -/* Make sure ReceiverResultReg holds the receiver, loaded from - the closure, which is what is initially in ReceiverResultReg */ - - /* StackToRegisterMappingCogit>>#compileFullBlockFramelessEntry: */ -static void NoDbgRegParms -compileFullBlockFramelessEntry(sqInt numCopied) -{ - initSimStackForFramelessBlock(initialPC); - flag("TODO"); - genLoadSlotsourceRegdestReg(FullClosureReceiverIndex, ReceiverResultReg, Arg0Reg); - genEnsureOopInRegNotForwardedscratchRegupdatingSlotin(Arg0Reg, TempReg, FullClosureReceiverIndex, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ReceiverResultReg); -} - - -/* Build a frame for a CogMethod activation. See CoInterpreter - class>>initializeFrameIndices. receiver (in ReceiverResultReg) - arg0 - ... - argN - caller's saved ip/this stackPage (for a base frame) - fp-> saved fp - method - context (uninitialized?) - receiver - first temp - ... - sp-> Nth temp - If there is a primitive and an error code the Nth temp is the error code. - Ensure SendNumArgsReg is set early on (incidentally to nilObj) because - it is the flag determining whether context switch is allowed on - stack-overflow. */ -/* We are in a method where the frame is needed *only* for instance variable - store, typically a setter method. - This case has 20% overhead with Immutability compared to setter without - immutability because of the stack - frame creation. We compile two path, one where the object is immutable, - one where it isn't. At the beginning - of the frame build, we take one path or the other depending on the - receiver mutability. - - Note: this specific case happens only where there are only instance - variabel stores. We could do something - similar for literal variable stores, but we don't as it's too uncommon. - */ - - /* StackToRegisterMappingCogit>>#compileTwoPathFrameBuild */ -#if IMMUTABILITY -static void -compileTwoPathFrameBuild(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt constant; - sqInt i; - sqInt iLimiT; - AbstractInstruction * jumpImmutable; - AbstractInstruction * jumpOld; - - assert(useTwoPaths); - assert(blockCount == 0); - jumpImmutable = genJumpImmutablescratchReg(ReceiverResultReg, TempReg); - - /* first path. The receiver is mutable */ - - /* N.B. FLAGS := destReg - scratchReg */ - /* begin checkQuickConstant:forInstruction: */ - storeCheckBoundary(); - anInstruction = genoperandoperand(CmpCqR, storeCheckBoundary(), ReceiverResultReg); - /* begin JumpAboveOrEqual: */ - jumpOld = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - assert(!needsFrame); - initSimStackForFramelessMethod(initialPC); - /* begin compileMethodBody */ - if (endPC < initialPC) { - goto l3; - } - compileAbstractInstructionsFromthrough(initialPC + (deltaToSkipPrimAndErrorStoreInheader(methodObj, methodHeader)), endPC); - l3: /* end compileMethodBody */; - - /* reset because it impacts inst var store compilation */ - useTwoPaths = 0; - needsFrame = 1; - jmpTarget(jumpOld, jmpTarget(jumpImmutable, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - genPushRegisterArgs(); - if (!needsFrame) { - return; - } - /* begin PushR: */ - genoperand(PushR, LinkReg); - /* begin PushR: */ - genoperand(PushR, FPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SPReg, FPReg); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperand(PushCw, ((sqInt)methodLabel))))); - /* begin genMoveNilR: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, SendNumArgsReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, constant, SendNumArgsReg); - } - /* begin PushR: */ - genoperand(PushR, SendNumArgsReg); - /* begin PushR: */ - genoperand(PushR, ReceiverResultReg); - for (i = (methodOrBlockNumArgs + 1), iLimiT = (temporaryCountOfMethodHeader(methodHeader)); i <= iLimiT; i += 1) { - /* begin PushR: */ - genoperand(PushR, SendNumArgsReg); - } - if (((primitiveIndexOfMethodheader(methodObj, methodHeader)) > 0) - && ((longStoreBytecodeForHeader(methodHeader)) == (fetchByteofObject((startPCOfMethod(methodObj)) + (sizeOfCallPrimitiveBytecode(methodHeader)), methodObj)))) { - compileGetErrorCode(); - } - stackCheckLabel = compileStackOverflowCheck(canContextSwitchIfActivatingheader(methodObj, methodHeader)); - initSimStackForFramefulMethod(initialPC); -} -#endif /* IMMUTABILITY */ - - -/* We are in a frameless method with at least two inst var stores. We compile - two paths, - one where the object is in new space, and one where it isn't. At the - beginning - of the method, we take one path or the other depending on the receiver - being in newSpace. - */ - - /* StackToRegisterMappingCogit>>#compileTwoPathFramelessInit */ -static void -compileTwoPathFramelessInit(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction * jumpOld; - - assert(!(IMMUTABILITY)); - assert(!(needsFrame)); - assert(useTwoPaths); - - /* first path. The receiver is young */ - - /* N.B. FLAGS := destReg - scratchReg */ - /* begin checkQuickConstant:forInstruction: */ - storeCheckBoundary(); - anInstruction = genoperandoperand(CmpCqR, storeCheckBoundary(), ReceiverResultReg); - /* begin JumpAboveOrEqual: */ - jumpOld = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - initSimStackForFramelessMethod(initialPC); - /* begin compileMethodBody */ - if (endPC < initialPC) { - goto l1; - } - compileAbstractInstructionsFromthrough(initialPC + (deltaToSkipPrimAndErrorStoreInheader(methodObj, methodHeader)), endPC); - l1: /* end compileMethodBody */; - - /* reset because it impacts inst var store compilation */ - useTwoPaths = 0; - jmpTarget(jumpOld, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); -} - - /* StackToRegisterMappingCogit>>#cPICMissTrampolineFor: */ -static sqInt NoDbgRegParms -cPICMissTrampolineFor(sqInt numArgs) -{ - return picMissTrampolines[((numArgs < (3)) ? numArgs : (3))]; -} - - -/* Replaces the Blue Book double-extended send [132], in which the first byte - was wasted on 8 bits of argument count. - Here we use 3 bits for the operation sub-type (opType), and the remaining - 5 bits for argument count where needed. - The last byte give access to 256 instVars or literals. - See also secondExtendedSendBytecode - */ - - /* StackToRegisterMappingCogit>>#doubleExtendedDoAnythingBytecode */ -static sqInt -doubleExtendedDoAnythingBytecode(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *abstractInstruction2; - sqInt opType; - - opType = ((usqInt)(byte1)) >> 5; - if (opType == 0) { - return genSendnumArgs(byte2, byte1 & 0x1F); - } - if (opType == 1) { - return genSendSupernumArgs(byte2, byte1 & 0x1F); - } - switch (opType) { - case 2: - if (isReadMediatedContextInstVarIndex(byte2)) { - genPushMaybeContextReceiverVariable(byte2); - } - else { - genPushReceiverVariable(byte2); - /* begin annotateInstructionForBytecode */ - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (abstractInstruction->annotation = HasBytecodePC); - return 0; - } - break; - case 3: - genPushLiteralIndex(byte2); - /* begin annotateInstructionForBytecode */ - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction1 = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction1 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (abstractInstruction1->annotation = HasBytecodePC); - return 0; - - case 4: - genPushLiteralVariable(byte2); - break; - case 7: - genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(0, byte2, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); -# if IMMUTABILITY - - /* genStorePop:LiteralVariable: annotates; don't annotate twice */ - return 0; -# endif - break; - default: - - /* 5 & 6 */ - if (isWriteMediatedContextInstVarIndex(byte2)) { - genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(opType == 6, byte2, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } - else { - genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(opType == 6, byte2, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } -# if IMMUTABILITY - - /* genStorePop:...ReceiverVariable: annotate; don't annotate twice */ - return 0; -# endif -; - } - assert(needsFrame); - assert(!(prevInstIsPCAnnotated())); - /* begin annotateBytecode: */ - abstractInstruction2 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction2->annotation = HasBytecodePC); - return 0; -} - - /* StackToRegisterMappingCogit>>#duplicateTopBytecode */ -static sqInt -duplicateTopBytecode(void) -{ - SimStackEntry desc; - - /* begin ssTopDescriptor */ - desc = simStack[simStackPtr]; - return ssPushDesc(desc); -} - - -/* Make sure there's a flagged fixup at the target pc in fixups. - Initially a fixup's target is just a flag. Later on it is replaced with a - proper instruction. */ - - /* StackToRegisterMappingCogit>>#ensureFixupAt: */ -static BytecodeFixup * NoDbgRegParms -ensureFixupAt(sqInt targetPC) -{ - BytecodeFixup *fixup; - - /* begin fixupAt: */ - fixup = fixupAtIndex(targetPC - initialPC); - traceFixupmerge(fixup, 1); - if ((((usqInt)((fixup->targetInstruction)))) <= NeedsNonMergeFixupFlag) { - - /* convert a non-merge into a merge */ - /* begin becomeMergeFixup */ - (fixup->targetInstruction) = ((AbstractInstruction *) NeedsMergeFixupFlag); - (fixup->simStackPtr = simStackPtr); - } - else { - if ((fixup->isTargetOfBackwardBranch)) { - - /* this is the target of a backward branch and - so doesn't have a simStackPtr assigned yet. */ - (fixup->simStackPtr = simStackPtr); - } - else { - assert(((fixup->simStackPtr)) == simStackPtr); - } - } - /* begin recordBcpc: */ - return fixup; -} - - -/* Make sure there's a flagged fixup at the target pc in fixups. - Initially a fixup's target is just a flag. Later on it is replaced with a - proper instruction. */ - - /* StackToRegisterMappingCogit>>#ensureNonMergeFixupAt: */ -static BytecodeFixup * NoDbgRegParms -ensureNonMergeFixupAt(sqInt targetPC) -{ - BytecodeFixup *fixup; - - /* begin fixupAt: */ - fixup = fixupAtIndex(targetPC - initialPC); - traceFixupmerge(fixup, 1); - if (((fixup->targetInstruction)) == 0) { - /* begin becomeNonMergeFixup */ - (fixup->targetInstruction) = ((AbstractInstruction *) NeedsNonMergeFixupFlag); - } - /* begin recordBcpc: */ - return fixup; -} - - /* StackToRegisterMappingCogit>>#ensureReceiverResultRegContainsSelf */ -static void -ensureReceiverResultRegContainsSelf(void) -{ - if (needsFrame) { - if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); - /* begin putSelfInReceiverResultReg */ - storeToReg(simSelf(), ReceiverResultReg); - ((simSelf())->liveRegister = ReceiverResultReg); - } - } - else { - assert(((((simSelf())->type)) == SSRegister) - && (((((simSelf())->registerr)) == ReceiverResultReg) - && (receiverIsInReceiverResultReg()))); - } -} - - /* StackToRegisterMappingCogit>>#evaluate:at: */ -static void NoDbgRegParms -evaluateat(BytecodeDescriptor *descriptor, sqInt pc) -{ - byte0 = fetchByteofObject(pc, methodObj); - assert(descriptor == (generatorAt(bytecodeSetOffset + byte0))); - loadSubsequentBytesForDescriptorat(descriptor, pc); - ((descriptor->generator))(); -} - - -/* Attempt to follow a branch to a pc. Handle branches to unconditional jumps - and branches to push: aBoolean; conditional branch pairs. If the branch - cannot be - followed answer targetBytecodePC. It is not possible to follow jumps to - conditional branches because the stack changes depth. That following is - left to the genJumpIf:to: - clients. */ - - /* StackToRegisterMappingCogit>>#eventualTargetOf: */ -static sqInt NoDbgRegParms -eventualTargetOf(sqInt targetBytecodePC) -{ - sqInt cond; - sqInt currentTarget; - BytecodeDescriptor *descriptor; - sqInt nExts; - sqInt nextPC; - sqInt span; - - cond = 0; - nextPC = (currentTarget = targetBytecodePC); - while (1) { - nExts = 0; - while (1) { - /* begin generatorForPC: */ - descriptor = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC, methodObj))); - if ((descriptor->isReturn)) { - return currentTarget; - } - if (!((descriptor->isExtension))) break; - nExts += 1; - nextPC += (descriptor->numBytes); - } - if ((isBranch(descriptor)) - && (!(((descriptor->isBranchTrue)) - || ((descriptor->isBranchFalse))))) { - /* begin spanFor:at:exts:in: */ - span = ((descriptor->spanFunction))(descriptor, nextPC, nExts, methodObj); - if (span < 0) { - - /* Do *not* follow backward branches; these are interrupt points and should not be elided. */ - return currentTarget; - } - nextPC = (nextPC + ((descriptor->numBytes))) + span; - } - else { - if (((descriptor->generator)) == genPushConstantTrueBytecode) { - cond = 1; - } - else { - if (((descriptor->generator)) == genPushConstantFalseBytecode) { - cond = 0; - } - else { - return currentTarget; - } - } - if (((fixupAt(nextPC))->isTargetOfBackwardBranch)) { - return currentTarget; - } - nextPC = eventualTargetOf(nextPC + ((descriptor->numBytes))); - nExts = 0; - while (1) { - /* begin generatorForPC: */ - descriptor = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC, methodObj))); - if ((descriptor->isReturn)) { - return currentTarget; - } - if (!((descriptor->isExtension))) break; - nExts += 1; - nextPC += (descriptor->numBytes); - } - if (!(isBranch(descriptor))) { - return currentTarget; - } - if ((isBranch(descriptor)) - && (!(((descriptor->isBranchTrue)) - || ((descriptor->isBranchFalse))))) { - return currentTarget; - } - nextPC = (cond == ((descriptor->isBranchTrue)) - ? (nextPC + ((descriptor->numBytes))) + (((descriptor->spanFunction))(descriptor, nextPC, nExts, methodObj)) - : nextPC + ((descriptor->numBytes))); - } - currentTarget = nextPC; - } - return 0; -} - - -/* Spill the closest register on stack not conflicting with regMask. - Assertion Failure if regMask has already all the registers */ - - /* StackToRegisterMappingCogit>>#freeAnyRegNotConflictingWith: */ -static sqInt NoDbgRegParms -freeAnyRegNotConflictingWith(sqInt regMask) -{ - CogSimStackEntry *desc; - sqInt index; - sqInt reg; - - assert(needsFrame); - reg = NoReg; - index = ((simSpillBase < 0) ? 0 : simSpillBase); - while ((reg == NoReg) - && (index < simStackPtr)) { - desc = simStackAt(index); - if (((desc->type)) == SSRegister) { - if (!(((regMask & (1U << ((desc->registerr)))) != 0))) { - reg = (desc->registerr); - } - } - index += 1; - } - assert(!((reg == NoReg))); - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << reg, simStackPtr, simNativeStackPtr); - return reg; -} - - -/* Return from block, assuming result already loaded into ReceiverResultReg. */ -/* Return from block, assuming result already loaded into ReceiverResultReg. */ - - /* StackToRegisterMappingCogit>>#genBlockReturn */ -static sqInt -genBlockReturn(void) -{ - if (needsFrame) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, FPReg, SPReg); - /* begin PopR: */ - genoperand(PopR, FPReg); - /* begin PopR: */ - genoperand(PopR, LinkReg); - } - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - - /* can't fall through */ - deadCode = 1; - return 0; -} - - -/* Generate special versions of the ceCallCogCodePopReceiverAndClassRegs - enilopmart that also pop register args from the stack to undo the pushing - of register args in the abort/miss trampolines. */ - - /* StackToRegisterMappingCogit>>#genCallPICEnilopmartNumArgs: */ -static void (*genCallPICEnilopmartNumArgs(sqInt numArgs))(void) - -{ - AbstractInstruction *anInstruction; - sqInt endAddress; - usqInt enilopmart; - sqInt quickConstant; - sqInt reg; - sqInt size; - - zeroOpcodeIndex(); - /* begin MoveCq:R: */ - quickConstant = varBaseAddress(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - genLoadStackPointers(backEnd); - /* begin PopR: */ - genoperand(PopR, ClassReg); - /* begin PopR: */ - genoperand(PopR, TempReg); - /* begin PopR: */ - reg = LinkReg; - genoperand(PopR, reg); - if (numArgs > 0) { - if (numArgs > 1) { - /* begin PopR: */ - genoperand(PopR, Arg1Reg); - assert((numRegArgs()) == 2); - } - /* begin PopR: */ - genoperand(PopR, Arg0Reg); - } - /* begin PopR: */ - genoperand(PopR, ReceiverResultReg); - /* begin JumpR: */ - genoperand(JumpR, TempReg); - computeMaximumSizes(); - size = generateInstructionsAt(methodZoneBase); - endAddress = outputInstructionsAt(methodZoneBase); - assert((methodZoneBase + size) == endAddress); - enilopmart = methodZoneBase; - methodZoneBase = alignUptoRoutineBoundary(endAddress); - stopsFromto(backEnd, endAddress, methodZoneBase - 1); - recordGeneratedRunTimeaddress(trampolineNamenumRegArgs("ceCallPIC", numArgs), enilopmart); - return ((void (*)(void)) enilopmart); -} - - -/* Override to push the register receiver and register arguments, if any. */ - - /* StackToRegisterMappingCogit>>#genExternalizePointersForPrimitiveCall */ -static sqInt -genExternalizePointersForPrimitiveCall(void) -{ - AbstractInstruction *anInstruction; - - genPushRegisterArgs(); - /* begin checkLiteral:forInstruction: */ - instructionPointerAddress(); - anInstruction = genoperandoperand(MoveRAw, LinkReg, instructionPointerAddress()); - return genSaveStackPointers(backEnd); -} - - -/* Override to push the register receiver and register arguments, if any. */ - - /* StackToRegisterMappingCogit>>#genExternalizeStackPointerForFastPrimitiveCall */ -static AbstractInstruction * -genExternalizeStackPointerForFastPrimitiveCall(void) -{ - AbstractInstruction *anInstruction; - - genPushRegisterArgs(); - return (/* begin checkLiteral:forInstruction: */ - stackPointerAddress(), - (anInstruction = genoperandoperand(MoveRAw, SPReg, stackPointerAddress())), - anInstruction); -} - - -/* Block compilation. At this point in the method create the block. Note its - start and defer generating code for it until after the method and any - other preceding - blocks. The block's actual code will be compiled later. */ -/* 253 11111101 eei i i kkk jjjjjjjj Push Closure Num Copied iii (+ Ext A - // 16 * 8) Num Args kkk (+ Ext A \\ 16 * 8) BlockSize jjjjjjjj (+ Ext B * - 256). ee = num extensions - */ - - /* StackToRegisterMappingCogit>>#genExtPushClosureBytecode */ -static sqInt -genExtPushClosureBytecode(void) -{ - sqInt i; - sqInt numArgs; - sqInt numCopied; - sqInt reg; - sqInt startpc; - - assert(needsFrame); - startpc = bytecodePC + (((generatorAt(byte0))->numBytes)); - addBlockStartAtnumArgsnumCopiedspan(startpc, (numArgs = (byte1 & 7) + ((extA % 16) * 8)), (numCopied = ((((usqInt)(byte1)) >> 3) & 7) + ((extA / 16) * 8)), byte2 + (((sqInt)((usqInt)(extB) << 8)))); - extA = (numExtB = (extB = 0)); - /* begin genInlineClosure:numArgs:numCopied: */ - assert(getActiveContextAllocatesInMachineCode()); - voidReceiverResultRegContainsSelf(); - /* begin ssAllocateCallReg:and:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg) | (1U << SendNumArgsReg)) | (1U << ClassReg)), simStackPtr, simNativeStackPtr); - genNoPopCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(startpc + 1, numArgs, numCopied, methodOrBlockNumArgs, methodNeedsLargeContext(methodObj), inBlock); - for (i = 1; i <= numCopied; i += 1) { - reg = ssStorePoptoPreferredReg(1, TempReg); - genStoreSourceRegslotIndexintoNewObjectInDestReg(reg, (ClosureFirstCopiedValueIndex + numCopied) - i, ReceiverResultReg); - } - ssPushRegister(ReceiverResultReg); - return 0; -} - - -/* Full Block creation compilation. The block's actual code will be compiled - separatedly. - */ -/* * 255 11111111 xxxxxxxx siyyyyyy push Closure Compiled block literal - index xxxxxxxx (+ Extend A * 256) numCopied yyyyyy receiverOnStack: s = 1 - ignoreOuterContext: i = 1 - */ - - /* StackToRegisterMappingCogit>>#genExtPushFullClosureBytecode */ -static sqInt -genExtPushFullClosureBytecode(void) -{ - sqInt compiledBlock; - sqInt i; - int ignoreContext; - sqInt numCopied; - int receiverIsOnStack; - sqInt reg; - - assert(needsFrame); - compiledBlock = getLiteral(byte1 + (((sqInt)((usqInt)(extA) << 8)))); - extA = 0; - numCopied = byte2 & (0x3F); - receiverIsOnStack = ((byte2 & (128)) != 0); - ignoreContext = ((byte2 & (64)) != 0); - voidReceiverResultRegContainsSelf(); - /* begin ssAllocateCallReg:and:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg) | (1U << SendNumArgsReg)) | (1U << ClassReg)), simStackPtr, simNativeStackPtr); - genCreateFullClosurenumArgsnumCopiedignoreContextcontextNumArgslargeinBlock(compiledBlock, argumentCountOf(compiledBlock), numCopied, ignoreContext, methodOrBlockNumArgs, methodNeedsLargeContext(methodObj), inBlock); - for (i = 1; i <= numCopied; i += 1) { - reg = ssStorePoptoPreferredReg(1, TempReg); - genStoreSourceRegslotIndexintoNewObjectInDestReg(reg, (FullClosureFirstCopiedValueIndex + numCopied) - i, ReceiverResultReg); - } - if (receiverIsOnStack) { - reg = ssStorePoptoPreferredReg(1, TempReg); - } - else { - storeToReg(simSelf(), (reg = TempReg)); - } - genStoreSourceRegslotIndexintoNewObjectInDestReg(reg, FullClosureReceiverIndex, ReceiverResultReg); - ssPushRegister(ReceiverResultReg); - return 0; -} - - -/* Enilopmarts transfer control from C into machine code (backwards - trampolines). - */ -/* Enilopmarts transfer control from C into machine code (backwards - trampolines). Override to add version for generic and PIC-specific entry - with reg args. */ - - /* StackToRegisterMappingCogit>>#generateEnilopmarts */ -static void -generateEnilopmarts(void) -{ - -# if Debug - /* begin genEnilopmartFor:forCall:called: */ - realCEEnterCogCodePopReceiverReg = genEnilopmartForandandforCallcalled(ReceiverResultReg, NoReg, NoReg, 0, "realCEEnterCogCodePopReceiverReg"); - ceEnterCogCodePopReceiverReg = enterCogCodePopReceiver; - /* begin genEnilopmartFor:forCall:called: */ - realCECallCogCodePopReceiverReg = genEnilopmartForandandforCallcalled(ReceiverResultReg, NoReg, NoReg, 1, "realCECallCogCodePopReceiverReg"); - ceCallCogCodePopReceiverReg = callCogCodePopReceiver; - /* begin genEnilopmartFor:and:forCall:called: */ - realCECallCogCodePopReceiverAndClassRegs = genEnilopmartForandandforCallcalled(ReceiverResultReg, ClassReg, NoReg, 1, "realCECallCogCodePopReceiverAndClassRegs"); - ceCallCogCodePopReceiverAndClassRegs = callCogCodePopReceiverAndClassRegs; -# else // Debug - /* begin genEnilopmartFor:forCall:called: */ - ceEnterCogCodePopReceiverReg = genEnilopmartForandandforCallcalled(ReceiverResultReg, NoReg, NoReg, 0, "ceEnterCogCodePopReceiverReg"); - /* begin genEnilopmartFor:forCall:called: */ - ceCallCogCodePopReceiverReg = genEnilopmartForandandforCallcalled(ReceiverResultReg, NoReg, NoReg, 1, "ceCallCogCodePopReceiverReg"); - /* begin genEnilopmartFor:and:forCall:called: */ - ceCallCogCodePopReceiverAndClassRegs = genEnilopmartForandandforCallcalled(ReceiverResultReg, ClassReg, NoReg, 1, "ceCallCogCodePopReceiverAndClassRegs"); -# endif // Debug - genPrimReturnEnterCogCodeEnilopmart(0); - cePrimReturnEnterCogCode = methodZoneBase; - outputInstructionsForGeneratedRuntimeAt(cePrimReturnEnterCogCode); - recordGeneratedRunTimeaddress("cePrimReturnEnterCogCode", cePrimReturnEnterCogCode); - genPrimReturnEnterCogCodeEnilopmart(1); - cePrimReturnEnterCogCodeProfiling = methodZoneBase; - outputInstructionsForGeneratedRuntimeAt(cePrimReturnEnterCogCodeProfiling); - recordGeneratedRunTimeaddress("cePrimReturnEnterCogCodeProfiling", cePrimReturnEnterCogCodeProfiling); -# if Debug - /* begin genEnilopmartFor:and:forCall:called: */ - realCECallCogCodePopReceiverArg0Regs = genEnilopmartForandandforCallcalled(ReceiverResultReg, Arg0Reg, NoReg, 1, "realCECallCogCodePopReceiverArg0Regs"); - ceCallCogCodePopReceiverArg0Regs = callCogCodePopReceiverArg0Regs; - realCECallCogCodePopReceiverArg1Arg0Regs = genEnilopmartForandandforCallcalled(ReceiverResultReg, Arg0Reg, Arg1Reg, 1, "realCECallCogCodePopReceiverArg1Arg0Regs"); - ceCallCogCodePopReceiverArg1Arg0Regs = callCogCodePopReceiverArg1Arg0Regs; -# else // Debug - /* begin genEnilopmartFor:and:forCall:called: */ - ceCallCogCodePopReceiverArg0Regs = genEnilopmartForandandforCallcalled(ReceiverResultReg, Arg0Reg, NoReg, 1, "ceCallCogCodePopReceiverArg0Regs"); - ceCallCogCodePopReceiverArg1Arg0Regs = genEnilopmartForandandforCallcalled(ReceiverResultReg, Arg0Reg, Arg1Reg, 1, "ceCallCogCodePopReceiverArg1Arg0Regs"); -# endif // Debug - ceCall0ArgsPIC = genCallPICEnilopmartNumArgs(0); - ceCall1ArgsPIC = genCallPICEnilopmartNumArgs(1); - ceCall2ArgsPIC = genCallPICEnilopmartNumArgs(2); - assert((numRegArgs()) == 2); -} - - -/* Size pc-dependent instructions and assign eventual addresses to all - instructions. Answer the size of the code. - Compute forward branches based on virtual address (abstract code starts at - 0), assuming that any branches branched over are long. - Compute backward branches based on actual address. - Reuse the fixups array to record the pc-dependent instructions that need - to have - their code generation postponed until after the others. - - Override to add handling for null branches (branches to the immediately - following instruction) occasioned by StackToRegisterMapping's following of - jumps. */ - - /* StackToRegisterMappingCogit>>#generateInstructionsAt: */ -static sqInt NoDbgRegParms -generateInstructionsAt(sqInt eventualAbsoluteAddress) -{ - sqInt absoluteAddress; - AbstractInstruction *abstractInstruction; - BytecodeFixup *fixup; - sqInt i; - sqInt j; - sqInt pcDependentIndex; - - absoluteAddress = eventualAbsoluteAddress; - pcDependentIndex = 0; - for (i = 0; i < opcodeIndex; i += 1) { - - /* N.B. if you want to break in resizing, break here, note the instruction index, back up to the - sender, restart, and step into computeMaximumSizes, breaking at this instruction's index. */ - abstractInstruction = abstractInstructionAt(i); - maybeBreakGeneratingFromto(absoluteAddress, absoluteAddress + ((abstractInstruction->maxSize))); - if (isPCDependent(abstractInstruction)) { - sizePCDependentInstructionAt(abstractInstruction, absoluteAddress); - if ((isJump(abstractInstruction)) - && ((((i + 1) < opcodeIndex) - && ((((AbstractInstruction *) (((abstractInstruction->operands))[0]))) == (abstractInstructionAt(i + 1)))) - || (((i + 2) < opcodeIndex) - && (((((AbstractInstruction *) (((abstractInstruction->operands))[0]))) == (abstractInstructionAt(i + 2))) - && ((((abstractInstructionAt(i + 1))->opcode)) == Nop))))) { - (abstractInstruction->opcode = Nop); - concretizeAt(abstractInstruction, absoluteAddress); - } - else { - fixup = fixupAtIndex(pcDependentIndex); - pcDependentIndex += 1; - (fixup->instructionIndex = i); - } - absoluteAddress += (abstractInstruction->machineCodeSize); - } - else { - - /* N.B. if you want to break in resizing, break here, note the instruction index, back up to the - sender, restart, and step into computeMaximumSizes, breaking at this instruction's index. */ - absoluteAddress = concretizeAt(abstractInstruction, absoluteAddress); - assert(((abstractInstruction->machineCodeSize)) == ((abstractInstruction->maxSize))); - } - } - for (j = 0; j < pcDependentIndex; j += 1) { - fixup = fixupAtIndex(j); - abstractInstruction = abstractInstructionAt((fixup->instructionIndex)); - maybeBreakGeneratingFromto((abstractInstruction->address), (((abstractInstruction->address)) + ((abstractInstruction->maxSize))) - 1); - concretizeAt(abstractInstruction, (abstractInstruction->address)); - } - return absoluteAddress - eventualAbsoluteAddress; -} - - -/* Generate the run-time entries for the various method and PIC entry misses - and aborts. - Read the class-side method trampolines for documentation on the various - trampolines - */ - - /* StackToRegisterMappingCogit>>#generateMissAbortTrampolines */ -static void -generateMissAbortTrampolines(void) -{ - sqInt numArgs; - sqInt numArgsLimiT; - - for (numArgs = 0, numArgsLimiT = (3); numArgs <= numArgsLimiT; numArgs += 1) { - methodAbortTrampolines[numArgs] = (genMethodAbortTrampolineFor(numArgs)); - } - for (numArgs = 0, numArgsLimiT = (3); numArgs <= numArgsLimiT; numArgs += 1) { - picAbortTrampolines[numArgs] = (genPICAbortTrampolineFor(numArgs)); - } - for (numArgs = 0, numArgsLimiT = (3); numArgs <= numArgsLimiT; numArgs += 1) { - picMissTrampolines[numArgs] = (genPICMissTrampolineFor(numArgs)); - } - /* begin genTrampolineFor:called:arg: */ - ceReapAndResetErrorCodeTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceReapAndResetErrorCodeFor, "ceReapAndResetErrorCodeTrampoline", 1, ClassReg, null, null, null, 0 /* emptyRegisterMask */, 1, NoReg, 0); -} - - -/* Override to generate code to push the register arg(s) for <= numRegArg - arity sends. - */ - - /* StackToRegisterMappingCogit>>#generateSendTrampolines */ -static void -generateSendTrampolines(void) -{ - sqInt numArgs; - - for (numArgs = 0; numArgs < NumSendTrampolines; numArgs += 1) { - ordinarySendTrampolines[numArgs] = (genSendTrampolineFornumArgscalledargargargarg(ceSendsupertonumArgs, numArgs, trampolineNamenumArgs("ceSend", numArgs), ClassReg, trampolineArgConstant(0), ReceiverResultReg, (numArgs <= (NumSendTrampolines - 2) - ? (/* begin trampolineArgConstant: */ - assert(numArgs >= 0), - -2 - numArgs) - : SendNumArgsReg))); - } - for (numArgs = 0; numArgs < NumSendTrampolines; numArgs += 1) { - directedSuperSendTrampolines[numArgs] = (genSendTrampolineFornumArgscalledargargargarg(ceSendabovetonumArgs, numArgs, trampolineNamenumArgs("ceDirectedSuperSend", numArgs), ClassReg, TempReg, ReceiverResultReg, (numArgs <= (NumSendTrampolines - 2) - ? (/* begin trampolineArgConstant: */ - assert(numArgs >= 0), - -2 - numArgs) - : SendNumArgsReg))); - directedSuperBindingSendTrampolines[numArgs] = (genSendTrampolineFornumArgscalledargargargarg(ceSendaboveClassBindingtonumArgs, numArgs, trampolineNamenumArgs("ceDirectedSuperBindingSend", numArgs), ClassReg, TempReg, ReceiverResultReg, (numArgs <= (NumSendTrampolines - 2) - ? (/* begin trampolineArgConstant: */ - assert(numArgs >= 0), - -2 - numArgs) - : SendNumArgsReg))); - } - for (numArgs = 0; numArgs < NumSendTrampolines; numArgs += 1) { - superSendTrampolines[numArgs] = (genSendTrampolineFornumArgscalledargargargarg(ceSendsupertonumArgs, numArgs, trampolineNamenumArgs("ceSuperSend", numArgs), ClassReg, trampolineArgConstant(1), ReceiverResultReg, (numArgs <= (NumSendTrampolines - 2) - ? (/* begin trampolineArgConstant: */ - assert(numArgs >= 0), - -2 - numArgs) - : SendNumArgsReg))); - } - firstSend = ordinarySendTrampolines[0]; - lastSend = superSendTrampolines[NumSendTrampolines - 1]; -} - - -/* Generate trampolines for tracing. In the simulator we can save a lot of - time and avoid noise instructions in the lastNInstructions log by - short-cutting these - trampolines, but we need them in the real vm. */ - - /* StackToRegisterMappingCogit>>#generateTracingTrampolines */ -static void -generateTracingTrampolines(void) -{ - /* begin genTrampolineFor:called:arg:regsToSave: */ - ceTraceLinkedSendTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceTraceLinkedSend, "ceTraceLinkedSendTrampoline", 1, ReceiverResultReg, null, null, null, CallerSavedRegisterMask, 1, NoReg, 0); - /* begin genTrampolineFor:called:regsToSave: */ - ceTraceBlockActivationTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceTraceBlockActivation, "ceTraceBlockActivationTrampoline", 0, null, null, null, null, CallerSavedRegisterMask, 1, NoReg, 0); - /* begin genTrampolineFor:called:arg:arg:regsToSave: */ - ceTraceStoreTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceTraceStoreOfinto, "ceTraceStoreTrampoline", 2, TempReg, ReceiverResultReg, null, null, CallerSavedRegisterMask, 1, NoReg, 0); -} - - -/* Generates the machine code for #== in the case where the instruction is - not followed by a branch - */ - - /* StackToRegisterMappingCogit>>#genIdenticalNoBranchArgIsConstant:rcvrIsConstant:argReg:rcvrReg:orNotIf: */ -static sqInt NoDbgRegParms -genIdenticalNoBranchArgIsConstantrcvrIsConstantargRegrcvrRegorNotIf(sqInt argIsConstant, sqInt rcvrIsConstant, sqInt argReg, sqInt rcvrRegOrNone, sqInt orNot) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - sqInt constant; - sqInt constant1; - sqInt constant11; - sqInt constant2; - sqInt constant3; - sqInt constant4; - AbstractInstruction *jumpEqual; - AbstractInstruction *jumpNotEqual; - AbstractInstruction *label; - sqInt resultReg; - - /* begin Label */ - label = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - /* begin genCmpArgIsConstant:rcvrIsConstant:argReg:rcvrReg: */ - assert((argReg != NoReg) - || (rcvrRegOrNone != NoReg)); - if (argIsConstant) { - /* begin genCmpConstant:R: */ - constant4 = ((ssTop())->constant); - if (shouldAnnotateObjectReference(constant4)) { - annotateobjRef(checkLiteralforInstruction(constant4, genoperandoperand(CmpCwR, constant4, rcvrRegOrNone)), constant4); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, constant4, rcvrRegOrNone); - } - } - else { - if (rcvrIsConstant) { - /* begin genCmpConstant:R: */ - constant11 = ((ssValue(1))->constant); - if (shouldAnnotateObjectReference(constant11)) { - annotateobjRef(checkLiteralforInstruction(constant11, genoperandoperand(CmpCwR, constant11, argReg)), constant11); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, constant11, argReg); - } - } - else { - /* begin CmpR:R: */ - assert(!((argReg == SPReg))); - genoperandoperand(CmpRR, argReg, rcvrRegOrNone); - } - } - ssPop(2); - resultReg = (rcvrRegOrNone == NoReg - ? argReg - : rcvrRegOrNone); - /* begin JumpZero: */ - jumpEqual = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - if (!argIsConstant) { - /* begin genEnsureOopInRegNotForwarded:scratchReg:jumpBackTo: */ - genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(argReg, TempReg, label, 0); - } - if (!rcvrIsConstant) { - /* begin genEnsureOopInRegNotForwarded:scratchReg:jumpBackTo: */ - genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(rcvrRegOrNone, TempReg, label, 0); - } - if (orNot) { - /* begin genMoveTrueR: */ - constant = trueObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, resultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, constant, resultReg); - } - } - else { - /* begin genMoveFalseR: */ - constant1 = falseObject(); - if (shouldAnnotateObjectReference(constant1)) { - annotateobjRef(checkLiteralforInstruction(constant1, genoperandoperand(MoveCwR, constant1, resultReg)), constant1); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(MoveCqR, constant1, resultReg); - } - } - /* begin Jump: */ - jumpNotEqual = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpEqual, (orNot - ? (/* begin genMoveFalseR: */ - (constant2 = falseObject()), - (shouldAnnotateObjectReference(constant2) - ? annotateobjRef(checkLiteralforInstruction(constant2, genoperandoperand(MoveCwR, constant2, resultReg)), constant2) - : (/* begin checkQuickConstant:forInstruction: */ - (anInstruction4 = genoperandoperand(MoveCqR, constant2, resultReg)), - anInstruction4))) - : (/* begin genMoveTrueR: */ - (constant3 = trueObject()), - (shouldAnnotateObjectReference(constant3) - ? annotateobjRef(checkLiteralforInstruction(constant3, genoperandoperand(MoveCwR, constant3, resultReg)), constant3) - : (/* begin checkQuickConstant:forInstruction: */ - (anInstruction5 = genoperandoperand(MoveCqR, constant3, resultReg)), - anInstruction5))))); - jmpTarget(jumpNotEqual, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushRegister(resultReg); - return 0; -} - - -/* Decompose code generation for #== into a common constant-folding version, - followed by a double dispatch through the objectRepresentation to a - version that doesn't deal with forwarders and a version that does. */ - - /* StackToRegisterMappingCogit>>#genInlinedIdenticalOrNotIf: */ -static sqInt NoDbgRegParms -genInlinedIdenticalOrNotIf(sqInt orNot) -{ - BytecodeDescriptor *primDescriptor; - sqInt result; - - primDescriptor = generatorAt(byte0); - if ((isUnannotatableConstant(ssTop())) - && (isUnannotatableConstant(ssValue(1)))) { - assert(!((primDescriptor->isMapped))); - result = ((orNot - ? (((ssTop())->constant)) != (((ssValue(1))->constant)) - : (((ssTop())->constant)) == (((ssValue(1))->constant))) - ? trueObject() - : falseObject()); - ssPop(2); - return ssPushConstant(result); - } - /* begin genInlinedIdenticalOrNotIfGuts: */ - return genForwardersInlinedIdenticalOrNotIf(orNot); -} - - /* StackToRegisterMappingCogit>>#genJumpBackTo: */ -static sqInt NoDbgRegParms -genJumpBackTo(sqInt targetBytecodePC) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *anInstruction; - sqInt i; - void *jumpTarget; - void *jumpTarget1; - - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - - /* can't fall through */ - deadCode = 1; - /* begin checkLiteral:forInstruction: */ - stackLimitAddress(); - anInstruction = genoperandoperand(MoveAwR, stackLimitAddress(), TempReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, SPReg); - /* begin JumpAboveOrEqual: */ - jumpTarget = fixupAtIndex(targetBytecodePC - initialPC); - genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)jumpTarget)); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceCheckForInterruptTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin annotateBytecode: */ - abstractInstruction1 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction1->annotation = HasBytecodePC); - /* begin Jump: */ - jumpTarget1 = fixupAtIndex(targetBytecodePC - initialPC); - genoperand(Jump, ((sqInt)jumpTarget1)); - return 0; -} - - /* StackToRegisterMappingCogit>>#genJumpTo: */ -static sqInt NoDbgRegParms -genJumpTo(sqInt targetBytecodePC) -{ - sqInt eventualTarget; - BytecodeFixup * fixup; - BytecodeDescriptor * generator; - sqInt i; - sqInt i1; - - eventualTarget = eventualTargetOf(targetBytecodePC); - if ((eventualTarget > bytecodePC) - && (((simStackPtr >= methodOrBlockNumArgs) - && (stackEntryIsBoolean(ssTop()))) - && ((((generator = generatorForPC(eventualTarget))->isBranchTrue)) - || (((generator = generatorForPC(eventualTarget))->isBranchFalse))))) { - eventualTarget = (eventualTarget + ((generator->numBytes))) + ((((generator->isBranchTrue)) == ((((ssTop())->constant)) == (trueObject())) - ? (/* begin spanFor:at:exts:in: */ - ((generator->spanFunction))(generator, eventualTarget, 0, methodObj)) - : 0)); - ssPop(1); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - fixup = ensureFixupAt(eventualTarget); - ssPop(-1); - } - else { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i1 <= simStackPtr; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - fixup = ensureFixupAt(eventualTarget); - } - - /* can't fall through */ - deadCode = 1; - /* begin Jump: */ - genoperand(Jump, ((sqInt)fixup)); - return 0; -} - - /* StackToRegisterMappingCogit>>#genMarshalledSend:numArgs:sendTable: */ -static sqInt NoDbgRegParms -genMarshalledSendnumArgssendTable(sqInt selectorIndex, sqInt numArgs, sqInt *sendTable) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt annotation; - - assert(needsFrame); - /* begin annotationForSendTable: */ - if (sendTable == ordinarySendTrampolines) { - annotation = IsSendCall; - goto l2; - } - if (sendTable == directedSuperSendTrampolines) { - annotation = IsDirectedSuperSend; - goto l2; - } - if (sendTable == directedSuperBindingSendTrampolines) { - annotation = IsDirectedSuperBindingSend; - goto l2; - } - assert(sendTable == superSendTrampolines); - annotation = IsSuperSend; - l2: /* end annotationForSendTable: */; - if ((annotation == IsSuperSend) - || (((annotation >= IsDirectedSuperSend) && (annotation <= IsDirectedSuperBindingSend)))) { - genEnsureOopInRegNotForwardedscratchReg(ReceiverResultReg, TempReg); - } - if (numArgs >= (NumSendTrampolines - 1)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, numArgs, SendNumArgsReg); - } - if (((annotation >= IsDirectedSuperSend) && (annotation <= IsDirectedSuperBindingSend))) { - /* begin genMoveConstant:R: */ - if (shouldAnnotateObjectReference(tempOop)) { - annotateobjRef(checkLiteralforInstruction(tempOop, genoperandoperand(MoveCwR, tempOop, TempReg)), tempOop); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, tempOop, TempReg); - } - } - genLoadInlineCacheWithSelector(selectorIndex); - ((genoperand(Call, sendTable[((numArgs < (NumSendTrampolines - 1)) ? numArgs : (NumSendTrampolines - 1))]))->annotation = annotation); - /* begin voidReceiverOptStatus */ - ((simSelf())->liveRegister = NoReg); - return ssPushRegister(ReceiverResultReg); -} - - -/* Generate the abort for a method. This abort performs either a call of - ceSICMiss: to handle a single-in-line cache miss or a call of - ceStackOverflow: to handle a - stack overflow. It distinguishes the two by testing ResultReceiverReg. If - the register is zero then this is a stack-overflow because a) the receiver - has already - been pushed and so can be set to zero before calling the abort, and b) the - receiver must always contain an object (and hence be non-zero) on SIC - miss. */ - - /* StackToRegisterMappingCogit>>#genMethodAbortTrampolineFor: */ -static usqInt NoDbgRegParms -genMethodAbortTrampolineFor(sqInt numArgs) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *jumpSICMiss; - - zeroOpcodeIndex(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, ReceiverResultReg); - /* begin JumpNonZero: */ - jumpSICMiss = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveR:Mw:r: */ - anInstruction = genoperandoperandoperand(MoveRMwr, LinkReg, 0, SPReg); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(ceStackOverflow, 1, SendNumArgsReg, null, null, null, 0 /* emptyRegisterMask */, 0, NoReg); - jmpTarget(jumpSICMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genPushRegisterArgsForAbortMissNumArgs(backEnd, numArgs); - return genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceSICMiss, trampolineNamenumRegArgs("ceMethodAbort", numArgs), 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 0, NoReg, 1); -} - - -/* Generate the abort for a PIC. This abort performs either a call of - ceInterpretMethodFromPIC:receiver: to handle invoking an uncogged - target or a call of ceMNUFromPICMNUMethod:receiver: to handle an - MNU dispatch in a closed PIC. It distinguishes the two by testing - ClassReg. If the register is zero then this is an MNU. */ - - /* StackToRegisterMappingCogit>>#genPICAbortTrampolineFor: */ -static usqInt NoDbgRegParms -genPICAbortTrampolineFor(sqInt numArgs) -{ - zeroOpcodeIndex(); - genPushRegisterArgsForAbortMissNumArgs(backEnd, numArgs); - return genInnerPICAbortTrampoline(trampolineNamenumRegArgs("cePICAbort", numArgs)); -} - - /* StackToRegisterMappingCogit>>#genPICMissTrampolineFor: */ -static usqInt NoDbgRegParms -genPICMissTrampolineFor(sqInt numArgs) -{ - usqInt startAddress; - - startAddress = methodZoneBase; - zeroOpcodeIndex(); - genPushRegisterArgsForNumArgsscratchReg(backEnd, numArgs, SendNumArgsReg); - genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceCPICMissreceiver, trampolineNamenumRegArgs("cePICMiss", numArgs), 2, ClassReg, ReceiverResultReg, null, null, 0 /* emptyRegisterMask */, 1, NoReg, 1); - return startAddress; -} - - /* StackToRegisterMappingCogit>>#genPopStackBytecode */ -static sqInt -genPopStackBytecode(void) -{ - AbstractInstruction *anInstruction; - - if (((ssTop())->spilled)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, BytesPerWord, SPReg); - } - ssPop(1); - return 0; -} - - -/* Check the argument count. Fail if wrong. - Get the method from the outerContext and see if it is cogged. If so, jump - to the - block entry or the no-context-switch entry, as appropriate, and we're - done. If not, - invoke the interpreter primitive. */ -/* Check the argument count. Fail if wrong. - Get the method from the outerContext and see if it is cogged. If so, jump - to the - block entry or the no-context-switch entry, as appropriate, and we're - done. If not, - invoke the interpreter primitive. - Override to push the register args first. */ - - /* StackToRegisterMappingCogit>>#genPrimitiveClosureValue */ -static sqInt -genPrimitiveClosureValue(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *jumpBCMethod; - AbstractInstruction *jumpFail1; - AbstractInstruction *jumpFail2; - AbstractInstruction *jumpFail3; - AbstractInstruction *jumpFail4; - AbstractInstruction *jumpFailNArgs; - sqInt offset; - void (*primitiveRoutine)(void); - sqInt result; - - genPushRegisterArgs(); - genLoadSlotsourceRegdestReg(ClosureNumArgsIndex, ReceiverResultReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)methodOrBlockNumArgs << 1) | 1); - anInstruction1 = genoperandoperand(CmpCqR, (((usqInt)methodOrBlockNumArgs << 1) | 1), TempReg); - /* begin JumpNonZero: */ - jumpFailNArgs = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(ClosureOuterContextIndex, ReceiverResultReg, ClassReg); - jumpFail1 = genJumpImmediate(ClassReg); - genGetCompactClassIndexNonImmOfinto(ClassReg, TempReg); - genCmpClassMethodContextCompactIndexR(TempReg); - /* begin JumpNonZero: */ - jumpFail2 = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(MethodIndex, ClassReg, SendNumArgsReg); - jumpFail3 = genJumpImmediate(SendNumArgsReg); - genGetFormatOfinto(SendNumArgsReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction2 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), TempReg); - /* begin JumpLess: */ - jumpFail4 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - genLoadSlotsourceRegdestReg(HeaderIndex, SendNumArgsReg, ClassReg); - jumpBCMethod = genJumpImmediate(ClassReg); - /* begin MoveM16:r:R: */ - offset = offsetof(CogMethod, blockEntryOffset); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperandoperand(MoveM16rR, offset, ClassReg, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, ClassReg, TempReg); - primitiveRoutine = functionPointerForCompiledMethodprimitiveIndexprimitivePropertyFlagsInto(methodObj, primitiveIndex, null); - if (primitiveRoutine == primitiveClosureValueNoContextSwitch) { - if (blockNoContextSwitchOffset == null) { - return NotFullyInitialized; - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, blockNoContextSwitchOffset, TempReg); - } - /* begin JumpR: */ - genoperand(JumpR, TempReg); - jmpTarget(jumpBCMethod, jmpTarget(jumpFail1, jmpTarget(jumpFail2, jmpTarget(jumpFail3, jmpTarget(jumpFail4, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))))); - if (((result = compileInterpreterPrimitiveflags(primitiveRoutine, primitivePropertyFlags(primitiveIndex)))) < 0) { - return result; - } - jmpTarget(jumpFailNArgs, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - -/* Check the argument count. Fail if wrong. - Get the method from the outerContext and see if it is cogged. If so, jump - to the - block entry or the no-context-switch entry, as appropriate, and we're - done. If not, - invoke the interpreter primitive. */ -/* Override to push the register args first. */ - - /* StackToRegisterMappingCogit>>#genPrimitiveFullClosureValue */ -static sqInt -genPrimitiveFullClosureValue(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *jumpBCMethod; - AbstractInstruction *jumpFail4; - AbstractInstruction *jumpFailImmediateMethod; - AbstractInstruction *jumpFailNArgs; - void (*primitiveRoutine)(void); - sqInt quickConstant; - sqInt result; - - genPushRegisterArgs(); - genLoadSlotsourceRegdestReg(ClosureNumArgsIndex, ReceiverResultReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)methodOrBlockNumArgs << 1) | 1); - anInstruction = genoperandoperand(CmpCqR, (((usqInt)methodOrBlockNumArgs << 1) | 1), TempReg); - /* begin JumpNonZero: */ - jumpFailNArgs = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(FullClosureCompiledBlockIndex, ReceiverResultReg, SendNumArgsReg); - jumpFailImmediateMethod = genJumpImmediate(SendNumArgsReg); - genGetFormatOfinto(SendNumArgsReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction1 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), TempReg); - /* begin JumpLess: */ - jumpFail4 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - genLoadSlotsourceRegdestReg(HeaderIndex, SendNumArgsReg, ClassReg); - jumpBCMethod = genJumpImmediate(ClassReg); - primitiveRoutine = functionPointerForCompiledMethodprimitiveIndexprimitivePropertyFlagsInto(methodObj, primitiveIndex, null); - /* begin AddCq:R: */ - quickConstant = (primitiveRoutine == primitiveFullClosureValueNoContextSwitch - ? fullBlockNoContextSwitchEntryOffset() - : fullBlockEntryOffset()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AddCqR, quickConstant, ClassReg); - /* begin JumpR: */ - genoperand(JumpR, ClassReg); - jmpTarget(jumpBCMethod, jmpTarget(jumpFailImmediateMethod, jmpTarget(jumpFail4, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))); - if (((result = compileInterpreterPrimitiveflags(primitiveRoutine, primitivePropertyFlags(primitiveIndex)))) < 0) { - return result; - } - jmpTarget(jumpFailNArgs, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - -/* Generate an in-line perform primitive. The lookup code requires the - selector to be in Arg0Reg. - adjustArgumentsForPerform: adjusts the arguments once - genLookupForPerformNumArgs: has generated the code for the lookup. */ - - /* StackToRegisterMappingCogit>>#genPrimitivePerform */ -static sqInt -genPrimitivePerform(void) -{ - AbstractInstruction *anInstruction; - sqInt offset; - - if (methodOrBlockNumArgs > 2 /* numRegArgs */) { - /* begin MoveMw:r:R: */ - offset = (methodOrBlockNumArgs - 1) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, SPReg, Arg0Reg); - } - return genLookupForPerformNumArgs(methodOrBlockNumArgs); -} - - /* StackToRegisterMappingCogit>>#genPushActiveContextBytecode */ -static sqInt -genPushActiveContextBytecode(void) -{ - assert(needsFrame); - voidReceiverResultRegContainsSelf(); - /* begin ssAllocateCallReg:and:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg) | (1U << SendNumArgsReg)) | (1U << ClassReg)), simStackPtr, simNativeStackPtr); - genGetActiveContextNumArgslargeinBlock(methodOrBlockNumArgs, methodNeedsLargeContext(methodObj), inBlock); - return ssPushRegister(ReceiverResultReg); -} - - -/* Block compilation. At this point in the method create the block. Note its - start and defer generating code for it until after the method and any - other preceding - blocks. The block's actual code will be compiled later. */ -/* 143 10001111 llllkkkk jjjjjjjj iiiiiiii Push Closure Num Copied llll Num - Args kkkk BlockSize jjjjjjjjiiiiiiii */ - - /* StackToRegisterMappingCogit>>#genPushClosureCopyCopiedValuesBytecode */ -static sqInt -genPushClosureCopyCopiedValuesBytecode(void) -{ - sqInt i; - sqInt numArgs; - sqInt numCopied; - sqInt reg; - sqInt startpc; - - assert(needsFrame); - startpc = bytecodePC + (((generatorAt(byte0))->numBytes)); - addBlockStartAtnumArgsnumCopiedspan(startpc, (numArgs = byte1 & 15), (numCopied = ((usqInt)(byte1)) >> 4), (((sqInt)((usqInt)(byte2) << 8))) + byte3); - /* begin genInlineClosure:numArgs:numCopied: */ - assert(getActiveContextAllocatesInMachineCode()); - voidReceiverResultRegContainsSelf(); - /* begin ssAllocateCallReg:and:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg) | (1U << SendNumArgsReg)) | (1U << ClassReg)), simStackPtr, simNativeStackPtr); - genNoPopCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(startpc + 1, numArgs, numCopied, methodOrBlockNumArgs, methodNeedsLargeContext(methodObj), inBlock); - for (i = 1; i <= numCopied; i += 1) { - reg = ssStorePoptoPreferredReg(1, TempReg); - genStoreSourceRegslotIndexintoNewObjectInDestReg(reg, (ClosureFirstCopiedValueIndex + numCopied) - i, ReceiverResultReg); - } - ssPushRegister(ReceiverResultReg); - return 0; -} - - -/* */ -/* Override to avoid the BytecodeSetHasDirectedSuperSend check, which is - unnecessary here given the simulation stack. */ - - /* StackToRegisterMappingCogit>>#genPushLiteralIndex: */ -static sqInt NoDbgRegParms -genPushLiteralIndex(sqInt literalIndex) -{ - sqInt literal; - - literal = getLiteral(literalIndex); - return genPushLiteral(literal); -} - - /* StackToRegisterMappingCogit>>#genPushLiteralVariable: */ -static sqInt NoDbgRegParms -genPushLiteralVariable(sqInt literalIndex) -{ - AbstractInstruction *anInstruction; - sqInt association; - sqInt bcpc; - BytecodeDescriptor *descriptor1; - sqInt eA; - sqInt eB; - sqInt freeReg; - sqInt savedB0; - sqInt savedB1; - sqInt savedB2; - sqInt savedB3; - sqInt savedEA; - sqInt savedEB; - sqInt savedNEB; - - - /* If followed by a directed super send bytecode, avoid generating any code yet. - The association will be passed to the directed send trampoline in a register - and fully dereferenced only when first linked. It will be ignored in later sends. */ - association = getLiteral(literalIndex); - assert(!(directedSendUsesBinding)); - /* begin nextDescriptorExtensionsAndNextPCInto: */ - descriptor1 = generatorAt(byte0); - savedB0 = byte0; - savedB1 = byte1; - savedB2 = byte2; - savedB3 = byte3; - savedEA = extA; - savedEB = extB; - savedNEB = numExtB; - bcpc = bytecodePC + ((descriptor1->numBytes)); - do { - if (bcpc > endPC) { - goto l1; - } - byte0 = (fetchByteofObject(bcpc, methodObj)) + bytecodeSetOffset; - descriptor1 = generatorAt(byte0); - loadSubsequentBytesForDescriptorat(descriptor1, bcpc); - if (!((descriptor1->isExtension))) { - eA = extA; - eB = extB; - extA = savedEA; - extB = savedEB; - numExtB = savedNEB; - byte0 = savedB0; - byte1 = savedB1; - byte2 = savedB2; - byte3 = savedB3; - if ((descriptor1 != null) - && ((((descriptor1->generator)) == genExtSendSuperBytecode) - && (eB >= 64))) { - ssPushConstant(association); - directedSendUsesBinding = 1; - return 0; - } - goto l1; - } - ((descriptor1->generator))(); - bcpc += (descriptor1->numBytes); - } while(1); - l1: /* end nextDescriptorExtensionsAndNextPCInto: */; - - /* N.B. Do _not_ use ReceiverResultReg to avoid overwriting receiver in assignment in frameless methods. */ - /* So far descriptors are not rich enough to describe the entire dereference so generate the register - load but don't push the result. There is an order-of-evaluation issue if we defer the dereference. */ - freeReg = allocateRegNotConflictingWith(0); - /* begin genMoveConstant:R: */ - if (shouldAnnotateObjectReference(association)) { - annotateobjRef(checkLiteralforInstruction(association, genoperandoperand(MoveCwR, association, TempReg)), association); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, association, TempReg); - } - genLoadSlotsourceRegdestReg(ValueIndex, TempReg, freeReg); - ssPushRegister(freeReg); - return 0; -} - - /* StackToRegisterMappingCogit>>#genPushLiteral: */ -static sqInt NoDbgRegParms -genPushLiteral(sqInt literal) -{ - return ssPushConstant(literal); -} - - /* StackToRegisterMappingCogit>>#genPushMaybeContextReceiverVariable: */ -static sqInt NoDbgRegParms -genPushMaybeContextReceiverVariable(sqInt slotIndex) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *jmpDone; - AbstractInstruction *jmpSingle; - - /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); - ensureReceiverResultRegContainsSelf(); - /* begin genPushMaybeContextSlotIndex: */ - assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { - - /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ - voidReceiverResultRegContainsSelf(); - } - if (slotIndex == InstructionPointerIndex) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, slotIndex, SendNumArgsReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceFetchContextInstVarTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - return ssPushRegister(SendNumArgsReg); - } - genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); - jmpSingle = genJumpNotSmallIntegerInScratchReg(TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, slotIndex, SendNumArgsReg); - /* begin CallRT: */ - abstractInstruction1 = genoperand(Call, ceFetchContextInstVarTrampoline); - (abstractInstruction1->annotation = IsRelativeCall); - /* begin Jump: */ - jmpDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jmpSingle, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genLoadSlotsourceRegdestReg(slotIndex, ReceiverResultReg, SendNumArgsReg); - jmpTarget(jmpDone, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return ssPushRegister(SendNumArgsReg); -} - - /* StackToRegisterMappingCogit>>#genPushNewArrayBytecode */ -static sqInt -genPushNewArrayBytecode(void) -{ - sqInt i; - sqInt i1; - int popValues; - sqInt size; - - assert(needsFrame); - voidReceiverResultRegContainsSelf(); - if ((popValues = byte1 > 0x7F)) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i1 <= simStackPtr; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - } - else { - /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); - } - size = byte1 & 0x7F; - if (!popValues) { - if (tryCollapseTempVectorInitializationOfSize(size)) { - return 0; - } - } - genNewArrayOfSizeinitialized(size, !popValues); - if (popValues) { - for (i = (size - 1); i >= 0; i += -1) { - /* begin PopR: */ - genoperand(PopR, TempReg); - genStoreSourceRegslotIndexintoNewObjectInDestReg(TempReg, i, ReceiverResultReg); - } - ssPop(size); - } - return ssPushRegister(ReceiverResultReg); -} - - /* StackToRegisterMappingCogit>>#genPushReceiverBytecode */ -static sqInt -genPushReceiverBytecode(void) -{ - if ((((simSelf())->liveRegister)) == ReceiverResultReg) { - return ssPushRegister(ReceiverResultReg); - } - return ssPushDesc(ssSelfDescriptor()); -} - - /* StackToRegisterMappingCogit>>#genPushReceiverVariable: */ -static sqInt NoDbgRegParms -genPushReceiverVariable(sqInt index) -{ - ensureReceiverResultRegContainsSelf(); - return ssPushBaseoffset(ReceiverResultReg, slotOffsetOfInstVarIndex(index)); -} - - -/* Ensure that the register args are pushed before the retpc for methods with - arity <= self numRegArgs. - */ -/* This isn't as clumsy on a RISC. But putting the receiver and - args above the return address means the CoInterpreter has a - single machine-code frame format which saves us a lot of work. */ - - /* StackToRegisterMappingCogit>>#genPushRegisterArgs */ -static void -genPushRegisterArgs(void) -{ - if (!(regArgsHaveBeenPushed - || (methodOrBlockNumArgs > 2 /* numRegArgs */))) { - genPushRegisterArgsForNumArgsscratchReg(backEnd, methodOrBlockNumArgs, SendNumArgsReg); - regArgsHaveBeenPushed = 1; - } -} - - /* StackToRegisterMappingCogit>>#genPushRemoteTempLongBytecode */ -static sqInt -genPushRemoteTempLongBytecode(void) -{ - AbstractInstruction *anInstruction; - sqInt offset; - sqInt regMask; - sqInt remoteTempReg; - sqInt tempVectReg; - - tempVectReg = allocateRegNotConflictingWith(0); - /* begin MoveMw:r:R: */ - offset = frameOffsetOfTemporary(byte2); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, FPReg, tempVectReg); - /* begin availableRegOrNoneNotConflictingWith: */ - regMask = 1U << tempVectReg; - remoteTempReg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); - if (remoteTempReg == NoReg) { - remoteTempReg = tempVectReg; - } - genLoadSlotsourceRegdestReg(byte1, tempVectReg, remoteTempReg); - return ssPushRegister(remoteTempReg); -} - - -/* If a frameless method (not a block), only argument temps can be accessed. - This is assured by the use of needsFrameIfMod16GENumArgs: in pushTemp. */ - - /* StackToRegisterMappingCogit>>#genPushTemporaryVariable: */ -static sqInt NoDbgRegParms -genPushTemporaryVariable(sqInt index) -{ - assert((inBlock > 0) - || (needsFrame - || (index < methodOrBlockNumArgs))); - return ssPushDesc(simStack[index + 1]); -} - - -/* In a frameless method ReceiverResultReg already contains self. - In a frameful method, ReceiverResultReg /may/ contain self. */ - - /* StackToRegisterMappingCogit>>#genReturnReceiver */ -static sqInt -genReturnReceiver(void) -{ - if (needsFrame) { - if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { - /* begin putSelfInReceiverResultReg */ - storeToReg(simSelf(), ReceiverResultReg); - } - } - return genUpArrowReturn(); -} - - /* StackToRegisterMappingCogit>>#genReturnTopFromBlock */ -static sqInt -genReturnTopFromBlock(void) -{ - assert(inBlock > 0); - popToReg(ssTop(), ReceiverResultReg); - ssPop(1); - return genBlockReturn(); -} - - /* StackToRegisterMappingCogit>>#genReturnTopFromMethod */ -static sqInt -genReturnTopFromMethod(void) -{ - popToReg(ssTop(), ReceiverResultReg); - ssPop(1); - return genUpArrowReturn(); -} - - /* StackToRegisterMappingCogit>>#genSendDirectedSuper:numArgs: */ -static sqInt NoDbgRegParms -genSendDirectedSupernumArgs(sqInt selectorIndex, sqInt numArgs) -{ - sqInt result; - - assert((((ssTop())->type)) == SSConstant); - tempOop = ((ssTop())->constant); - ssPop(1); - marshallSendArguments(numArgs); - result = genMarshalledSendnumArgssendTable(selectorIndex, numArgs, (directedSendUsesBinding - ? directedSuperBindingSendTrampolines - : directedSuperSendTrampolines)); - directedSendUsesBinding = 0; - return result; -} - - /* StackToRegisterMappingCogit>>#genSendSuper:numArgs: */ -static sqInt NoDbgRegParms -genSendSupernumArgs(sqInt selectorIndex, sqInt numArgs) -{ - marshallSendArguments(numArgs); - return genMarshalledSendnumArgssendTable(selectorIndex, numArgs, superSendTrampolines); -} - - -/* Generate a trampoline with four arguments. - Hack: a negative value indicates an abstract register, a non-negative - value indicates a constant. */ - - /* StackToRegisterMappingCogit>>#genSendTrampolineFor:numArgs:called:arg:arg:arg:arg: */ -static usqInt NoDbgRegParms -genSendTrampolineFornumArgscalledargargargarg(void *aRoutine, sqInt numArgs, char *aString, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3) -{ - sqInt routine; - usqInt startAddress; - - startAddress = methodZoneBase; - zeroOpcodeIndex(); - genPushRegisterArgsForNumArgsscratchReg(backEnd, numArgs, SendNumArgsReg); - /* begin selectorIndexDereferenceRoutine */ - routine = null; - if (!(routine == null)) { - - /* Explicitly save LinkReg via ExtraReg2; it's presumably faster than pushing/popping */ - /* begin MoveR:R: */ - genoperandoperand(MoveRR, LinkReg, Extra2Reg); - /* begin Call: */ - genoperand(Call, routine); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Extra2Reg, LinkReg); - } - genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(aRoutine, aString, 4, regOrConst0, regOrConst1, regOrConst2, regOrConst3, 0 /* emptyRegisterMask */, 1, NoReg, 1); - return startAddress; -} - - /* StackToRegisterMappingCogit>>#genSend:numArgs: */ -static sqInt NoDbgRegParms -genSendnumArgs(sqInt selectorIndex, sqInt numArgs) -{ - marshallSendArguments(numArgs); - return genMarshalledSendnumArgssendTable(selectorIndex, numArgs, ordinarySendTrampolines); -} - - /* StackToRegisterMappingCogit>>#genSpecialSelectorArithmetic */ -static sqInt -genSpecialSelectorArithmetic(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - sqInt argInt; - int argIsConst; - sqInt argIsInt; - sqInt i; - sqInt index; - AbstractInstruction *jumpContinue; - AbstractInstruction *jumpNotSmallInts; - BytecodeDescriptor *primDescriptor; - sqInt rcvrInt; - int rcvrIsConst; - sqInt rcvrIsInt; - sqInt result; - - primDescriptor = generatorAt(byte0); - argIsInt = ((argIsConst = (((ssTop())->type)) == SSConstant)) - && ((((argInt = ((ssTop())->constant))) & 1)); - rcvrIsInt = (((rcvrIsConst = (((ssValue(1))->type)) == SSConstant)) - && ((((rcvrInt = ((ssValue(1))->constant))) & 1))) - || ((mclassIsSmallInteger()) - && (isSameEntryAs(ssValue(1), simSelf()))); - if (argIsInt - && (rcvrIsInt - && (rcvrIsConst))) { - rcvrInt = (rcvrInt >> 1); - argInt = (argInt >> 1); - switch ((primDescriptor->opcode)) { - case AddRR: - result = rcvrInt + argInt; - break; - case SubRR: - result = rcvrInt - argInt; - break; - case AndRR: - result = rcvrInt & argInt; - break; - case OrRR: - result = rcvrInt | argInt; - break; - default: - error("Case not found and no otherwise clause"); - } - if (isIntegerValue(result)) { - - /* Must annotate the bytecode for correct pc mapping. */ - return (ssPop(2), - ssPushAnnotatedConstant((((usqInt)result << 1) | 1))); - } - return genSpecialSelectorSend(); - } - if ((rcvrIsConst - && (!rcvrIsInt)) - || (argIsConst - && (!argIsInt))) { - return genSpecialSelectorSend(); - } - if (!(argIsInt - || (rcvrIsInt))) { - return genSpecialSelectorSend(); - } - if (argIsInt) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 2)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 2)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 2))); i <= (simStackPtr - 2); i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 2) + 1; - } - popToReg(ssValue(1), ReceiverResultReg); - ssPop(2); - } - else { - marshallSendArguments(1); - } - jumpNotSmallInts = (!(rcvrIsInt - && (argIsInt)) - ? (argIsInt - ? genJumpNotSmallInteger(ReceiverResultReg) - : (rcvrIsInt - ? genJumpNotSmallInteger(Arg0Reg) - : (/* begin genJumpNotSmallIntegersIn:and:scratch: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg), - /* begin AndR:R: */ - genoperandoperand(AndRR, Arg0Reg, TempReg), - genJumpNotSmallIntegerInScratchReg(TempReg)))) - : 0); - switch ((primDescriptor->opcode)) { - case AddRR: - if (argIsInt) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, argInt - ConstZero, ReceiverResultReg); - /* begin JumpNoOverflow: */ - jumpContinue = genConditionalBranchoperand(JumpNoOverflow, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(SubCqR, argInt - ConstZero, ReceiverResultReg); - } - else { - genRemoveSmallIntegerTagsInScratchReg(ReceiverResultReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - /* begin JumpNoOverflow: */ - jumpContinue = genConditionalBranchoperand(JumpNoOverflow, ((sqInt)0)); - if (rcvrIsInt - && (rcvrIsConst)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, rcvrInt, ReceiverResultReg); - } - else { - /* begin SubR:R: */ - genoperandoperand(SubRR, Arg0Reg, ReceiverResultReg); - genSetSmallIntegerTagsIn(ReceiverResultReg); - } - } - break; - case SubRR: - if (argIsInt) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(SubCqR, argInt - ConstZero, ReceiverResultReg); - /* begin JumpNoOverflow: */ - jumpContinue = genConditionalBranchoperand(JumpNoOverflow, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(AddCqR, argInt - ConstZero, ReceiverResultReg); - } - else { - genRemoveSmallIntegerTagsInScratchReg(Arg0Reg); - /* begin SubR:R: */ - genoperandoperand(SubRR, Arg0Reg, ReceiverResultReg); - /* begin JumpNoOverflow: */ - jumpContinue = genConditionalBranchoperand(JumpNoOverflow, ((sqInt)0)); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - genSetSmallIntegerTagsIn(Arg0Reg); - } - break; - case AndRR: - if (argIsInt) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(AndCqR, argInt, ReceiverResultReg); - } - else { - /* begin AndR:R: */ - genoperandoperand(AndRR, Arg0Reg, ReceiverResultReg); - } - jumpContinue = (!(jumpNotSmallInts == null) - ? (/* begin Jump: */ - genoperand(Jump, ((sqInt)0))) - : 0); - break; - case OrRR: - if (argIsInt) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(OrCqR, argInt, ReceiverResultReg); - } - else { - /* begin OrR:R: */ - genoperandoperand(OrRR, Arg0Reg, ReceiverResultReg); - } - jumpContinue = (!(jumpNotSmallInts == null) - ? (/* begin Jump: */ - genoperand(Jump, ((sqInt)0))) - : 0); - break; - default: - error("Case not found and no otherwise clause"); - } - if (jumpNotSmallInts == null) { - if (!jumpContinue) { - - /* overflow cannot happen */ - /* begin annotateInstructionForBytecode */ - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (abstractInstruction->annotation = HasBytecodePC); - ssPushRegister(ReceiverResultReg); - return 0; - } - } - else { - jmpTarget(jumpNotSmallInts, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - if (argIsInt) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(MoveCqR, argInt, Arg0Reg); - } - index = byte0 - ( -#if MULTIPLEBYTECODESETS - (bytecodeSetOffset == 0x100 - ? AltFirstSpecialSelector + 0x100 - : FirstSpecialSelector) -#else - FirstSpecialSelector -#endif - ); - genMarshalledSendnumArgssendTable((-index) - 1, 1, ordinarySendTrampolines); - jmpTarget(jumpContinue, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - /* StackToRegisterMappingCogit>>#genSpecialSelectorClass */ -static sqInt -genSpecialSelectorClass(void) -{ - sqInt requiredReg1; - sqInt topReg; - - topReg = registerOrNone(ssTop()); - ssPop(1); - if ((topReg == NoReg) - || (topReg == ClassReg)) { - /* begin ssAllocateRequiredReg:and: */ - requiredReg1 = (topReg = SendNumArgsReg); - ssAllocateRequiredRegMaskupThroughupThroughNative((1U << requiredReg1) | (1U << ClassReg), simStackPtr, simNativeStackPtr); - } - else { - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr, simNativeStackPtr); - } - ssPush(1); - popToReg(ssTop(), topReg); - genGetClassObjectOfintoscratchRegmayBeAForwarder(topReg, ClassReg, TempReg, mayBeAForwarder(ssTop())); - return (ssPop(1), - ssPushRegister(ClassReg)); -} - - -/* Assumes both operands are ints */ - - /* StackToRegisterMappingCogit>>#genStaticallyResolvedSpecialSelectorComparison */ -static sqInt -genStaticallyResolvedSpecialSelectorComparison(void) -{ - sqInt argInt; - BytecodeDescriptor *primDescriptor; - sqInt rcvrInt; - int result; - - primDescriptor = generatorAt(byte0); - argInt = ((ssTop())->constant); - rcvrInt = ((ssValue(1))->constant); - switch ((primDescriptor->opcode)) { - case JumpLess: - result = rcvrInt < argInt; - break; - case JumpLessOrEqual: - result = rcvrInt <= argInt; - break; - case JumpGreater: - result = rcvrInt > argInt; - break; - case JumpGreaterOrEqual: - result = rcvrInt >= argInt; - break; - case JumpZero: - result = rcvrInt == argInt; - break; - case JumpNonZero: - result = rcvrInt != argInt; - break; - default: - error("Case not found and no otherwise clause"); - } - ssPop(2); - return ssPushAnnotatedConstant((result - ? trueObject() - : falseObject())); -} - - -/* We need a frame because the association has to be in ReceiverResultReg for - the various trampolines - and ReceiverResultReg holds only the receiver in frameless methods. - */ - - /* StackToRegisterMappingCogit>>#genStorePop:LiteralVariable:needsStoreCheck:needsImmutabilityCheck: */ -static sqInt NoDbgRegParms -genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt litVarIndex, sqInt needsStoreCheck, sqInt needsImmCheck) -{ - AbstractInstruction *anInstruction; - sqInt association; - sqInt i; - sqInt topReg; - - assert(needsFrame); - /* begin genLoadLiteralVariable:in: */ - association = getLiteral(litVarIndex); - voidReceiverResultRegContainsSelf(); - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); - /* begin genMoveConstant:R: */ - if (shouldAnnotateObjectReference(association)) { - annotateobjRef(checkLiteralforInstruction(association, genoperandoperand(MoveCwR, association, ReceiverResultReg)), association); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, association, ReceiverResultReg); - } - /* begin genGenericStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr:needsImmutabilityCheck: */ -# if IMMUTABILITY - if (needsImmCheck) { - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); - ssStoreAndReplacePoptoReg(popBoolean, ClassReg); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0); - } -# endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); - ssStorePoptoReg(popBoolean, topReg); - return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); -} - - -/* The reason we need a frame here is that assigning to an inst var of a - context may - involve wholesale reorganization of stack pages, and the only way to - preserve the - execution state of an activation in that case is if it has a frame. */ - - /* StackToRegisterMappingCogit>>#genStorePop:MaybeContextReceiverVariable:needsStoreCheck:needsImmutabilityCheck: */ -static sqInt NoDbgRegParms -genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt slotIndex, sqInt needsStoreCheck, sqInt needsImmCheck) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *abstractInstruction2; - AbstractInstruction *abstractInstruction3; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt i; - AbstractInstruction *immutabilityFailure; - AbstractInstruction *mutableJump; - - immutabilityFailure = ((AbstractInstruction *) 0); - assert(needsFrame); - ssFlushUpThroughReceiverVariable(slotIndex); - ensureReceiverResultRegContainsSelf(); - /* begin genGenericStorePop:MaybeContextSlotIndex:needsStoreCheck:needsRestoreRcvr:needsImmutabilityCheck: */ - assert(needsFrame); -# if IMMUTABILITY - if (needsImmCheck) { - mutableJump = genJumpMutablescratchReg(ReceiverResultReg, TempReg); - /* begin genStoreTrampolineCall: */ - assert(IMMUTABILITY); - if (slotIndex >= (NumStoreTrampolines - 1)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, slotIndex, TempReg); - /* begin CallRT: */ - abstractInstruction3 = genoperand(Call, ceStoreTrampolines[NumStoreTrampolines - 1]); - (abstractInstruction3->annotation = IsRelativeCall); - } - else { - /* begin CallRT: */ - abstractInstruction1 = genoperand(Call, ceStoreTrampolines[slotIndex]); - (abstractInstruction1->annotation = IsRelativeCall); - } - /* begin annotateBytecode: */ - abstractInstruction2 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction2->annotation = HasBytecodePC); - /* begin putSelfInReceiverResultReg */ - storeToReg(simSelf(), ReceiverResultReg); - /* begin Jump: */ - immutabilityFailure = genoperand(Jump, ((sqInt)0)); - jmpTarget(mutableJump, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } -# endif // IMMUTABILITY - ssPop(1); - /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); - ssPush(1); - genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); - ssStoreAndReplacePoptoReg(popBoolean, ClassReg); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, slotIndex, SendNumArgsReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceStoreContextInstVarTrampoline); - (abstractInstruction->annotation = IsRelativeCall); -# if IMMUTABILITY - if (needsImmCheck) { - jmpTarget(immutabilityFailure, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } -# endif - return 0; -} - - /* StackToRegisterMappingCogit>>#genStorePop:ReceiverVariable:needsStoreCheck:needsImmutabilityCheck: */ -static sqInt NoDbgRegParms -genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt slotIndex, sqInt needsStoreCheck, sqInt needsImmCheck) -{ - sqInt i; - sqInt needsImmCheck1; - sqInt needsStoreCheck1; - sqInt topReg; - - ssFlushUpThroughReceiverVariable(slotIndex); - ensureReceiverResultRegContainsSelf(); - /* begin genGenericStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr:needsImmutabilityCheck: */ - needsStoreCheck1 = (!useTwoPaths) - && (needsStoreCheck); - needsImmCheck1 = needsImmCheck - && (!useTwoPaths); -# if IMMUTABILITY - if (needsImmCheck1) { - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); - ssStoreAndReplacePoptoReg(popBoolean, ClassReg); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck1, 1); - } -# endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); - ssStorePoptoReg(popBoolean, topReg); - return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck1); -} - - -/* The only reason we assert needsFrame here is that in a frameless method - ReceiverResultReg must and does contain only self, but the ceStoreCheck - trampoline expects the target of the store to be in ReceiverResultReg. So - in a frameless method we would have a conflict between the receiver and - the temote temp store, unless we we smart enough to realise that - ReceiverResultReg was unused after the literal variable store, unlikely - given that methods return self by default. */ - - /* StackToRegisterMappingCogit>>#genStorePop:RemoteTemp:At:needsStoreCheck: */ -static sqInt NoDbgRegParms -genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt remoteTempIndex, sqInt needsStoreCheck) -{ - AbstractInstruction *anInstruction; - sqInt offset; - sqInt topReg; - - assert(needsFrame); - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); - voidReceiverResultRegContainsSelf(); - /* begin MoveMw:r:R: */ - offset = frameOffsetOfTemporary(remoteTempIndex); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, FPReg, ReceiverResultReg); - /* begin genGenericStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr:needsImmutabilityCheck: */ -# if IMMUTABILITY - -# endif - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); - ssStorePoptoReg(popBoolean, topReg); - return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); -} - - /* StackToRegisterMappingCogit>>#genStorePop:TemporaryVariable: */ -static sqInt NoDbgRegParms -genStorePopTemporaryVariable(sqInt popBoolean, sqInt tempIndex) -{ - AbstractInstruction *anInstruction; - sqInt offset; - sqInt reg; - - ssFlushUpThroughTemporaryVariable(tempIndex); - reg = ssStorePoptoPreferredReg(popBoolean, TempReg); - /* begin MoveR:Mw:r: */ - offset = frameOffsetOfTemporary(tempIndex); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveRMwr, reg, offset, FPReg); - ((simStackAt(tempIndex + 1))->bcptr = bytecodePC); - return 0; -} - - -/* Generate a method return from within a method or a block. - Frameless method activation looks like - CISCs (x86): - receiver - args - sp-> ret pc. - RISCs (ARM): - receiver - args - ret pc in LR. - A fully framed activation is described in CoInterpreter - class>initializeFrameIndices. Return pops receiver and arguments off the - stack. Callee pushes the result. */ - - /* StackToRegisterMappingCogit>>#genUpArrowReturn */ -static sqInt -genUpArrowReturn(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - sqInt i; - sqInt offset; - - - /* can't fall through */ - deadCode = 1; - if (inBlock > 0) { - assert(needsFrame); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceNonLocalReturnTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin annotateBytecode: */ - abstractInstruction1 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction1->annotation = HasBytecodePC); - return 0; - } - if ( -# if IMMUTABILITY - needsFrame - && (!useTwoPaths) -# else - needsFrame -# endif - ) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, FPReg, SPReg); - /* begin PopR: */ - genoperand(PopR, FPReg); - /* begin PopR: */ - genoperand(PopR, LinkReg); - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - else { - /* begin RetN: */ - offset = ((methodOrBlockNumArgs > 2 /* numRegArgs */) - || (regArgsHaveBeenPushed) - ? (methodOrBlockNumArgs + 1) * BytesPerWord - : 0); - genoperand(RetN, offset); - } - return 0; -} - - /* StackToRegisterMappingCogit>>#genVanillaInlinedIdenticalOrNotIf: */ -static sqInt NoDbgRegParms -genVanillaInlinedIdenticalOrNotIf(sqInt orNot) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - int argIsConstant; - sqInt argNeedsReg; - sqInt argReg; - sqInt argReg1; - BytecodeDescriptor *branchDescriptor; - BytecodeDescriptor *branchDescriptor1; - sqInt constant; - sqInt constant1; - sqInt i; - void *jumpTarget; - void *jumpTarget1; - void *jumpTarget2; - void *jumpTarget3; - sqInt nExts; - sqInt nextPC; - sqInt nextPC1; - sqInt postBranchPC; - sqInt postBranchPC1; - BytecodeDescriptor *primDescriptor; - sqInt rcvrIsConstant; - sqInt rcvrNeedsReg; - sqInt rcvrReg; - sqInt rcvrReg1; - sqInt reg; - sqInt rNext1; - sqInt rTop1; - sqInt targetBytecodePC; - sqInt targetPC; - sqInt topRegistersMask; - - /* begin extractMaybeBranchDescriptorInto: */ - primDescriptor = generatorAt(byte0); - nextPC1 = bytecodePC + ((primDescriptor->numBytes)); - nExts = 0; - while (1) { - while (1) { - /* begin generatorForPC: */ - branchDescriptor1 = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC1, methodObj))); - if (!((branchDescriptor1->isExtension))) break; - nExts += 1; - nextPC1 += (branchDescriptor1->numBytes); - } - /* begin isUnconditionalBranch */ - if (!((isBranch(branchDescriptor1)) - && (!(((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse)))))) break; - nextPC1 = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - } - targetBytecodePC = (postBranchPC1 = 0); - if (((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse))) { - targetBytecodePC = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - postBranchPC1 = eventualTargetOf(nextPC1 + ((branchDescriptor1->numBytes))); - } - else { - nextPC1 = bytecodePC + ((primDescriptor->numBytes)); - } - branchDescriptor = branchDescriptor1; - nextPC = nextPC1; - postBranchPC = postBranchPC1; - targetPC = targetBytecodePC; - - /* They can't be both constants to use correct machine opcodes. - However annotable constants can't be resolved statically, hence we need to careful. */ - argIsConstant = (((ssTop())->type)) == SSConstant; - rcvrIsConstant = (!argIsConstant) - && ((((ssValue(1))->type)) == SSConstant); - /* begin allocateEqualsEqualsRegistersArgNeedsReg:rcvrNeedsReg:into: */ - argNeedsReg = !argIsConstant; - rcvrNeedsReg = !rcvrIsConstant; - assert(argNeedsReg - || (rcvrNeedsReg)); - argReg1 = (rcvrReg1 = NoReg); - if (argNeedsReg) { - if (rcvrNeedsReg) { - /* begin allocateRegForStackTopTwoEntriesInto: */ - topRegistersMask = 0; - rTop1 = (rNext1 = NoReg); - if ((registerOrNone(ssTop())) != NoReg) { - rTop1 = registerOrNone(ssTop()); - } - if ((registerOrNone(ssValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; - } - if (rTop1 == NoReg) { - rTop1 = allocateRegNotConflictingWith(topRegistersMask); - } - if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); - } - assert(!(((rTop1 == NoReg) - || (rNext1 == NoReg)))); - argReg1 = rTop1; - rcvrReg1 = rNext1; - popToReg(ssTop(), argReg1); - popToReg(ssValue(1), rcvrReg1); - } - else { - argReg1 = allocateRegForStackEntryAtnotConflictingWith(0, 0); - popToReg(ssTop(), argReg1); - if (((ssValue(1))->spilled)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AddCqR, BytesPerWord, SPReg); - } - } - } - else { - assert(rcvrNeedsReg); - assert(!((((ssTop())->spilled)))); - rcvrReg1 = allocateRegForStackEntryAtnotConflictingWith(1, 0); - popToReg(ssValue(1), rcvrReg1); - } - assert(!((argNeedsReg - && (argReg1 == NoReg)))); - assert(!((rcvrNeedsReg - && (rcvrReg1 == NoReg)))); - rcvrReg = rcvrReg1; - argReg = argReg1; - if (!(((branchDescriptor->isBranchTrue)) - || ((branchDescriptor->isBranchFalse)))) { - return genIdenticalNoBranchArgIsConstantrcvrIsConstantargRegrcvrRegorNotIf(argIsConstant, rcvrIsConstant, argReg, rcvrReg, orNot); - } - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 2)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 2)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 2))); i <= (simStackPtr - 2); i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 2) + 1; - } - /* begin genCmpArgIsConstant:rcvrIsConstant:argReg:rcvrReg: */ - assert((argReg != NoReg) - || (rcvrReg != NoReg)); - if (argIsConstant) { - /* begin genCmpConstant:R: */ - constant = ((ssTop())->constant); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(CmpCwR, constant, rcvrReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, constant, rcvrReg); - } - } - else { - if (rcvrIsConstant) { - /* begin genCmpConstant:R: */ - constant1 = ((ssValue(1))->constant); - if (shouldAnnotateObjectReference(constant1)) { - annotateobjRef(checkLiteralforInstruction(constant1, genoperandoperand(CmpCwR, constant1, argReg)), constant1); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, constant1, argReg); - } - } - else { - /* begin CmpR:R: */ - assert(!((argReg == SPReg))); - genoperandoperand(CmpRR, argReg, rcvrReg); - } - } - ssPop(2); - if ((((fixupAt(nextPC))->targetInstruction)) == 0) { - - /* The next instruction is dead. we can skip it. */ - deadCode = 1; - ensureFixupAt(targetPC); - ensureFixupAt(postBranchPC); - } - else { - assert(!(deadCode)); - } - if (orNot == ((branchDescriptor->isBranchTrue))) { - - /* a == b ifFalse: ... or a ~~ b ifTrue: ... jump on equal to post-branch pc */ - ensureNonMergeFixupAt(targetPC); - /* begin JumpZero: */ - jumpTarget = ensureNonMergeFixupAt(postBranchPC); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget)); - /* begin Jump: */ - jumpTarget1 = ensureNonMergeFixupAt(targetPC); - genoperand(Jump, ((sqInt)jumpTarget1)); - } - else { - - /* orNot is true for ~~ */ - /* a == b ifTrue: ... or a ~~ b ifFalse: ... jump on equal to target pc */ - /* begin JumpZero: */ - jumpTarget2 = ensureNonMergeFixupAt(targetPC); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget2)); - /* begin Jump: */ - jumpTarget3 = ensureNonMergeFixupAt(postBranchPC); - genoperand(Jump, ((sqInt)jumpTarget3)); - } - if (!deadCode) { - ssPushConstant(trueObject()); - } - return 0; -} - - /* StackToRegisterMappingCogit>>#initSimStackForFramefulMethod: */ -static void NoDbgRegParms -initSimStackForFramefulMethod(sqInt startpc) -{ - CogSimStackEntry * cascade0; - CogSimStackEntry *desc; - sqInt i; - - - /* N.B. Includes num args */ - simStackPtr = methodOrBlockNumTemps; - simSpillBase = methodOrBlockNumTemps + 1; - cascade0 = simSelf(); - (cascade0->type = SSBaseOffset); - (cascade0->spilled = 1); - (cascade0->registerr = FPReg); - (cascade0->offset = FoxMFReceiver); - (cascade0->liveRegister = NoReg); - for (i = 1; i <= methodOrBlockNumArgs; i += 1) { - desc = simStackAt(i); - (desc->type = SSBaseOffset); - (desc->spilled = 1); - (desc->registerr = FPReg); - (desc->offset = FoxCallerSavedIP + (((methodOrBlockNumArgs - i) + 1) * BytesPerWord)); - (desc->bcptr = startpc); - } - for (i = (methodOrBlockNumArgs + 1); i <= simStackPtr; i += 1) { - desc = simStackAt(i); - (desc->type = SSBaseOffset); - (desc->spilled = 1); - (desc->registerr = FPReg); - (desc->offset = FoxMFReceiver - ((i - methodOrBlockNumArgs) * BytesPerWord)); - (desc->bcptr = startpc); - } -} - - -/* The register receiver (the closure itself) and args are pushed by the - closure value primitive(s) - and hence a frameless block has all arguments and copied values pushed to - the stack. However, - the method receiver (self) is put in the ReceiverResultReg by the block - entry. - */ - - /* StackToRegisterMappingCogit>>#initSimStackForFramelessBlock: */ -static void NoDbgRegParms -initSimStackForFramelessBlock(sqInt startpc) -{ - CogSimStackEntry * cascade0; - CogSimStackEntry *desc; - sqInt i; - - cascade0 = simSelf(); - (cascade0->type = SSRegister); - (cascade0->spilled = 0); - (cascade0->registerr = ReceiverResultReg); - (cascade0->liveRegister = ReceiverResultReg); - assert(methodOrBlockNumTemps >= methodOrBlockNumArgs); - for (i = 1; i <= methodOrBlockNumTemps; i += 1) { - desc = simStackAt(i); - (desc->type = SSBaseOffset); - (desc->spilled = 1); - (desc->registerr = SPReg); - (desc->offset = (methodOrBlockNumArgs - i) * BytesPerWord); - (desc->bcptr = startpc); - } - - /* N.B. Includes num args */ - simStackPtr = methodOrBlockNumTemps; - simSpillBase = methodOrBlockNumTemps + 1; - } - - /* StackToRegisterMappingCogit>>#initSimStackForFramelessMethod: */ -static void NoDbgRegParms -initSimStackForFramelessMethod(sqInt startpc) -{ - CogSimStackEntry * cascade0; - CogSimStackEntry *desc; - sqInt i; - - cascade0 = simSelf(); - (cascade0->type = SSRegister); - (cascade0->spilled = 0); - (cascade0->registerr = ReceiverResultReg); - (cascade0->liveRegister = ReceiverResultReg); - assert(methodOrBlockNumTemps == methodOrBlockNumArgs); - assert((numRegArgs()) <= 2); - if (((methodOrBlockNumArgs >= 1) && (methodOrBlockNumArgs <= 2 /* numRegArgs */))) { - desc = simStackAt(1); - (desc->type = SSRegister); - (desc->spilled = 0); - (desc->registerr = Arg0Reg); - (desc->bcptr = startpc); - if (methodOrBlockNumArgs > 1) { - desc = simStackAt(2); - (desc->type = SSRegister); - (desc->spilled = 0); - (desc->registerr = Arg1Reg); - (desc->bcptr = startpc); - } - } - else { - for (i = 1; i <= methodOrBlockNumArgs; i += 1) { - desc = simStackAt(i); - (desc->type = SSBaseOffset); - (desc->registerr = SPReg); - (desc->spilled = 1); - (desc->offset = (methodOrBlockNumArgs - i) * BytesPerWord); - (desc->bcptr = startpc); - } - } - simStackPtr = methodOrBlockNumArgs; - simSpillBase = methodOrBlockNumArgs + 1; - } - - -/* Do not inline (inBlock access) */ - - /* StackToRegisterMappingCogit>>#isNonForwarderReceiver: */ -static sqInt NoDbgRegParms -isNonForwarderReceiver(sqInt reg) -{ - return ((((simSelf())->liveRegister)) == ReceiverResultReg) - && ((inBlock == 0) - && (reg == ReceiverResultReg)); -} - - /* StackToRegisterMappingCogit>>#liveRegisters */ -static sqInt -liveRegisters(void) -{ - sqInt i; - sqInt regsSet; - - if (needsFrame) { - regsSet = 0; - } - else { - /* begin registerMaskFor: */ - regsSet = 1U << ReceiverResultReg; - if ((methodOrBlockNumArgs <= 2 /* numRegArgs */) - && (methodOrBlockNumArgs > 0)) { - regsSet = regsSet | (1U << Arg0Reg); - if (methodOrBlockNumArgs > 1) { - regsSet = regsSet | (1U << Arg1Reg); - } - } - } - for (i = (((simSpillBase < 0) ? 0 : simSpillBase)); i <= simStackPtr; i += 1) { - regsSet = regsSet | (registerMask(simStackAt(i))); - } - return regsSet; -} - - -/* insert nops for dead code that is mapped so that bc - to mc mapping is not many to one */ - - /* StackToRegisterMappingCogit>>#mapDeadDescriptorIfNeeded: */ -static sqInt NoDbgRegParms -mapDeadDescriptorIfNeeded(BytecodeDescriptor *descriptor) -{ - AbstractInstruction *abstractInstruction; - - flag("annotateInstruction"); - if (((descriptor->isMapped)) - || ((inBlock > 0) - && ((descriptor->isMappedInBlock)))) { - /* begin annotateBytecode: */ - abstractInstruction = gen(Nop); - (abstractInstruction->annotation = HasBytecodePC); - } - return 0; -} - - -/* Spill everything on the simulated stack that needs spilling (that below - receiver and arguments). - Marshall receiver and arguments to stack and/or registers depending on arg - count. If the args don't fit in registers push receiver and args (spill - everything), but still assign - the receiver to ReceiverResultReg. */ - - /* StackToRegisterMappingCogit>>#marshallSendArguments: */ -static void NoDbgRegParms -marshallSendArguments(sqInt numArgs) -{ - sqInt anyRefs; - CogSimStackEntry * cascade0; - sqInt i; - sqInt i1; - sqInt i2; - sqInt numSpilled; - - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= ((simStackPtr - numArgs) - 1)) { - for (i2 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < ((simStackPtr - numArgs) - 1)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : ((simStackPtr - numArgs) - 1))); i2 < (simStackPtr - numArgs); i2 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i2), frameOffsetOfTemporary(i2 - 1), FPReg); - } - simSpillBase = ((simStackPtr - numArgs) - 1) + 1; - } - if (numArgs > 2 /* numRegArgs */) { - - /* If there are no spills and no references to ReceiverResultReg - the fetch of ReceiverResultReg from the stack can be avoided - by assigning directly to ReceiverResultReg and pushing it. */ - numSpilled = numberOfSpillsInTopNItems(numArgs + 1); - anyRefs = anyReferencesToRegisterinTopNItems(ReceiverResultReg, numArgs + 1); - if ((numSpilled > 0) - || (anyRefs)) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - storeToReg(simStackAt(simStackPtr - numArgs), ReceiverResultReg); - } - else { - cascade0 = simStackAt(simStackPtr - numArgs); - storeToReg(cascade0, ReceiverResultReg); - (cascade0->type = SSRegister); - (cascade0->registerr = ReceiverResultReg); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i1 <= simStackPtr; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - } - } - else { - - /* Move the args to the register arguments, being careful to do - so last to first so e.g. previous contents don't get overwritten. - Also check for any arg registers in use by other args. */ - if (numArgs > 0) { - if (numArgs > 1) { - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 2, simNativeStackPtr); - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg1Reg, simStackPtr - 1, simNativeStackPtr); - } - else { - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); - } - } - if (numArgs > 1) { - popToReg(simStackAt(simStackPtr), Arg1Reg); - } - if (numArgs > 0) { - popToReg(simStackAt((simStackPtr - numArgs) + 1), Arg0Reg); - } - popToReg(simStackAt(simStackPtr - numArgs), ReceiverResultReg); - } - ssPop(numArgs + 1); -} - - -/* For assert checking; or rather for avoiding assert fails when dealing with - the hack for block temps in the SqueakV3PlusClosures bytecode set. - */ - - /* StackToRegisterMappingCogit>>#maybeCompilingFirstPassOfBlockWithInitialPushNil */ -static sqInt -maybeCompilingFirstPassOfBlockWithInitialPushNil(void) -{ - return (inBlock == InVanillaBlock) - && ((methodOrBlockNumTemps > methodOrBlockNumArgs) - && (compilationPass == 1)); -} - - -/* If this bytecode has a fixup, some kind of merge needs to be done. There - are 4 cases: - 1) the bytecode has no fixup (fixup isNotAFixup) - do nothing - 2) the bytecode has a non merge fixup - the fixup has needsNonMergeFixup. - The code generating non merge fixup (currently only special selector code) - is responsible - for the merge so no need to do it. - We set deadCode to false as the instruction can be reached from jumps. - 3) the bytecode has a merge fixup, but execution flow *cannot* fall - through to the merge point. - the fixup has needsMergeFixup and deadCode = true. - ignores the current simStack as it does not mean anything - restores the simStack to the state the jumps to the merge point expects it - to be. - 4) the bytecode has a merge fixup and execution flow *can* fall through to - the merge point. - the fixup has needsMergeFixup and deadCode = false. - flushes the stack to the stack pointer so the fall through execution path - simStack is - in the state the merge point expects it to be. - restores the simStack to the state the jumps to the merge point expects it - to be. - - In addition, if this is a backjump merge point, we patch the fixup to hold - the current simStackPtr - for later assertions. */ - - /* StackToRegisterMappingCogit>>#mergeWithFixupIfRequired: */ -static sqInt NoDbgRegParms -mergeWithFixupIfRequired(BytecodeFixup *fixup) -{ - CogSimStackEntry * cascade0; - sqInt i; - sqInt i1; - - /* begin assertCorrectSimStackPtr */ - assert((simSpillBase >= methodOrBlockNumTemps) - || ((maybeCompilingFirstPassOfBlockWithInitialPushNil()) - && (simSpillBase > methodOrBlockNumArgs))); - if (needsFrame - && (simSpillBase > 0)) { - assert((((simStackAt(simSpillBase - 1))->spilled)) == 1); - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); - } - if (((fixup->targetInstruction)) == 0) { - return 0; - } - if ((((usqInt)((fixup->targetInstruction)))) == NeedsNonMergeFixupFlag) { - deadCode = 0; - return 0; - } - assert(isMergeFixup(fixup)); - traceMerge(fixup); - if (deadCode) { - - /* case 3 */ - /* Would like to assert fixup simStackPtr >= methodOrBlockNumTemps - but can't because of the initialNils hack. */ - assert((((fixup->simStackPtr)) >= methodOrBlockNumTemps) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - simStackPtr = (fixup->simStackPtr); - } - else { - - /* case 4 */ - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - } - deadCode = 0; - if ((fixup->isTargetOfBackwardBranch)) { - (fixup->simStackPtr = simStackPtr); - } - (fixup->targetInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(simStackPtr == ((fixup->simStackPtr))); - /* begin restoreSimStackAtMergePoint: */ - ((simSelf())->liveRegister = NoReg); - for (i1 = (methodOrBlockNumTemps + 1); i1 <= simStackPtr; i1 += 1) { - cascade0 = simStackAt(i1); - (cascade0->type = SSSpill); - (cascade0->offset = FoxMFReceiver - ((i1 - methodOrBlockNumArgs) * BytesPerOop)); - (cascade0->registerr = FPReg); - (cascade0->spilled = 1); - } - simSpillBase = simStackPtr + 1; - return 0; -} - - /* StackToRegisterMappingCogit>>#methodAbortTrampolineFor: */ -static sqInt NoDbgRegParms -methodAbortTrampolineFor(sqInt numArgs) -{ - return methodAbortTrampolines[((numArgs < (3)) ? numArgs : (3))]; -} - - -/* This is a hook for subclasses to filter out methods they can't deal with. */ -/* Frameless methods with local temporaries cause problems, - mostly in asserts, and yet they matter not at all for performance. - Shun them. */ - - /* StackToRegisterMappingCogit>>#methodFoundInvalidPostScan */ -static sqInt -methodFoundInvalidPostScan(void) -{ - if (!needsFrame) { - return methodOrBlockNumTemps > methodOrBlockNumArgs; - } - return 0; -} - - /* StackToRegisterMappingCogit>>#needsFrameIfMod16GENumArgs: */ -static sqInt NoDbgRegParms -needsFrameIfMod16GENumArgs(sqInt stackDelta) -{ - return (byte0 % 16) >= methodOrBlockNumArgs; -} - - -/* As of August 2013, the code generator can't deal with spills in frameless - methods (the - issue is to do with the stack offset to get at an argument, which is - changed when there's a spill). - In e.g. TextColor>>#dominates: other ^other class == self class the second - send of class - needs also rto allocate a register that the first one used, but the first - one's register can't be - spilled. So avoid this by only allowing class to be sent if the stack - contains a single element. */ - - /* StackToRegisterMappingCogit>>#needsFrameIfStackGreaterThanOne: */ -static sqInt NoDbgRegParms -needsFrameIfStackGreaterThanOne(sqInt stackDelta) -{ - return stackDelta > 1; -} - - /* StackToRegisterMappingCogit>>#numberOfSpillsInTopNItems: */ -static sqInt NoDbgRegParms -numberOfSpillsInTopNItems(sqInt n) -{ - sqInt i; - - for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { - if ((((simStackAt(i))->type)) == SSSpill) { - return n - (simStackPtr - i); - } - } - return 0; -} - - /* StackToRegisterMappingCogit>>#picAbortTrampolineFor: */ -static sqInt NoDbgRegParms -picAbortTrampolineFor(sqInt numArgs) -{ - return picAbortTrampolines[((numArgs < (3)) ? numArgs : (3))]; -} - - /* StackToRegisterMappingCogit>>#prevInstIsPCAnnotated */ -static sqInt -prevInstIsPCAnnotated(void) -{ - sqInt prevIndex; - AbstractInstruction *prevInst; - - if (!(opcodeIndex > 0)) { - return 0; - } - prevIndex = opcodeIndex - 1; - while (1) { - if (prevIndex <= 0) { - return 0; - } - prevInst = abstractInstructionAt(prevIndex); - if (isPCMappedAnnotation((!((prevInst->annotation)) - ? 0 - : (prevInst->annotation)))) { - return 1; - } - if (!(((prevInst->opcode)) == Label)) break; - prevIndex -= 1; - } - return 0; -} - - -/* Used to mark ReceiverResultReg as dead or not containing simSelf. - Used when the simStack has already been flushed, e.g. for sends. */ - - /* StackToRegisterMappingCogit>>#receiverIsInReceiverResultReg */ -static sqInt -receiverIsInReceiverResultReg(void) -{ - return (((simSelf())->liveRegister)) == ReceiverResultReg; -} - - -/* When a block must be recompiled due to overestimating the - numInitialNils fixups must be restored, which means rescannning - since backward branches need their targets initialized. */ - - /* StackToRegisterMappingCogit>>#reinitializeFixupsFrom:through: */ -static void NoDbgRegParms -reinitializeFixupsFromthrough(sqInt start, sqInt end) -{ - BytecodeDescriptor *descriptor; - sqInt distance; - BytecodeFixup * fixup; - sqInt nExts; - sqInt pc; - BytecodeFixup * self_in_reinitialize; - sqInt targetPC; - - pc = start; - nExts = 0; - while (pc <= end) { - /* begin reinitialize */ - self_in_reinitialize = fixupAtIndex(pc - initialPC); - (self_in_reinitialize->targetInstruction) = 0; - (self_in_reinitialize->simStackPtr) = 0; - byte0 = (fetchByteofObject(pc, methodObj)) + bytecodeSetOffset; - descriptor = generatorAt(byte0); - if ((isBranch(descriptor)) - && ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, pc, nExts, methodObj)) < 0))) { - /* begin spanFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, pc, nExts, methodObj); - targetPC = (pc + ((descriptor->numBytes))) + distance; - /* begin initializeFixupAt: */ - fixup = fixupAtIndex(targetPC - initialPC); - /* begin initializeFixup: */ - (fixup->targetInstruction) = ((AbstractInstruction *) NeedsMergeFixupFlag); - /* begin setIsBackwardBranchFixup */ - (fixup->isTargetOfBackwardBranch) = 1; - } - if ((descriptor->isBlockCreation)) { - /* begin spanFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, pc, nExts, methodObj); - pc = (pc + ((descriptor->numBytes))) + distance; - } - else { - pc += (descriptor->numBytes); - } - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } -} - - -/* Scan the block to determine if the block needs a frame or not */ - - /* StackToRegisterMappingCogit>>#scanBlock: */ -static sqInt NoDbgRegParms -scanBlock(BlockStart *blockStart) -{ - BytecodeDescriptor *descriptor; - sqInt end; - sqInt framelessStackDelta; - sqInt nExts; - sqInt numPushNils; - sqInt (* const numPushNilsFunction)(struct _BytecodeDescriptor *,sqInt,sqInt,sqInt) = squeakV3orSistaV1NumPushNils; - sqInt pc; - sqInt pushingNils; - - needsFrame = 0; - prevBCDescriptor = null; - methodOrBlockNumArgs = (blockStart->numArgs); - inBlock = InVanillaBlock; - pc = (blockStart->startpc); - end = ((blockStart->startpc)) + ((blockStart->span)); - framelessStackDelta = (nExts = (extA = (numExtB = (extB = 0)))); - pushingNils = 1; - while (pc < end) { - byte0 = (fetchByteofObject(pc, methodObj)) + bytecodeSetOffset; - descriptor = generatorAt(byte0); - if ((descriptor->isExtension)) { - loadSubsequentBytesForDescriptorat(descriptor, pc); - ((descriptor->generator))(); - } - if (!needsFrame) { - if ((((descriptor->needsFrameFunction)) == null) - || (((descriptor->needsFrameFunction))(framelessStackDelta))) { - needsFrame = 1; - } - else { - framelessStackDelta += (descriptor->stackDelta); - } - } - /* begin maybeNoteDescriptor:blockStart: */ - if ((descriptor->isInstVarRef)) { - (blockStart->hasInstVarRef = 1); - } - if (pushingNils - && (!((descriptor->isExtension)))) { - - /* Count the initial number of pushed nils acting as temp initializers. We can't tell - whether an initial pushNil is an operand reference or a temp initializer, except - when the pushNil is a jump target (has a fixup), which never happens: - self systemNavigation browseAllSelect: - [:m| | ebc | - (ebc := m embeddedBlockClosures - select: [:ea| ea decompile statements first isMessage] - thenCollect: [:ea| ea decompile statements first selector]) notEmpty - and: [(#(whileTrue whileFalse whileTrue: whileFalse:) intersection: ebc) notEmpty]] - or if the bytecode set has a push multiple nils bytecode. We simply count initial nils. - Rarely we may end up over-estimating. We will correct by checking the stack depth - at the end of the block in compileBlockBodies. */ - if (((numPushNils = numPushNilsFunction(descriptor, pc, nExts, methodObj))) > 0) { - assert(((descriptor->numBytes)) == 1); - (blockStart->numInitialNils = ((blockStart->numInitialNils)) + numPushNils); - } - else { - pushingNils = 0; - } - } - /* begin nextBytecodePCFor:at:exts:in: */ - pc = (pc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? ((descriptor->spanFunction))(descriptor, pc, nExts, methodObj) - : 0)); - if ((descriptor->isExtension)) { - nExts += 1; - } - else { - nExts = (extA = (numExtB = (extB = 0))); - } - prevBCDescriptor = descriptor; - } - if (!needsFrame) { - assert((framelessStackDelta >= 0) - && (((blockStart->numInitialNils)) >= framelessStackDelta)); - (blockStart->numInitialNils = ((blockStart->numInitialNils)) - framelessStackDelta); - } - return 0; -} - - -/* Scan the method (and all embedded blocks) to determine - - what the last bytecode is; extra bytes at the end of a method are used - to encode things like source pointers or temp names - - if the method needs a frame or not - - what are the targets of any backward branches. - - how many blocks it creates - Answer the block count or on error a negative error code */ - - /* StackToRegisterMappingCogit>>#scanMethod */ -static sqInt -scanMethod(void) -{ - BytecodeDescriptor *descriptor; - sqInt distance; - BytecodeFixup * fixup; - sqInt framelessStackDelta; - sqInt latestContinuation; - sqInt nExts; - sqInt numBlocks; - sqInt pc; - sqInt seenInstVarStore; - sqInt targetPC; - - needsFrame = (useTwoPaths = (seenInstVarStore = 0)); - /* begin maybeInitNumCounters */ - numCounters = 0; - prevBCDescriptor = null; - if ((primitiveIndex > 0) - && (isQuickPrimitiveIndex(primitiveIndex))) { - return 0; - } - pc = (latestContinuation = initialPC); - numBlocks = (framelessStackDelta = (nExts = (extA = (numExtB = (extB = 0))))); - while (pc <= endPC) { - byte0 = (fetchByteofObject(pc, methodObj)) + bytecodeSetOffset; - descriptor = generatorAt(byte0); - if ((descriptor->isExtension)) { - if (((descriptor->opcode)) == Nop) { - - /* unknown bytecode tag; see Cogit class>>#generatorTableFrom: */ - return EncounteredUnknownBytecode; - } - loadSubsequentBytesForDescriptorat(descriptor, pc); - ((descriptor->generator))(); - } - if (((descriptor->isReturn)) - && (pc >= latestContinuation)) { - endPC = pc; - } - if (!needsFrame) { - if ((((descriptor->needsFrameFunction)) == null) - || (((descriptor->needsFrameFunction))(framelessStackDelta))) { - - /* With immutability we win simply by avoiding a frame build if the receiver is young and not immutable. */ -# if IMMUTABILITY - if ((descriptor->is1ByteInstVarStore)) { - useTwoPaths = 1; - } - else { - needsFrame = 1; - useTwoPaths = 0; - } -# else // IMMUTABILITY - needsFrame = 1; - useTwoPaths = 0; -# endif - } - else { - - /* Without immutability we win if there are two or more stores and the receiver is new. */ - framelessStackDelta += (descriptor->stackDelta); -# if IMMUTABILITY -# else - if ((descriptor->is1ByteInstVarStore)) { - if (seenInstVarStore) { - useTwoPaths = 1; - } - else { - seenInstVarStore = 1; - } - } -# endif // IMMUTABILITY - } - } - if (isBranch(descriptor)) { - /* begin spanFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, pc, nExts, methodObj); - targetPC = (pc + ((descriptor->numBytes))) + distance; - if ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, pc, nExts, methodObj)) < 0)) { - /* begin initializeFixupAt: */ - fixup = fixupAtIndex(targetPC - initialPC); - /* begin initializeFixup: */ - (fixup->targetInstruction) = ((AbstractInstruction *) NeedsMergeFixupFlag); - /* begin setIsBackwardBranchFixup */ - (fixup->isTargetOfBackwardBranch) = 1; - } - else { - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - /* begin maybeCountCounter */ - numCounters += 1; - } - } - latestContinuation = maybeDealWithUnsafeJumpForDescriptorpclatestContinuation(descriptor, pc, latestContinuation); - if ((descriptor->isBlockCreation)) { - numBlocks += 1; - /* begin spanFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, pc, nExts, methodObj); - targetPC = (pc + ((descriptor->numBytes))) + distance; - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - pc += (descriptor->numBytes); - nExts = ((descriptor->isExtension) - ? nExts + 1 - : (extA = (numExtB = (extB = 0)))); - prevBCDescriptor = descriptor; - } - return numBlocks; -} - - /* StackToRegisterMappingCogit>>#squeakV3orSistaV1PushNilSize:numInitialNils: */ -static sqInt NoDbgRegParms -squeakV3orSistaV1PushNilSizenumInitialNils(sqInt aMethodObj, sqInt numInitialNils) -{ - return (methodUsesAlternateBytecodeSet(aMethodObj) - ? /* begin sistaV1PushNilSize:numInitialNils: */ numInitialNils - : numInitialNils); -} - - /* StackToRegisterMappingCogit>>#squeakV3orSistaV1:Num:Push:Nils: */ -static sqInt NoDbgRegParms -squeakV3orSistaV1NumPushNils(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - return (bytecodeSetOffset == 0 - ? (((descriptor->generator)) == genPushConstantNilBytecode - ? 1 - : 0) - : (/* begin sistaV1:Num:Push:Nils: */ - (((descriptor->generator)) == genPushConstantNilBytecode - ? 1 - : 0))); -} - - /* StackToRegisterMappingCogit>>#ssAllocateRequiredRegMask:upThrough:upThroughNative: */ -static void NoDbgRegParms -ssAllocateRequiredRegMaskupThroughupThroughNative(sqInt requiredRegsMask, sqInt stackPtr, sqInt nativeStackPtr) -{ - sqInt i; - sqInt i1; - sqInt lastRequired; - sqInt lastRequiredNative; - sqInt liveRegs; - - lastRequired = -1; - - /* compute live regs while noting the last occurrence of required regs. - If these are not free we must spill from simSpillBase to last occurrence. - Note we are conservative here; we could allocate FPReg in frameless methods. */ - lastRequiredNative = -1; - /* begin registerMaskFor:and: */ - liveRegs = (1U << FPReg) | (1U << SPReg); - for (i = (((simSpillBase < 0) ? 0 : simSpillBase)); i <= stackPtr; i += 1) { - liveRegs = liveRegs | (registerMask(simStackAt(i))); - if ((((registerMask(simStackAt(i))) & requiredRegsMask) != 0)) { - lastRequired = i; - } - } - if (((liveRegs & requiredRegsMask) != 0)) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= lastRequired) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < lastRequired) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : lastRequired)); i1 <= lastRequired; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = lastRequired + 1; - } - assert(!(((((liveRegisters()) & requiredRegsMask) != 0)))); - } -} - - -/* Any occurrences on the stack of the value being stored (which is the top - of stack) - must be flushed, and hence any values colder than them stack. */ - - /* StackToRegisterMappingCogit>>#ssFlushUpThroughReceiverVariable: */ -static void NoDbgRegParms -ssFlushUpThroughReceiverVariable(sqInt slotIndex) -{ - sqInt i; - sqInt index; - - /* begin ssFlushUpThrough: */ - assert(simSpillBase >= 0); - for (index = (simStackPtr - 1); index >= simSpillBase; index += -1) { - if (((((simStackAt(index))->type)) == SSBaseOffset) - && (((((simStackAt(index))->registerr)) == ReceiverResultReg) - && ((((simStackAt(index))->offset)) == (slotOffsetOfInstVarIndex(slotIndex))))) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= index) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < index) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : index)); i <= index; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = index + 1; - } - goto l1; - } - } - l1: /* end ssFlushUpThrough: */; -} - - -/* Any occurrences on the stack of the value being stored (which is the top - of stack) - must be flushed, and hence any values colder than them stack. */ - - /* StackToRegisterMappingCogit>>#ssFlushUpThroughTemporaryVariable: */ -static void NoDbgRegParms -ssFlushUpThroughTemporaryVariable(sqInt tempIndex) -{ - sqInt i; - sqInt index; - sqInt offset; - - offset = ((simStackAt(tempIndex + 1))->offset); - assert(offset == (frameOffsetOfTemporary(tempIndex))); - /* begin ssFlushUpThrough: */ - assert(simSpillBase >= 0); - for (index = (simStackPtr - 1); index >= simSpillBase; index += -1) { - if (((((simStackAt(index))->type)) == SSBaseOffset) - && (((((simStackAt(index))->registerr)) == FPReg) - && ((((simStackAt(index))->offset)) == offset))) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= index) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < index) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : index)); i <= index; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = index + 1; - } - goto l1; - } - } - l1: /* end ssFlushUpThrough: */; -} - - /* StackToRegisterMappingCogit>>#ssPop: */ -static void NoDbgRegParms -ssPop(sqInt n) -{ - sqInt i; - - assert(((simStackPtr - n) >= methodOrBlockNumTemps) - || (((!needsFrame) - && ((simStackPtr - n) >= 0)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil()))); - simStackPtr -= n; - /* begin updateSimSpillBase */ - assert(((simSpillBase > methodOrBlockNumTemps) - && (simStackPtr >= methodOrBlockNumTemps)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - if (simSpillBase > simStackPtr) { - simSpillBase = simStackPtr + 1; - while (((simSpillBase - 1) > methodOrBlockNumTemps) - && (!(((simStackAt(simSpillBase - 1))->spilled)))) { - simSpillBase -= 1; - } - } - else { - while ((((simStackAt(simSpillBase))->spilled)) - && (simSpillBase <= simStackPtr)) { - simSpillBase += 1; - } - } - for (i = (methodOrBlockNumTemps + 1); i <= ((((simSpillBase - 1) < simStackPtr) ? (simSpillBase - 1) : simStackPtr)); i += 1) { - assert((((simStackAt(i))->spilled)) == 1); - } - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); -} - - /* StackToRegisterMappingCogit>>#ssPushAnnotatedConstant: */ -static sqInt NoDbgRegParms -ssPushAnnotatedConstant(sqInt literal) -{ - AbstractInstruction *abstractInstruction; - - ssPushConstant(literal); - /* begin annotateInstructionForBytecode */ - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (abstractInstruction->annotation = HasBytecodePC); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushBase:offset: */ -static sqInt NoDbgRegParms -ssPushBaseoffset(sqInt reg, sqInt offset) -{ - CogSimStackEntry * cascade0; - sqInt i; - - ssPush(1); - cascade0 = ssTop(); - (cascade0->type = SSBaseOffset); - (cascade0->spilled = 0); - (cascade0->registerr = reg); - (cascade0->offset = offset); - (cascade0->bcptr = bytecodePC); - /* begin updateSimSpillBase */ - assert(((simSpillBase > methodOrBlockNumTemps) - && (simStackPtr >= methodOrBlockNumTemps)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - if (simSpillBase > simStackPtr) { - simSpillBase = simStackPtr + 1; - while (((simSpillBase - 1) > methodOrBlockNumTemps) - && (!(((simStackAt(simSpillBase - 1))->spilled)))) { - simSpillBase -= 1; - } - } - else { - while ((((simStackAt(simSpillBase))->spilled)) - && (simSpillBase <= simStackPtr)) { - simSpillBase += 1; - } - } - for (i = (methodOrBlockNumTemps + 1); i <= ((((simSpillBase - 1) < simStackPtr) ? (simSpillBase - 1) : simStackPtr)); i += 1) { - assert((((simStackAt(i))->spilled)) == 1); - } - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushConstant: */ -static sqInt NoDbgRegParms -ssPushConstant(sqInt literal) -{ - CogSimStackEntry * cascade0; - sqInt i; - - ssPush(1); - cascade0 = ssTop(); - (cascade0->type = SSConstant); - (cascade0->spilled = 0); - (cascade0->constant = literal); - (cascade0->bcptr = bytecodePC); - /* begin updateSimSpillBase */ - assert(((simSpillBase > methodOrBlockNumTemps) - && (simStackPtr >= methodOrBlockNumTemps)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - if (simSpillBase > simStackPtr) { - simSpillBase = simStackPtr + 1; - while (((simSpillBase - 1) > methodOrBlockNumTemps) - && (!(((simStackAt(simSpillBase - 1))->spilled)))) { - simSpillBase -= 1; - } - } - else { - while ((((simStackAt(simSpillBase))->spilled)) - && (simSpillBase <= simStackPtr)) { - simSpillBase += 1; - } - } - for (i = (methodOrBlockNumTemps + 1); i <= ((((simSpillBase - 1) < simStackPtr) ? (simSpillBase - 1) : simStackPtr)); i += 1) { - assert((((simStackAt(i))->spilled)) == 1); - } - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushDesc: */ -static sqInt NoDbgRegParms -ssPushDesc(SimStackEntry simStackEntry) -{ - sqInt i; - - if (((simStackEntry.type)) == SSSpill) { - (simStackEntry.type = SSBaseOffset); - } - (simStackEntry.spilled = 0); - (simStackEntry.bcptr = bytecodePC); - simStack[(simStackPtr += 1)] = simStackEntry; - /* begin updateSimSpillBase */ - assert(((simSpillBase > methodOrBlockNumTemps) - && (simStackPtr >= methodOrBlockNumTemps)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - if (simSpillBase > simStackPtr) { - simSpillBase = simStackPtr + 1; - while (((simSpillBase - 1) > methodOrBlockNumTemps) - && (!(((simStackAt(simSpillBase - 1))->spilled)))) { - simSpillBase -= 1; - } - } - else { - while ((((simStackAt(simSpillBase))->spilled)) - && (simSpillBase <= simStackPtr)) { - simSpillBase += 1; - } - } - for (i = (methodOrBlockNumTemps + 1); i <= ((((simSpillBase - 1) < simStackPtr) ? (simSpillBase - 1) : simStackPtr)); i += 1) { - assert((((simStackAt(i))->spilled)) == 1); - } - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushRegister: */ -static sqInt NoDbgRegParms -ssPushRegister(sqInt reg) -{ - CogSimStackEntry * cascade0; - sqInt i; - - ssPush(1); - cascade0 = ssTop(); - (cascade0->type = SSRegister); - (cascade0->spilled = 0); - (cascade0->registerr = reg); - (cascade0->bcptr = bytecodePC); - /* begin updateSimSpillBase */ - assert(((simSpillBase > methodOrBlockNumTemps) - && (simStackPtr >= methodOrBlockNumTemps)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - if (simSpillBase > simStackPtr) { - simSpillBase = simStackPtr + 1; - while (((simSpillBase - 1) > methodOrBlockNumTemps) - && (!(((simStackAt(simSpillBase - 1))->spilled)))) { - simSpillBase -= 1; - } - } - else { - while ((((simStackAt(simSpillBase))->spilled)) - && (simSpillBase <= simStackPtr)) { - simSpillBase += 1; - } - } - for (i = (methodOrBlockNumTemps + 1); i <= ((((simSpillBase - 1) < simStackPtr) ? (simSpillBase - 1) : simStackPtr)); i += 1) { - assert((((simStackAt(i))->spilled)) == 1); - } - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPush: */ -static void NoDbgRegParms -ssPush(sqInt n) -{ - simStackPtr += n; -} - - /* StackToRegisterMappingCogit>>#ssSelfDescriptor */ -static SimStackEntry -ssSelfDescriptor(void) -{ - return simStack[0]; -} - - -/* In addition to ssStorePop:toReg:, if this is a store and not - a popInto I change the simulated stack to use the register - for the top value */ - - /* StackToRegisterMappingCogit>>#ssStoreAndReplacePop:toReg: */ -static void NoDbgRegParms -ssStoreAndReplacePoptoReg(sqInt popBoolean, sqInt reg) -{ - char topSpilled; - - topSpilled = ((ssTop())->spilled); - ssStorePoptoReg(popBoolean - || (topSpilled), reg); - if (!popBoolean) { - if (!topSpilled) { - ssPop(1); - } - ssPushRegister(reg); - } -} - - -/* Store or pop the top simulated stack entry to a register. - Use preferredReg if the entry is not itself a register. - Answer the actual register the result ends up in. */ - - /* StackToRegisterMappingCogit>>#ssStorePop:toPreferredReg: */ -static sqInt NoDbgRegParms -ssStorePoptoPreferredReg(sqInt popBoolean, sqInt preferredReg) -{ - sqInt actualReg; - - actualReg = preferredReg; - if ((((ssTop())->type)) == SSRegister) { - assert(!(((ssTop())->spilled))); - actualReg = ((ssTop())->registerr); - } - ssStorePoptoReg(popBoolean, actualReg); - return actualReg; -} - - -/* Store or pop the top simulated stack entry to a register. - N.B.: popToReg: and storeToReg: does not generate anything if - it moves a register to the same register. */ - - /* StackToRegisterMappingCogit>>#ssStorePop:toReg: */ -static void NoDbgRegParms -ssStorePoptoReg(sqInt popBoolean, sqInt reg) -{ - if (popBoolean) { - popToReg(ssTop(), reg); - ssPop(1); - } - else { - storeToReg(ssTop(), reg); - } -} - - /* StackToRegisterMappingCogit>>#ssTop */ -static CogSimStackEntry * -ssTop(void) -{ - return simStackAt(simStackPtr); -} - - /* StackToRegisterMappingCogit>>#ssValue: */ -static CogSimStackEntry * NoDbgRegParms -ssValue(sqInt n) -{ - return simStackAt(simStackPtr - n); -} - - /* StackToRegisterMappingCogit>>#stackEntryIsBoolean: */ -static sqInt NoDbgRegParms -stackEntryIsBoolean(CogSimStackEntry *simStackEntry) -{ - return (((simStackEntry->type)) == SSConstant) - && ((((simStackEntry->constant)) == (trueObject())) - || (((simStackEntry->constant)) == (falseObject()))); -} - - -/* Answer if the stack is valid up to, but not including, simSpillBase. */ - - /* StackToRegisterMappingCogit>>#tempsValidAndVolatileEntriesSpilled */ -static sqInt -tempsValidAndVolatileEntriesSpilled(void) -{ - sqInt culprit; - sqInt i; - - culprit = 0; - for (i = 1; i <= methodOrBlockNumTemps; i += 1) { - if (!(((((simStackAt(i))->type)) == SSBaseOffset) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil()))) { - if (!culprit) { - culprit = i; - } - return 0; - } - } - for (i = (methodOrBlockNumTemps + 1); i < simSpillBase; i += 1) { - if (!(((simStackAt(i))->spilled))) { - if (!culprit) { - culprit = i; - } - return 0; - } - } - return 1; -} - - -/* If the sequence of bytecodes is - push: (Array new: 1) - popIntoTemp: tempIndex - pushConstant: const or pushTemp: n - popIntoTemp: 0 inVectorAt: tempIndex - collapse this into - tempAt: tempIndex put: {const or temp} - and answer true, otherwise answer false. - One might think that we should look for a sequence of more than - one pushes and pops but this is extremely rare. - Exclude pushRcvr: n to avoid potential complications with context inst - vars. */ - - /* StackToRegisterMappingCogit>>#tryCollapseTempVectorInitializationOfSize: */ -static sqInt NoDbgRegParms -tryCollapseTempVectorInitializationOfSize(sqInt slots) -{ - sqInt pc; - sqInt pc1; - sqInt pc2; - BytecodeDescriptor *pushArrayDesc; - BytecodeDescriptor *pushValueDesc; - sqInt reg; - sqInt remoteTempIndex; - BytecodeDescriptor *storeArrayDesc; - BytecodeDescriptor *storeValueDesc; - sqInt tempIndex; - - if (slots != 1) { - return 0; - } - /* begin generatorForPC: */ - pushArrayDesc = generatorAt(bytecodeSetOffset + (fetchByteofObject(bytecodePC, methodObj))); - assert(((pushArrayDesc->generator)) == genPushNewArrayBytecode); - /* begin generatorForPC: */ - pc = bytecodePC + ((pushArrayDesc->numBytes)); - storeArrayDesc = generatorAt(bytecodeSetOffset + (fetchByteofObject(pc, methodObj))); - if (((storeArrayDesc->generator)) == genStoreAndPopTemporaryVariableBytecode) { - tempIndex = (fetchByteofObject(bytecodePC + ((pushArrayDesc->numBytes)), methodObj)) & 7; - } - else { - if (!(((storeArrayDesc->generator)) == genLongStoreAndPopTemporaryVariableBytecode)) { - return 0; - } - tempIndex = fetchByteofObject((bytecodePC + ((pushArrayDesc->numBytes))) + 1, methodObj); - } - /* begin generatorForPC: */ - pc1 = (bytecodePC + ((pushArrayDesc->numBytes))) + ((storeArrayDesc->numBytes)); - pushValueDesc = generatorAt(bytecodeSetOffset + (fetchByteofObject(pc1, methodObj))); - if (!((((pushValueDesc->generator)) == genPushLiteralConstantBytecode) - || ((((pushValueDesc->generator)) == genPushQuickIntegerConstantBytecode) - || (((pushValueDesc->generator)) == genPushTemporaryVariableBytecode)))) { - return 0; - } - /* begin generatorForPC: */ - pc2 = ((bytecodePC + ((pushArrayDesc->numBytes))) + ((storeArrayDesc->numBytes))) + ((pushValueDesc->numBytes)); - storeValueDesc = generatorAt(bytecodeSetOffset + (fetchByteofObject(pc2, methodObj))); - remoteTempIndex = fetchByteofObject((((bytecodePC + ((pushArrayDesc->numBytes))) + ((storeArrayDesc->numBytes))) + ((pushValueDesc->numBytes))) + 2, methodObj); - if (!((((storeValueDesc->generator)) == genStoreAndPopRemoteTempLongBytecode) - && (tempIndex == remoteTempIndex))) { - return 0; - } - genNewArrayOfSizeinitialized(1, 0); - evaluateat(pushValueDesc, (bytecodePC + ((pushArrayDesc->numBytes))) + ((storeArrayDesc->numBytes))); - reg = ssStorePoptoPreferredReg(1, TempReg); - genStoreSourceRegslotIndexintoNewObjectInDestReg(reg, 0, ReceiverResultReg); - ssPushRegister(ReceiverResultReg); - evaluateat(storeArrayDesc, bytecodePC + ((pushArrayDesc->numBytes))); - - /* + pushArrayDesc numBytes this gets added by nextBytecodePCFor:at:exts:in: */ - bytecodePC = ((bytecodePC + ((storeArrayDesc->numBytes))) + ((pushValueDesc->numBytes))) + ((storeValueDesc->numBytes)); - return 1; -} - - /* StackToRegisterMappingCogit>>#violatesEnsureSpilledSpillAssert */ -static sqInt -violatesEnsureSpilledSpillAssert(void) -{ - return 1; -} - - -/* Used when ReceiverResultReg is allocated for other than simSelf, and - there may be references to ReceiverResultReg which need to be spilled. */ - - /* StackToRegisterMappingCogit>>#voidReceiverResultRegContainsSelf */ -static void -voidReceiverResultRegContainsSelf(void) -{ - sqInt i; - sqInt i1; - sqInt spillIndex; - - /* begin voidReceiverOptStatus */ - ((simSelf())->liveRegister = NoReg); - spillIndex = 0; - for (i = ((((methodOrBlockNumTemps + 1) < simSpillBase) ? simSpillBase : (methodOrBlockNumTemps + 1))); i <= simStackPtr; i += 1) { - if ((registerOrNone(simStackAt(i))) == ReceiverResultReg) { - spillIndex = i; - } - } - if (spillIndex > 0) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= spillIndex) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < spillIndex) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : spillIndex)); i1 <= spillIndex; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = spillIndex + 1; - } - } -} diff --git a/spursistasrc/vm/cointerp.c b/spursistasrc/vm/cointerp.c index 4a54c98436..faa0079901 100644 --- a/spursistasrc/vm/cointerp.c +++ b/spursistasrc/vm/cointerp.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - CoInterpreter VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CoInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 " __DATE__ ; +static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -490,6 +490,7 @@ extern sqInt ceSendabovetonumArgs(sqInt selector, sqInt methodClass, sqInt rcvr, extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern sqInt ceSistaTrap(void); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethod); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); @@ -666,7 +667,6 @@ static void primitiveExitCriticalSection(void); static void primitiveFlushCacheByMethod(void); static void primitiveFlushCacheBySelector(void); extern usqInt primitiveFunctionPointerAddress(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); EXPORT(sqInt) primitiveMethodPCData(void); static void primitiveMethodXray(void); EXPORT(void) primitiveMinimumUnusedHeadroom(void); @@ -1192,7 +1192,6 @@ static sqInt NoDbgRegParms isPureBitsFormat(sqInt format); extern sqInt isReallyYoung(sqInt oop); static sqInt NoDbgRegParms isRemembered(sqInt objOop); static sqInt NoDbgRegParms isSegmentBridge(sqInt objOop); -static sqInt NoDbgRegParms isSemaphoreOop(sqInt anOop); extern sqInt isShorts(sqInt oop); extern sqInt isUnambiguouslyForwarder(sqInt objOop); extern sqInt isUnmarked(sqInt objOop); @@ -1422,7 +1421,6 @@ EXPORT(sqInt) callbackLeave(sqInt cbID); extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHeader); extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkForEventsMayContextSwitch(sqInt mayContextSwitch); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); @@ -1705,7 +1703,6 @@ static sqInt NoDbgRegParms updateDisplayLeftTopRightBottom(sqInt l, sqInt t, sqI static sqInt NoDbgRegParms validBCPCinMethod(sqInt thePC, usqInt aMethod); static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, char *fp); static sqInt validStackPageBaseFrames(void); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt wakeHighestPriority(void); static sqInt NeverInline writeImageFileIO(void); static usqInt NoDbgRegParms cloneContext(sqInt aContext); @@ -1728,7 +1725,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1768,8 +1764,8 @@ _iss sqInt argumentCount; _iss sqLong nextProfileTick; _iss sqInt primTraceLog[256]; _iss StackPage * stackPage; -_iss sqInt nilObj; _iss usqInt method; +_iss sqInt nilObj; _iss sqInt bytecodeSetSelector; _iss usqInt oldSpaceStart; _iss usqInt endOfMemory; @@ -1803,15 +1799,14 @@ _iss usqInt lastMobileObject; _iss sqInt tempOop; _iss sqInt numClassTablePages; _iss sqInt lkupClass; -_iss sqInt futureSurvivorStart; _iss sqInt profileProcess; -_iss sqInt profileSemaphore; +_iss sqInt futureSurvivorStart; _iss sqInt mournQueue; _iss sqInt numRememberedEphemerons; +_iss sqInt profileMethod; _iss sqInt jmpDepth; _iss sqInt mobileStart; -_iss sqInt profileMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; +_iss sqInt profileSemaphore; _iss sqInt growHeadroom; _iss sqInt tenureThreshold; _iss sqInt lastCoggableInterpretedBlockMethod; @@ -1819,7 +1814,6 @@ _iss sqInt lastUncoggableInterpretedBlockMethod; _iss char * objStackInvalidBecause; _iss sqInt sweepIndex; _iss sqInt ephemeronList; -_iss sqInt longRunningPrimitiveCheckMethod; _iss sqInt tenureCriterion; _iss usqInt totalHeapSizeIncludingBridges; _iss sqInt becomeEffectsFlags; @@ -1875,7 +1869,6 @@ _iss sqInt freeSpaceCheckOopToIgnore; _iss usqInt heapSizeAtPreviousGC; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss sqInt methodDictLinearSearchLimit; _iss sqInt statGrowMemory; _iss sqInt statMaxPageCountWhenMapping; @@ -1887,7 +1880,6 @@ _iss sqInt extraFramesToMoveOnOverflow; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; _iss sqInt inFFIFlags; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss sqInt refCountToShrinkRT; _iss sqInt signalLowSpace; @@ -1917,16 +1909,14 @@ _iss sqInt preferredPinningSegment; _iss sqInt statCoalesces; _iss sqInt theUnknownShort; _iss usqLong nextWakeupUsecs; -_iss usqLong statGCEndUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; -_iss usqLong statCheckForEvents; -_iss usqLong gcStartUsecs; _iss sqLong oldSpaceUsePriorToScavenge; +_iss usqLong statGCEndUsecs; _iss usqLong statIOProcessEvents; +_iss usqLong gcStartUsecs; _iss usqLong statAllocatedBytes; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statCompactionUsecs; _iss usqLong statForceInterruptCheck; _iss usqLong statFullGCUsecs; @@ -1940,9 +1930,11 @@ _iss usqLong statSweepUsecs; _iss usqLong statCodeCompactionUsecs; _iss usqLong statSGCDeltaUsecs; _iss usqLong gcSweepEndUsecs; -_iss usqLong longRunningPrimitiveGCUsecs; _iss usqLong statIGCDeltaUsecs; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; _iss usqLong statFGCDeltaUsecs; _iss usqLong statIncrGCUsecs; _iss SpurContiguousObjStack savedFirstFieldsSpace; @@ -2619,7 +2611,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Open Smalltalk Cog[Spur] VM [CoInterpreterPrimitives VMMaker.oscog-eem.3024]"; +const char *interpreterVersion = "Open Smalltalk Cog[Spur] VM [CoInterpreterPrimitives VMMaker.oscog-eem.3031]"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */; char primitiveDoMixedArithmetic = 1; char expensiveAsserts = 0; @@ -18128,6 +18120,27 @@ ceStackOverflow(sqInt contextSwitchIfNotNil) error("should not be reached"); } + +/* A primitive has succeeded and the nextProfileTick has been reached (all + done in machine code). + Now take a sample. c.f. checkProfileTick: */ + + /* CoInterpreter>>#ceTakeProfileSample: */ +void +ceTakeProfileSample(CogMethod *aCogMethod) +{ DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt objOop; + sqInt objOop1; + + /* begin fetchPointer:ofObject: */ + objOop1 = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(SchedulerAssociation) << (shiftForWord()))))); + objOop = longAt((objOop1 + BaseHeaderSize) + (((int)((usqInt)(ValueIndex) << (shiftForWord()))))); + GIV(profileProcess) = longAt((objOop + BaseHeaderSize) + (((int)((usqInt)(ActiveProcessIndex) << (shiftForWord()))))); + GIV(profileMethod) = (aCogMethod->methodObject); + forceInterruptCheck(); + GIV(nextProfileTick) = 0; +} + /* CoInterpreter>>#ceTraceBlockActivation */ void ceTraceBlockActivation(void) @@ -20126,24 +20139,6 @@ void forceInterruptCheckFromHeartbeat(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; sqLowLevelMFence(); if (GIV(deferSmash)) { GIV(deferredSmash) = 1; @@ -21938,7 +21933,8 @@ mnuMethodOrNilFor(sqInt rcvr) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt currentClass; sqInt dictionary; - sqInt index; + sqInt fieldIndex; + usqInt index; usqInt length; sqInt mask; sqInt methodArray; @@ -21987,7 +21983,7 @@ mnuMethodOrNilFor(sqInt rcvr) wrapAround = 0; while (1) { /* begin fetchPointer:ofObject: */ - nextSelector = longAt((dictionary + BaseHeaderSize) + (((sqInt)((usqInt)(index) << (shiftForWord()))))); + nextSelector = longAt((dictionary + BaseHeaderSize) + (index << (shiftForWord()))); if (nextSelector == GIV(nilObj)) { mnuMethod = null; goto l11; @@ -22005,10 +22001,12 @@ mnuMethodOrNilFor(sqInt rcvr) } methodArray = objOop; /* begin followField:ofObject: */ - objOop1 = longAt((methodArray + BaseHeaderSize) + (((sqInt)((usqInt)((index - SelectorStart)) << (shiftForWord()))))); + fieldIndex = index - SelectorStart; + /* begin fetchPointer:ofObject: */ + objOop1 = longAt((methodArray + BaseHeaderSize) + (((sqInt)((usqInt)(fieldIndex) << (shiftForWord()))))); if (((!(objOop1 & (tagMask())))) && ((!((longAt(objOop1)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - objOop1 = fixFollowedFieldofObjectwithInitialValue(index - SelectorStart, methodArray, objOop1); + objOop1 = fixFollowedFieldofObjectwithInitialValue(fieldIndex, methodArray, objOop1); } mnuMethod = objOop1; goto l11; @@ -26568,56 +26566,6 @@ primitiveFunctionPointerAddress(void) return ((usqInt)((&primitiveFunctionPointer))); } - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* CoInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; - int flushState; - sqInt sema; - char *sp; - - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (sema == GIV(nilObj)) { - flushState = GIV(longRunningPrimitiveCheckSemaphore) != null; - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - flushState = GIV(longRunningPrimitiveCheckSemaphore) == null; - if (!(((!(sema & (tagMask())))) - && (((longAt(sema)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(ClassSemaphore) << (shiftForWord())))))))))) { - return (GIV(primFailCode) = PrimErrBadArgument); - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(longRunningPrimitiveCheckSemaphore) == null)) - || (((stackValue(0)) == GIV(longRunningPrimitiveCheckSemaphore)) - && (isSemaphoreOop(sema)))); - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - if (flushState) { - ceInvokeInterpret(); - } - return 0; -} - /* CoInterpreterPrimitives>>#primitiveMethodPCData */ EXPORT(sqInt) primitiveMethodPCData(void) @@ -26930,14 +26878,9 @@ primitiveObjectAtPut(void) EXPORT(sqInt) primitiveProfileSemaphore(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; int flushState; sqInt sema; - char *sp; - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); if (sema == GIV(nilObj)) { flushState = GIV(profileSemaphore) != GIV(nilObj); @@ -26949,28 +26892,21 @@ primitiveProfileSemaphore(void) return (GIV(primFailCode) = PrimErrBadArgument); } } + GIV(profileSemaphore) = sema; /* If we've switched profiling on or off we must void machine code (and machine code pcs in contexts) since we will start or stop testing the profile clock in machine code primitive invocations, and so generate slightly different code from here on in. */ - GIV(profileSemaphore) = sema; - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(profileSemaphore) == (nilObject()))) - || (((stackValue(0)) == GIV(profileSemaphore)) - && (isSemaphoreOop(sema)))); - } GIV(profileProcess) = (GIV(profileMethod) = GIV(nilObj)); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; if (flushState) { - ceInvokeInterpret(); + flushExternalPrimitives(); + } + else { + /* begin methodReturnReceiver */ + assert(!((failed()))); + /* begin pop: */ + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; } return 0; } @@ -35746,26 +35682,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -38471,15 +38409,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -38497,15 +38430,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -38529,39 +38457,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((integerPointer & 1)) { - deltaTicks = (integerPointer >> 1); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((deltaTicks & 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 1)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -52711,14 +52618,6 @@ isSegmentBridge(sqInt objOop) return ((longAt(objOop)) & (classIndexMask())) == (segmentBridgePun()); } - /* SpurMemoryManager>>#isSemaphoreOop: */ -static sqInt NoDbgRegParms -isSemaphoreOop(sqInt anOop) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - return ((!(anOop & (tagMask())))) - && (((longAt(anOop)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(ClassSemaphore) << (shiftForWord())))))))); -} - /* Answer if the argument contains only indexable 16-bit half words (no oops). See comment in formatOf: @@ -54986,8 +54885,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) sqInt referent; sqInt referent1; sqInt referent2; - sqInt referent3; - sqInt referent4; sqInt sizeOfUnusedEden; StackPage *thePage; @@ -55115,38 +55012,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - if ((!((longAt(GIV(longRunningPrimitiveCheckMethod))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckMethod))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((GIV(longRunningPrimitiveCheckMethod) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent3 & (tagMask())))) - && ((!((longAt(referent3)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((referent3 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckMethod) = referent3; - } - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - if ((!((longAt(GIV(longRunningPrimitiveCheckSemaphore))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckSemaphore))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((GIV(longRunningPrimitiveCheckSemaphore) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent4 & (tagMask())))) - && ((!((longAt(referent4)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((referent4 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckSemaphore) = referent4; - } - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -62597,7 +62462,7 @@ updatePointersInsavedFirstFieldPointer(sqInt obj, sqInt firstFieldPtr) assert((ReceiverIndex + ((sp >> 1))) < (lengthOf(obj))); contextSize = (sp >> 1); l6: /* end fetchStackPointerOf: */; - numPointerSlots = CtxtTempFrameStart + contextSize; + numPointerSlots = ((usqInt) (CtxtTempFrameStart + contextSize)); goto l10; } /* begin numSlotsOf: */ @@ -62627,7 +62492,7 @@ updatePointersInsavedFirstFieldPointer(sqInt obj, sqInt firstFieldPtr) /* begin literalCountOfMethodHeader: */ assert((header & 1)); numLiterals = ((header >> 1)) & AlternateHeaderNumLiteralsMask; - numPointerSlots = numLiterals + LiteralStart; + numPointerSlots = ((usqInt) (numLiterals + LiteralStart)); l10: /* end numPointerSlotsWhileCompactingOf:withFormat:savedFirstFieldPointer: */; if ((fmt <= 5 /* lastPointerFormat */) && (numPointerSlots > 0)) { @@ -64009,33 +63874,6 @@ checkAllAccessibleObjectsOkay(void) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -64126,9 +63964,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { /* begin signalLowSpace: */ GIV(signalLowSpace) = 0; @@ -66876,8 +66711,8 @@ static sqInt getErrorObjectFromPrimFailCode(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt classIndex; - usqInt clone; - usqInt errObj; + sqInt clone; + sqInt errObj; sqInt fieldIndex; sqInt i; usqInt newObj; @@ -68921,7 +68756,8 @@ lookupSelectorinClass(sqInt selector, sqInt class) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt currentClass; sqInt dictionary; - sqInt index; + sqInt fieldIndex; + usqInt index; usqInt length; sqInt mask; sqInt meth; @@ -68965,7 +68801,7 @@ lookupSelectorinClass(sqInt selector, sqInt class) wrapAround = 0; while (1) { /* begin fetchPointer:ofObject: */ - nextSelector = longAt((dictionary + BaseHeaderSize) + (((sqInt)((usqInt)(index) << (shiftForWord()))))); + nextSelector = longAt((dictionary + BaseHeaderSize) + (index << (shiftForWord()))); if (nextSelector == GIV(nilObj)) { meth = null; goto l8; @@ -68983,10 +68819,12 @@ lookupSelectorinClass(sqInt selector, sqInt class) } methodArray = objOop2; /* begin followField:ofObject: */ - objOop1 = longAt((methodArray + BaseHeaderSize) + (((sqInt)((usqInt)((index - SelectorStart)) << (shiftForWord()))))); + fieldIndex = index - SelectorStart; + /* begin fetchPointer:ofObject: */ + objOop1 = longAt((methodArray + BaseHeaderSize) + (((sqInt)((usqInt)(fieldIndex) << (shiftForWord()))))); if (((!(objOop1 & (tagMask())))) && ((!((longAt(objOop1)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - objOop1 = fixFollowedFieldofObjectwithInitialValue(index - SelectorStart, methodArray, objOop1); + objOop1 = fixFollowedFieldofObjectwithInitialValue(fieldIndex, methodArray, objOop1); } meth = objOop1; goto l8; @@ -69168,23 +69006,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i = 1; i <= GIV(jmpDepth); i += 1) { oop = GIV(suspendedCallbacks)[i]; @@ -73095,8 +72916,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -73125,18 +72946,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -76346,22 +76169,6 @@ validStackPageBaseFrames(void) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Return the highest priority process that is ready to run. To save time looking at many empty lists before finding a runnable process the VM maintains a variable holding the @@ -78991,74 +78798,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((addressCouldBeObj(lrpcm)) - && ((!(((longAt(lrpcm)) & (classIndexMask())) == (isFreeObjectClassIndexPun()))) - && (((((usqInt)((longAt(lrpcm)))) >> (formatShift())) & (formatMask())) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - assert(!(isForwarded(result))); - if ((assert(isNonImmediate(result)), - oopisGreaterThanOrEqualTo(result, GIV(oldSpaceStart)))) { - - /* most stores into young objects */ - if (((!(lrpcm & (tagMask())))) - && (oopisLessThan(lrpcm, GIV(newSpaceLimit)))) { - /* begin possibleRootStoreInto: */ - if (!(((((usqInt)((longAt(result)))) >> (rememberedBitShift())) & 1) != 0)) { - remember(result); - } - } - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 1) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 1) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -81553,15 +81292,13 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveGreaterOrEqualLargeIntegers\000\377\000", (void*)primitiveGreaterOrEqualLargeIntegers}, {(void*)_m, "primitiveGreaterThanLargeIntegers\000\377\000", (void*)primitiveGreaterThanLargeIntegers}, {(void*)_m, "primitiveHeartbeatFrequency\000\377\000", (void*)primitiveHeartbeatFrequency}, - {(void*)_m, "primitiveHighResClock\000\377\000", (void*)primitiveHighResClock}, + {(void*)_m, "primitiveHighResClock\000\377\001", (void*)primitiveHighResClock}, {(void*)_m, "primitiveImageFormatVersion\000\377\000", (void*)primitiveImageFormatVersion}, {(void*)_m, "primitiveInterruptChecksPerMSec\000\377\000", (void*)primitiveInterruptChecksPerMSec}, {(void*)_m, "primitiveIsBigEnder\000\377\000", (void*)primitiveIsBigEnder}, {(void*)_m, "primitiveIsWindowObscured\000\377\000", (void*)primitiveIsWindowObscured}, {(void*)_m, "primitiveLessOrEqualLargeIntegers\000\377\000", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers\000\377\000", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive\000\377\000", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore\000\000\000", (void*)primitiveLongRunningPrimitiveSemaphore}, {(void*)_m, "primitiveMethodPCData\000\000\000", (void*)primitiveMethodPCData}, {(void*)_m, "primitiveMillisecondClockMask\000\377\000", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveMinimumUnusedHeadroom\000\377\000", (void*)primitiveMinimumUnusedHeadroom}, @@ -81569,10 +81306,10 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveMultiplyLargeIntegers\000\000\000", (void*)primitiveMultiplyLargeIntegers}, {(void*)_m, "primitiveNotEqualLargeIntegers\000\377\000", (void*)primitiveNotEqualLargeIntegers}, {(void*)_m, "primitivePathToUsing\000\000\000", (void*)primitivePathToUsing}, - {(void*)_m, "primitiveProfilePrimitive\000\377\000", (void*)primitiveProfilePrimitive}, - {(void*)_m, "primitiveProfileSample\000\377\000", (void*)primitiveProfileSample}, + {(void*)_m, "primitiveProfilePrimitive\000\377\001", (void*)primitiveProfilePrimitive}, + {(void*)_m, "primitiveProfileSample\000\377\001", (void*)primitiveProfileSample}, {(void*)_m, "primitiveProfileSemaphore\000\000\000", (void*)primitiveProfileSemaphore}, - {(void*)_m, "primitiveProfileStart\000\000\000", (void*)primitiveProfileStart}, + {(void*)_m, "primitiveProfileStart\000\000\001", (void*)primitiveProfileStart}, {(void*)_m, "primitiveQuoLargeIntegers\000\000\000", (void*)primitiveQuoLargeIntegers}, {(void*)_m, "primitiveRemLargeIntegers\000\000\000", (void*)primitiveRemLargeIntegers}, {(void*)_m, "primitiveResetCountersInMethod\000\000\000", (void*)primitiveResetCountersInMethod}, diff --git a/spursistasrc/vm/cointerp.h b/spursistasrc/vm/cointerp.h index fcda3cd055..6970d88bd2 100644 --- a/spursistasrc/vm/cointerp.h +++ b/spursistasrc/vm/cointerp.h @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ @@ -51,6 +51,7 @@ extern sqInt ceSendabovetonumArgs(sqInt selector, sqInt methodClass, sqInt rcvr, extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern sqInt ceSistaTrap(void); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethod); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); diff --git a/spursistasrc/vm/gcc3x-cointerp.c b/spursistasrc/vm/gcc3x-cointerp.c index 8b87fef2be..942a5bd8c6 100644 --- a/spursistasrc/vm/gcc3x-cointerp.c +++ b/spursistasrc/vm/gcc3x-cointerp.c @@ -2,11 +2,11 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - CoInterpreter VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CoInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 " __DATE__ ; +static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -493,6 +493,7 @@ extern sqInt ceSendabovetonumArgs(sqInt selector, sqInt methodClass, sqInt rcvr, extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern sqInt ceSistaTrap(void); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethod); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); @@ -669,7 +670,6 @@ static void primitiveExitCriticalSection(void); static void primitiveFlushCacheByMethod(void); static void primitiveFlushCacheBySelector(void); extern usqInt primitiveFunctionPointerAddress(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); EXPORT(sqInt) primitiveMethodPCData(void); static void primitiveMethodXray(void); EXPORT(void) primitiveMinimumUnusedHeadroom(void); @@ -1195,7 +1195,6 @@ static sqInt NoDbgRegParms isPureBitsFormat(sqInt format); extern sqInt isReallyYoung(sqInt oop); static sqInt NoDbgRegParms isRemembered(sqInt objOop); static sqInt NoDbgRegParms isSegmentBridge(sqInt objOop); -static sqInt NoDbgRegParms isSemaphoreOop(sqInt anOop); extern sqInt isShorts(sqInt oop); extern sqInt isUnambiguouslyForwarder(sqInt objOop); extern sqInt isUnmarked(sqInt objOop); @@ -1425,7 +1424,6 @@ EXPORT(sqInt) callbackLeave(sqInt cbID); extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHeader); extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkForEventsMayContextSwitch(sqInt mayContextSwitch); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); @@ -1708,7 +1706,6 @@ static sqInt NoDbgRegParms updateDisplayLeftTopRightBottom(sqInt l, sqInt t, sqI static sqInt NoDbgRegParms validBCPCinMethod(sqInt thePC, usqInt aMethod); static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, char *fp); static sqInt validStackPageBaseFrames(void); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt wakeHighestPriority(void); static sqInt NeverInline writeImageFileIO(void); static usqInt NoDbgRegParms cloneContext(sqInt aContext); @@ -1731,7 +1728,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1771,8 +1767,8 @@ _iss sqInt argumentCount; _iss sqLong nextProfileTick; _iss sqInt primTraceLog[256]; _iss StackPage * stackPage; -_iss sqInt nilObj; _iss usqInt method; +_iss sqInt nilObj; _iss sqInt bytecodeSetSelector; _iss usqInt oldSpaceStart; _iss usqInt endOfMemory; @@ -1806,15 +1802,14 @@ _iss usqInt lastMobileObject; _iss sqInt tempOop; _iss sqInt numClassTablePages; _iss sqInt lkupClass; -_iss sqInt futureSurvivorStart; _iss sqInt profileProcess; -_iss sqInt profileSemaphore; +_iss sqInt futureSurvivorStart; _iss sqInt mournQueue; _iss sqInt numRememberedEphemerons; +_iss sqInt profileMethod; _iss sqInt jmpDepth; _iss sqInt mobileStart; -_iss sqInt profileMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; +_iss sqInt profileSemaphore; _iss sqInt growHeadroom; _iss sqInt tenureThreshold; _iss sqInt lastCoggableInterpretedBlockMethod; @@ -1822,7 +1817,6 @@ _iss sqInt lastUncoggableInterpretedBlockMethod; _iss char * objStackInvalidBecause; _iss sqInt sweepIndex; _iss sqInt ephemeronList; -_iss sqInt longRunningPrimitiveCheckMethod; _iss sqInt tenureCriterion; _iss usqInt totalHeapSizeIncludingBridges; _iss sqInt becomeEffectsFlags; @@ -1878,7 +1872,6 @@ _iss sqInt freeSpaceCheckOopToIgnore; _iss usqInt heapSizeAtPreviousGC; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss sqInt methodDictLinearSearchLimit; _iss sqInt statGrowMemory; _iss sqInt statMaxPageCountWhenMapping; @@ -1890,7 +1883,6 @@ _iss sqInt extraFramesToMoveOnOverflow; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; _iss sqInt inFFIFlags; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss sqInt refCountToShrinkRT; _iss sqInt signalLowSpace; @@ -1920,16 +1912,14 @@ _iss sqInt preferredPinningSegment; _iss sqInt statCoalesces; _iss sqInt theUnknownShort; _iss usqLong nextWakeupUsecs; -_iss usqLong statGCEndUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; -_iss usqLong statCheckForEvents; -_iss usqLong gcStartUsecs; _iss sqLong oldSpaceUsePriorToScavenge; +_iss usqLong statGCEndUsecs; _iss usqLong statIOProcessEvents; +_iss usqLong gcStartUsecs; _iss usqLong statAllocatedBytes; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statCompactionUsecs; _iss usqLong statForceInterruptCheck; _iss usqLong statFullGCUsecs; @@ -1943,9 +1933,11 @@ _iss usqLong statSweepUsecs; _iss usqLong statCodeCompactionUsecs; _iss usqLong statSGCDeltaUsecs; _iss usqLong gcSweepEndUsecs; -_iss usqLong longRunningPrimitiveGCUsecs; _iss usqLong statIGCDeltaUsecs; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; _iss usqLong statFGCDeltaUsecs; _iss usqLong statIncrGCUsecs; _iss SpurContiguousObjStack savedFirstFieldsSpace; @@ -2622,7 +2614,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Open Smalltalk Cog[Spur] VM [CoInterpreterPrimitives VMMaker.oscog-eem.3024]"; +const char *interpreterVersion = "Open Smalltalk Cog[Spur] VM [CoInterpreterPrimitives VMMaker.oscog-eem.3031]"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */; char primitiveDoMixedArithmetic = 1; char expensiveAsserts = 0; @@ -18137,6 +18129,27 @@ ceStackOverflow(sqInt contextSwitchIfNotNil) error("should not be reached"); } + +/* A primitive has succeeded and the nextProfileTick has been reached (all + done in machine code). + Now take a sample. c.f. checkProfileTick: */ + + /* CoInterpreter>>#ceTakeProfileSample: */ +void +ceTakeProfileSample(CogMethod *aCogMethod) +{ DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt objOop; + sqInt objOop1; + + /* begin fetchPointer:ofObject: */ + objOop1 = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(SchedulerAssociation) << (shiftForWord()))))); + objOop = longAt((objOop1 + BaseHeaderSize) + (((int)((usqInt)(ValueIndex) << (shiftForWord()))))); + GIV(profileProcess) = longAt((objOop + BaseHeaderSize) + (((int)((usqInt)(ActiveProcessIndex) << (shiftForWord()))))); + GIV(profileMethod) = (aCogMethod->methodObject); + forceInterruptCheck(); + GIV(nextProfileTick) = 0; +} + /* CoInterpreter>>#ceTraceBlockActivation */ void ceTraceBlockActivation(void) @@ -20135,24 +20148,6 @@ void forceInterruptCheckFromHeartbeat(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; sqLowLevelMFence(); if (GIV(deferSmash)) { GIV(deferredSmash) = 1; @@ -21947,7 +21942,8 @@ mnuMethodOrNilFor(sqInt rcvr) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt currentClass; sqInt dictionary; - sqInt index; + sqInt fieldIndex; + usqInt index; usqInt length; sqInt mask; sqInt methodArray; @@ -21996,7 +21992,7 @@ mnuMethodOrNilFor(sqInt rcvr) wrapAround = 0; while (1) { /* begin fetchPointer:ofObject: */ - nextSelector = longAt((dictionary + BaseHeaderSize) + (((sqInt)((usqInt)(index) << (shiftForWord()))))); + nextSelector = longAt((dictionary + BaseHeaderSize) + (index << (shiftForWord()))); if (nextSelector == GIV(nilObj)) { mnuMethod = null; goto l11; @@ -22014,10 +22010,12 @@ mnuMethodOrNilFor(sqInt rcvr) } methodArray = objOop; /* begin followField:ofObject: */ - objOop1 = longAt((methodArray + BaseHeaderSize) + (((sqInt)((usqInt)((index - SelectorStart)) << (shiftForWord()))))); + fieldIndex = index - SelectorStart; + /* begin fetchPointer:ofObject: */ + objOop1 = longAt((methodArray + BaseHeaderSize) + (((sqInt)((usqInt)(fieldIndex) << (shiftForWord()))))); if (((!(objOop1 & (tagMask())))) && ((!((longAt(objOop1)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - objOop1 = fixFollowedFieldofObjectwithInitialValue(index - SelectorStart, methodArray, objOop1); + objOop1 = fixFollowedFieldofObjectwithInitialValue(fieldIndex, methodArray, objOop1); } mnuMethod = objOop1; goto l11; @@ -26577,56 +26575,6 @@ primitiveFunctionPointerAddress(void) return ((usqInt)((&primitiveFunctionPointer))); } - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* CoInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; - int flushState; - sqInt sema; - char *sp; - - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (sema == GIV(nilObj)) { - flushState = GIV(longRunningPrimitiveCheckSemaphore) != null; - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - flushState = GIV(longRunningPrimitiveCheckSemaphore) == null; - if (!(((!(sema & (tagMask())))) - && (((longAt(sema)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(ClassSemaphore) << (shiftForWord())))))))))) { - return (GIV(primFailCode) = PrimErrBadArgument); - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(longRunningPrimitiveCheckSemaphore) == null)) - || (((stackValue(0)) == GIV(longRunningPrimitiveCheckSemaphore)) - && (isSemaphoreOop(sema)))); - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - if (flushState) { - ceInvokeInterpret(); - } - return 0; -} - /* CoInterpreterPrimitives>>#primitiveMethodPCData */ EXPORT(sqInt) primitiveMethodPCData(void) @@ -26939,14 +26887,9 @@ primitiveObjectAtPut(void) EXPORT(sqInt) primitiveProfileSemaphore(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; int flushState; sqInt sema; - char *sp; - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); if (sema == GIV(nilObj)) { flushState = GIV(profileSemaphore) != GIV(nilObj); @@ -26958,28 +26901,21 @@ primitiveProfileSemaphore(void) return (GIV(primFailCode) = PrimErrBadArgument); } } + GIV(profileSemaphore) = sema; /* If we've switched profiling on or off we must void machine code (and machine code pcs in contexts) since we will start or stop testing the profile clock in machine code primitive invocations, and so generate slightly different code from here on in. */ - GIV(profileSemaphore) = sema; - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(profileSemaphore) == (nilObject()))) - || (((stackValue(0)) == GIV(profileSemaphore)) - && (isSemaphoreOop(sema)))); - } GIV(profileProcess) = (GIV(profileMethod) = GIV(nilObj)); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; if (flushState) { - ceInvokeInterpret(); + flushExternalPrimitives(); + } + else { + /* begin methodReturnReceiver */ + assert(!((failed()))); + /* begin pop: */ + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; } return 0; } @@ -35755,26 +35691,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -38480,15 +38418,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -38506,15 +38439,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -38538,39 +38466,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((integerPointer & 1)) { - deltaTicks = (integerPointer >> 1); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((deltaTicks & 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 1)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -52720,14 +52627,6 @@ isSegmentBridge(sqInt objOop) return ((longAt(objOop)) & (classIndexMask())) == (segmentBridgePun()); } - /* SpurMemoryManager>>#isSemaphoreOop: */ -static sqInt NoDbgRegParms -isSemaphoreOop(sqInt anOop) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - return ((!(anOop & (tagMask())))) - && (((longAt(anOop)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(ClassSemaphore) << (shiftForWord())))))))); -} - /* Answer if the argument contains only indexable 16-bit half words (no oops). See comment in formatOf: @@ -54995,8 +54894,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) sqInt referent; sqInt referent1; sqInt referent2; - sqInt referent3; - sqInt referent4; sqInt sizeOfUnusedEden; StackPage *thePage; @@ -55124,38 +55021,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - if ((!((longAt(GIV(longRunningPrimitiveCheckMethod))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckMethod))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((GIV(longRunningPrimitiveCheckMethod) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent3 & (tagMask())))) - && ((!((longAt(referent3)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((referent3 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckMethod) = referent3; - } - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - if ((!((longAt(GIV(longRunningPrimitiveCheckSemaphore))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckSemaphore))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((GIV(longRunningPrimitiveCheckSemaphore) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent4 & (tagMask())))) - && ((!((longAt(referent4)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((referent4 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckSemaphore) = referent4; - } - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -62606,7 +62471,7 @@ updatePointersInsavedFirstFieldPointer(sqInt obj, sqInt firstFieldPtr) assert((ReceiverIndex + ((sp >> 1))) < (lengthOf(obj))); contextSize = (sp >> 1); l6: /* end fetchStackPointerOf: */; - numPointerSlots = CtxtTempFrameStart + contextSize; + numPointerSlots = ((usqInt) (CtxtTempFrameStart + contextSize)); goto l10; } /* begin numSlotsOf: */ @@ -62636,7 +62501,7 @@ updatePointersInsavedFirstFieldPointer(sqInt obj, sqInt firstFieldPtr) /* begin literalCountOfMethodHeader: */ assert((header & 1)); numLiterals = ((header >> 1)) & AlternateHeaderNumLiteralsMask; - numPointerSlots = numLiterals + LiteralStart; + numPointerSlots = ((usqInt) (numLiterals + LiteralStart)); l10: /* end numPointerSlotsWhileCompactingOf:withFormat:savedFirstFieldPointer: */; if ((fmt <= 5 /* lastPointerFormat */) && (numPointerSlots > 0)) { @@ -64018,33 +63883,6 @@ checkAllAccessibleObjectsOkay(void) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -64135,9 +63973,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { /* begin signalLowSpace: */ GIV(signalLowSpace) = 0; @@ -66885,8 +66720,8 @@ static sqInt getErrorObjectFromPrimFailCode(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt classIndex; - usqInt clone; - usqInt errObj; + sqInt clone; + sqInt errObj; sqInt fieldIndex; sqInt i; usqInt newObj; @@ -68930,7 +68765,8 @@ lookupSelectorinClass(sqInt selector, sqInt class) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt currentClass; sqInt dictionary; - sqInt index; + sqInt fieldIndex; + usqInt index; usqInt length; sqInt mask; sqInt meth; @@ -68974,7 +68810,7 @@ lookupSelectorinClass(sqInt selector, sqInt class) wrapAround = 0; while (1) { /* begin fetchPointer:ofObject: */ - nextSelector = longAt((dictionary + BaseHeaderSize) + (((sqInt)((usqInt)(index) << (shiftForWord()))))); + nextSelector = longAt((dictionary + BaseHeaderSize) + (index << (shiftForWord()))); if (nextSelector == GIV(nilObj)) { meth = null; goto l8; @@ -68992,10 +68828,12 @@ lookupSelectorinClass(sqInt selector, sqInt class) } methodArray = objOop2; /* begin followField:ofObject: */ - objOop1 = longAt((methodArray + BaseHeaderSize) + (((sqInt)((usqInt)((index - SelectorStart)) << (shiftForWord()))))); + fieldIndex = index - SelectorStart; + /* begin fetchPointer:ofObject: */ + objOop1 = longAt((methodArray + BaseHeaderSize) + (((sqInt)((usqInt)(fieldIndex) << (shiftForWord()))))); if (((!(objOop1 & (tagMask())))) && ((!((longAt(objOop1)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - objOop1 = fixFollowedFieldofObjectwithInitialValue(index - SelectorStart, methodArray, objOop1); + objOop1 = fixFollowedFieldofObjectwithInitialValue(fieldIndex, methodArray, objOop1); } meth = objOop1; goto l8; @@ -69177,23 +69015,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i = 1; i <= GIV(jmpDepth); i += 1) { oop = GIV(suspendedCallbacks)[i]; @@ -73104,8 +72925,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -73134,18 +72955,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -76355,22 +76178,6 @@ validStackPageBaseFrames(void) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Return the highest priority process that is ready to run. To save time looking at many empty lists before finding a runnable process the VM maintains a variable holding the @@ -79000,74 +78807,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((addressCouldBeObj(lrpcm)) - && ((!(((longAt(lrpcm)) & (classIndexMask())) == (isFreeObjectClassIndexPun()))) - && (((((usqInt)((longAt(lrpcm)))) >> (formatShift())) & (formatMask())) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - assert(!(isForwarded(result))); - if ((assert(isNonImmediate(result)), - oopisGreaterThanOrEqualTo(result, GIV(oldSpaceStart)))) { - - /* most stores into young objects */ - if (((!(lrpcm & (tagMask())))) - && (oopisLessThan(lrpcm, GIV(newSpaceLimit)))) { - /* begin possibleRootStoreInto: */ - if (!(((((usqInt)((longAt(result)))) >> (rememberedBitShift())) & 1) != 0)) { - remember(result); - } - } - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 1) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 1) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -81562,15 +81301,13 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveGreaterOrEqualLargeIntegers\000\377\000", (void*)primitiveGreaterOrEqualLargeIntegers}, {(void*)_m, "primitiveGreaterThanLargeIntegers\000\377\000", (void*)primitiveGreaterThanLargeIntegers}, {(void*)_m, "primitiveHeartbeatFrequency\000\377\000", (void*)primitiveHeartbeatFrequency}, - {(void*)_m, "primitiveHighResClock\000\377\000", (void*)primitiveHighResClock}, + {(void*)_m, "primitiveHighResClock\000\377\001", (void*)primitiveHighResClock}, {(void*)_m, "primitiveImageFormatVersion\000\377\000", (void*)primitiveImageFormatVersion}, {(void*)_m, "primitiveInterruptChecksPerMSec\000\377\000", (void*)primitiveInterruptChecksPerMSec}, {(void*)_m, "primitiveIsBigEnder\000\377\000", (void*)primitiveIsBigEnder}, {(void*)_m, "primitiveIsWindowObscured\000\377\000", (void*)primitiveIsWindowObscured}, {(void*)_m, "primitiveLessOrEqualLargeIntegers\000\377\000", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers\000\377\000", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive\000\377\000", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore\000\000\000", (void*)primitiveLongRunningPrimitiveSemaphore}, {(void*)_m, "primitiveMethodPCData\000\000\000", (void*)primitiveMethodPCData}, {(void*)_m, "primitiveMillisecondClockMask\000\377\000", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveMinimumUnusedHeadroom\000\377\000", (void*)primitiveMinimumUnusedHeadroom}, @@ -81578,10 +81315,10 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveMultiplyLargeIntegers\000\000\000", (void*)primitiveMultiplyLargeIntegers}, {(void*)_m, "primitiveNotEqualLargeIntegers\000\377\000", (void*)primitiveNotEqualLargeIntegers}, {(void*)_m, "primitivePathToUsing\000\000\000", (void*)primitivePathToUsing}, - {(void*)_m, "primitiveProfilePrimitive\000\377\000", (void*)primitiveProfilePrimitive}, - {(void*)_m, "primitiveProfileSample\000\377\000", (void*)primitiveProfileSample}, + {(void*)_m, "primitiveProfilePrimitive\000\377\001", (void*)primitiveProfilePrimitive}, + {(void*)_m, "primitiveProfileSample\000\377\001", (void*)primitiveProfileSample}, {(void*)_m, "primitiveProfileSemaphore\000\000\000", (void*)primitiveProfileSemaphore}, - {(void*)_m, "primitiveProfileStart\000\000\000", (void*)primitiveProfileStart}, + {(void*)_m, "primitiveProfileStart\000\000\001", (void*)primitiveProfileStart}, {(void*)_m, "primitiveQuoLargeIntegers\000\000\000", (void*)primitiveQuoLargeIntegers}, {(void*)_m, "primitiveRemLargeIntegers\000\000\000", (void*)primitiveRemLargeIntegers}, {(void*)_m, "primitiveResetCountersInMethod\000\000\000", (void*)primitiveResetCountersInMethod}, diff --git a/spursrc/vm/cogit.c b/spursrc/vm/cogit.c index d7cc3d371e..8d71e53f42 100644 --- a/spursrc/vm/cogit.c +++ b/spursrc/vm/cogit.c @@ -1,5 +1,5 @@ /* Automatically generated by - Cogit VMMaker.oscog-nice.2712 uuid: da64ef0b-fb0a-4770-ac16-f9b448234615 + Cogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ #if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7__) || defined(__arm__) || defined(__arm32__) || defined(ARM32) || defined(_M_ARM) @@ -10,10 +10,6 @@ # include "cogitIA32.c" -#elif defined(__MIPSEL__) - -# include "cogitMIPSEL.c" - #else # error As yet no Cogit implementation appears to exist for your platform. # error Consider implementing it, starting by adding a subclass of CogAbstractInstruction. diff --git a/spursrc/vm/cogit.h b/spursrc/vm/cogit.h index 2a623169bf..403f0da618 100644 --- a/spursrc/vm/cogit.h +++ b/spursrc/vm/cogit.h @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + CCodeGenerator VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ diff --git a/spursrc/vm/cogitARMv5.c b/spursrc/vm/cogitARMv5.c index 5d39798a37..a996ac8e52 100644 --- a/spursrc/vm/cogitARMv5.c +++ b/spursrc/vm/cogitARMv5.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + CCodeGenerator VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + StackToRegisterMappingCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 " __DATE__ ; +static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__cogitBuildInfo = __buildInfo; @@ -89,7 +89,7 @@ char *__cogitBuildInfo = __buildInfo; #define CMMaxUsageCount 7 #define CMMethod 2 #define CMOpenPIC 5 -#define CMPSMULL 165 +#define CMPSMULL 167 #define CmpC32R 113 #define CmpCqR 105 #define CmpCwR 112 @@ -240,6 +240,8 @@ char *__cogitBuildInfo = __buildInfo; #define MoveMwrR 50 #define MoveNotOpcode 15 #define MoveOpcode 13 +#define MovePerfCnt64RL 159 +#define MovePerfCnt64RRL 158 #define MoveRAb 49 #define MoveRAw 46 #define MoveRdM64r 76 @@ -252,7 +254,7 @@ char *__cogitBuildInfo = __buildInfo; #define MoveRXwrR 53 #define MoveXbrRR 67 #define MoveXwrRR 52 -#define MSR 159 +#define MSR 161 #define MULTIPLEBYTECODESETS 1 #define MulRdRd 134 #define NativePopR 84 @@ -281,7 +283,7 @@ char *__cogitBuildInfo = __buildInfo; #define PC 15 #define PCReg 15 #define PL 5 -#define PopLDM 161 +#define PopLDM 163 #define PopR 80 #define PrefetchAw 87 #define PrimCallCollectsProfileSamples 8 @@ -297,7 +299,7 @@ char *__cogitBuildInfo = __buildInfo; #define PushCq 82 #define PushCw 83 #define PushR 81 -#define PushSTM 162 +#define PushSTM 164 #define ReceiverIndex 5 #define ReceiverResultReg 5 #define RetN 9 @@ -312,7 +314,7 @@ char *__cogitBuildInfo = __buildInfo; #define SignExtend8RR 151 #define SistaV1BytecodeSet 1 #define SistaVM 0 -#define SMULL 158 +#define SMULL 160 #define SmallContextSlots 22 #define SP 13 #define SPReg 13 @@ -324,6 +326,7 @@ char *__cogitBuildInfo = __buildInfo; #define SSSpill 4 #define StackPointerIndex 2 #define Stop 11 +#define SubbRR 121 #define SubCqR 107 #define SubCwR 115 #define SubOpcode 2 @@ -467,7 +470,7 @@ static void NoDbgRegParms cloneLiteralFrom(AbstractInstruction * self_in_cloneLi static sqInt NoDbgRegParms genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer); static sqInt NoDbgRegParms genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers); static sqInt NoDbgRegParms genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers); -static sqInt NoDbgRegParms genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg); +static sqInt NoDbgRegParms genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg); static sqInt NoDbgRegParms genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers); static AbstractInstruction * NoDbgRegParms genSwapRRScratch(AbstractInstruction * self_in_genSwapRRScratch, sqInt regA, sqInt regB, sqInt regTmp); static void NoDbgRegParms genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister); @@ -744,6 +747,8 @@ static BytecodeDescriptor * loadBytesAndGetDescriptor(void); static void NoDbgRegParms loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc); static AbstractInstruction * NoDbgRegParms gMoveAwR(sqInt address, sqInt reg); static AbstractInstruction * NoDbgRegParms gMoveCwR(sqInt wordConstant, sqInt reg); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters); static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg); static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC); @@ -790,6 +795,7 @@ static void NoDbgRegParms recordGeneratedRunTimeaddress(char *aString, sqInt add extern sqInt recordPrimTraceFunc(void); static void recordRunTimeObjectReferences(void); static sqInt NoDbgRegParms registerMaskFor(sqInt reg); +static sqInt NoDbgRegParms registerMaskForand(sqInt reg1, sqInt reg2); static void NoDbgRegParms relocateCallsAndSelfReferencesInMethod(CogMethod *cogMethod); static void NoDbgRegParms relocateCallsInClosedPIC(CogMethod *cPIC); static sqInt NoDbgRegParms relocateIfCallOrMethodReferencemcpcdelta(sqInt annotation, char *mcpc, CogMethod *refDeltaArg); @@ -1141,6 +1147,7 @@ static sqInt genStoreAndPopReceiverVariableBytecode(void); static sqInt genStoreAndPopRemoteTempLongBytecode(void); static sqInt genStoreAndPopTemporaryVariableBytecode(void); static sqInt genStoreRemoteTempLongBytecode(void); +static void genTakeProfileSample(void); static sqInt genUnconditionalTrapBytecode(void); extern sqInt mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj); static sqInt numSpecialSelectors(void); @@ -2694,28 +2701,28 @@ addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *an static sqInt NoDbgRegParms availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << DPFPReg0)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg0))) != 0))) { return DPFPReg0; } - if (!(((liveRegsMask & (1U << DPFPReg1)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg1))) != 0))) { return DPFPReg1; } - if (!(((liveRegsMask & (1U << DPFPReg2)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg2))) != 0))) { return DPFPReg2; } - if (!(((liveRegsMask & (1U << DPFPReg3)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg3))) != 0))) { return DPFPReg3; } - if (!(((liveRegsMask & (1U << DPFPReg4)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg4))) != 0))) { return DPFPReg4; } - if (!(((liveRegsMask & (1U << DPFPReg5)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg5))) != 0))) { return DPFPReg5; } - if (!(((liveRegsMask & (1U << DPFPReg6)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg6))) != 0))) { return DPFPReg6; } - if (!(((liveRegsMask & (1U << DPFPReg7)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg7))) != 0))) { return DPFPReg7; } return NoReg; @@ -2815,11 +2822,11 @@ genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers) used immediately afterwards. */ - /* CogAbstractInstruction>>#genLoadStackPointersForFastPrimCall: */ + /* CogAbstractInstruction>>#genLoadStackPointersForPrimCall: */ static sqInt NoDbgRegParms -genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg) +genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg) { - genLoadStackPointers(self_in_genLoadStackPointersForFastPrimCall); + genLoadStackPointers(self_in_genLoadStackPointersForPrimCall); return 0; } @@ -3099,28 +3106,28 @@ andrnimmror(AbstractInstruction * self_in_andrnimmror, sqInt destReg, sqInt srcR static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << Extra0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra0Reg))) != 0))) { return Extra0Reg; } - if (!(((liveRegsMask & (1U << Extra1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra1Reg))) != 0))) { return Extra1Reg; } - if (!(((liveRegsMask & (1U << Extra2Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra2Reg))) != 0))) { return Extra2Reg; } - if (!(((liveRegsMask & (1U << Arg1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg1Reg))) != 0))) { return Arg1Reg; } - if (!(((liveRegsMask & (1U << Arg0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg0Reg))) != 0))) { return Arg0Reg; } - if (!(((liveRegsMask & (1U << SendNumArgsReg)) != 0))) { + if (!(((liveRegsMask & ((1U << SendNumArgsReg))) != 0))) { return SendNumArgsReg; } - if (!(((liveRegsMask & (1U << ClassReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ClassReg))) != 0))) { return ClassReg; } - if (!(((liveRegsMask & (1U << ReceiverResultReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ReceiverResultReg))) != 0))) { return ReceiverResultReg; } return NoReg; @@ -10225,7 +10232,7 @@ compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numAr regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1U << resultRegOrNone)) - (1U << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1U << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1U << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ regMaskCopy = ((usqInt)regsToSave); @@ -11852,7 +11859,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) startAddress = methodZoneBase; callerSavedReg = 0; pushedVarBaseReg = 0; - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { /* VarBaseReg is not caller-saved; must save and restore it, either by using an available caller-saved reg or push/pop. */ @@ -11902,7 +11909,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) operandTwo2 = cStackPointerAddress(); checkLiteralforInstruction(operandTwo2, genoperandoperand(MoveRAw, NativeSPReg, operandTwo2)); } - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { if (pushedVarBaseReg) { gNativePopR(VarBaseReg); } @@ -13253,6 +13260,22 @@ gMoveCwR(sqInt wordConstant, sqInt reg) return checkLiteralforInstruction(wordConstant, genoperandoperand(MoveCwR, wordConstant, reg)); } + /* Cogit>>#MovePerfCnt64R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters) +{ + assert(0); + return genoperandoperand(MovePerfCnt64RL, destReg, liveRegisters); +} + + /* Cogit>>#MovePerfCnt64R:R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters) +{ + assert(0); + return genoperandoperandoperand(MovePerfCnt64RRL, destRegLo, destRegHi, liveRegisters); +} + /* Answer the address of the null byte at the end of the method map. */ @@ -14787,11 +14810,21 @@ recordRunTimeObjectReferences(void) } } + +/* N.B. (self registerMaskFor: NoReg) = 0 */ + /* Cogit>>#registerMaskFor: */ static sqInt NoDbgRegParms registerMaskFor(sqInt reg) { - return 1U << reg; + return ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); +} + + /* Cogit>>#registerMaskFor:and: */ +static sqInt NoDbgRegParms +registerMaskForand(sqInt reg1, sqInt reg2) +{ + return (1U << reg1) | (1U << reg2); } /* Cogit>>#relocateCallsAndSelfReferencesInMethod: */ @@ -21831,7 +21864,7 @@ generateObjectRepresentationTrampolines(void) genoperand(RetN, 0); jmpTarget(jumpSC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); } - ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))), 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), CheckRememberedInTrampoline); ceStoreCheckContextReceiverTrampoline = genStoreCheckContextReceiverTrampoline(); @@ -24125,7 +24158,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jumpRC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg)); jmpTarget(jumpImmutable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); @@ -24141,7 +24174,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* Store check */ jumpImmutable1 = genJumpImmutablescratchReg(ReceiverResultReg, SendNumArgsReg); - compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), 0 /* emptyRegisterMask */); genLoadStackPointers(backEnd()); @@ -25286,7 +25319,7 @@ registerMask(SimStackEntry * self_in_registerMask) || (((self_in_registerMask->type)) == SSRegister) ? (/* begin registerMaskFor: */ (reg = (self_in_registerMask->registerr)), - 1U << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg))) : 0); } @@ -25299,7 +25332,7 @@ registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone) return (((self_in_registerMaskOrNone->type)) == SSRegister ? (/* begin registerMaskFor: */ (reg = (self_in_registerMaskOrNone->registerr)), - 1U << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg))) : 0); } @@ -25691,40 +25724,24 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) { sqInt address; sqInt address1; - sqInt address10; - sqInt address11; - sqInt address12; - sqInt address13; - sqInt address3; - sqInt address4; - sqInt address5; + sqInt address2; sqInt address6; + sqInt address7; sqInt address8; sqInt address9; + AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; AbstractInstruction *anInstruction4; AbstractInstruction *anInstruction5; AbstractInstruction *anInstruction6; AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction * continuePostSampleNonPrim; - AbstractInstruction * continuePostSamplePrim; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; - AbstractInstruction * jmpSampleNonPrim; - AbstractInstruction * jmpSamplePrim; sqInt offset; sqInt offset1; sqInt offset2; - sqInt operand1; - sqInt operand3; - sqInt reg; sqInt retpc; - continuePostSampleNonPrim = ((AbstractInstruction *) 0); - continuePostSamplePrim = ((AbstractInstruction *) 0); - jmpSampleNonPrim = ((AbstractInstruction *) 0); - jmpSamplePrim = ((AbstractInstruction *) 0); assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); genExternalizePointersForPrimitiveCall(); /* begin genLoadCStackPointersForPrimCall */ @@ -25734,54 +25751,36 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) else { genLoadCStackPointer(backEnd); } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick if so */ - /* begin MoveAw:R: */ - address = nextProfileTickAddress(); - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address, genoperandoperand(MoveAwR, address, TempReg)); - /* begin MoveAw:R: */ - address1 = (nextProfileTickAddress()) + BytesPerWord; - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address1, genoperandoperand(MoveAwR, address1, ClassReg)); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSampleNonPrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSampleNonPrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } if (recordPrimTraceForMethod(methodObj)) { genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(MoveCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction8)) { - (anInstruction8->dependent = locateLiteral(0)); + anInstruction4 = genoperandoperand(MoveCqR, 0, TempReg); + if (usesOutOfLineLiteral(anInstruction4)) { + (anInstruction4->dependent = locateLiteral(0)); } /* begin MoveR:Aw: */ - address11 = primFailCodeAddress(); + address6 = primFailCodeAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address11, genoperandoperand(MoveRAw, TempReg, address11)); + checkLiteralforInstruction(address6, genoperandoperand(MoveRAw, TempReg, address6)); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); - if (usesOutOfLineLiteral(anInstruction1)) { - (anInstruction1->dependent = locateLiteral(methodOrBlockNumArgs)); + anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); + if (usesOutOfLineLiteral(anInstruction)) { + (anInstruction->dependent = locateLiteral(methodOrBlockNumArgs)); } } /* begin MoveR:Aw: */ - address12 = argumentCountAddress(); + address7 = argumentCountAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address12, genoperandoperand(MoveRAw, TempReg, address12)); + checkLiteralforInstruction(address7, genoperandoperand(MoveRAw, TempReg, address7)); if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { /* begin MoveCw:R: */ checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg)); /* begin MoveR:Aw: */ - address3 = primitiveFunctionPointerAddress(); + address = primitiveFunctionPointerAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address3, genoperandoperand(MoveRAw, TempReg, address3)); + checkLiteralforInstruction(address, genoperandoperand(MoveRAw, TempReg, address)); } if (((flags & (PrimCallNeedsNewMethod + PrimCallMayEndureCodeCompaction)) != 0)) { @@ -25793,22 +25792,21 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) /* begin MoveMw:r:R: */ offset = offsetof(CogMethod, methodObject); /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - if (usesOutOfLineLiteral(anInstruction2)) { - (anInstruction2->dependent = locateLiteral(offset)); + anInstruction1 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); + if (usesOutOfLineLiteral(anInstruction1)) { + (anInstruction1->dependent = locateLiteral(offset)); } /* begin MoveR:Aw: */ - address4 = newMethodAddress(); + address1 = newMethodAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address4, genoperandoperand(MoveRAw, TempReg, address4)); + checkLiteralforInstruction(address1, genoperandoperand(MoveRAw, TempReg, address1)); } /* begin PrefetchAw: */ - address13 = primFailCodeAddress(); + address8 = primFailCodeAddress(); /* begin gen:literal: */ - checkLiteralforInstruction(address13, genoperand(PrefetchAw, address13)); + checkLiteralforInstruction(address8, genoperand(PrefetchAw, address8)); if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - /* Sideways call the C primitive routine so that we return through cePrimReturnEnterCogCode. */ /* On Spur ceActivateFailingPrimitiveMethod: would like to retry if forwarders are found. So insist on PrimCallNeedsPrimitiveFunction being set too. */ assert(((flags & PrimCallNeedsPrimitiveFunction) != 0)); @@ -25821,103 +25819,48 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) checkLiteralforInstruction(retpc, genoperandoperand(MoveCwR, retpc, LR)); /* begin gen:literal: */ checkLiteralforInstruction(((sqInt)(((sqInt)primitiveRoutine))), genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine))))); - jmp = (jmpSamplePrim = (continuePostSamplePrim = null)); + return 0; } - else { - - /* Call the C primitive routine. */ - genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); - /* begin gen:literal: */ - checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperand(CallFull, ((sqInt)primitiveRoutine))); - /* begin genRemoveNArgsFromStack: */ - assert(0 <= 4); - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin MoveAw:R: */ - address5 = nextProfileTickAddress(); - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address5, genoperandoperand(MoveAwR, address5, TempReg)); - /* begin MoveAw:R: */ - address6 = (nextProfileTickAddress()) + BytesPerWord; - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address6, genoperandoperand(MoveAwR, address6, ClassReg)); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSamplePrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSamplePrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - maybeCompileRetryOnPrimitiveFail(primitiveIndex); - /* begin MoveAw:R: */ - address8 = instructionPointerAddress(); - reg = LinkReg; - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address8, genoperandoperand(MoveAwR, address8, reg)); - genLoadStackPointers(backEnd); - /* begin MoveAw:R: */ - address9 = primFailCodeAddress(); - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address9, genoperandoperand(MoveAwR, address9, TempReg)); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction4)) { - (anInstruction4->dependent = locateLiteral(0)); - } - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset1 = 0; - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); - if (usesOutOfLineLiteral(anInstruction5)) { - (anInstruction5->dependent = locateLiteral(offset1)); - } - /* begin RetN: */ - genoperand(RetN, BytesPerWord); + genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); + /* begin gen:literal: */ + checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperand(CallFull, ((sqInt)primitiveRoutine))); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 4); + maybeCompileRetryOnPrimitiveFail(primitiveIndex); + genLoadStackPointersForPrimCall(backEnd, ClassReg); + /* begin MoveAw:R: */ + address2 = instructionPointerAddress(); + /* begin gen:literal:operand: */ + checkLiteralforInstruction(address2, genoperandoperand(MoveAwR, address2, LinkReg)); + /* begin MoveAw:R: */ + address9 = primFailCodeAddress(); + /* begin gen:literal:operand: */ + checkLiteralforInstruction(address9, genoperandoperand(MoveAwR, address9, TempReg)); + flag("ask concrete code gen if move sets condition codes?"); + /* begin checkQuickConstant:forInstruction: */ + anInstruction5 = genoperandoperand(CmpCqR, 0, TempReg); + if (usesOutOfLineLiteral(anInstruction5)) { + (anInstruction5->dependent = locateLiteral(0)); } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* The sample is collected by cePrimReturnEnterCogCode for external calls */ - if (!(jmpSamplePrim == null)) { - - /* Call ceCheckProfileTick: to record sample and then continue. */ - jmpTarget(jmpSamplePrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin gen:literal: */ - operand1 = ((usqIntptr_t)ceCheckProfileTick); - checkLiteralforInstruction(operand1, genoperand(CallFull, operand1)); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSamplePrim)); - } - jmpTarget(jmpSampleNonPrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(MoveCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction6)) { - (anInstruction6->dependent = locateLiteral(0)); - } - /* begin MoveR:Aw: */ - address10 = newMethodAddress(); - /* begin gen:operand:literal: */ - checkLiteralforInstruction(address10, genoperandoperand(MoveRAw, TempReg, address10)); - /* begin gen:literal: */ - operand3 = ((usqIntptr_t)ceCheckProfileTick); - checkLiteralforInstruction(operand3, genoperand(CallFull, operand3)); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSampleNonPrim)); + /* begin JumpNonZero: */ + jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + /* begin MoveMw:r:R: */ + offset1 = 0; + /* begin checkQuickConstant:forInstruction: */ + anInstruction6 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); + if (usesOutOfLineLiteral(anInstruction6)) { + (anInstruction6->dependent = locateLiteral(offset1)); } - if (!(jmp == null)) { - - /* Jump to restore of receiver reg and proceed to frame build for failure. */ - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin MoveMw:r:R: */ - offset2 = BytesPerWord * (methodOrBlockNumArgs + (0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); - if (usesOutOfLineLiteral(anInstruction7)) { - (anInstruction7->dependent = locateLiteral(offset2)); - } + continueAfterProfileSample = anInstruction6; + /* begin RetN: */ + genoperand(RetN, BytesPerWord); + jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + /* begin MoveMw:r:R: */ + offset2 = BytesPerWord * (methodOrBlockNumArgs + (0)); + /* begin checkQuickConstant:forInstruction: */ + anInstruction7 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); + if (usesOutOfLineLiteral(anInstruction7)) { + (anInstruction7->dependent = locateLiteral(offset2)); } return 0; } @@ -25947,7 +25890,7 @@ compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)) if ((methodOrBlockNumArgs > 2 /* numRegArgs */) || (methodOrBlockNumArgs == 0)) { /* begin registerMaskFor: */ - liveRegsMask = 1U << ReceiverResultReg; + liveRegsMask = (1U << ReceiverResultReg); } else { if (methodOrBlockNumArgs > 1) { @@ -26039,6 +25982,7 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags AbstractInstruction *anInstruction8; AbstractInstruction *anInstruction9; sqInt calleeSavedRegisterMask; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; sqInt linkRegSaveRegister; sqInt offset; @@ -26075,12 +26019,12 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags /* begin gen:operand:literal: */ checkLiteralforInstruction(address5, genoperandoperand(MoveRAw, TempReg, address5)); genExternalizeStackPointerForFastPrimitiveCall(); - calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | (1U << ClassReg)) - (1U << ClassReg)); + calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | ((1U << ClassReg))) - ((1U << ClassReg))); linkRegSaveRegister = availableRegisterOrNoneIn(calleeSavedRegisterMask); assert(!((linkRegSaveRegister == NoReg))); /* begin MoveR:R: */ genoperandoperand(MoveRR, LinkReg, linkRegSaveRegister); - calleeSavedRegisterMask = ((calleeSavedRegisterMask | (1U << linkRegSaveRegister)) - (1U << linkRegSaveRegister)); + calleeSavedRegisterMask = ((calleeSavedRegisterMask | (((linkRegSaveRegister < 0) ? (((usqInt)(1)) >> (-linkRegSaveRegister)) : (1U << linkRegSaveRegister)))) - (((linkRegSaveRegister < 0) ? (((usqInt)(1)) >> (-linkRegSaveRegister)) : (1U << linkRegSaveRegister)))); spRegSaveRegister = NoReg; /* begin Label */ retry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); @@ -26089,8 +26033,11 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags } else { } + genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); /* begin gen:literal: */ - checkLiteralforInstruction(primitiveRoutine, genoperand(CallFull, primitiveRoutine)); + checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperand(CallFull, ((sqInt)primitiveRoutine))); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 4); /* begin MoveAw:R: */ address6 = primFailCodeAddress(); /* begin gen:literal:operand: */ @@ -26109,7 +26056,7 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags /* begin MoveAw:R: */ address7 = stackPointerAddress(); /* begin gen:literal:operand: */ - checkLiteralforInstruction(address7, genoperandoperand(MoveAwR, address7, TempReg)); + continueAfterProfileSample = checkLiteralforInstruction(address7, genoperandoperand(MoveAwR, address7, TempReg)); /* begin checkQuickConstant:forInstruction: */ anInstruction1 = genoperandoperandoperand(MoveMwrR, 0, TempReg, ReceiverResultReg); if (usesOutOfLineLiteral(anInstruction1)) { @@ -26155,10 +26102,11 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags else { genLoadCStackPointer(backEnd); } + genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); /* begin gen:literal: */ operand1 = ((usqIntptr_t)checkForAndFollowForwardedPrimitiveState); checkLiteralforInstruction(operand1, genoperand(CallFull, operand1)); - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); /* begin checkQuickConstant:forInstruction: */ anInstruction6 = genoperandoperand(CmpCqR, 0, ABIResultReg); if (usesOutOfLineLiteral(anInstruction6)) { @@ -26183,12 +26131,12 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags /* must reload SPReg to undo any alignment change, */ if (((flags & PrimCallOnSmalltalkStackAlign2x) != 0)) { - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); } } /* begin MoveR:R: */ genoperandoperand(MoveRR, linkRegSaveRegister, LinkReg); - if (((ABICallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((ABICallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* begin MoveMw:r:R: */ offset1 = (methodOrBlockNumArgs + (0)) * BytesPerWord; /* begin checkQuickConstant:forInstruction: */ @@ -27237,24 +27185,16 @@ static void NoDbgRegParms genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) { sqInt address; - sqInt address1; sqInt address3; - sqInt address6; - sqInt address7; - sqInt address8; + sqInt address4; + sqInt address5; AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction7; - sqInt callTarget; - AbstractInstruction *continuePostSample; - AbstractInstruction * inst; + AbstractInstruction *anInstruction4; + AbstractInstruction *anInstruction6; AbstractInstruction *jmpFail; - AbstractInstruction *jmpSample; sqInt quickConstant; sqInt reg; - continuePostSample = ((AbstractInstruction *) 0); - jmpSample = ((AbstractInstruction *) 0); zeroOpcodeIndex(); /* begin MoveCq:R: */ quickConstant = varBaseAddress(); @@ -27263,34 +27203,15 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) if (usesOutOfLineLiteral(anInstruction)) { (anInstruction->dependent = locateLiteral(quickConstant)); } - if (profiling) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick: if so. - N.B. nextProfileTick is 64-bits so 32-bit systems need to test both halves. */ - /* begin MoveAw:R: */ - address = nextProfileTickAddress(); - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address, genoperandoperand(MoveAwR, address, TempReg)); - /* begin MoveAw:R: */ - address1 = (nextProfileTickAddress()) + BytesPerWord; - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address1, genoperandoperand(MoveAwR, address1, ClassReg)); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSample = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } /* begin MoveAw:R: */ - address6 = primFailCodeAddress(); + address3 = primFailCodeAddress(); /* begin gen:literal:operand: */ - checkLiteralforInstruction(address6, genoperandoperand(MoveAwR, address6, TempReg)); + checkLiteralforInstruction(address3, genoperandoperand(MoveAwR, address3, TempReg)); flag("ask concrete code gen if move sets condition codes?"); /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(CmpCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction7)) { - (anInstruction7->dependent = locateLiteral(0)); + anInstruction6 = genoperandoperand(CmpCqR, 0, TempReg); + if (usesOutOfLineLiteral(anInstruction6)) { + (anInstruction6->dependent = locateLiteral(0)); } /* begin JumpNonZero: */ jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); @@ -27298,44 +27219,29 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) /* begin PopR: */ genoperand(PopR, ReceiverResultReg); /* begin MoveAw:R: */ - address3 = instructionPointerAddress(); + address = instructionPointerAddress(); /* begin gen:literal:operand: */ - checkLiteralforInstruction(address3, genoperandoperand(MoveAwR, address3, PCReg)); + checkLiteralforInstruction(address, genoperandoperand(MoveAwR, address, PCReg)); jmpTarget(jmpFail, gMoveAwR(newMethodAddress(), SendNumArgsReg)); /* begin MoveAw:R: */ - address7 = cStackPointerAddress(); + address4 = cStackPointerAddress(); /* begin gen:literal:operand: */ - checkLiteralforInstruction(address7, genoperandoperand(MoveAwR, address7, SPReg)); + checkLiteralforInstruction(address4, genoperandoperand(MoveAwR, address4, SPReg)); compileCallFornumArgsargargargargresultRegregsToSave(ceActivateFailingPrimitiveMethod, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); /* begin MoveAw:R: */ - address8 = instructionPointerAddress(); + address5 = instructionPointerAddress(); reg = LinkReg; /* begin gen:literal:operand: */ - checkLiteralforInstruction(address8, genoperandoperand(MoveAwR, address8, reg)); + checkLiteralforInstruction(address5, genoperandoperand(MoveAwR, address5, reg)); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); - if (usesOutOfLineLiteral(anInstruction5)) { - (anInstruction5->dependent = locateLiteral(0)); + anInstruction4 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); + if (usesOutOfLineLiteral(anInstruction4)) { + (anInstruction4->dependent = locateLiteral(0)); } /* begin RetN: */ genoperand(RetN, BytesPerWord); - if (profiling) { - - /* Call ceCheckProfileTick: to record sample and then continue. newMethod - should be up-to-date. Need to save and restore the link reg around this call. */ - jmpTarget(jmpSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - /* begin CallFullRT: */ - callTarget = (usqIntptr_t)ceCheckProfileTick; - /* begin gen:literal: */ - checkLiteralforInstruction(callTarget, genoperand(CallFull, callTarget)); - genoperand(PopR, LinkReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSample)); } -} /* SimpleStackBasedCogit>>#genPushConstantFalseBytecode */ static sqInt @@ -27701,6 +27607,21 @@ genStoreRemoteTempLongBytecode(void) && (shouldAnnotateObjectReference(((ssTop())->constant))))); } + /* SimpleStackBasedCogit>>#genTakeProfileSample */ +static void +genTakeProfileSample(void) +{ + sqInt operand1; + + addDependent(methodLabel, annotateAbsolutePCRef(gMoveCwR(((sqInt)methodLabel), ClassReg))); + genMarshallNArgsargargargarg(backEnd, 1, ClassReg, null, null, null); + /* begin gen:literal: */ + operand1 = ((usqIntptr_t)ceTakeProfileSample); + checkLiteralforInstruction(operand1, genoperand(CallFull, operand1)); + /* begin genRemoveNArgsFromStack: */ + assert(1 <= 4); + } + /* SistaV1: * 217 Trap */ @@ -28043,7 +27964,7 @@ primitiveGeneratorOrNil(void) static sqInt NoDbgRegParms registerisInMask(sqInt reg, sqInt mask) { - return ((mask & (1U << reg)) != 0); + return ((mask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)))) != 0); } /* SimpleStackBasedCogit>>#v3:Block:Code:Size: */ @@ -28394,7 +28315,7 @@ anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n) sqInt regMask; /* begin registerMaskFor: */ - regMask = 1U << reg; + regMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { if ((((registerMask(simStackAt(i))) & regMask) != 0)) { return 1; @@ -29440,7 +29361,7 @@ ensureReceiverResultRegContainsSelf(void) if (needsFrame) { if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin putSelfInReceiverResultReg */ storeToReg(simSelf(), ReceiverResultReg); ((simSelf())->liveRegister = ReceiverResultReg); @@ -29572,7 +29493,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) && (index < simStackPtr)) { desc = simStackAt(index); if (((desc->type)) == SSRegister) { - if (!(((regMask & (1U << ((desc->registerr)))) != 0))) { + if (!(((regMask & (((((desc->registerr)) < 0) ? (((usqInt)(1)) >> (-((desc->registerr)))) : (1U << ((desc->registerr)))))) != 0))) { reg = (desc->registerr); } } @@ -29580,7 +29501,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) } assert(!((reg == NoReg))); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << reg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)), simStackPtr, simNativeStackPtr); return reg; } @@ -30125,13 +30046,13 @@ genForwardersInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -31112,11 +31033,11 @@ genPushMaybeContextReceiverVariable(sqInt slotIndex) AbstractInstruction *jmpSingle; /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ensureReceiverResultRegContainsSelf(); /* begin genPushMaybeContextSlotIndex: */ assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ voidReceiverResultRegContainsSelf(); @@ -31174,7 +31095,7 @@ genPushNewArrayBytecode(void) } else { /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << SendNumArgsReg)) | ((1U << ReceiverResultReg))), simStackPtr, simNativeStackPtr); } size = byte1 & 0x7F; if (!popValues) { @@ -31250,7 +31171,7 @@ genPushRemoteTempLongBytecode(void) (anInstruction->dependent = locateLiteral(offset)); } /* begin availableRegOrNoneNotConflictingWith: */ - regMask = 1U << tempVectReg; + regMask = ((tempVectReg < 0) ? (((usqInt)(1)) >> (-tempVectReg)) : (1U << tempVectReg)); remoteTempReg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); if (remoteTempReg == NoReg) { remoteTempReg = tempVectReg; @@ -31628,11 +31549,11 @@ genSpecialSelectorClass(void) || (topReg == ClassReg)) { /* begin ssAllocateRequiredReg:and: */ requiredReg1 = (topReg = SendNumArgsReg); - ssAllocateRequiredRegMaskupThroughupThroughNative((1U << requiredReg1) | (1U << ClassReg), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((((requiredReg1 < 0) ? (((usqInt)(1)) >> (-requiredReg1)) : (1U << requiredReg1))) | ((1U << ClassReg)), simStackPtr, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr, simNativeStackPtr); } ssPush(1); popToReg(ssTop(), topReg); @@ -31871,7 +31792,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean association = getLiteral(litVarIndex); voidReceiverResultRegContainsSelf(); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin genMoveConstant:R: */ if (shouldAnnotateObjectReference(association)) { annotateobjRef(gMoveCwR(association, ReceiverResultReg), association); @@ -31887,7 +31808,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean # if IMMUTABILITY if (needsImmCheck) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -31901,7 +31822,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -31965,7 +31886,7 @@ genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqI # endif // IMMUTABILITY ssPop(1); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ClassReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ssPush(1); genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); @@ -32013,7 +31934,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea # if IMMUTABILITY if (needsImmCheck1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -32027,7 +31948,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck1, 1); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck1); } @@ -32051,7 +31972,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt assert(needsFrame); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); /* begin MoveMw:r:R: */ offset = frameOffsetOfTemporary(remoteTempIndex); @@ -32064,7 +31985,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt # if IMMUTABILITY # endif - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -32255,13 +32176,13 @@ genVanillaInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -32524,12 +32445,12 @@ liveRegisters(void) } else { /* begin registerMaskFor: */ - regsSet = 1U << ReceiverResultReg; + regsSet = (1U << ReceiverResultReg); if ((methodOrBlockNumArgs <= 2 /* numRegArgs */) && (methodOrBlockNumArgs > 0)) { - regsSet = regsSet | (1U << Arg0Reg); + regsSet = regsSet | ((1U << Arg0Reg)); if (methodOrBlockNumArgs > 1) { - regsSet = regsSet | (1U << Arg1Reg); + regsSet = regsSet | ((1U << Arg1Reg)); } } } @@ -32632,13 +32553,13 @@ marshallSendArguments(sqInt numArgs) if (numArgs > 0) { if (numArgs > 1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 2, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 2, simNativeStackPtr); /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg1Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg1Reg), simStackPtr - 1, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 1, simNativeStackPtr); } } if (numArgs > 1) { diff --git a/spursrc/vm/cogitIA32.c b/spursrc/vm/cogitIA32.c index 55675b9eb0..eae6349bfb 100644 --- a/spursrc/vm/cogitIA32.c +++ b/spursrc/vm/cogitIA32.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + CCodeGenerator VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + StackToRegisterMappingCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 " __DATE__ ; +static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__cogitBuildInfo = __buildInfo; @@ -54,17 +54,17 @@ char *__cogitBuildInfo = __buildInfo; #define ArithmeticShiftRightRR 92 #define BadRegisterSet 1 #define BlockCreationBytecodeSize 4 -#define BSR 168 +#define BSR 170 #define BytecodeSetHasDirectedSuperSend 1 #define Call 6 #define CallerSavedRegisterMask 0x6 #define CallFull 7 #define CallR 8 -#define CDQ 159 +#define CDQ 161 #if !defined(CheckRememberedInTrampoline) /* Allow this to be overridden on the compiler command line */ # define CheckRememberedInTrampoline 0 #endif -#define CLD 164 +#define CLD 166 #define ClassArray 7 #define ClassArrayCompactIndex 51 #define ClassBlockClosureCompactIndex 37 @@ -86,7 +86,7 @@ char *__cogitBuildInfo = __buildInfo; #define CMMaxUsageCount 7 #define CMMethod 2 #define CMOpenPIC 5 -#define CMPXCHGRAw 174 +#define CMPXCHGRAw 176 #define CmpC32R 113 #define CmpCqR 105 #define CmpCwR 112 @@ -101,7 +101,7 @@ char *__cogitBuildInfo = __buildInfo; #define ConvertRRs 150 #define ConvertRsR 149 #define ConvertRsRd 147 -#define CPUID 158 +#define CPUID 160 #define Debug DEBUGVM #define DisplacementMask 0x1F #define DisplacementX2N 0 @@ -139,8 +139,8 @@ char *__cogitBuildInfo = __buildInfo; #define FoxSavedFP 0 #define FoxThisContext -8 #define FPReg 5 -#define FSTPD 163 -#define FSTPS 162 +#define FSTPD 165 +#define FSTPS 164 #define FullClosureCompiledBlockIndex 1 #define FullClosureFirstCopiedValueIndex 4 #define FullClosureReceiverIndex 3 @@ -151,11 +151,11 @@ char *__cogitBuildInfo = __buildInfo; #define HashMultiplyConstant 1664525 #define HashMultiplyMask 0xFFFFFFF #define HeaderIndex 0 -#define IDIVR 160 +#define IDIVR 162 #if !defined(IMMUTABILITY) /* Allow this to be overridden on the compiler command line */ # define IMMUTABILITY 1 #endif -#define IMULRR 161 +#define IMULRR 163 #define InFullBlock 2 #define InstanceSpecificationIndex 2 #define InstructionPointerIndex 1 @@ -206,10 +206,10 @@ char *__cogitBuildInfo = __buildInfo; #define Label 1 #define LargeContextSlots 62 #define LastJump 42 -#define LFENCE 170 +#define LFENCE 172 #undef LinkReg #define Literal 2 -#define LOCK 173 +#define LOCK 175 #define LoadEffectiveAddressMwrR 88 #define LogicalShiftLeftCqR 95 #define LogicalShiftLeftCqRR 129 @@ -232,11 +232,11 @@ char *__cogitBuildInfo = __buildInfo; #define MethodCacheSelector 1 #define MethodIndex 3 #define MethodTooBig -4 -#define MFENCE 171 +#define MFENCE 173 #define MFMethodFlagHasContextFlag 1 #define MFMethodFlagIsBlockFlag 2 -#define MOVSB 166 -#define MOVSD 167 +#define MOVSB 168 +#define MOVSD 169 #define ModReg 3 #define ModRegInd 0 #define ModRegRegDisp32 2 @@ -253,6 +253,8 @@ char *__cogitBuildInfo = __buildInfo; #define MoveM8rR 54 #define MoveMbrR 65 #define MoveMwrR 50 +#define MovePerfCnt64RL 159 +#define MovePerfCnt64RRL 158 #define MoveRAb 49 #define MoveRAw 46 #define MoveRdM64r 76 @@ -310,17 +312,17 @@ char *__cogitBuildInfo = __buildInfo; #define PushCq 82 #define PushCw 83 #define PushR 81 -#define REP 165 +#define REP 167 #define ReceiverIndex 5 #define ReceiverResultReg 2 #define RetN 9 #undef RISCTempReg -#define SETE 175 +#define SETE 177 #define SelectorCannotInterpret 34 #define SelectorDoesNotUnderstand 20 #define SenderIndex 0 #define SendNumArgsReg 3 -#define SFENCE 172 +#define SFENCE 174 #define ShouldNotJIT -8 #define SIB1 0 #define SIB4 2 @@ -353,7 +355,7 @@ char *__cogitBuildInfo = __buildInfo; #define UnimplementedPrimitive -7 #define ValueIndex 1 #undef VarBaseReg -#define XCHGRR 169 +#define XCHGRR 171 #define XorCwR 118 #define XorRdRd 137 #define XorRR 104 @@ -483,7 +485,7 @@ static sqInt NoDbgRegParms concretizeAt(AbstractInstruction * self_in_concretize static sqInt NoDbgRegParms genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer); static sqInt NoDbgRegParms genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers); static sqInt NoDbgRegParms genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers); -static sqInt NoDbgRegParms genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg); +static sqInt NoDbgRegParms genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg); static sqInt NoDbgRegParms genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers); static void NoDbgRegParms genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister); static sqInt NoDbgRegParms hasVarBaseRegister(AbstractInstruction * self_in_hasVarBaseRegister); @@ -509,6 +511,7 @@ static sqInt NoDbgRegParms cmpC32RTempByteSize(AbstractInstruction * self_in_cmp static sqInt NoDbgRegParms computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize); static sqInt NoDbgRegParms computeShiftRRSize(AbstractInstruction * self_in_computeShiftRRSize); static sqInt NoDbgRegParms concretizeFill32(AbstractInstruction * self_in_concretizeFill32); +static sqInt NoDbgRegParms concretizeMovePerfCnt64RRL(AbstractInstruction * self_in_concretizeMovePerfCnt64RRL); static sqInt NoDbgRegParms concretizeOpRR(AbstractInstruction * self_in_concretizeOpRR, sqInt x86opcode); static sqInt NoDbgRegParms concretizeReverseOpRR(AbstractInstruction * self_in_concretizeReverseOpRR, sqInt x86opcode); static sqInt NoDbgRegParms concretizeSet(AbstractInstruction * self_in_concretizeSet, sqInt conditionCode); @@ -728,6 +731,8 @@ extern void linkSendAtintooffsetreceiver(sqInt callSiteReturnAddress, CogMethod static BytecodeDescriptor * loadBytesAndGetDescriptor(void); static void NoDbgRegParms loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc); static AbstractInstruction * NoDbgRegParms gMoveCwR(sqInt wordConstant, sqInt reg); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters); static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg); static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC); @@ -1100,6 +1105,7 @@ static sqInt genStoreAndPopReceiverVariableBytecode(void); static sqInt genStoreAndPopRemoteTempLongBytecode(void); static sqInt genStoreAndPopTemporaryVariableBytecode(void); static sqInt genStoreRemoteTempLongBytecode(void); +static void genTakeProfileSample(void); static sqInt genUnconditionalTrapBytecode(void); extern sqInt mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj); static sqInt numSpecialSelectors(void); @@ -2656,28 +2662,28 @@ addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *an static sqInt NoDbgRegParms availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << DPFPReg0)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg0))) != 0))) { return DPFPReg0; } - if (!(((liveRegsMask & (1U << DPFPReg1)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg1))) != 0))) { return DPFPReg1; } - if (!(((liveRegsMask & (1U << DPFPReg2)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg2))) != 0))) { return DPFPReg2; } - if (!(((liveRegsMask & (1U << DPFPReg3)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg3))) != 0))) { return DPFPReg3; } - if (!(((liveRegsMask & (1U << DPFPReg4)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg4))) != 0))) { return DPFPReg4; } - if (!(((liveRegsMask & (1U << DPFPReg5)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg5))) != 0))) { return DPFPReg5; } - if (!(((liveRegsMask & (1U << DPFPReg6)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg6))) != 0))) { return DPFPReg6; } - if (!(((liveRegsMask & (1U << DPFPReg7)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg7))) != 0))) { return DPFPReg7; } return NoReg; @@ -2692,19 +2698,19 @@ availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegi static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << Arg1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg1Reg))) != 0))) { return Arg1Reg; } - if (!(((liveRegsMask & (1U << Arg0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg0Reg))) != 0))) { return Arg0Reg; } - if (!(((liveRegsMask & (1U << SendNumArgsReg)) != 0))) { + if (!(((liveRegsMask & ((1U << SendNumArgsReg))) != 0))) { return SendNumArgsReg; } - if (!(((liveRegsMask & (1U << ClassReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ClassReg))) != 0))) { return ClassReg; } - if (!(((liveRegsMask & (1U << ReceiverResultReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ReceiverResultReg))) != 0))) { return ReceiverResultReg; } return NoReg; @@ -2819,9 +2825,9 @@ genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers) used immediately afterwards. */ - /* CogAbstractInstruction>>#genLoadStackPointersForFastPrimCall: */ + /* CogAbstractInstruction>>#genLoadStackPointersForPrimCall: */ static sqInt NoDbgRegParms -genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg) +genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg) { AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; @@ -3171,6 +3177,7 @@ computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize) case OrRR: case XorRR: case SubRR: + case SubbRR: case NegateR: case NotR: case MoveRR: @@ -3409,6 +3416,11 @@ computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize) ? 7 : 0); + case MovePerfCnt64RRL: + + /* it is easier to calculate the right value by concretizing. We concretize twice, but so what? */ + return concretizeMovePerfCnt64RRL(self_in_computeMaximumSize); + default: error("Case not found and no otherwise clause"); } @@ -3448,6 +3460,63 @@ concretizeFill32(AbstractInstruction * self_in_concretizeFill32) return 4; } + +/* Generate code for + 0x0: 50 pushl %eax + 0x1: 52 pushl %edx + 0x2: 0f 31 rdtsc + 0x4: 89 f8 movl %edi, %eax + 0x6: 89 f2 movl %esi, %edx + 0x8: 5a popl %edx + et al */ + + /* CogIA32Compiler>>#concretizeMovePerfCnt64RRL */ +static sqInt NoDbgRegParms +concretizeMovePerfCnt64RRL(AbstractInstruction * self_in_concretizeMovePerfCnt64RRL) +{ + usqInt liveRegisters; + sqInt offset; + usqInt regHi; + usqInt regLo; + + regLo = ((self_in_concretizeMovePerfCnt64RRL->operands))[0]; + regHi = ((self_in_concretizeMovePerfCnt64RRL->operands))[1]; + liveRegisters = ((self_in_concretizeMovePerfCnt64RRL->operands))[2]; + offset = 0; + if (((liveRegisters & ((1U << EAX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[0] = 80; + offset += 1; + } + if (((liveRegisters & ((1U << EDX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset] = 82; + offset += 1; + } + assert(!(((regLo == EDX) + || (regHi == EAX)))); + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset] = 15; + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset + 1] = 49; + offset += 2; + if (regHi != EDX) { + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset] = 137; + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset + 1] = (modRMRO(self_in_concretizeMovePerfCnt64RRL, ModReg, regHi, EDX)); + offset += 2; + } + if (regLo != EAX) { + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset + 4] = 137; + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset + 5] = (modRMRO(self_in_concretizeMovePerfCnt64RRL, ModReg, regLo, EAX)); + offset += 2; + } + if (((liveRegisters & ((1U << EDX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset] = 90; + offset += 1; + } + if (((liveRegisters & ((1U << EAX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset] = 88; + offset += 1; + } + return offset; +} + /* CogIA32Compiler>>#concretizeOpRR: */ static sqInt NoDbgRegParms concretizeOpRR(AbstractInstruction * self_in_concretizeOpRR, sqInt x86opcode) @@ -3791,7 +3860,6 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) usqInt regLHS10; usqInt regLHS11; usqInt regLHS12; - usqInt regLHS13; usqInt regLHS2; usqInt regLHS3; usqInt regLHS4; @@ -3805,7 +3873,6 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) usqInt regRHS10; usqInt regRHS11; usqInt regRHS12; - usqInt regRHS13; usqInt regRHS2; usqInt regRHS3; usqInt regRHS4; @@ -4956,31 +5023,26 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) return concretizeOpRR(self_in_dispatchConcretize, 43); case SubbRR: - /* begin concretizeSubbRR */ - regLHS9 = ((self_in_dispatchConcretize->operands))[0]; - regRHS9 = ((self_in_dispatchConcretize->operands))[1]; - ((self_in_dispatchConcretize->machineCode))[0] = 27; - ((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, regLHS9, regRHS9)); - return 2; + return concretizeOpRR(self_in_dispatchConcretize, 27); case SubRdRd: /* begin concretizeSEE2OpRdRd: */ - regRHS10 = ((self_in_dispatchConcretize->operands))[0]; - regLHS10 = ((self_in_dispatchConcretize->operands))[1]; + regRHS9 = ((self_in_dispatchConcretize->operands))[0]; + regLHS9 = ((self_in_dispatchConcretize->operands))[1]; ((self_in_dispatchConcretize->machineCode))[0] = 242; ((self_in_dispatchConcretize->machineCode))[1] = 15; ((self_in_dispatchConcretize->machineCode))[2] = 92; - ((self_in_dispatchConcretize->machineCode))[3] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS10, regLHS10)); + ((self_in_dispatchConcretize->machineCode))[3] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS9, regLHS9)); return 4; case SubRsRs: /* begin concretizeSEEOpRsRs: */ - regRHS11 = ((self_in_dispatchConcretize->operands))[0]; - regLHS11 = ((self_in_dispatchConcretize->operands))[1]; + regRHS10 = ((self_in_dispatchConcretize->operands))[0]; + regLHS10 = ((self_in_dispatchConcretize->operands))[1]; ((self_in_dispatchConcretize->machineCode))[0] = 243; ((self_in_dispatchConcretize->machineCode))[1] = 15; ((self_in_dispatchConcretize->machineCode))[2] = 92; - ((self_in_dispatchConcretize->machineCode))[3] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS11, regLHS11)); + ((self_in_dispatchConcretize->machineCode))[3] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS10, regLHS10)); return 4; case SqrtRd: @@ -5026,21 +5088,21 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) case XorRdRd: /* begin concretizeXorRdRd */ - regRHS12 = ((self_in_dispatchConcretize->operands))[0]; - regLHS12 = ((self_in_dispatchConcretize->operands))[1]; + regRHS11 = ((self_in_dispatchConcretize->operands))[0]; + regLHS11 = ((self_in_dispatchConcretize->operands))[1]; ((self_in_dispatchConcretize->machineCode))[0] = 102; ((self_in_dispatchConcretize->machineCode))[1] = 15; ((self_in_dispatchConcretize->machineCode))[2] = 87; - ((self_in_dispatchConcretize->machineCode))[3] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS12, regLHS12)); + ((self_in_dispatchConcretize->machineCode))[3] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS11, regLHS11)); return 4; case XorRsRs: /* begin concretizeXorRsRs */ - regRHS13 = ((self_in_dispatchConcretize->operands))[0]; - regLHS13 = ((self_in_dispatchConcretize->operands))[1]; + regRHS12 = ((self_in_dispatchConcretize->operands))[0]; + regLHS12 = ((self_in_dispatchConcretize->operands))[1]; ((self_in_dispatchConcretize->machineCode))[0] = 15; ((self_in_dispatchConcretize->machineCode))[1] = 87; - ((self_in_dispatchConcretize->machineCode))[2] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS13, regLHS13)); + ((self_in_dispatchConcretize->machineCode))[2] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS12, regLHS12)); return 3; case NegateR: @@ -6034,6 +6096,9 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) case ZeroExtend16RR: return concretizeZeroExtend16RR(self_in_dispatchConcretize); + case MovePerfCnt64RRL: + return concretizeMovePerfCnt64RRL(self_in_dispatchConcretize); + default: error("Case not found and no otherwise clause"); } @@ -6687,7 +6752,7 @@ genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask) assert(!((((regMask & (registerMaskForand(ESP, EBP))) != 0)))); for (reg = EAX; reg <= EDI; reg += 1) { - if (((regMask & (1U << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)))) != 0)) { genoperand(PopR, reg); } } @@ -6708,7 +6773,7 @@ genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask) assert(((EDI - EAX) + 1) == 8); assert(!((((regMask & (registerMaskForand(ESP, EBP))) != 0)))); for (reg = EDI; reg >= EAX; reg += -1) { - if (((regMask & (1U << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)))) != 0)) { genoperand(PushR, reg); } } @@ -9799,7 +9864,7 @@ compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numAr regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1U << resultRegOrNone)) - (1U << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1U << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1U << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ regMaskCopy = ((usqInt)regsToSave); @@ -12692,6 +12757,22 @@ gMoveCwR(sqInt wordConstant, sqInt reg) return anInstruction; } + /* Cogit>>#MovePerfCnt64R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters) +{ + assert(BytesPerWord == 8); + return genoperandoperand(MovePerfCnt64RL, destReg, liveRegisters); +} + + /* Cogit>>#MovePerfCnt64R:R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters) +{ + assert(BytesPerWord == 4); + return genoperandoperandoperand(MovePerfCnt64RRL, destRegLo, destRegHi, liveRegisters); +} + /* Answer the address of the null byte at the end of the method map. */ @@ -14223,11 +14304,14 @@ recordRunTimeObjectReferences(void) } } + +/* N.B. (self registerMaskFor: NoReg) = 0 */ + /* Cogit>>#registerMaskFor: */ static sqInt NoDbgRegParms registerMaskFor(sqInt reg) { - return 1U << reg; + return ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } /* Cogit>>#registerMaskFor:and: */ @@ -20506,7 +20590,7 @@ generateObjectRepresentationTrampolines(void) genoperand(RetN, 0); jmpTarget(jumpSC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); } - ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))), 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), CheckRememberedInTrampoline); ceStoreCheckContextReceiverTrampoline = genStoreCheckContextReceiverTrampoline(); @@ -22313,7 +22397,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jumpRC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg)); jmpTarget(jumpImmutable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); @@ -22329,7 +22413,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* Store check */ jumpImmutable1 = genJumpImmutablescratchReg(ReceiverResultReg, SendNumArgsReg); - compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), 0 /* emptyRegisterMask */); genLoadStackPointers(backEnd()); @@ -22894,7 +22978,7 @@ registerMask(SimStackEntry * self_in_registerMask) || (((self_in_registerMask->type)) == SSRegister) ? (/* begin registerMaskFor: */ (reg = (self_in_registerMask->registerr)), - 1U << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg))) : 0); } @@ -22907,7 +22991,7 @@ registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone) return (((self_in_registerMaskOrNone->type)) == SSRegister ? (/* begin registerMaskFor: */ (reg = (self_in_registerMaskOrNone->registerr)), - 1U << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg))) : 0); } @@ -23088,54 +23172,43 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) { AbstractInstruction *abstractInstruction; AbstractInstruction *abstractInstruction1; - AbstractInstruction *abstractInstruction2; - AbstractInstruction *abstractInstruction3; sqInt address; - sqInt address1; - sqInt address2; AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; + AbstractInstruction *anInstruction10; AbstractInstruction *anInstruction11; + AbstractInstruction *anInstruction110; AbstractInstruction *anInstruction13; AbstractInstruction *anInstruction14; + AbstractInstruction *anInstruction15; + AbstractInstruction *anInstruction16; AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction18; AbstractInstruction *anInstruction19; + AbstractInstruction *anInstruction2; AbstractInstruction *anInstruction20; AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction25; + AbstractInstruction *anInstruction210; + AbstractInstruction *anInstruction22; AbstractInstruction *anInstruction26; AbstractInstruction *anInstruction27; - AbstractInstruction *anInstruction28; - AbstractInstruction *anInstruction29; - AbstractInstruction *anInstruction30; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction35; - AbstractInstruction *anInstruction36; + AbstractInstruction *anInstruction3; AbstractInstruction *anInstruction4; AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - AbstractInstruction * continuePostSampleNonPrim; - AbstractInstruction * continuePostSamplePrim; + AbstractInstruction * continueAfterProfileSample; + sqInt effectiveLiveRegisters; AbstractInstruction * jmp; - AbstractInstruction * jmpSampleNonPrim; - AbstractInstruction * jmpSamplePrim; + AbstractInstruction * jumpToTakeSample; + sqInt liveRegisters; sqInt offset; sqInt offset1; sqInt offset2; - sqInt operand; - sqInt operand2; - sqInt reg; + sqInt regHi; + sqInt regLo; sqInt retpc; - continuePostSampleNonPrim = ((AbstractInstruction *) 0); - continuePostSamplePrim = ((AbstractInstruction *) 0); - jmpSampleNonPrim = ((AbstractInstruction *) 0); - jmpSamplePrim = ((AbstractInstruction *) 0); + jumpToTakeSample = ((AbstractInstruction *) 0); assert(!((0))); genExternalizePointersForPrimitiveCall(); /* begin genLoadCStackPointersForPrimCall */ @@ -23145,45 +23218,28 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) else { genLoadCStackPointer(backEnd); } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick if so */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin MoveAw:R: */ - address = (nextProfileTickAddress()) + BytesPerWord; - /* begin checkLiteral:forInstruction: */ - anInstruction1 = genoperandoperand(MoveAwR, address, ClassReg); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSampleNonPrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSampleNonPrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } if (recordPrimTraceForMethod(methodObj)) { genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction28 = genoperandoperand(MoveCqR, 0, TempReg); + anInstruction15 = genoperandoperand(MoveCqR, 0, TempReg); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction29 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); + anInstruction16 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); + anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); } /* begin checkLiteral:forInstruction: */ argumentCountAddress(); - anInstruction30 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); + anInstruction17 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { /* begin checkLiteral:forInstruction: */ ((sqInt)primitiveRoutine); - anInstruction5 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); + anInstruction1 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); /* begin checkLiteral:forInstruction: */ primitiveFunctionPointerAddress(); - anInstruction6 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); + anInstruction2 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); } if (((flags & (PrimCallNeedsNewMethod + PrimCallMayEndureCodeCompaction)) != 0)) { @@ -23195,135 +23251,120 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) /* begin MoveMw:r:R: */ offset = offsetof(CogMethod, methodObject); /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); + anInstruction3 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); /* begin checkLiteral:forInstruction: */ newMethodAddress(); - anInstruction8 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); + anInstruction4 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); } /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction31 = genoperand(PrefetchAw, primFailCodeAddress()); + anInstruction18 = genoperand(PrefetchAw, primFailCodeAddress()); if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - /* Sideways call the C primitive routine so that we return through cePrimReturnEnterCogCode. */ /* On Spur ceActivateFailingPrimitiveMethod: would like to retry if forwarders are found. So insist on PrimCallNeedsPrimitiveFunction being set too. */ assert(((flags & PrimCallNeedsPrimitiveFunction) != 0)); /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l23; + goto l11; if (null < NoReg) { /* begin checkQuickConstant:forInstruction: */ - anInstruction35 = genoperand(PushCq, -2 - null); + anInstruction26 = genoperand(PushCq, -2 - null); } else { genoperand(PushR, null); } - l23: /* end genMarshallNArgs:arg:arg:arg:arg: */; + l11: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin genSubstituteReturnAddress: */ retpc = (((flags & PrimCallCollectsProfileSamples) != 0) ? cePrimReturnEnterCogCodeProfiling : cePrimReturnEnterCogCode); /* begin checkLiteral:forInstruction: */ - anInstruction36 = genoperand(PushCw, retpc); + anInstruction27 = genoperand(PushCw, retpc); /* begin annotateCall: */ - anInstruction9 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); - abstractInstruction = anInstruction9; + anInstruction5 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); + abstractInstruction = anInstruction5; (abstractInstruction->annotation = IsRelativeCall); - jmp = (jmpSamplePrim = (continuePostSamplePrim = null)); + return 0; } - else { - - /* Call the C primitive routine. */ - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l31; - genoperand(PushR, 0); - l31: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin annotateCall: */ - anInstruction11 = genoperand(CallFull, ((sqInt)primitiveRoutine)); - abstractInstruction1 = anInstruction11; - (abstractInstruction1->annotation = IsRelativeCall); - /* begin genRemoveNArgsFromStack: */ - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction13 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin MoveAw:R: */ - address1 = (nextProfileTickAddress()) + BytesPerWord; - /* begin checkLiteral:forInstruction: */ - anInstruction14 = genoperandoperand(MoveAwR, address1, ClassReg); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSamplePrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSamplePrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + goto l25; + genoperand(PushR, 0); + l25: /* end genMarshallNArgs:arg:arg:arg:arg: */; + /* begin annotateCall: */ + anInstruction7 = genoperand(CallFull, ((sqInt)primitiveRoutine)); + abstractInstruction1 = anInstruction7; + (abstractInstruction1->annotation = IsRelativeCall); + /* begin genRemoveNArgsFromStack: */ + maybeCompileRetryOnPrimitiveFail(primitiveIndex); + genLoadStackPointersForPrimCall(backEnd, ClassReg); + /* begin checkLiteral:forInstruction: */ + instructionPointerAddress(); + anInstruction10 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); + /* begin checkQuickConstant:forInstruction: */ + anInstruction11 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + /* begin checkLiteral:forInstruction: */ + primFailCodeAddress(); + anInstruction19 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + flag("ask concrete code gen if move sets condition codes?"); + /* begin checkQuickConstant:forInstruction: */ + anInstruction20 = genoperandoperand(CmpCqR, 0, TempReg); + /* begin JumpNonZero: */ + jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + flag("endianness"); + assert(!(((((registerMaskForand(ClassReg, SendNumArgsReg)) & liveRegisters) != 0)))); + effectiveLiveRegisters = liveRegisters | ((1U << ClassReg) | (1U << SendNumArgsReg)); + regLo = Arg0Reg; + regHi = Arg1Reg; + /* begin preferredRegisterPairForMovePerfCnt64RRLInto: */ + if (!(((liveRegisters & ((1U << EAX))) != 0))) { + regLo = EAX; + } + if (!(((liveRegisters & ((1U << EDX))) != 0))) { + regHi = EDX; } - maybeCompileRetryOnPrimitiveFail(primitiveIndex); - /* begin MoveAw:R: */ - address2 = instructionPointerAddress(); - reg = ClassReg; /* begin checkLiteral:forInstruction: */ - anInstruction17 = genoperandoperand(MoveAwR, address2, reg); - genLoadStackPointers(backEnd); + nextProfileTickAddress(); + anInstruction110 = genoperandoperand(MoveAwR, nextProfileTickAddress(), ClassReg); + /* begin MoveAw:R: */ + address = (nextProfileTickAddress()) + 4; /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction18 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - /* begin PushR: */ - genoperand(PushR, ClassReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset1 = BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, BytesPerWord); + anInstruction210 = genoperandoperand(MoveAwR, address, SendNumArgsReg); + gMovePerfCnt64RRL(regLo, regHi, liveRegisters); + /* begin SubR:R: */ + genoperandoperand(SubRR, regLo, ClassReg); + /* begin SubbR:R: */ + genoperandoperand(SubbRR, regHi, SendNumArgsReg); + /* begin JumpGreaterOrEqual: */ + jumpToTakeSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l47; + l47: /* end genCheckForProfileTimerTick: */; } + /* begin MoveMw:r:R: */ + offset1 = BytesPerWord; + /* begin checkQuickConstant:forInstruction: */ + anInstruction21 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); + continueAfterProfileSample = anInstruction21; + /* begin RetN: */ + genoperand(RetN, BytesPerWord); if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* The sample is collected by cePrimReturnEnterCogCode for external calls */ - if (!(jmpSamplePrim == null)) { - - /* Call ceCheckProfileTick: to record sample and then continue. */ - jmpTarget(jmpSamplePrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin annotateCall: */ - operand = ((usqIntptr_t)ceCheckProfileTick); - /* begin checkLiteral:forInstruction: */ - anInstruction21 = genoperand(CallFull, operand); - abstractInstruction2 = anInstruction21; - (abstractInstruction2->annotation = IsRelativeCall); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSamplePrim)); - } - jmpTarget(jmpSampleNonPrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction25 = genoperandoperand(MoveCqR, 0, TempReg); - /* begin checkLiteral:forInstruction: */ - newMethodAddress(); - anInstruction26 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); - /* begin annotateCall: */ - operand2 = ((usqIntptr_t)ceCheckProfileTick); + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); /* begin checkLiteral:forInstruction: */ - anInstruction23 = genoperand(CallFull, operand2); - abstractInstruction3 = anInstruction23; - (abstractInstruction3->annotation = IsRelativeCall); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSampleNonPrim)); - } - if (!(jmp == null)) { - - /* Jump to restore of receiver reg and proceed to frame build for failure. */ - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin MoveMw:r:R: */ - offset2 = BytesPerWord * (methodOrBlockNumArgs + (1)); + instructionPointerAddress(); + anInstruction13 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction27 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); + anInstruction14 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + /* begin Jump: */ + genoperand(Jump, ((sqInt)continueAfterProfileSample)); } + jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + /* begin MoveMw:r:R: */ + offset2 = BytesPerWord * (methodOrBlockNumArgs + (1)); + /* begin checkQuickConstant:forInstruction: */ + anInstruction22 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); return 0; } @@ -23353,7 +23394,7 @@ compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)) if ((methodOrBlockNumArgs > 2 /* numRegArgs */) || (methodOrBlockNumArgs == 0)) { /* begin registerMaskFor: */ - liveRegsMask = 1U << ReceiverResultReg; + liveRegsMask = (1U << ReceiverResultReg); } else { if (methodOrBlockNumArgs > 1) { @@ -23431,10 +23472,12 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags { AbstractInstruction *abstractInstruction; AbstractInstruction *abstractInstruction1; + sqInt address; AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; AbstractInstruction *anInstruction10; AbstractInstruction *anInstruction11; + AbstractInstruction *anInstruction110; AbstractInstruction *anInstruction12; AbstractInstruction *anInstruction13; AbstractInstruction *anInstruction14; @@ -23445,6 +23488,7 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags AbstractInstruction *anInstruction19; AbstractInstruction *anInstruction20; AbstractInstruction *anInstruction21; + AbstractInstruction *anInstruction210; AbstractInstruction *anInstruction22; AbstractInstruction *anInstruction23; AbstractInstruction *anInstruction4; @@ -23453,15 +23497,22 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags AbstractInstruction *anInstruction7; AbstractInstruction *anInstruction9; sqInt calleeSavedRegisterMask; + AbstractInstruction * continueAfterProfileSample; + sqInt effectiveLiveRegisters; AbstractInstruction * jmp; + AbstractInstruction * jumpToTakeSample; + sqInt liveRegisters; sqInt offset; sqInt offset1; sqInt operand; + sqInt regHi; + sqInt regLo; sqInt retpcOffset; AbstractInstruction * retry; AbstractInstruction * skip; sqInt spRegSaveRegister; + jumpToTakeSample = ((AbstractInstruction *) 0); assert(((flags & PrimCallOnSmalltalkStack) != 0)); assert(!((0))); if (recordFastCCallPrimTraceForMethod(methodObj)) { @@ -23480,7 +23531,7 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags argumentCountAddress(); anInstruction20 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); genExternalizeStackPointerForFastPrimitiveCall(); - calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | (1U << ClassReg)) - (1U << ClassReg)); + calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | ((1U << ClassReg))) - ((1U << ClassReg))); spRegSaveRegister = NoReg; /* begin Label */ retry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); @@ -23489,10 +23540,15 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags } else { } + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + goto l35; + genoperand(PushR, 0); + l35: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin annotateCall: */ - anInstruction1 = genoperand(CallFull, primitiveRoutine); + anInstruction1 = genoperand(CallFull, ((sqInt)primitiveRoutine)); abstractInstruction = anInstruction1; (abstractInstruction->annotation = IsRelativeCall); + /* begin genRemoveNArgsFromStack: */ /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); anInstruction21 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); @@ -23504,9 +23560,42 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags anInstruction22 = genoperandoperand(CmpCqR, 0, TempReg); /* begin JumpNonZero: */ jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + flag("endianness"); + assert(!(((((registerMaskForand(ClassReg, SendNumArgsReg)) & liveRegisters) != 0)))); + effectiveLiveRegisters = liveRegisters | ((1U << ClassReg) | (1U << SendNumArgsReg)); + regLo = Arg0Reg; + regHi = Arg1Reg; + /* begin preferredRegisterPairForMovePerfCnt64RRLInto: */ + if (!(((liveRegisters & ((1U << EAX))) != 0))) { + regLo = EAX; + } + if (!(((liveRegisters & ((1U << EDX))) != 0))) { + regHi = EDX; + } + /* begin checkLiteral:forInstruction: */ + nextProfileTickAddress(); + anInstruction110 = genoperandoperand(MoveAwR, nextProfileTickAddress(), ClassReg); + /* begin MoveAw:R: */ + address = (nextProfileTickAddress()) + 4; + /* begin checkLiteral:forInstruction: */ + anInstruction210 = genoperandoperand(MoveAwR, address, SendNumArgsReg); + gMovePerfCnt64RRL(regLo, regHi, liveRegisters); + /* begin SubR:R: */ + genoperandoperand(SubRR, regLo, ClassReg); + /* begin SubbR:R: */ + genoperandoperand(SubbRR, regHi, SendNumArgsReg); + /* begin JumpGreaterOrEqual: */ + jumpToTakeSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l51; + l51: /* end genCheckForProfileTimerTick: */; + } /* begin checkLiteral:forInstruction: */ stackPointerAddress(); anInstruction23 = genoperandoperand(MoveAwR, stackPointerAddress(), TempReg); + continueAfterProfileSample = anInstruction23; /* The original retpc is (argumentCount + 1) words below stackPointer. */ retpcOffset = -((methodOrBlockNumArgs + 1) * BytesPerWord); @@ -23520,6 +23609,12 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags anInstruction6 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, TempReg); /* begin RetN: */ genoperand(RetN, 0); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); + /* begin Jump: */ + genoperand(Jump, ((sqInt)continueAfterProfileSample)); + } jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); if ((accessorDepthForExternalPrimitiveMethod(methodObj)) >= 0) { @@ -23550,13 +23645,17 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags else { genLoadCStackPointer(backEnd); } + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + goto l27; + genoperand(PushR, 0); + l27: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin annotateCall: */ operand = ((usqIntptr_t)checkForAndFollowForwardedPrimitiveState); /* begin checkLiteral:forInstruction: */ anInstruction7 = genoperand(CallFull, operand); abstractInstruction1 = anInstruction7; (abstractInstruction1->annotation = IsRelativeCall); - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); /* begin checkQuickConstant:forInstruction: */ anInstruction14 = genoperandoperand(CmpCqR, 0, ABIResultReg); /* begin JumpZero: */ @@ -23574,10 +23673,10 @@ compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags /* must reload SPReg to undo any alignment change, */ if (((flags & PrimCallOnSmalltalkStackAlign2x) != 0)) { - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); + genLoadStackPointersForPrimCall(backEnd, ClassReg); } } - if (((ABICallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((ABICallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* begin MoveMw:r:R: */ offset1 = (methodOrBlockNumArgs + (1)) * BytesPerWord; /* begin checkQuickConstant:forInstruction: */ @@ -24554,79 +24653,101 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) sqInt address; sqInt address1; AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; + AbstractInstruction *anInstruction11; AbstractInstruction *anInstruction12; AbstractInstruction *anInstruction13; AbstractInstruction *anInstruction14; AbstractInstruction *anInstruction15; AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction2; + AbstractInstruction *anInstruction7; AbstractInstruction *anInstruction8; AbstractInstruction *anInstruction9; sqInt callTarget; AbstractInstruction *continuePostSample; + sqInt effectiveLiveRegisters; AbstractInstruction *jmpFail; AbstractInstruction *jmpSample; - sqInt reg; + sqInt liveRegisters; + sqInt reg1; + sqInt regHi; + sqInt regLo; continuePostSample = ((AbstractInstruction *) 0); jmpSample = ((AbstractInstruction *) 0); zeroOpcodeIndex(); - if (profiling) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick: if so. - N.B. nextProfileTick is 64-bits so 32-bit systems need to test both halves. */ + /* begin checkLiteral:forInstruction: */ + primFailCodeAddress(); + anInstruction12 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + flag("ask concrete code gen if move sets condition codes?"); + /* begin checkQuickConstant:forInstruction: */ + anInstruction13 = genoperandoperand(CmpCqR, 0, TempReg); + /* begin JumpNonZero: */ + jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (profiling + && (1)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + flag("endianness"); + assert(!(((((registerMaskForand(ClassReg, SendNumArgsReg)) & liveRegisters) != 0)))); + effectiveLiveRegisters = liveRegisters | ((1U << ClassReg) | (1U << SendNumArgsReg)); + regLo = Arg0Reg; + regHi = Arg1Reg; + /* begin preferredRegisterPairForMovePerfCnt64RRLInto: */ + if (!(((liveRegisters & ((1U << EAX))) != 0))) { + regLo = EAX; + } + if (!(((liveRegisters & ((1U << EDX))) != 0))) { + regHi = EDX; + } /* begin checkLiteral:forInstruction: */ nextProfileTickAddress(); - anInstruction1 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); + anInstruction1 = genoperandoperand(MoveAwR, nextProfileTickAddress(), ClassReg); /* begin MoveAw:R: */ - address = (nextProfileTickAddress()) + BytesPerWord; + address = (nextProfileTickAddress()) + 4; /* begin checkLiteral:forInstruction: */ - anInstruction2 = genoperandoperand(MoveAwR, address, ClassReg); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSample = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + anInstruction2 = genoperandoperand(MoveAwR, address, SendNumArgsReg); + gMovePerfCnt64RRL(regLo, regHi, liveRegisters); + /* begin SubR:R: */ + genoperandoperand(SubRR, regLo, ClassReg); + /* begin SubbR:R: */ + genoperandoperand(SubbRR, regHi, SendNumArgsReg); + /* begin JumpGreaterOrEqual: */ + jmpSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l17; + l17: /* end genCheckForProfileTimerTick: */; /* begin Label */ continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); } /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction13 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkLiteral:forInstruction: */ instructionPointerAddress(); - anInstruction8 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); + anInstruction7 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); + anInstruction8 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + anInstruction9 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jmpFail, checkLiteralforInstruction(newMethodAddress(), genoperandoperand(MoveAwR, newMethodAddress(), SendNumArgsReg))); /* begin checkLiteral:forInstruction: */ cStackPointerAddress(); - anInstruction15 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); + anInstruction14 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); compileCallFornumArgsargargargargresultRegregsToSave(ceActivateFailingPrimitiveMethod, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); /* begin MoveAw:R: */ address1 = instructionPointerAddress(); - reg = ClassReg; + reg1 = ClassReg; /* begin checkLiteral:forInstruction: */ - anInstruction16 = genoperandoperand(MoveAwR, address1, reg); + anInstruction15 = genoperandoperand(MoveAwR, address1, reg1); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveMwrR, BytesPerWord, SPReg, ReceiverResultReg); + anInstruction11 = genoperandoperandoperand(MoveMwrR, BytesPerWord, SPReg, ReceiverResultReg); /* begin PushR: */ genoperand(PushR, ClassReg); /* begin RetN: */ genoperand(RetN, BytesPerWord); - if (profiling) { + if (profiling + && (1)) { /* Call ceCheckProfileTick: to record sample and then continue. newMethod should be up-to-date. Need to save and restore the link reg around this call. */ @@ -24635,8 +24756,8 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) /* begin CallFullRT: */ callTarget = (usqIntptr_t)ceCheckProfileTick; /* begin annotateCall: */ - anInstruction17 = genoperand(CallFull, callTarget); - abstractInstruction = anInstruction17; + anInstruction16 = genoperand(CallFull, callTarget); + abstractInstruction = anInstruction16; (abstractInstruction->annotation = IsRelativeCall); /* begin Jump: */ genoperand(Jump, ((sqInt)continuePostSample)); @@ -24992,6 +25113,30 @@ genStoreRemoteTempLongBytecode(void) && (shouldAnnotateObjectReference(((ssTop())->constant))))); } + /* SimpleStackBasedCogit>>#genTakeProfileSample */ +static void +genTakeProfileSample(void) +{ + AbstractInstruction *abstractInstruction; + AbstractInstruction *anInstruction; + AbstractInstruction *anInstruction6; + sqInt operand; + + addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + genoperand(PushR, ClassReg); + l3: /* end genMarshallNArgs:arg:arg:arg:arg: */; + /* begin annotateCall: */ + operand = ((usqIntptr_t)ceTakeProfileSample); + /* begin checkLiteral:forInstruction: */ + anInstruction = genoperand(CallFull, operand); + abstractInstruction = anInstruction; + (abstractInstruction->annotation = IsRelativeCall); + /* begin genRemoveNArgsFromStack: */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction6 = genoperandoperand(AddCqR, 4, ESP); + } + /* SistaV1: * 217 Trap */ @@ -25334,7 +25479,7 @@ primitiveGeneratorOrNil(void) static sqInt NoDbgRegParms registerisInMask(sqInt reg, sqInt mask) { - return ((mask & (1U << reg)) != 0); + return ((mask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)))) != 0); } /* SimpleStackBasedCogit>>#v3:Block:Code:Size: */ @@ -25675,7 +25820,7 @@ anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n) sqInt regMask; /* begin registerMaskFor: */ - regMask = 1U << reg; + regMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { if ((((registerMask(simStackAt(i))) & regMask) != 0)) { return 1; @@ -26679,7 +26824,7 @@ ensureReceiverResultRegContainsSelf(void) if (needsFrame) { if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin putSelfInReceiverResultReg */ storeToReg(simSelf(), ReceiverResultReg); ((simSelf())->liveRegister = ReceiverResultReg); @@ -26811,7 +26956,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) && (index < simStackPtr)) { desc = simStackAt(index); if (((desc->type)) == SSRegister) { - if (!(((regMask & (1U << ((desc->registerr)))) != 0))) { + if (!(((regMask & (((((desc->registerr)) < 0) ? (((usqInt)(1)) >> (-((desc->registerr)))) : (1U << ((desc->registerr)))))) != 0))) { reg = (desc->registerr); } } @@ -26819,7 +26964,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) } assert(!((reg == NoReg))); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << reg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)), simStackPtr, simNativeStackPtr); return reg; } @@ -27359,13 +27504,13 @@ genForwardersInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -28263,11 +28408,11 @@ genPushMaybeContextReceiverVariable(sqInt slotIndex) AbstractInstruction *jmpSingle; /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ensureReceiverResultRegContainsSelf(); /* begin genPushMaybeContextSlotIndex: */ assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ voidReceiverResultRegContainsSelf(); @@ -28319,7 +28464,7 @@ genPushNewArrayBytecode(void) } else { /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << SendNumArgsReg)) | ((1U << ReceiverResultReg))), simStackPtr, simNativeStackPtr); } size = byte1 & 0x7F; if (!popValues) { @@ -28392,7 +28537,7 @@ genPushRemoteTempLongBytecode(void) /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperandoperand(MoveMwrR, offset, FPReg, tempVectReg); /* begin availableRegOrNoneNotConflictingWith: */ - regMask = 1U << tempVectReg; + regMask = ((tempVectReg < 0) ? (((usqInt)(1)) >> (-tempVectReg)) : (1U << tempVectReg)); remoteTempReg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); if (remoteTempReg == NoReg) { remoteTempReg = tempVectReg; @@ -28742,11 +28887,11 @@ genSpecialSelectorClass(void) || (topReg == ClassReg)) { /* begin ssAllocateRequiredReg:and: */ requiredReg1 = (topReg = SendNumArgsReg); - ssAllocateRequiredRegMaskupThroughupThroughNative((1U << requiredReg1) | (1U << ClassReg), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((((requiredReg1 < 0) ? (((usqInt)(1)) >> (-requiredReg1)) : (1U << requiredReg1))) | ((1U << ClassReg)), simStackPtr, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr, simNativeStackPtr); } ssPush(1); popToReg(ssTop(), topReg); @@ -28979,7 +29124,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean association = getLiteral(litVarIndex); voidReceiverResultRegContainsSelf(); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin genMoveConstant:R: */ if (shouldAnnotateObjectReference(association)) { annotateobjRef(checkLiteralforInstruction(association, genoperandoperand(MoveCwR, association, ReceiverResultReg)), association); @@ -28992,7 +29137,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean # if IMMUTABILITY if (needsImmCheck) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -29006,7 +29151,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -29067,7 +29212,7 @@ genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqI # endif // IMMUTABILITY ssPop(1); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ClassReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ssPush(1); genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); @@ -29112,7 +29257,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea # if IMMUTABILITY if (needsImmCheck1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -29126,7 +29271,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck1, 1); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck1); } @@ -29150,7 +29295,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt assert(needsFrame); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); /* begin MoveMw:r:R: */ offset = frameOffsetOfTemporary(remoteTempIndex); @@ -29160,7 +29305,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt # if IMMUTABILITY # endif - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -29346,13 +29491,13 @@ genVanillaInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -29606,12 +29751,12 @@ liveRegisters(void) } else { /* begin registerMaskFor: */ - regsSet = 1U << ReceiverResultReg; + regsSet = (1U << ReceiverResultReg); if ((methodOrBlockNumArgs <= 2 /* numRegArgs */) && (methodOrBlockNumArgs > 0)) { - regsSet = regsSet | (1U << Arg0Reg); + regsSet = regsSet | ((1U << Arg0Reg)); if (methodOrBlockNumArgs > 1) { - regsSet = regsSet | (1U << Arg1Reg); + regsSet = regsSet | ((1U << Arg1Reg)); } } } @@ -29714,13 +29859,13 @@ marshallSendArguments(sqInt numArgs) if (numArgs > 0) { if (numArgs > 1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 2, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 2, simNativeStackPtr); /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg1Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg1Reg), simStackPtr - 1, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 1, simNativeStackPtr); } } if (numArgs > 1) { diff --git a/spursrc/vm/cogitMIPSEL.c b/spursrc/vm/cogitMIPSEL.c deleted file mode 100644 index fed645cd6f..0000000000 --- a/spursrc/vm/cogitMIPSEL.c +++ /dev/null @@ -1,30433 +0,0 @@ -/* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 - from - StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 - */ -static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 " __DATE__ ; -char *__cogitBuildInfo = __buildInfo; - - - -#include "sqConfig.h" -#include -#include -#include -#include -#include "sqPlatformSpecific.h" -#include "sqMemoryAccess.h" -#include "sqCogStackAlignment.h" -#include "dispdbg.h" -#include "cogmethod.h" -#if COGMTVM -#include "cointerpmt.h" -#else -#include "cointerp.h" -#endif -#include "cogit.h" -#include - - -/*** Constants ***/ -#define A0 4 -#define A1 5 -#define A2 6 -#define A3 7 -#define ABICalleeSavedRegisterMask 0xFF0000 -#define ABICallerSavedRegisterMask 0x300FF00 -#define ABIResultReg 2 -#define ADDIU 9 -#define ADDU 33 -#define AddCheckOverflowCqR 162 -#define AddCheckOverflowRR 163 -#define AddCqR 106 -#define AddCqRR 123 -#define AddCwR 114 -#define AddRdRd 132 -#define AddRR 100 -#define AddRRR 126 -#define AlignmentNops 3 -#define AltBlockCreationBytecodeSize 3 -#define AltFirstSpecialSelector 96 -#define AltNumSpecialSelectors 32 -#define AND 36 -#define ANDI 12 -#define AndCqR 108 -#define AndCqRR 124 -#define AndCwR 116 -#define AndRR 102 -#define AnnotationShift 5 -#define Arg0Reg 17 -#define Arg1Reg 18 -#define ArithmeticShiftRightCqR 91 -#define ArithmeticShiftRightCqRR 128 -#define ArithmeticShiftRightRR 92 -#define AT 1 -#define BadRegisterSet 1 -#define BEQ 4 -#define BGEZ 1 -#define BGTZ 7 -#define BLEZ 6 -#define BLTZ 0 -#define BlockCreationBytecodeSize 4 -#define BNE 5 -#define BREAK 13 -#define BranchTemp 11 -#define BrEqualRR 167 -#define BrLongEqualRR 177 -#define BrLongNotEqualRR 178 -#define BrNotEqualRR 168 -#define BrSignedGreaterEqualRR 176 -#define BrSignedGreaterRR 175 -#define BrSignedLessEqualRR 174 -#define BrSignedLessRR 173 -#define BrUnsignedGreaterEqualRR 172 -#define BrUnsignedGreaterRR 171 -#define BrUnsignedLessEqualRR 170 -#define BrUnsignedLessRR 169 -#define BytecodeSetHasDirectedSuperSend 1 -#define Call 6 -#define CallerSavedRegisterMask 0x0 -#define CallFull 7 -#if !defined(CheckRememberedInTrampoline) /* Allow this to be overridden on the compiler command line */ -# define CheckRememberedInTrampoline 0 -#endif -#define ClassArray 7 -#define ClassArrayCompactIndex 51 -#define ClassBlockClosureCompactIndex 37 -#define ClassFloatCompactIndex 34 -#define ClassFullBlockClosureCompactIndex 38 -#define ClassLargePositiveIntegerCompactIndex 33 -#define ClassMethodContextCompactIndex 36 -#define ClassPointCompactIndex 54 -#define ClassReg 19 -#define ClosureFirstCopiedValueIndex 3 -#define ClosureIndex 4 -#define ClosureNumArgsIndex 2 -#define ClosureOuterContextIndex 0 -#define ClosureStartPCIndex 1 -#define ClzRR 157 -#define CMBlock 3 -#define CMClosedPIC 4 -#define CMFree 1 -#define CMMaxUsageCount 7 -#define CMMethod 2 -#define CMOpenPIC 5 -#define Cmp 8 -#define CmpC32R 113 -#define CmpCqR 105 -#define CmpCwR 112 -#define CmpRdRd 131 -#define CmpRR 99 -#define CompletePrimitive 4 -#define ConcreteVarBaseReg 22 -#define ConstZero 1 -#define ConvertRRd 145 -#define Debug DEBUGVM -#define DIV 26 -#define DisplacementMask 0x1F -#define DisplacementX2N 0 -#define DivRdRd 135 -#define DivRR 159 -#undef DPFPReg0 -#undef DPFPReg1 -#undef DPFPReg2 -#undef DPFPReg3 -#undef DPFPReg4 -#undef DPFPReg5 -#undef DPFPReg6 -#undef DPFPReg7 -#define EncounteredUnknownBytecode -6 -#undef Extra0Reg -#undef Extra2Reg -#define FastCPrimitiveUseCABIFlag 4 -#define Fill32 4 -#define FirstAnnotation 64 -#define FirstJump 12 -#define FirstSpecialSelector 176 -#define FoxCallerSavedIP 4 -#define FoxIFSavedIP -16 -#define FoxMethod -4 -#define FoxMFReceiver -12 -#define FoxSavedFP 0 -#define FoxThisContext -8 -#define FP 30 -#define FPReg 30 -#define FullClosureCompiledBlockIndex 1 -#define FullClosureFirstCopiedValueIndex 4 -#define FullClosureReceiverIndex 3 -#define GCModeBecome 8 -#define GCModeFull 1 -#define GCModeNewSpace 2 -#define HasBytecodePC 5 -#define HashMultiplyConstant 1664525 -#define HashMultiplyMask 0xFFFFFFF -#define HeaderIndex 0 -#define HintLoad 0 -#define HintStore 1 -#if !defined(IMMUTABILITY) /* Allow this to be overridden on the compiler command line */ -# define IMMUTABILITY 1 -#endif -#define InFullBlock 2 -#define InstanceSpecificationIndex 2 -#define InstructionPointerIndex 1 -#define InsufficientCodeSpace -2 -#define InVanillaBlock 1 -#define IsAbsPCReference 3 -#define IsAnnotationExtension 1 -#define IsDirectedSuperBindingSend 10 -#define IsDirectedSuperSend 9 -#define IsDisplacementX2N 0 -#define IsNSDynamicSuperSend null -#define IsNSSelfSend null -#define IsNSSendCall null -#define IsObjectReference 2 -#define IsRelativeCall 4 -#define IsSendCall 7 -#define IsSuperSend 8 -#define J 2 -#define JAL 3 -#define JALR 9 -#define JR 8 -#define Jump 16 -#define JumpAbove 33 -#define JumpAboveOrEqual 32 -#define JumpBelow 31 -#define JumpBelowOrEqual 34 -#define JumpCarry 25 -#define JumpFPEqual 35 -#define JumpFPGreater 39 -#define JumpFPGreaterOrEqual 40 -#define JumpFPLess 37 -#define JumpFPLessOrEqual 38 -#define JumpFPNotEqual 36 -#define JumpFPOrdered 41 -#define JumpFPUnordered 42 -#define JumpFull 12 -#define JumpGreater 29 -#define JumpGreaterOrEqual 28 -#define JumpLess 27 -#define JumpLessOrEqual 30 -#define JumpLong 13 -#define JumpLongNonZero 15 -#define JumpLongZero 14 -#define JumpNegative 19 -#define JumpNoCarry 26 -#define JumpNonNegative 20 -#define JumpNonZero 18 -#define JumpNoOverflow 22 -#define JumpOverflow 21 -#define JumpR 10 -#define JumpZero 17 -#define Label 1 -#define LargeContextSlots 62 -#define LastJump 42 -#define LB 32 -#define LBU 36 -#define LH 33 -#define LHU 37 -#define LinkReg 31 -#define Literal 2 -#define LoadEffectiveAddressMwrR 88 -#define LogicalShiftLeftCqR 95 -#define LogicalShiftLeftCqRR 129 -#define LogicalShiftLeftRR 96 -#define LogicalShiftRightCqR 93 -#define LogicalShiftRightCqRR 130 -#define LogicalShiftRightRR 94 -#define LowcodeVM 0 -#define LUI 15 -#define LW 35 -#define MapEnd 0 -#define MaxCompiledPrimitiveIndex 575 -#define MaxCPICCases 6 -#define MaxMethodSize 65535 -#define MaxNegativeErrorCode -8 -#define MaxStackAllocSize 1572864 -#define MaxStackCheckOffset 0xFFF -#define MaxX2NDisplacement 992 -#define MethodCacheClass 2 -#define MethodCacheMask 0xFFC -#define MethodCacheMethod 3 -#define MethodCacheSelector 1 -#define MethodIndex 3 -#define MethodTooBig -4 -#define MFHI 16 -#define MFLO 18 -#define MFMethodFlagHasContextFlag 1 -#define MFMethodFlagIsBlockFlag 2 -#define MoveAbR 48 -#define MoveAwR 44 -#define MoveC32R 71 -#define MoveCqR 69 -#define MoveCwR 70 -#define MoveHighR 161 -#define MoveLowR 160 -#define MoveM16rR 57 -#define MoveM64rRd 75 -#define MoveMbrR 65 -#define MoveMwrR 50 -#define MoveRAb 49 -#define MoveRAw 46 -#define MoveRdM64r 76 -#define MoveRdRd 74 -#define MoveRM16r 58 -#define MoveRMbr 66 -#define MoveRMwr 51 -#define MoveRR 43 -#define MoveRXbrR 68 -#define MoveRXwrR 53 -#define MoveXbrRR 67 -#define MoveXwrRR 52 -#define MULT 24 -#define MULTIPLEBYTECODESETS 1 -#define MulCheckOverflowRR 164 -#define MulRdRd 134 -#define MulRR 158 -#define NativePopR 84 -#define NativePushR 85 -#define NativeRetN 86 -#define NativeSPReg 29 -#define NeedsMergeFixupFlag 2 -#define NeedsNonMergeFixupFlag 1 -#define NegateR 89 -#define NewspeakVM 0 -#define Nop 5 -#define NoReg -1 -#define NotFullyInitialized -1 -#define NumObjRefsInRuntime 0 -#define NumOopsPerNSC 6 -#define NumSendTrampolines 4 -#define NumSpecialSelectors 32 -#define NumStoreTrampolines 5 -#define NumTrampolines (67 + (COGMTVM ? 1 : 0) + (IMMUTABILITY ? 5 : 0)) -#define OneInstruction 4 -#define OR 37 -#define ORI 13 -#define OrCqR 109 -#define OrCqRR 125 -#define OrCwR 117 -#define OrRR 103 -#define Overflow 8 -#define OverflowTemp1 9 -#define OverflowTemp2 10 -#undef PCReg -#define PopR 80 -#define PREF 51 -#define PrefetchAw 87 -#define PrimCallCollectsProfileSamples 8 -#define PrimCallDoNotJIT 16 -#define PrimCallMayEndureCodeCompaction 4 -#define PrimCallNeedsNewMethod 1 -#define PrimCallNeedsPrimitiveFunction 2 -#define PrimCallOnSmalltalkStack 64 -#define PrimCallOnSmalltalkStackAlign2x 128 -#define PrimErrNoMemory 9 -#define PrimNumberExternalCall 117 -#define PrimNumberFFICall 120 -#define PushCq 82 -#define PushCw 83 -#define PushR 81 -#define R0 0 -#define R28 28 -#define RA 31 -#define REGIMM 1 -#define ReceiverIndex 5 -#define ReceiverResultReg 16 -#define RetN 9 -#define RISCTempReg 1 -#define SB 40 -#define SelectorCannotInterpret 34 -#define SelectorDoesNotUnderstand 20 -#define SenderIndex 0 -#define SendNumArgsReg 20 -#define SH 41 -#define ShouldNotJIT -8 -#define SignExtend16RR 152 -#define SignExtend8RR 151 -#define SistaV1BytecodeSet 1 -#define SistaVM 0 -#define SLL 0 -#define SLLV 4 -#define SLT 42 -#define SLTI 10 -#define SLTIU 11 -#define SLTU 43 -#define SmallContextSlots 22 -#define SP 29 -#define SPECIAL 0 -#define SPReg 29 -#define SPURVM 1 -#define SqrtRd 136 -#define SRA 3 -#define SRAV 7 -#define SRL 2 -#define SRLV 6 -#define SSBaseOffset 1 -#define SSConstant 2 -#define SSRegister 3 -#define SSSpill 4 -#define StackPointerIndex 2 -#define Stop 11 -#define SUBU 35 -#define SubCheckOverflowCqR 165 -#define SubCheckOverflowRR 166 -#define SubCqR 107 -#define SubCwR 115 -#define SubRdRd 133 -#define SubRR 101 -#define SubRRR 127 -#define SW 43 -#define TargetReg 25 -#define TempReg 21 -#define TempVectReadBarrier 0 -#define TstCqR 110 -#define UnfailingPrimitive 3 -#define UnimplementedPrimitive -7 -#define ValueIndex 1 -#define VarBaseReg 22 -#define XOR 38 -#define XORI 14 -#define XorCqR 111 -#define XorCwR 118 -#define XorRR 104 -#define YoungSelectorInPIC -5 -#define ZR 0 - -typedef struct _AbstractInstruction { - unsigned char opcode; - unsigned char machineCodeSize; - unsigned char maxSize; - unsigned char annotation; - unsigned int machineCode[7]; - usqInt operands[3]; - usqInt address; - struct _AbstractInstruction *dependent; - } AbstractInstruction; - -#define CogMIPSELCompiler AbstractInstruction -#define CogAbstractInstruction AbstractInstruction - - -typedef struct { - AbstractInstruction *fakeHeader; - AbstractInstruction *fillInstruction; - sqInt numArgs; - sqInt numCopied; - sqInt numInitialNils; - sqInt startpc; - AbstractInstruction *entryLabel; - AbstractInstruction *stackCheckLabel; - sqInt span; - sqInt hasInstVarRef; - } BlockStart; - -#define CogBlockStart BlockStart - - -typedef struct _BytecodeDescriptor { - sqInt (*generator)(void); - sqInt NoDbgRegParms (*spanFunction)(struct _BytecodeDescriptor *,sqInt,sqInt,sqInt); - sqInt NoDbgRegParms (*needsFrameFunction)(sqInt); - signed char stackDelta; - unsigned char opcode; - unsigned char numBytes; - unsigned isBranchTrue : 1; - unsigned isBranchFalse : 1; - unsigned isReturn : 1; - unsigned isBlockCreation : 1; - unsigned isMapped : 1; - unsigned isMappedInBlock : 1; - unsigned isExtension : 1; - unsigned isInstVarRef : 1; - unsigned is1ByteInstVarStore : 1; - unsigned hasUnsafeJump : 1; - } BytecodeDescriptor; - -#define CogBytecodeDescriptor BytecodeDescriptor - - -typedef struct { - sqInt (*primitiveGenerator)(void); - sqInt primNumArgs; - } PrimitiveDescriptor; - -#define CogPrimitiveDescriptor PrimitiveDescriptor - - -typedef struct { - char type; - char spilled; - signed char liveRegister; - signed char registerr; - sqInt offset; - sqInt constant; - sqInt bcptr; - } SimStackEntry; - -#define CogSimStackEntry SimStackEntry - - -typedef struct { - AbstractInstruction *targetInstruction; - unsigned char simStackPtr; - char isTargetOfBackwardBranch; - unsigned short instructionIndex; -#if LowcodeVM - short simNativeStackPtr; - unsigned short simNativeStackSize; -#endif - } BytecodeFixup; - -#define CogSSBytecodeFixup BytecodeFixup -#define CogBytecodeFixup BytecodeFixup - - -typedef struct { - sqInt isReceiverResultRegLive; - CogSimStackEntry *ssEntry; - } CogSSOptStatus; - - - -/*** Function Prototypes ***/ - - -#if !PRODUCTION && defined(PlatformNoDbgRegParms) -# define NoDbgRegParms PlatformNoDbgRegParms -#endif - -#if !defined(NoDbgRegParms) -# define NoDbgRegParms /*empty*/ -#endif - - - -#if !defined(NeverInline) -# define NeverInline /*empty*/ -#endif - -static AbstractInstruction * NoDbgRegParms addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *anInstruction); -static sqInt NoDbgRegParms availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask); -static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask); -static void NoDbgRegParms cloneLiteralFrom(AbstractInstruction * self_in_cloneLiteralFrom, AbstractInstruction *existingLiteral); -static sqInt NoDbgRegParms genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer); -static sqInt NoDbgRegParms genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers); -static sqInt NoDbgRegParms genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers); -static sqInt NoDbgRegParms genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg); -static sqInt NoDbgRegParms genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers); -static AbstractInstruction * NoDbgRegParms genSwapRRScratch(AbstractInstruction * self_in_genSwapRRScratch, sqInt regA, sqInt regB, sqInt regTmp); -static void NoDbgRegParms genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister); -static void NoDbgRegParms initializeSharableLiteral(AbstractInstruction * self_in_initializeSharableLiteral, sqInt literal); -static void NoDbgRegParms initializeUniqueLiteral(AbstractInstruction * self_in_initializeUniqueLiteral, sqInt literal); -static sqInt NoDbgRegParms isWithinMwOffsetRange(AbstractInstruction * self_in_isWithinMwOffsetRange, sqInt anAddress); -static AbstractInstruction * NoDbgRegParms jmpTarget(AbstractInstruction * self_in_jmpTarget, AbstractInstruction *anAbstractInstruction); -static void NoDbgRegParms resolveJumpTarget(AbstractInstruction * self_in_resolveJumpTarget); -static sqInt NoDbgRegParms rewriteCallFullAttarget(AbstractInstruction * self_in_rewriteCallFullAttarget, sqInt callSiteReturnAddress, sqInt callTargetAddress); -static sqInt NoDbgRegParms rewriteJumpFullAttarget(AbstractInstruction * self_in_rewriteJumpFullAttarget, sqInt callSiteReturnAddress, sqInt callTargetAddress); -static CogMethod * NoDbgRegParms cmHomeMethod(CogBlockMethod * self_in_cmHomeMethod); -static sqInt NoDbgRegParms isBranch(BytecodeDescriptor * self_in_isBranch); -static AbstractInstruction * NoDbgRegParms gAddCqR(sqInt quickConstant, sqInt reg); -static AbstractInstruction * NoDbgRegParms gAddCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); -static AbstractInstruction * NoDbgRegParms gAndCqR(sqInt quickConstant, sqInt reg); -static AbstractInstruction * NoDbgRegParms gAndCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); -static AbstractInstruction * NoDbgRegParms gArithmeticShiftRightCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); -extern sqInt abortOffset(void); -static void addCleanBlockStarts(void); -extern void addCogMethodsToHeapMap(void); -static sqInt NoDbgRegParms addressIsInCurrentCompilation(sqInt address); -static sqInt NoDbgRegParms addressIsInFixups(BytecodeFixup *address); -static sqInt NoDbgRegParms addressOfEndOfCaseinCPIC(sqInt n, CogMethod *cPIC); -static void alignMethodZoneBase(void); -static sqInt NoDbgRegParms alignUptoRoutineBoundary(sqInt anAddress); -static sqInt allMachineCodeObjectReferencesValid(void); -static sqInt allMethodsHaveCorrectHeader(void); -static AbstractInstruction * NoDbgRegParms annotateAbsolutePCRef(AbstractInstruction *abstractInstruction); -static AbstractInstruction * NoDbgRegParms annotateBytecode(AbstractInstruction *abstractInstruction); -static AbstractInstruction * NoDbgRegParms annotateobjRef(AbstractInstruction *abstractInstruction, sqInt anOop); -static void NoDbgRegParms assertSaneJumpTarget(AbstractInstruction *jumpTarget); -static void assertValidDualZone(void); -static sqInt NoDbgRegParms availableRegisterOrNoneIn(sqInt liveRegsMask); -static sqInt NoDbgRegParms blockDispatchTargetsForperformarg(CogMethod *cogMethod, usqInt (*binaryFunction)(sqInt mcpc, sqInt arg), sqInt arg); -extern sqInt bytecodePCForstartBcpcin(sqInt mcpc, sqInt startbcpc, CogBlockMethod *cogMethod); -static AbstractInstruction * NoDbgRegParms CallRTregistersToBeSavedMask(sqInt callTarget, sqInt registersToBeSaved); -static AbstractInstruction * NoDbgRegParms gCall(sqInt callTarget); -static AbstractInstruction * NoDbgRegParms gCmpCqR(sqInt quickConstant, sqInt reg); -extern void callCogCodePopReceiver(void); -extern void callCogCodePopReceiverAndClassRegs(void); -static sqInt NoDbgRegParms ceCPICMissreceiver(CogMethod *cPIC, sqInt receiver); -extern void ceFree(void *pointer); -static void* NoDbgRegParms ceMalloc(size_t size); -static sqInt NoDbgRegParms ceSICMiss(sqInt receiver); -static sqInt NoDbgRegParms checkIfValidOopRefAndTargetpccogMethod(sqInt annotation, char *mcpc, CogMethod *cogMethod); -static sqInt NoDbgRegParms checkIfValidOopRefpccogMethod(sqInt annotation, char *mcpc, CogMethod *cogMethod); -extern sqInt checkIntegrityOfObjectReferencesInCode(sqInt gcModes); -static sqInt NoDbgRegParms checkMaybeObjRefInClosedPIC(sqInt maybeObject); -static sqInt NoDbgRegParms checkValidObjectReferencesInClosedPIC(CogMethod *cPIC); -static sqInt NoDbgRegParms NeverInline cleanUpFailingCogCodeConstituents(CogMethod *cogMethodArg); -static sqInt NoDbgRegParms closedPICRefersToUnmarkedObject(CogMethod *cPIC); -extern char * codeEntryFor(char *address); -extern char * codeEntryNameFor(char *address); -extern sqInt cogCodeBase(void); -extern sqInt cogCodeConstituents(sqInt withDetails); -static void NoDbgRegParms cogExtendPICCaseNMethodtagisMNUCase(CogMethod *cPIC, sqInt caseNMethod, sqInt caseNTag, sqInt isMNUCase); -extern CogMethod * cogFullBlockMethodnumCopied(sqInt aMethodObj, sqInt numCopied); -extern void cogitPostGCAction(sqInt gcMode); -extern sqInt cogMethodDoesntLookKosher(CogMethod *cogMethod); -extern CogMethod * cogMNUPICSelectorreceivermethodOperandnumArgs(sqInt selector, sqInt rcvr, sqInt methodOperand, sqInt numArgs); -static CogMethod * NoDbgRegParms cogOpenPICSelectornumArgs(sqInt selector, sqInt numArgs); -static CogMethod * NoDbgRegParms cogPICSelectornumArgsCase0MethodCase1MethodtagisMNUCase(sqInt selector, sqInt numArgs, CogMethod *case0CogMethod, sqInt case1MethodOrNil, sqInt case1Tag, sqInt isMNUCase); -extern CogMethod * cogselector(sqInt aMethodObj, sqInt aSelectorOop); -static sqInt NoDbgRegParms collectCogConstituentForAnnotationMcpcBcpcMethod(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *cogMethodArg); -static sqInt NoDbgRegParms collectCogMethodConstituent(CogMethod *cogMethod); -extern void compactCogCompiledCode(void); -static void compactPICsWithFreedTargets(void); -static AbstractInstruction * compileAbort(void); -static sqInt NoDbgRegParms compileBlockDispatchFromto(sqInt lowBlockStartIndex, sqInt highBlockStartIndex); -static void NoDbgRegParms compileBlockEntry(BlockStart *blockStart); -static void NoDbgRegParms compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt resultRegOrNone, sqInt regMask); -static AbstractInstruction * compileCPICEntry(void); -static sqInt NoDbgRegParms compileEntireFullBlockMethod(sqInt numCopied); -static void compileEntry(void); -static sqInt compileFullBlockEntry(void); -static sqInt compileMethodBody(void); -static sqInt NoDbgRegParms compilePICAbort(sqInt numArgs); -static AbstractInstruction * NoDbgRegParms compileStackOverflowCheck(sqInt canContextSwitch); -static void NoDbgRegParms compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone); -static void computeEntryOffsets(void); -static void computeFullBlockEntryOffsets(void); -static usqInt computeGoodVarBaseAddress(void); -static void computeMaximumSizes(void); -static sqInt NoDbgRegParms configureCPICCase0Case1MethodtagisMNUCasenumArgsdelta(CogMethod *cPIC, CogMethod *case0CogMethod, sqInt case1Method, sqInt case1Tag, sqInt isMNUCase, sqInt numArgs, sqInt addrDelta); -static sqInt NoDbgRegParms configureMNUCPICmethodOperandnumArgsdelta(CogMethod *cPIC, sqInt methodOperand, sqInt numArgs, sqInt addrDelta); -static sqInt NoDbgRegParms cPICCompactAndIsNowEmpty(CogMethod *cPIC); -static sqInt NoDbgRegParms cPICHasForwardedClass(CogMethod *cPIC); -static sqInt NoDbgRegParms cPICHasFreedTargets(CogMethod *cPIC); -static usqInt cPICPrototypeCaseOffset(void); -static sqInt NoDbgRegParms cPICHasTarget(CogMethod *cPIC, CogMethod *targetMethod); -static sqInt NoDbgRegParms createCPICData(CogMethod *cPIC); -static AbstractInstruction * NoDbgRegParms gDivRRQuoRem(sqInt rDivisor, sqInt rDividend, sqInt rQuotient, sqInt rRemainder); -extern sqInt defaultCogCodeSize(void); -static sqInt NoDbgRegParms deltaToSkipPrimAndErrorStoreInheader(sqInt aMethodObj, sqInt aMethodHeader); -static sqInt NoDbgRegParms endPCOf(sqInt aMethod); -extern void enterCogCodePopReceiver(void); -static sqInt NoDbgRegParms entryPointTagIsSelector(sqInt entryPoint); -static sqInt NoDbgRegParms expectedClosedPICPrototype(CogMethod *cPIC); -static sqInt extABytecode(void); -static sqInt extBBytecode(void); -static sqInt NoDbgRegParms fillInBlockHeadersAt(sqInt startAddress); -static void NoDbgRegParms fillInMethodHeadersizeselector(CogMethod *method, sqInt size, sqInt selector); -static sqInt NoDbgRegParms findBackwardBranchIsBackwardBranchMcpcBcpcMatchingBcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *targetBcpc); -static usqInt NoDbgRegParms findBlockMethodWithEntrystartBcpc(sqInt blockEntryMcpc, sqInt startBcpc); -static usqInt NoDbgRegParms findMapLocationForMcpcinMethod(usqInt targetMcpc, CogMethod *cogMethod); -extern CogBlockMethod * findMethodForStartBcpcinHomeMethod(sqInt startbcpc, CogMethod *cogMethod); -static sqInt NoDbgRegParms findIsBackwardBranchMcpcBcpcMatchingMcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *targetMcpc); -static sqInt NoDbgRegParms firstMappedPCFor(CogMethod *cogMethod); -static sqInt firstPrototypeMethodOop(void); -static BytecodeFixup * NoDbgRegParms fixupAt(sqInt fixupPC); -extern void followForwardedLiteralsIn(CogMethod *cogMethod); -extern void followForwardedMethods(void); -static sqInt NoDbgRegParms followMaybeObjRefInClosedPICAt(sqInt mcpc); -static sqInt NoDbgRegParms followMethodReferencesInClosedPIC(CogMethod *cPIC); -extern void followMovableLiteralsAndUpdateYoungReferrers(void); -extern void freeCogMethod(CogMethod *cogMethod); -extern void freeUnmarkedMachineCode(void); -static AbstractInstruction * NoDbgRegParms genCallMustBeBooleanFor(sqInt boolean); -static AbstractInstruction * NoDbgRegParms genConditionalBranchoperand(sqInt opcode, sqInt operandOne); -static void (*genEnilopmartForandandforCallcalled(sqInt regArg1, sqInt regArg2OrNone, sqInt regArg3OrNone, sqInt forCall, char *trampolineName))(void) ; -static void NoDbgRegParms genEnilopmartReturn(sqInt forCall); -static void NoDbgRegParms NeverInline generateCaptureCStackPointers(sqInt captureFramePointer); -static void generateClosedPICPrototype(void); -static CogMethod * generateCogFullBlock(void); -static CogMethod * NoDbgRegParms generateCogMethod(sqInt selector); -static sqInt NoDbgRegParms generateMapAtstart(usqInt addressOrNull, usqInt startAddress); -static void generateOpenPICPrototype(void); -static void generateRunTimeTrampolines(void); -static void generateStackPointerCapture(void); -static void generateTrampolines(void); -static BytecodeDescriptor * NoDbgRegParms generatorForPC(sqInt pc); -static void genGetLeafCallStackPointers(void); -static usqInt NoDbgRegParms genInnerPICAbortTrampoline(char *name); -static void (*genInvokeInterpretTrampoline(void))(void) ; -static void NoDbgRegParms genLoadInlineCacheWithSelector(sqInt selectorIndex); -static usqInt genReturnToInterpreterTrampoline(void); -static sqInt NoDbgRegParms genSmalltalkToCStackSwitch(sqInt pushLinkReg); -static usqInt NoDbgRegParms genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(void *aRoutine, char *trampolineName, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone, sqInt appendBoolean); -static void NoDbgRegParms genTrampolineReturn(sqInt lnkRegWasPushed); -static AbstractInstruction * NoDbgRegParms gen(sqInt opcode); -static AbstractInstruction * NoDbgRegParms genoperand(sqInt opcode, sqInt operand); -static AbstractInstruction * NoDbgRegParms genoperandoperand(sqInt opcode, sqInt operandOne, sqInt operandTwo); -static AbstractInstruction * NoDbgRegParms genoperandoperandoperand(sqInt opcode, sqInt operandOne, sqInt operandTwo, sqInt operandThree); -static sqInt NoDbgRegParms getLiteral(sqInt litIndex); -static sqInt NoDbgRegParms incrementUsageOfTargetIfLinkedSendmcpcignored(sqInt annotation, char *mcpc, sqInt superfluity); -static sqInt initialClosedPICUsageCount(void); -static void initializeBackend(void); -extern void initializeCodeZoneFromupTo(sqInt startAddress, sqInt endAddress); -static sqInt initialMethodUsageCount(void); -static sqInt initialOpenPICUsageCount(void); -static sqInt NoDbgRegParms inverseBranchFor(sqInt opcode); -static sqInt NoDbgRegParms isPCMappedAnnotation(sqInt annotation); -extern sqInt isPCWithinMethodZone(void *address); -extern sqInt isSendReturnPC(sqInt retpc); -static AbstractInstruction * NoDbgRegParms gJumpFPEqual(void *jumpTarget); -static AbstractInstruction * NoDbgRegParms gJumpFPGreaterOrEqual(void *jumpTarget); -static AbstractInstruction * NoDbgRegParms gJumpFPGreater(void *jumpTarget); -static AbstractInstruction * NoDbgRegParms gJumpFPNotEqual(void *jumpTarget); -static AbstractInstruction * NoDbgRegParms gLogicalShiftLeftCqR(sqInt quickConstant, sqInt reg); -static AbstractInstruction * NoDbgRegParms gLogicalShiftLeftCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); -static AbstractInstruction * NoDbgRegParms gLogicalShiftRightCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); -static AbstractInstruction * lastOpcode(void); -extern void linkSendAtintooffsetreceiver(sqInt callSiteReturnAddress, CogMethod *sendingMethod, CogMethod *targetMethod, sqInt theEntryOffset, sqInt receiver); -static BytecodeDescriptor * loadBytesAndGetDescriptor(void); -static void NoDbgRegParms loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc); -static AbstractInstruction * NoDbgRegParms gMoveCwR(sqInt wordConstant, sqInt reg); -static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); -static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg); -static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC); -static void mapObjectReferencesInGeneratedRuntime(void); -static void mapObjectReferencesInMachineCodeForBecome(void); -static void mapObjectReferencesInMachineCodeForFullGC(void); -static void mapObjectReferencesInMachineCodeForYoungGC(void); -extern void mapObjectReferencesInMachineCode(sqInt gcMode); -extern void markAndTraceMachineCodeOfMarkedMethods(void); -static void markAndTraceObjectReferencesInGeneratedRuntime(void); -static sqInt NoDbgRegParms markAndTraceOrFreeCogMethodfirstVisit(CogMethod *cogMethod, sqInt firstVisit); -static sqInt NoDbgRegParms markAndTraceOrFreePICTargetin(sqInt entryPoint, CogMethod *cPIC); -static sqInt NoDbgRegParms markLiteralsAndUnlinkIfUnmarkedSendpcmethod(sqInt annotation, char *mcpc, sqInt cogMethod); -static sqInt NoDbgRegParms markLiteralspcmethod(sqInt annotation, char *mcpc, CogMethod *cogMethod); -extern void markMethodAndReferents(CogBlockMethod *aCogMethod); -extern usqInt maxCogMethodAddress(void); -static sqInt maybeAllocAndInitIRCs(void); -static sqInt NoDbgRegParms maybeFreeCogMethodDoesntLookKosher(CogMethod *cogMethod); -static sqInt mclassIsSmallInteger(void); -extern usqInt mcPCForBackwardBranchstartBcpcin(sqInt bcpc, sqInt startbcpc, CogBlockMethod *cogMethod); -static sqInt NoDbgRegParms methodhasSameCodeAscheckPenultimate(sqInt methodA, sqInt methodB, sqInt comparePenultimateLiteral); -extern sqInt mnuOffset(void); -static AbstractInstruction * NoDbgRegParms gNativePopR(sqInt reg); -static AbstractInstruction * NoDbgRegParms gNativePushR(sqInt reg); -static AbstractInstruction * NoDbgRegParms gNativeRetN(sqInt offset); -static sqInt NoDbgRegParms needsFrameIfImmutability(sqInt stackDelta); -static sqInt NoDbgRegParms needsFrameIfInBlock(sqInt stackDelta); -static sqInt NoDbgRegParms needsFrameNever(sqInt stackDelta); -static sqInt NoDbgRegParms noAssertMethodClassAssociationOf(sqInt methodPointer); -static sqInt noCogMethodsMaximallyMarked(void); -static sqInt NoDbgRegParms noTargetsFreeInClosedPIC(CogMethod *cPIC); -static AbstractInstruction * NoDbgRegParms gOrCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); -static sqInt NoDbgRegParms outputInstructionsAt(sqInt startAddress); -static sqInt NoDbgRegParms outputInstructionsForGeneratedRuntimeAt(sqInt startAddress); -static AbstractInstruction * NoDbgRegParms gPushCw(sqInt wordConstant); -extern sqInt patchToOpenPICFornumArgsreceiver(sqInt selector, sqInt numArgs, sqInt receiver); -static sqInt picAbortDiscriminatorValue(void); -static sqInt picInterpretAbortOffset(void); -static AbstractInstruction * previousInstruction(void); -extern void printCogMethodFor(void *address); -extern void printTrampolineTable(void); -static sqInt processorHasDivQuoRemAndMClassIsSmallInteger(void); -static sqInt processorHasMultiplyAndMClassIsSmallInteger(void); -static void NoDbgRegParms recordGeneratedRunTimeaddress(char *aString, sqInt address); -extern sqInt recordPrimTraceFunc(void); -static void recordRunTimeObjectReferences(void); -static sqInt NoDbgRegParms registerMaskFor(sqInt reg); -static sqInt NoDbgRegParms registerMaskForandand(sqInt reg1, sqInt reg2, sqInt reg3); -static void NoDbgRegParms relocateCallsAndSelfReferencesInMethod(CogMethod *cogMethod); -static void NoDbgRegParms relocateCallsInClosedPIC(CogMethod *cPIC); -static sqInt NoDbgRegParms relocateIfCallOrMethodReferencemcpcdelta(sqInt annotation, char *mcpc, CogMethod *refDeltaArg); -static sqInt NoDbgRegParms remapIfObjectRefpchasYoung(sqInt annotation, char *mcpc, CogMethod *hasYoungPtr); -static sqInt NoDbgRegParms remapMaybeObjRefInClosedPICAt(sqInt mcpc); -static void NoDbgRegParms rewriteCPICCaseAttagobjReftarget(sqInt followingAddress, sqInt newTag, sqInt newObjRef, sqInt newTarget); -static AbstractInstruction * NoDbgRegParms gSubRRR(sqInt subReg, sqInt fromReg, sqInt destReg); -static sqInt scanForCleanBlocks(void); -extern void setBreakMethod(sqInt anObj); -extern void setSelectorOfto(CogMethod *cogMethod, sqInt aSelectorOop); -static sqInt NoDbgRegParms spanForCleanBlockStartingAt(sqInt startPC); -static usqInt NoDbgRegParms stackCheckOffsetOfBlockAtisMcpc(sqInt blockEntryMcpc, sqInt mcpc); -static sqInt subsequentPrototypeMethodOop(void); -extern sqInt traceLinkedSendOffset(void); -static sqInt NoDbgRegParms trampolineArgConstant(sqInt booleanOrInteger); -static char * NoDbgRegParms trampolineNamenumArgs(char *routinePrefix, sqInt numArgs); -static char * NoDbgRegParms trampolineNamenumArgslimit(char *routinePrefix, int numArgs, sqInt argsLimit); -static char * NoDbgRegParms trampolineNamenumRegArgs(char *routinePrefix, sqInt numArgs); -static sqInt unknownBytecode(void); -extern void unlinkAllSends(void); -static sqInt NoDbgRegParms unlinkIfFreeOrLinkedSendpcof(sqInt annotation, char *mcpc, CogMethod *theSelector); -static sqInt NoDbgRegParms unlinkIfInvalidClassSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity); -static sqInt NoDbgRegParms unlinkIfLinkedSendToFreepcignored(sqInt annotation, char *mcpc, sqInt superfluity); -static sqInt NoDbgRegParms unlinkIfLinkedSendpcif(sqInt annotation, char *mcpc, CogMethod *criterionArg); -static sqInt NoDbgRegParms unlinkIfLinkedSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity); -static sqInt NoDbgRegParms unlinkIfLinkedSendpcto(sqInt annotation, char *mcpc, sqInt theCogMethod); -extern void unlinkSendsLinkedForInvalidClasses(void); -extern void unlinkSendsOfisMNUSelector(sqInt selector, sqInt isMNUSelector); -extern void unlinkSendsToFree(void); -extern void unlinkSendsToMethodsSuchThatAndFreeIf(sqInt (*criterion)(CogMethod *), sqInt freeIfTrue); -extern void unlinkSendsToandFreeIf(sqInt targetMethodObject, sqInt freeIfTrue); -extern void voidCogCompiledCode(void); -static void zeroOpcodeIndex(void); -static void zeroOpcodeIndexForNewOpcodes(void); -static sqInt NoDbgRegParms counters(CogMethod * self_in_counters); -static void NoDbgRegParms addToOpenPICList(CogMethod *anOpenPIC); -static void NoDbgRegParms addToYoungReferrers(CogMethod *cogMethod); -static usqInt NoDbgRegParms allocate(sqInt numBytes); -extern CogMethod * cogMethodContaining(usqInt mcpc); -static void compactCompiledCode(void); -static void NoDbgRegParms ensureInYoungReferrers(CogMethod *cogMethod); -static void followForwardedLiteralsInOpenPICList(void); -static void NoDbgRegParms freeMethod(CogMethod *cogMethod); -static void freeOlderMethodsForCompaction(void); -extern sqInt kosherYoungReferrers(void); -static sqInt NoDbgRegParms mcpcisAtStackCheckOfBlockMethodIn(sqInt mcpc, CogMethod *cogMethod); -extern CogMethod * methodFor(void *address); -extern sqInt methodsCompiledToMachineCodeInto(sqInt arrayObj); -extern sqInt numMethods(void); -extern sqInt numMethodsOfType(sqInt cogMethodType); -static sqInt NoDbgRegParms occurrencesInYoungReferrers(CogMethod *cogMethod); -static CogMethod * NoDbgRegParms openPICWithSelector(sqInt aSelector); -static void planCompaction(void); -extern void printCogMethods(void); -extern void printCogMethodsOfType(sqInt cmType); -extern void printCogMethodsWithMethod(sqInt methodOop); -extern void printCogMethodsWithPrimitive(sqInt primIdx); -extern void printCogMethodsWithSelector(sqInt selectorOop); -extern void printCogYoungReferrers(void); -extern sqInt printOpenPICList(void); -extern sqInt pruneYoungReferrers(void); -static sqInt relocateAndPruneYoungReferrers(void); -static sqInt relocateMethodsPreCompaction(void); -static sqInt NoDbgRegParms removeFromOpenPICList(CogMethod *anOpenPIC); -static sqInt NoDbgRegParms roundUpLength(sqInt numBytes); -static void voidOpenPICList(void); -static void voidUnpairedMethodList(void); -static void voidYoungReferrersPostTenureAll(void); -EXPORT(char *) whereIsMaybeCodeThing(sqInt anOop); -static sqInt NoDbgRegParms addiuRRC(AbstractInstruction * self_in_addiuRRC, sqInt destReg, sqInt srcReg, sqInt imm); -static sqInt NoDbgRegParms adduRRR(AbstractInstruction * self_in_adduRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms andiRRC(AbstractInstruction * self_in_andiRRC, sqInt destReg, sqInt srcReg, sqInt imm); -static sqInt NoDbgRegParms andRRR(AbstractInstruction * self_in_andRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms beqRRoffset(AbstractInstruction * self_in_beqRRoffset, sqInt leftReg, sqInt rightReg, sqInt offset); -static sqInt NoDbgRegParms bgezRoffset(AbstractInstruction * self_in_bgezRoffset, sqInt cmpReg, sqInt offset); -static sqInt NoDbgRegParms bgtzRoffset(AbstractInstruction * self_in_bgtzRoffset, sqInt cmpReg, sqInt offset); -static sqInt NoDbgRegParms blezRoffset(AbstractInstruction * self_in_blezRoffset, sqInt cmpReg, sqInt offset); -static sqInt NoDbgRegParms bltzRoffset(AbstractInstruction * self_in_bltzRoffset, sqInt cmpReg, sqInt offset); -static sqInt NoDbgRegParms bneRRoffset(AbstractInstruction * self_in_bneRRoffset, sqInt leftReg, sqInt rightReg, sqInt offset); -static sqInt NoDbgRegParms callInstructionByteSize(AbstractInstruction * self_in_callInstructionByteSize); -static usqInt NoDbgRegParms callTargetFromReturnAddress(AbstractInstruction * self_in_callTargetFromReturnAddress, sqInt callSiteReturnAddress); -static sqInt NoDbgRegParms clzRRR(AbstractInstruction * self_in_clzRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms cmpC32RTempByteSize(AbstractInstruction * self_in_cmpC32RTempByteSize); -static sqInt NoDbgRegParms computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize); -static sqInt NoDbgRegParms concretizeAddCheckOverflowCqR(AbstractInstruction * self_in_concretizeAddCheckOverflowCqR); -static sqInt NoDbgRegParms concretizeAddCheckOverflowRR(AbstractInstruction * self_in_concretizeAddCheckOverflowRR); -static sqInt NoDbgRegParms concretizeAddCqR(AbstractInstruction * self_in_concretizeAddCqR); -static sqInt NoDbgRegParms concretizeAddCwR(AbstractInstruction * self_in_concretizeAddCwR); -static sqInt NoDbgRegParms concretizeAddRRDest(AbstractInstruction * self_in_concretizeAddRRDest, sqInt destReg); -static usqInt NoDbgRegParms concretizeAlignmentNops(AbstractInstruction * self_in_concretizeAlignmentNops); -static sqInt NoDbgRegParms concretizeAndCqR(AbstractInstruction * self_in_concretizeAndCqR); -static sqInt NoDbgRegParms concretizeAndCqRDest(AbstractInstruction * self_in_concretizeAndCqRDest, sqInt destReg); -static sqInt NoDbgRegParms concretizeAndCwR(AbstractInstruction * self_in_concretizeAndCwR); -static sqInt NoDbgRegParms concretizeAndRR(AbstractInstruction * self_in_concretizeAndRR); -static sqInt NoDbgRegParms concretizeArithmeticShiftRightCqR(AbstractInstruction * self_in_concretizeArithmeticShiftRightCqR); -static sqInt NoDbgRegParms concretizeArithmeticShiftRightRR(AbstractInstruction * self_in_concretizeArithmeticShiftRightRR); -static sqInt NoDbgRegParms concretizeAt(AbstractInstruction * self_in_concretizeAt, sqInt actualAddress); -static sqInt NoDbgRegParms concretizeBrEqualRR(AbstractInstruction * self_in_concretizeBrEqualRR); -static sqInt NoDbgRegParms concretizeBrLongEqualRR(AbstractInstruction * self_in_concretizeBrLongEqualRR); -static sqInt NoDbgRegParms concretizeBrLongNotEqualRR(AbstractInstruction * self_in_concretizeBrLongNotEqualRR); -static sqInt NoDbgRegParms concretizeBrNotEqualRR(AbstractInstruction * self_in_concretizeBrNotEqualRR); -static sqInt NoDbgRegParms concretizeBrSignedGreaterEqualRR(AbstractInstruction * self_in_concretizeBrSignedGreaterEqualRR); -static sqInt NoDbgRegParms concretizeBrSignedGreaterRR(AbstractInstruction * self_in_concretizeBrSignedGreaterRR); -static sqInt NoDbgRegParms concretizeBrSignedLessEqualRR(AbstractInstruction * self_in_concretizeBrSignedLessEqualRR); -static sqInt NoDbgRegParms concretizeBrSignedLessRR(AbstractInstruction * self_in_concretizeBrSignedLessRR); -static sqInt NoDbgRegParms concretizeBrUnsignedGreaterEqualRR(AbstractInstruction * self_in_concretizeBrUnsignedGreaterEqualRR); -static sqInt NoDbgRegParms concretizeBrUnsignedGreaterRR(AbstractInstruction * self_in_concretizeBrUnsignedGreaterRR); -static sqInt NoDbgRegParms concretizeBrUnsignedLessEqualRR(AbstractInstruction * self_in_concretizeBrUnsignedLessEqualRR); -static sqInt NoDbgRegParms concretizeBrUnsignedLessRR(AbstractInstruction * self_in_concretizeBrUnsignedLessRR); -static sqInt NoDbgRegParms concretizeCall(AbstractInstruction * self_in_concretizeCall); -static sqInt NoDbgRegParms concretizeCallFull(AbstractInstruction * self_in_concretizeCallFull); -static sqInt NoDbgRegParms concretizeClzRR(AbstractInstruction * self_in_concretizeClzRR); -static sqInt NoDbgRegParms concretizeCmpCqR(AbstractInstruction * self_in_concretizeCmpCqR); -static sqInt NoDbgRegParms concretizeCmpCwR(AbstractInstruction * self_in_concretizeCmpCwR); -static sqInt NoDbgRegParms concretizeCmpRR(AbstractInstruction * self_in_concretizeCmpRR); -static sqInt NoDbgRegParms concretizeDivRR(AbstractInstruction * self_in_concretizeDivRR); -static sqInt NoDbgRegParms concretizeFill32(AbstractInstruction * self_in_concretizeFill32); -static sqInt NoDbgRegParms concretizeJump(AbstractInstruction * self_in_concretizeJump); -static sqInt NoDbgRegParms concretizeJumpFull(AbstractInstruction * self_in_concretizeJumpFull); -static sqInt NoDbgRegParms concretizeJumpLong(AbstractInstruction * self_in_concretizeJumpLong); -static sqInt NoDbgRegParms concretizeJumpLongNonZero(AbstractInstruction * self_in_concretizeJumpLongNonZero); -static sqInt NoDbgRegParms concretizeJumpLongZero(AbstractInstruction * self_in_concretizeJumpLongZero); -static sqInt NoDbgRegParms concretizeJumpNonZero(AbstractInstruction * self_in_concretizeJumpNonZero); -static sqInt NoDbgRegParms concretizeJumpNoOverflow(AbstractInstruction * self_in_concretizeJumpNoOverflow); -static sqInt NoDbgRegParms concretizeJumpOverflow(AbstractInstruction * self_in_concretizeJumpOverflow); -static sqInt NoDbgRegParms concretizeJumpR(AbstractInstruction * self_in_concretizeJumpR); -static sqInt NoDbgRegParms concretizeJumpSignedGreaterEqual(AbstractInstruction * self_in_concretizeJumpSignedGreaterEqual); -static sqInt NoDbgRegParms concretizeJumpSignedGreaterThan(AbstractInstruction * self_in_concretizeJumpSignedGreaterThan); -static sqInt NoDbgRegParms concretizeJumpSignedLessEqual(AbstractInstruction * self_in_concretizeJumpSignedLessEqual); -static sqInt NoDbgRegParms concretizeJumpSignedLessThan(AbstractInstruction * self_in_concretizeJumpSignedLessThan); -static sqInt NoDbgRegParms concretizeJumpUnsignedGreaterEqual(AbstractInstruction * self_in_concretizeJumpUnsignedGreaterEqual); -static sqInt NoDbgRegParms concretizeJumpUnsignedGreaterThan(AbstractInstruction * self_in_concretizeJumpUnsignedGreaterThan); -static sqInt NoDbgRegParms concretizeJumpUnsignedLessEqual(AbstractInstruction * self_in_concretizeJumpUnsignedLessEqual); -static sqInt NoDbgRegParms concretizeJumpUnsignedLessThan(AbstractInstruction * self_in_concretizeJumpUnsignedLessThan); -static sqInt NoDbgRegParms concretizeJumpZero(AbstractInstruction * self_in_concretizeJumpZero); -static sqInt NoDbgRegParms concretizeLoadEffectiveAddressMwrR(AbstractInstruction * self_in_concretizeLoadEffectiveAddressMwrR); -static sqInt NoDbgRegParms concretizeLogicalShiftLeftCqR(AbstractInstruction * self_in_concretizeLogicalShiftLeftCqR); -static sqInt NoDbgRegParms concretizeLogicalShiftLeftRR(AbstractInstruction * self_in_concretizeLogicalShiftLeftRR); -static sqInt NoDbgRegParms concretizeLogicalShiftRightCqR(AbstractInstruction * self_in_concretizeLogicalShiftRightCqR); -static sqInt NoDbgRegParms concretizeLogicalShiftRightRR(AbstractInstruction * self_in_concretizeLogicalShiftRightRR); -static sqInt NoDbgRegParms concretizeMoveAbR(AbstractInstruction * self_in_concretizeMoveAbR); -static sqInt NoDbgRegParms concretizeMoveAwR(AbstractInstruction * self_in_concretizeMoveAwR); -static sqInt NoDbgRegParms concretizeMoveCqR(AbstractInstruction * self_in_concretizeMoveCqR); -static sqInt NoDbgRegParms concretizeMoveCwR(AbstractInstruction * self_in_concretizeMoveCwR); -static sqInt NoDbgRegParms concretizeMoveHighR(AbstractInstruction * self_in_concretizeMoveHighR); -static sqInt NoDbgRegParms concretizeMoveLowR(AbstractInstruction * self_in_concretizeMoveLowR); -static sqInt NoDbgRegParms concretizeMoveM16rR(AbstractInstruction * self_in_concretizeMoveM16rR); -static sqInt NoDbgRegParms concretizeMoveMbrR(AbstractInstruction * self_in_concretizeMoveMbrR); -static sqInt NoDbgRegParms concretizeMoveMwrR(AbstractInstruction * self_in_concretizeMoveMwrR); -static sqInt NoDbgRegParms concretizeMoveRAb(AbstractInstruction * self_in_concretizeMoveRAb); -static sqInt NoDbgRegParms concretizeMoveRAw(AbstractInstruction * self_in_concretizeMoveRAw); -static sqInt NoDbgRegParms concretizeMoveRM16r(AbstractInstruction * self_in_concretizeMoveRM16r); -static sqInt NoDbgRegParms concretizeMoveRMbr(AbstractInstruction * self_in_concretizeMoveRMbr); -static sqInt NoDbgRegParms concretizeMoveRMwr(AbstractInstruction * self_in_concretizeMoveRMwr); -static sqInt NoDbgRegParms concretizeMoveRR(AbstractInstruction * self_in_concretizeMoveRR); -static sqInt NoDbgRegParms concretizeMoveRXbrR(AbstractInstruction * self_in_concretizeMoveRXbrR); -static sqInt NoDbgRegParms concretizeMoveRXwrR(AbstractInstruction * self_in_concretizeMoveRXwrR); -static sqInt NoDbgRegParms concretizeMoveXbrRR(AbstractInstruction * self_in_concretizeMoveXbrRR); -static sqInt NoDbgRegParms concretizeMoveXwrRR(AbstractInstruction * self_in_concretizeMoveXwrRR); -static sqInt NoDbgRegParms concretizeMulCheckOverflowRR(AbstractInstruction * self_in_concretizeMulCheckOverflowRR); -static sqInt NoDbgRegParms concretizeNegateR(AbstractInstruction * self_in_concretizeNegateR); -static sqInt NoDbgRegParms concretizeNop(AbstractInstruction * self_in_concretizeNop); -static sqInt NoDbgRegParms concretizeOrCqR(AbstractInstruction * self_in_concretizeOrCqR); -static sqInt NoDbgRegParms concretizeOrCqRR(AbstractInstruction * self_in_concretizeOrCqRR); -static sqInt NoDbgRegParms concretizeOrCwR(AbstractInstruction * self_in_concretizeOrCwR); -static sqInt NoDbgRegParms concretizeOrRR(AbstractInstruction * self_in_concretizeOrRR); -static sqInt NoDbgRegParms concretizePopR(AbstractInstruction * self_in_concretizePopR); -static sqInt NoDbgRegParms concretizePrefetchAw(AbstractInstruction * self_in_concretizePrefetchAw); -static sqInt NoDbgRegParms concretizePushCq(AbstractInstruction * self_in_concretizePushCq); -static sqInt NoDbgRegParms concretizePushCw(AbstractInstruction * self_in_concretizePushCw); -static sqInt NoDbgRegParms concretizePushR(AbstractInstruction * self_in_concretizePushR); -static sqInt NoDbgRegParms concretizeRetN(AbstractInstruction * self_in_concretizeRetN); -static sqInt NoDbgRegParms concretizeStop(AbstractInstruction * self_in_concretizeStop); -static sqInt NoDbgRegParms concretizeSubCheckOverflowCqR(AbstractInstruction * self_in_concretizeSubCheckOverflowCqR); -static sqInt NoDbgRegParms concretizeSubCheckOverflowRR(AbstractInstruction * self_in_concretizeSubCheckOverflowRR); -static sqInt NoDbgRegParms concretizeSubCqR(AbstractInstruction * self_in_concretizeSubCqR); -static sqInt NoDbgRegParms concretizeSubCwR(AbstractInstruction * self_in_concretizeSubCwR); -static sqInt NoDbgRegParms concretizeSubRRDest(AbstractInstruction * self_in_concretizeSubRRDest, sqInt destReg); -static sqInt NoDbgRegParms concretizeTstCqR(AbstractInstruction * self_in_concretizeTstCqR); -static sqInt NoDbgRegParms concretizeTstCwR(AbstractInstruction * self_in_concretizeTstCwR); -static sqInt NoDbgRegParms concretizeUnimplemented(AbstractInstruction * self_in_concretizeUnimplemented); -static sqInt NoDbgRegParms concretizeXorCwR(AbstractInstruction * self_in_concretizeXorCwR); -static sqInt NoDbgRegParms concretizeXorRR(AbstractInstruction * self_in_concretizeXorRR); -static sqInt NoDbgRegParms dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize); -static sqInt NoDbgRegParms divRR(AbstractInstruction * self_in_divRR, sqInt dividendReg, sqInt divisorReg); -static sqInt NoDbgRegParms fullCallsAreRelative(AbstractInstruction * self_in_fullCallsAreRelative); -static sqInt NoDbgRegParms functionAtAddress(AbstractInstruction * self_in_functionAtAddress, sqInt mcpc); -static sqInt NoDbgRegParms genDivRRQuoRem(AbstractInstruction * self_in_genDivRRQuoRem, sqInt abstractRegDivisor, sqInt abstractRegDividend, sqInt abstractRegQuotient, sqInt abstractRegRemainder); -static AbstractInstruction * NoDbgRegParms genMulRR(AbstractInstruction * self_in_genMulRR, sqInt regSource, sqInt regDest); -static void NoDbgRegParms genPushRegisterArgsForAbortMissNumArgs(AbstractInstruction * self_in_genPushRegisterArgsForAbortMissNumArgs, sqInt numArgs); -static void NoDbgRegParms genPushRegisterArgsForNumArgsscratchReg(AbstractInstruction * self_in_genPushRegisterArgsForNumArgsscratchReg, sqInt numArgs, sqInt ignored); -static sqInt NoDbgRegParms genRemoveNArgsFromStack(AbstractInstruction * self_in_genRemoveNArgsFromStack, sqInt n); -static sqInt NoDbgRegParms genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask); -static sqInt NoDbgRegParms genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask); -static AbstractInstruction * NoDbgRegParms genSubstituteReturnAddress(AbstractInstruction * self_in_genSubstituteReturnAddress, sqInt retpc); -static sqInt NoDbgRegParms hasVarBaseRegister(AbstractInstruction * self_in_hasVarBaseRegister); -static usqInt NoDbgRegParms high16BitsOf(AbstractInstruction * self_in_high16BitsOf, usqInt word); -static usqInt NoDbgRegParms inlineCacheTagAt(AbstractInstruction * self_in_inlineCacheTagAt, usqInt callSiteReturnAddress); -static sqInt NoDbgRegParms instructionSizeAt(AbstractInstruction * self_in_instructionSizeAt, sqInt pc); -static sqInt NoDbgRegParms isCallPrecedingReturnPC(AbstractInstruction * self_in_isCallPrecedingReturnPC, sqInt mcpc); -static sqInt NoDbgRegParms isJump(AbstractInstruction * self_in_isJump); -static sqInt NoDbgRegParms isJumpAt(AbstractInstruction * self_in_isJumpAt, sqInt pc); -static sqInt NoDbgRegParms isPCDependent(AbstractInstruction * self_in_isPCDependent); -static sqInt NoDbgRegParms isShortOffset(AbstractInstruction * self_in_isShortOffset, sqInt offset); -static sqInt NoDbgRegParms itypersrteitherImmediate(AbstractInstruction * self_in_itypersrteitherImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate); -static sqInt NoDbgRegParms itypersrtsignedImmediate(AbstractInstruction * self_in_itypersrtsignedImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate); -static sqInt NoDbgRegParms itypersrtunsignedImmediate(AbstractInstruction * self_in_itypersrtunsignedImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate); -static sqInt NoDbgRegParms jA(AbstractInstruction * self_in_jA, sqInt target); -static sqInt NoDbgRegParms jalA(AbstractInstruction * self_in_jalA, sqInt target); -static sqInt NoDbgRegParms jalR(AbstractInstruction * self_in_jalR, sqInt targetReg); -static sqInt NoDbgRegParms jR(AbstractInstruction * self_in_jR, sqInt targetReg); -static sqInt NoDbgRegParms jtypetarget(AbstractInstruction * self_in_jtypetarget, sqInt op, sqInt target); -static sqInt NoDbgRegParms jumpLongByteSize(AbstractInstruction * self_in_jumpLongByteSize); -static sqInt NoDbgRegParms jumpLongConditionalByteSize(AbstractInstruction * self_in_jumpLongConditionalByteSize); -static usqInt NoDbgRegParms jumpLongConditionalTargetBeforeFollowingAddress(AbstractInstruction * self_in_jumpLongConditionalTargetBeforeFollowingAddress, sqInt mcpc); -static usqInt NoDbgRegParms jumpLongTargetBeforeFollowingAddress(AbstractInstruction * self_in_jumpLongTargetBeforeFollowingAddress, sqInt mcpc); -static sqInt NoDbgRegParms jumpShortByteSize(AbstractInstruction * self_in_jumpShortByteSize); -static usqInt NoDbgRegParms jumpTargetPCAt(AbstractInstruction * self_in_jumpTargetPCAt, sqInt pc); -static sqInt NoDbgRegParms lbRbaseoffset(AbstractInstruction * self_in_lbRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset); -static sqInt NoDbgRegParms lbuRbaseoffset(AbstractInstruction * self_in_lbuRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset); -static sqInt NoDbgRegParms lhRbaseoffset(AbstractInstruction * self_in_lhRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset); -static sqInt NoDbgRegParms lhuRbaseoffset(AbstractInstruction * self_in_lhuRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset); -static usqInt NoDbgRegParms literalAtAddress(AbstractInstruction * self_in_literalAtAddress, sqInt mcpc); -static sqInt NoDbgRegParms literalAtAddressput(AbstractInstruction * self_in_literalAtAddressput, sqInt mcpc, sqInt newLiteral); -static usqInt NoDbgRegParms literalBeforeFollowingAddress(AbstractInstruction * self_in_literalBeforeFollowingAddress, sqInt followingAddress); -static sqInt NoDbgRegParms loadLiteralByteSize(AbstractInstruction * self_in_loadLiteralByteSize); -static sqInt NoDbgRegParms loadPICLiteralByteSize(AbstractInstruction * self_in_loadPICLiteralByteSize); -static usqInt NoDbgRegParms low16BitsOf(AbstractInstruction * self_in_low16BitsOf, usqInt word); -static sqInt NoDbgRegParms luiRC(AbstractInstruction * self_in_luiRC, sqInt destReg, sqInt imm); -static sqInt NoDbgRegParms lwRbaseoffset(AbstractInstruction * self_in_lwRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset); -static sqInt NoDbgRegParms machineCodeBytes(AbstractInstruction * self_in_machineCodeBytes); -static sqInt NoDbgRegParms machineCodeWords(AbstractInstruction * self_in_machineCodeWords); -static sqInt NoDbgRegParms mfhiR(AbstractInstruction * self_in_mfhiR, sqInt destReg); -static sqInt NoDbgRegParms mfloR(AbstractInstruction * self_in_mfloR, sqInt destReg); -static sqInt NoDbgRegParms mipsbreak(AbstractInstruction * self_in_mipsbreak, sqInt code); -static sqInt NoDbgRegParms multRR(AbstractInstruction * self_in_multRR, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms nop(AbstractInstruction * self_in_nop); -static AbstractInstruction * NoDbgRegParms noteFollowingConditionalBranch(AbstractInstruction * self_in_noteFollowingConditionalBranch, AbstractInstruction *branch); -static AbstractInstruction * NoDbgRegParms noteFollowingOverflowBranch(AbstractInstruction * self_in_noteFollowingOverflowBranch, AbstractInstruction *branch); -static sqInt NoDbgRegParms numIntRegArgs(AbstractInstruction * self_in_numIntRegArgs); -static sqInt NoDbgRegParms opcodeAtAddress(AbstractInstruction * self_in_opcodeAtAddress, sqInt mcpc); -static sqInt NoDbgRegParms oriRRC(AbstractInstruction * self_in_oriRRC, sqInt destReg, sqInt srcReg, sqInt imm); -static sqInt NoDbgRegParms orRRR(AbstractInstruction * self_in_orRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static void NoDbgRegParms padIfPossibleWithStopsFromto(AbstractInstruction * self_in_padIfPossibleWithStopsFromto, sqInt startAddr, sqInt endAddr); -static sqInt NoDbgRegParms prefRoffsethint(AbstractInstruction * self_in_prefRoffsethint, sqInt baseReg, sqInt offset, sqInt hint); -static sqInt NoDbgRegParms pushLinkRegisterByteSize(AbstractInstruction * self_in_pushLinkRegisterByteSize); -static AbstractInstruction * NoDbgRegParms relocateCallBeforeReturnPCby(AbstractInstruction * self_in_relocateCallBeforeReturnPCby, sqInt retpc, sqInt delta); -static AbstractInstruction * NoDbgRegParms relocateJumpLongBeforeFollowingAddressby(AbstractInstruction * self_in_relocateJumpLongBeforeFollowingAddressby, sqInt pc, sqInt delta); -static void NoDbgRegParms relocateJumpLongConditionalBeforeFollowingAddressby(AbstractInstruction * self_in_relocateJumpLongConditionalBeforeFollowingAddressby, sqInt pc, sqInt delta); -static AbstractInstruction * NoDbgRegParms relocateMethodReferenceBeforeAddressby(AbstractInstruction * self_in_relocateMethodReferenceBeforeAddressby, sqInt pc, sqInt delta); -static sqInt NoDbgRegParms rewriteCallAttarget(AbstractInstruction * self_in_rewriteCallAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress); -static void NoDbgRegParms rewriteConditionalJumpLongAttarget(AbstractInstruction * self_in_rewriteConditionalJumpLongAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress); -static void NoDbgRegParms rewriteCPICJumpAttarget(AbstractInstruction * self_in_rewriteCPICJumpAttarget, usqInt addressFollowingJump, usqInt jumpTargetAddr); -static sqInt NoDbgRegParms rewriteInlineCacheAttagtarget(AbstractInstruction * self_in_rewriteInlineCacheAttagtarget, usqInt callSiteReturnAddress, sqInt cacheTag, usqInt callTargetAddress); -static void NoDbgRegParms rewriteInlineCacheTagat(AbstractInstruction * self_in_rewriteInlineCacheTagat, sqInt cacheTag, usqInt callSiteReturnAddress); -static void NoDbgRegParms rewriteITypeBranchAtAddresstarget(AbstractInstruction * self_in_rewriteITypeBranchAtAddresstarget, sqInt mcpc, sqInt newTarget); -static void NoDbgRegParms rewriteJTypeAtAddressdelta(AbstractInstruction * self_in_rewriteJTypeAtAddressdelta, sqInt mcpc, sqInt delta); -static void NoDbgRegParms rewriteJTypeAtAddresstarget(AbstractInstruction * self_in_rewriteJTypeAtAddresstarget, sqInt mcpc, sqInt newTarget); -static sqInt NoDbgRegParms rewriteJumpLongAttarget(AbstractInstruction * self_in_rewriteJumpLongAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress); -static sqInt NoDbgRegParms rtAtAddress(AbstractInstruction * self_in_rtAtAddress, sqInt mcpc); -static sqInt NoDbgRegParms rtypersrtrdsafunct(AbstractInstruction * self_in_rtypersrtrdsafunct, sqInt op, sqInt rs, sqInt rt, sqInt rd, sqInt sa, sqInt funct); -static sqInt NoDbgRegParms sbRbaseoffset(AbstractInstruction * self_in_sbRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset); -static sqInt NoDbgRegParms setsConditionCodesFor(AbstractInstruction * self_in_setsConditionCodesFor, sqInt aConditionalJumpOpcode); -static sqInt NoDbgRegParms shRbaseoffset(AbstractInstruction * self_in_shRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset); -static usqInt NoDbgRegParms sizePCDependentInstructionAt(AbstractInstruction * self_in_sizePCDependentInstructionAt, sqInt eventualAbsoluteAddress); -static sqInt NoDbgRegParms sllRRC(AbstractInstruction * self_in_sllRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount); -static sqInt NoDbgRegParms sllvRRR(AbstractInstruction * self_in_sllvRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms sltiRRC(AbstractInstruction * self_in_sltiRRC, sqInt destReg, sqInt leftReg, sqInt imm); -static sqInt NoDbgRegParms sltiuRRC(AbstractInstruction * self_in_sltiuRRC, sqInt destReg, sqInt leftReg, sqInt imm); -static sqInt NoDbgRegParms sltRRR(AbstractInstruction * self_in_sltRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms sltuRRR(AbstractInstruction * self_in_sltuRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms sraRRC(AbstractInstruction * self_in_sraRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount); -static sqInt NoDbgRegParms sravRRR(AbstractInstruction * self_in_sravRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms srlRRC(AbstractInstruction * self_in_srlRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount); -static sqInt NoDbgRegParms srlvRRR(AbstractInstruction * self_in_srlvRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms stop(AbstractInstruction * self_in_stop); -static void NoDbgRegParms stopsFromto(AbstractInstruction * self_in_stopsFromto, sqInt startAddr, sqInt endAddr); -static sqInt NoDbgRegParms storeLiteralbeforeFollowingAddress(AbstractInstruction * self_in_storeLiteralbeforeFollowingAddress, sqInt literal, sqInt followingAddress); -static sqInt NoDbgRegParms subuRRR(AbstractInstruction * self_in_subuRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms swRbaseoffset(AbstractInstruction * self_in_swRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset); -static usqInt NoDbgRegParms targetFromITypeAtAddress(AbstractInstruction * self_in_targetFromITypeAtAddress, usqInt mcpc); -static usqInt NoDbgRegParms targetFromJTypeAtAddress(AbstractInstruction * self_in_targetFromJTypeAtAddress, usqInt mcpc); -static sqInt NoDbgRegParms xoriRRC(AbstractInstruction * self_in_xoriRRC, sqInt destReg, sqInt srcReg, sqInt imm); -static sqInt NoDbgRegParms xorRRR(AbstractInstruction * self_in_xorRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms zoneCallsAreRelative(AbstractInstruction * self_in_zoneCallsAreRelative); -static sqInt NoDbgRegParms checkValidObjectReference(sqInt anOop); -static AbstractInstruction * NoDbgRegParms genCmpClassFloatCompactIndexR(sqInt reg); -static AbstractInstruction * NoDbgRegParms genCmpClassMethodContextCompactIndexR(sqInt reg); -static sqInt NoDbgRegParms genGetMethodHeaderOfintoscratch(sqInt methodReg, sqInt headerReg, sqInt scratchReg); -static sqInt NoDbgRegParms genLoadSlotsourceRegdestReg(sqInt index, sqInt sourceReg, sqInt destReg); -static sqInt genPrimitiveAdd(void); -static sqInt genPrimitiveBitAnd(void); -static sqInt genPrimitiveBitOr(void); -static sqInt genPrimitiveBitShift(void); -static sqInt genPrimitiveBitXor(void); -static sqInt genPrimitiveClass(void); -static sqInt genPrimitiveDiv(void); -static sqInt genPrimitiveDivide(void); -static sqInt genPrimitiveEqual(void); -static sqInt genPrimitiveGreaterOrEqual(void); -static sqInt genPrimitiveGreaterThan(void); -static sqInt genPrimitiveHighBit(void); -static sqInt genPrimitiveIdentical(void); -static sqInt genPrimitiveLessOrEqual(void); -static sqInt genPrimitiveLessThan(void); -static sqInt genPrimitiveMod(void); -static sqInt genPrimitiveMultiply(void); -static sqInt genPrimitiveNewMethod(void); -static sqInt genPrimitiveNotEqual(void); -static sqInt genPrimitiveNotIdentical(void); -static sqInt genPrimitiveQuo(void); -static sqInt genPrimitiveSubtract(void); -static sqInt NoDbgRegParms genSmallIntegerComparison(sqInt jumpOpcode); -static sqInt NoDbgRegParms genSmallIntegerComparisonorDoubleComparisoninvert(sqInt jumpOpcode, AbstractInstruction * NoDbgRegParms (*jumpFPOpcodeGenerator)(void *), sqInt invertComparison); -static sqInt NoDbgRegParms isUnannotatableConstant(CogSimStackEntry *simStackEntry); -static sqInt NoDbgRegParms classForInlineCacheTag(sqInt inlineCacheTag); -static sqInt NoDbgRegParms genAddSmallIntegerTagsTo(sqInt aRegister); -static sqInt NoDbgRegParms genClearAndSetSmallIntegerTagsIn(sqInt scratchReg); -static void NoDbgRegParms genConvertCharacterToSmallIntegerInReg(sqInt reg); -static sqInt NoDbgRegParms genConvertIntegerInRegtoSmallIntegerInReg(sqInt srcReg, sqInt destReg); -static sqInt NoDbgRegParms genConvertIntegerToSmallIntegerInReg(sqInt reg); -static void NoDbgRegParms genConvertSmallIntegerToCharacterInReg(sqInt reg); -static sqInt NoDbgRegParms genConvertSmallIntegerToIntegerInReg(sqInt reg); -static sqInt NoDbgRegParms genGetHashFieldNonImmOfasSmallIntegerInto(sqInt instReg, sqInt destReg); -static sqInt NoDbgRegParms genGetHashFieldNonImmOfinto(sqInt instReg, sqInt destReg); -static AbstractInstruction * NoDbgRegParms genGetInlineCacheClassTagFromintoforEntry(sqInt sourceReg, sqInt destReg, sqInt forEntry); -static sqInt NoDbgRegParms genGetNumBytesOfinto(sqInt srcReg, sqInt destReg); -static sqInt NoDbgRegParms genGetOverflowSlotsOfinto(sqInt srcReg, sqInt destReg); -static AbstractInstruction * NoDbgRegParms genJumpIsSmallIntegerValuescratch(sqInt aRegister, sqInt scratchReg); -static AbstractInstruction * NoDbgRegParms genJumpNotSmallIntegerInScratchReg(sqInt aRegister); -static AbstractInstruction * NoDbgRegParms genJumpNotSmallIntegerValuescratch(sqInt aRegister, sqInt scratchReg); -static AbstractInstruction * NoDbgRegParms genJumpNotSmallInteger(sqInt aRegister); -static AbstractInstruction * NoDbgRegParms genJumpSmallInteger(sqInt aRegister); -static sqInt genPrimitiveAtPut(void); -static sqInt NoDbgRegParms genPrimitiveAtPutSigned(sqInt signedVersion); -static sqInt NoDbgRegParms genPrimitiveAtSigned(sqInt signedVersion); -static sqInt genPrimitiveIdentityHash(void); -static sqInt genPrimitiveImmediateAsInteger(void); -static sqInt genPrimitiveNew(void); -static sqInt genPrimitiveNewWithArg(void); -static sqInt genPrimitiveShallowCopy(void); -static sqInt genPrimitiveStringAt(void); -static sqInt genPrimitiveStringAtPut(void); -static sqInt NoDbgRegParms genRemoveSmallIntegerTagsInScratchReg(sqInt scratchReg); -static sqInt NoDbgRegParms genShiftAwaySmallIntegerTagsInScratchReg(sqInt scratchReg); -static sqInt NoDbgRegParms getLiteralCountOfplusOneinBytesintoscratch(sqInt methodReg, sqInt plusOne, sqInt inBytes, sqInt litCountReg, sqInt scratchReg); -static sqInt NoDbgRegParms inlineCacheTagForInstance(sqInt oop); -static AbstractInstruction * NoDbgRegParms jumpNotSmallIntegerUnsignedValueInRegister(sqInt reg); -static sqInt NoDbgRegParms markAndTraceCacheTagLiteralinatpc(sqInt literal, CogMethod *cogMethodOrNil, usqInt address); -static sqInt numSmallIntegerBits(void); -static sqInt NoDbgRegParms validInlineCacheTag(usqInt classIndexOrTagPattern); -static void callStoreCheckTrampoline(void); -static sqInt NoDbgRegParms checkValidDerivedObjectReference(sqInt bodyAddress); -static sqInt NoDbgRegParms checkValidOopReference(sqInt anOop); -static sqInt NoDbgRegParms couldBeDerivedObject(sqInt bodyAddress); -static sqInt NoDbgRegParms couldBeObject(sqInt literal); -static usqInt NoDbgRegParms genActiveContextTrampolineLargeinBlockcalled(sqInt isLarge, sqInt isInBlock, char *aString); -static AbstractInstruction * NoDbgRegParms genCheckRememberedBitOfscratch(sqInt objReg, sqInt scratchReg); -static sqInt NoDbgRegParms genConvertCharacterToCodeInReg(sqInt reg); -static sqInt NoDbgRegParms genConvertIntegerToCharacterInReg(sqInt reg); -static sqInt NoDbgRegParms genCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(sqInt bcpc, sqInt numArgs, sqInt numCopied, sqInt ctxtNumArgs, sqInt isLargeCtxt, sqInt isInBlock); -static sqInt NoDbgRegParms genCreateFullClosurenumArgsnumCopiedignoreContextcontextNumArgslargeinBlock(sqInt compiledBlock, sqInt numArgs, sqInt numCopied, sqInt ignoreContext, sqInt contextNumArgs, sqInt contextIsLarge, sqInt contextIsBlock); -static sqInt NoDbgRegParms genEnsureObjInRegNotForwardedscratchReg(sqInt reg, sqInt scratch); -static sqInt NoDbgRegParms genEnsureOopInRegNotForwardedscratchReg(sqInt reg, sqInt scratch); -static sqInt NoDbgRegParms genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(sqInt reg, sqInt scratch, void *fwdJumpTarget, void *nonFwdJumpTargetOrZero); -static sqInt NoDbgRegParms genEnsureOopInRegNotForwardedscratchRegupdatingSlotin(sqInt reg, sqInt scratch, sqInt index, sqInt objReg); -static void generateObjectRepresentationTrampolines(void); -static sqInt NoDbgRegParms genGetActiveContextLargeinBlock(sqInt isLarge, sqInt isInBlock); -static sqInt NoDbgRegParms genGetActiveContextNumArgslargeinBlock(sqInt numArgs, sqInt isLargeContext, sqInt isInBlock); -static sqInt NoDbgRegParms genGetBitsofFormatByteOfinto(sqInt mask, sqInt sourceReg, sqInt destReg); -static sqInt NoDbgRegParms genGetClassIndexOfNonImminto(sqInt sourceReg, sqInt destReg); -static sqInt NoDbgRegParms genGetClassObjectOfClassIndexintoscratchReg(sqInt instReg, sqInt destReg, sqInt scratchReg); -static sqInt NoDbgRegParms genGetClassObjectOfintoscratchRegmayBeAForwarder(sqInt instReg, sqInt destReg, sqInt scratchReg, sqInt mayBeForwarder); -static AbstractInstruction * NoDbgRegParms genGetClassTagOfintoscratchReg(sqInt instReg, sqInt destReg, sqInt scratchReg); -static sqInt NoDbgRegParms genGetCompactClassIndexNonImmOfinto(sqInt instReg, sqInt destReg); -static sqInt NoDbgRegParms genGetDoubleValueOfinto(sqInt srcReg, sqInt destFPReg); -static sqInt NoDbgRegParms genGetFormatOfinto(sqInt srcReg, sqInt destReg); -static sqInt NoDbgRegParms genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(sqInt sourceReg, sqInt destReg, sqInt scratchRegOrNone); -static sqInt NoDbgRegParms genGetNumSlotsOfinto(sqInt srcReg, sqInt destReg); -static sqInt NoDbgRegParms genGetRawSlotSizeOfNonImminto(sqInt sourceReg, sqInt destReg); -static AbstractInstruction * NoDbgRegParms genJumpImmediate(sqInt aRegister); -#if IMMUTABILITY -static AbstractInstruction * NoDbgRegParms genJumpImmutablescratchReg(sqInt sourceReg, sqInt scratchReg); -#endif /* IMMUTABILITY */ -#if IMMUTABILITY -static AbstractInstruction * NoDbgRegParms genJumpMutablescratchReg(sqInt sourceReg, sqInt scratchReg); -#endif /* IMMUTABILITY */ -static AbstractInstruction * NoDbgRegParms genJumpNotCharacterInScratchReg(sqInt reg); -static sqInt NoDbgRegParms genNewArrayOfSizeinitialized(sqInt size, sqInt initialize); -static sqInt NoDbgRegParms genNoPopCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(sqInt bcpc, sqInt numArgs, sqInt numCopied, sqInt ctxtNumArgs, sqInt isLargeCtxt, sqInt isInBlock); -static sqInt genPrimitiveAsCharacter(void); -static sqInt genPrimitiveAt(void); -static sqInt NoDbgRegParms genPrimitiveIdenticalOrNotIf(sqInt orNot); -static sqInt genPrimitiveIntegerAt(void); -static sqInt genPrimitiveIntegerAtPut(void); -static sqInt genPrimitiveMakePoint(void); -static sqInt genPrimitiveObjectAt(void); -static sqInt genPrimitiveSize(void); -static sqInt genPrimitiveStringCompareWith(void); -static sqInt genPrimitiveStringReplace(void); -static sqInt NoDbgRegParms genSetSmallIntegerTagsIn(sqInt scratchReg); -static usqInt genStoreCheckContextReceiverTrampoline(void); -static sqInt NoDbgRegParms genStoreCheckReceiverRegvalueRegscratchReginFrame(sqInt destReg, sqInt valueReg, sqInt scratchReg, sqInt inFrame); -static sqInt NoDbgRegParms genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt inFrame, sqInt needsStoreCheck); -static sqInt NoDbgRegParms genStoreSourceRegslotIndexintoNewObjectInDestReg(sqInt sourceReg, sqInt index, sqInt destReg); -#if IMMUTABILITY -static usqInt NoDbgRegParms genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex); -#endif /* IMMUTABILITY */ -#if IMMUTABILITY -static sqInt NoDbgRegParms genStoreWithImmutabilityAndStoreCheckSourceRegslotIndexdestRegscratchRegneedRestoreRcvr(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt needRestoreRcvr); -#endif /* IMMUTABILITY */ -#if IMMUTABILITY -static sqInt NoDbgRegParms genStoreWithImmutabilityButNoStoreCheckSourceRegslotIndexdestRegscratchRegneedRestoreRcvr(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt needRestoreRcvr); -#endif /* IMMUTABILITY */ -#if IMMUTABILITY -static sqInt NoDbgRegParms genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt needsStoreCheck, sqInt needRestoreRcvr); -#endif /* IMMUTABILITY */ -static sqInt getActiveContextAllocatesInMachineCode(void); -static sqInt NoDbgRegParms inlineCacheTagIsYoung(sqInt cacheTag); -static AbstractInstruction * NoDbgRegParms jumpNotCharacterUnsignedValueInRegister(sqInt reg); -static sqInt NoDbgRegParms markAndTraceLiteralinatpc(sqInt literal, CogMethod *cogMethodOrNil, usqInt address); -static void NoDbgRegParms markAndTraceLiteralinat(sqInt literal, CogMethod *cogMethod, sqInt *address); -static void NoDbgRegParms markAndTraceUpdatedLiteralin(sqInt objOop, CogMethod *cogMethodOrNil); -static sqInt NoDbgRegParms maybeCompileRetryOnPrimitiveFail(sqInt primIndex); -static sqInt NoDbgRegParms maybeShiftClassTagRegisterForMethodCacheProbe(sqInt classTagReg); -static sqInt numCharacterBits(void); -extern sqInt numRegArgs(void); -static sqInt NoDbgRegParms remapObject(sqInt objOop); -static sqInt NoDbgRegParms remapOop(sqInt objOop); -static sqInt NoDbgRegParms shouldAnnotateObjectReference(sqInt anOop); -static sqInt NoDbgRegParms slotOffsetOfInstVarIndex(sqInt index); -static SimStackEntry * NoDbgRegParms ensureSpilledAtfrom(SimStackEntry * self_in_ensureSpilledAtfrom, sqInt baseOffset, sqInt baseRegister); -static sqInt NoDbgRegParms isSameEntryAs(SimStackEntry * self_in_isSameEntryAs, CogSimStackEntry *ssEntry); -static sqInt NoDbgRegParms mayBeAForwarder(SimStackEntry * self_in_mayBeAForwarder); -static void NoDbgRegParms popToReg(SimStackEntry * self_in_popToReg, sqInt reg); -static sqInt NoDbgRegParms registerMask(SimStackEntry * self_in_registerMask); -static sqInt NoDbgRegParms registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone); -static sqInt NoDbgRegParms registerOrNone(SimStackEntry * self_in_registerOrNone); -static void NoDbgRegParms storeToReg(SimStackEntry * self_in_storeToReg, sqInt reg); -static sqInt NoDbgRegParms isMergeFixup(BytecodeFixup * self_in_isMergeFixup); -static AbstractInstruction * NoDbgRegParms checkLiteralforInstruction(sqInt literal, AbstractInstruction *anInstruction); -static AbstractInstruction * NoDbgRegParms checkQuickConstantforInstruction(sqInt literal, AbstractInstruction *anInstruction); -extern sqInt cogMethodHasExternalPrim(CogMethod *aCogMethod); -extern sqInt cogMethodHasMachineCodePrim(CogMethod *aCogMethod); -static sqInt compileBlockDispatch(void); -static void compileGetErrorCode(void); -static sqInt compileInterpreterPrimitive(void); -static sqInt NoDbgRegParms compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags); -static sqInt NoDbgRegParms compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)); -static sqInt NoDbgRegParms compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags); -static AbstractInstruction * NoDbgRegParms compileOpenPICMethodCacheProbeForwithShiftbaseRegOrNone(sqInt selector, sqInt shift, sqInt baseRegOrNone); -static void NoDbgRegParms compileOpenPICnumArgs(sqInt selector, sqInt numArgs); -static AbstractInstruction * NoDbgRegParms compilePerformMethodCacheProbeForwithShiftbaseRegOrNone(sqInt selectorReg, sqInt shift, sqInt baseRegOrNone); -static sqInt compilePrimitive(void); -static sqInt extendedPushBytecode(void); -static sqInt extendedStoreAndPopBytecode(void); -static sqInt extendedStoreBytecode(void); -static sqInt NoDbgRegParms frameOffsetOfTemporary(sqInt index); -static sqInt genCallMappedInlinedPrimitive(void); -static sqInt genExtendedSendBytecode(void); -static sqInt genExtendedSuperBytecode(void); -static sqInt genExtJumpIfFalse(void); -static sqInt genExtJumpIfTrue(void); -static sqInt genExtNopBytecode(void); -static sqInt genExtPushCharacterBytecode(void); -static sqInt genExtPushIntegerBytecode(void); -static sqInt genExtPushLiteralBytecode(void); -static sqInt genExtPushLiteralVariableBytecode(void); -static sqInt genExtPushPseudoVariable(void); -static sqInt genExtPushReceiverVariableBytecode(void); -static sqInt genExtSendBytecode(void); -static sqInt genExtSendSuperBytecode(void); -static sqInt genExtStoreAndPopLiteralVariableBytecode(void); -static sqInt genExtStoreAndPopReceiverVariableBytecode(void); -static sqInt genExtStoreLiteralVariableBytecode(void); -static sqInt genExtStoreReceiverVariableBytecode(void); -static sqInt genExtUnconditionalJump(void); -static sqInt genFastPrimFail(void); -static void NoDbgRegParms genFastPrimTraceUsingand(sqInt r1, sqInt r2); -static sqInt genLongJumpIfFalse(void); -static sqInt genLongJumpIfTrue(void); -static sqInt genLongPushTemporaryVariableBytecode(void); -static sqInt genLongStoreAndPopTemporaryVariableBytecode(void); -static sqInt genLongStoreTemporaryVariableBytecode(void); -static sqInt genLongUnconditionalBackwardJump(void); -static sqInt genLongUnconditionalForwardJump(void); -static sqInt NoDbgRegParms genLookupForPerformNumArgs(sqInt numArgs); -static usqInt NoDbgRegParms genMustBeBooleanTrampolineForcalled(sqInt boolean, char *trampolineName); -static sqInt genPrimitiveHashMultiply(void); -static void NoDbgRegParms genPrimReturnEnterCogCodeEnilopmart(sqInt profiling); -static sqInt genPushConstantFalseBytecode(void); -static sqInt genPushConstantNilBytecode(void); -static sqInt genPushConstantOneBytecode(void); -static sqInt genPushConstantTrueBytecode(void); -static sqInt genPushConstantZeroBytecode(void); -static sqInt genPushLiteralConstantBytecode(void); -static sqInt genPushLiteralVariable16CasesBytecode(void); -static sqInt genPushLiteralVariableBytecode(void); -static sqInt genPushQuickIntegerConstantBytecode(void); -static sqInt genPushReceiverVariableBytecode(void); -static sqInt genPushTemporaryVariableBytecode(void); -extern sqInt genQuickReturnConst(void); -extern sqInt genQuickReturnInstVar(void); -extern sqInt genQuickReturnSelf(void); -static sqInt genReturnFalse(void); -static sqInt genReturnNil(void); -static sqInt genReturnNilFromBlock(void); -static sqInt genReturnTrue(void); -static sqInt genSecondExtendedSendBytecode(void); -static sqInt genSendLiteralSelector0ArgsBytecode(void); -static sqInt genSendLiteralSelector1ArgBytecode(void); -static sqInt genSendLiteralSelector2ArgsBytecode(void); -static sqInt genShortJumpIfFalse(void); -static sqInt genShortJumpIfTrue(void); -static sqInt genShortUnconditionalJump(void); -static sqInt genSpecialSelectorEqualsEquals(void); -static sqInt genSpecialSelectorNotEqualsEquals(void); -static sqInt genSpecialSelectorSend(void); -static sqInt genStoreAndPopReceiverVariableBytecode(void); -static sqInt genStoreAndPopRemoteTempLongBytecode(void); -static sqInt genStoreAndPopTemporaryVariableBytecode(void); -static sqInt genStoreRemoteTempLongBytecode(void); -static sqInt genUnconditionalTrapBytecode(void); -extern sqInt mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj); -static sqInt numSpecialSelectors(void); -static usqInt NoDbgRegParms pcDataForBlockEntryMethod(sqInt blockEntryMcpc, sqInt cogMethod); -static sqInt NoDbgRegParms pcDataForAnnotationMcpcBcpcMethod(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *cogMethodArg); -static PrimitiveDescriptor * primitiveGeneratorOrNil(void); -static sqInt NoDbgRegParms registerisInMask(sqInt reg, sqInt mask); -static sqInt NoDbgRegParms v3BlockCodeSize(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt NoDbgRegParms v3LongForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt NoDbgRegParms v3LongBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt NoDbgRegParms v3ShortForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt NoDbgRegParms v4BlockCodeSize(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt NoDbgRegParms v4LongForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt NoDbgRegParms v4LongBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static BlockStart * NoDbgRegParms addBlockStartAtnumArgsnumCopiedspan(sqInt bytecodepc, sqInt numArgs, sqInt numCopied, sqInt span); -static void NoDbgRegParms adjustArgumentsForPerform(sqInt numArgs); -static sqInt NoDbgRegParms allocateRegForStackEntryAtnotConflictingWith(sqInt index, sqInt regMask); -static sqInt NoDbgRegParms allocateRegNotConflictingWith(sqInt regMask); -static sqInt NoDbgRegParms anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n); -extern void callCogCodePopReceiverArg0Regs(void); -extern void callCogCodePopReceiverArg1Arg0Regs(void); -static sqInt NoDbgRegParms compileAbstractInstructionsFromthrough(sqInt start, sqInt end); -static sqInt compileBlockBodies(void); -static void NoDbgRegParms compileBlockFrameBuild(BlockStart *blockStart); -static void NoDbgRegParms compileBlockFramelessEntry(BlockStart *blockStart); -static CogMethod * NoDbgRegParms compileCogFullBlockMethod(sqInt numCopied); -static CogMethod * NoDbgRegParms compileCogMethod(sqInt selector); -static sqInt compileEntireMethod(void); -static void compileFrameBuild(void); -static void NoDbgRegParms compileFullBlockFramelessEntry(sqInt numCopied); -static void NoDbgRegParms compileFullBlockMethodFrameBuild(sqInt numCopied); -#if IMMUTABILITY -static void compileTwoPathFrameBuild(void); -#endif /* IMMUTABILITY */ -static void compileTwoPathFramelessInit(void); -static sqInt NoDbgRegParms cPICMissTrampolineFor(sqInt numArgs); -static sqInt doubleExtendedDoAnythingBytecode(void); -static sqInt duplicateTopBytecode(void); -static BytecodeFixup * NoDbgRegParms ensureFixupAt(sqInt targetPC); -static BytecodeFixup * NoDbgRegParms ensureNonMergeFixupAt(sqInt targetPC); -static void ensureReceiverResultRegContainsSelf(void); -static void NoDbgRegParms evaluateat(BytecodeDescriptor *descriptor, sqInt pc); -static sqInt NoDbgRegParms eventualTargetOf(sqInt targetBytecodePC); -static sqInt NoDbgRegParms freeAnyRegNotConflictingWith(sqInt regMask); -static sqInt genBlockReturn(void); -static void (*genCallPICEnilopmartNumArgs(sqInt numArgs))(void) ; -static sqInt genCallPrimitiveBytecode(void); -static sqInt genExternalizePointersForPrimitiveCall(void); -static AbstractInstruction * genExternalizeStackPointerForFastPrimitiveCall(void); -static sqInt genExtPushClosureBytecode(void); -static sqInt genExtPushFullClosureBytecode(void); -static void generateEnilopmarts(void); -static sqInt NoDbgRegParms generateInstructionsAt(sqInt eventualAbsoluteAddress); -static void generateMissAbortTrampolines(void); -static void generateSendTrampolines(void); -static void generateTracingTrampolines(void); -static sqInt NoDbgRegParms genForwardersInlinedIdenticalOrNotIf(sqInt orNot); -static sqInt NoDbgRegParms genIdenticalNoBranchArgIsConstantrcvrIsConstantargRegrcvrRegorNotIf(sqInt argIsConstant, sqInt rcvrIsConstant, sqInt argReg, sqInt rcvrRegOrNone, sqInt orNot); -static sqInt NoDbgRegParms genInlinedIdenticalOrNotIf(sqInt orNot); -static sqInt NoDbgRegParms genJumpBackTo(sqInt targetBytecodePC); -static sqInt NoDbgRegParms genJumpIfto(sqInt boolean, sqInt targetBytecodePC); -static sqInt NoDbgRegParms genJumpTo(sqInt targetBytecodePC); -static sqInt NoDbgRegParms genMarshalledSendnumArgssendTable(sqInt selectorIndex, sqInt numArgs, sqInt *sendTable); -static usqInt NoDbgRegParms genMethodAbortTrampolineFor(sqInt numArgs); -static usqInt NoDbgRegParms genPICAbortTrampolineFor(sqInt numArgs); -static usqInt NoDbgRegParms genPICMissTrampolineFor(sqInt numArgs); -static sqInt genPopStackBytecode(void); -static sqInt genPrimitiveClosureValue(void); -static sqInt genPrimitiveFullClosureValue(void); -static sqInt genPrimitivePerform(void); -static sqInt genPushActiveContextBytecode(void); -static sqInt genPushClosureCopyCopiedValuesBytecode(void); -static sqInt NoDbgRegParms genPushLiteralIndex(sqInt literalIndex); -static sqInt NoDbgRegParms genPushLiteralVariable(sqInt literalIndex); -static sqInt NoDbgRegParms genPushLiteral(sqInt literal); -static sqInt NoDbgRegParms genPushMaybeContextReceiverVariable(sqInt slotIndex); -static sqInt genPushNewArrayBytecode(void); -static sqInt genPushReceiverBytecode(void); -static sqInt NoDbgRegParms genPushReceiverVariable(sqInt index); -static void genPushRegisterArgs(void); -static sqInt genPushRemoteTempLongBytecode(void); -static sqInt NoDbgRegParms genPushTemporaryVariable(sqInt index); -static sqInt genReturnReceiver(void); -static sqInt genReturnTopFromBlock(void); -static sqInt genReturnTopFromMethod(void); -static sqInt NoDbgRegParms genSendDirectedSupernumArgs(sqInt selectorIndex, sqInt numArgs); -static sqInt NoDbgRegParms genSendSupernumArgs(sqInt selectorIndex, sqInt numArgs); -static usqInt NoDbgRegParms genSendTrampolineFornumArgscalledargargargarg(void *aRoutine, sqInt numArgs, char *aString, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3); -static sqInt NoDbgRegParms genSendnumArgs(sqInt selectorIndex, sqInt numArgs); -static sqInt genSpecialSelectorArithmetic(void); -static sqInt genSpecialSelectorClass(void); -static sqInt genSpecialSelectorComparison(void); -static sqInt genStaticallyResolvedSpecialSelectorComparison(void); -static sqInt NoDbgRegParms genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt litVarIndex, sqInt needsStoreCheck, sqInt needsImmCheck); -static sqInt NoDbgRegParms genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt slotIndex, sqInt needsStoreCheck, sqInt needsImmCheck); -static sqInt NoDbgRegParms genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt slotIndex, sqInt needsStoreCheck, sqInt needsImmCheck); -static sqInt NoDbgRegParms genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt remoteTempIndex, sqInt needsStoreCheck); -static sqInt NoDbgRegParms genStorePopTemporaryVariable(sqInt popBoolean, sqInt tempIndex); -static sqInt genUpArrowReturn(void); -static sqInt NoDbgRegParms genVanillaInlinedIdenticalOrNotIf(sqInt orNot); -static void NoDbgRegParms initSimStackForFramefulMethod(sqInt startpc); -static void NoDbgRegParms initSimStackForFramelessBlock(sqInt startpc); -static void NoDbgRegParms initSimStackForFramelessMethod(sqInt startpc); -static sqInt NoDbgRegParms isNonForwarderReceiver(sqInt reg); -static sqInt liveRegisters(void); -static sqInt NoDbgRegParms mapDeadDescriptorIfNeeded(BytecodeDescriptor *descriptor); -static void NoDbgRegParms marshallSendArguments(sqInt numArgs); -static sqInt maybeCompilingFirstPassOfBlockWithInitialPushNil(void); -static sqInt NoDbgRegParms mergeWithFixupIfRequired(BytecodeFixup *fixup); -static sqInt NoDbgRegParms methodAbortTrampolineFor(sqInt numArgs); -static sqInt methodFoundInvalidPostScan(void); -static sqInt NoDbgRegParms needsFrameIfMod16GENumArgs(sqInt stackDelta); -static sqInt NoDbgRegParms needsFrameIfStackGreaterThanOne(sqInt stackDelta); -static sqInt NoDbgRegParms numberOfSpillsInTopNItems(sqInt n); -static sqInt NoDbgRegParms picAbortTrampolineFor(sqInt numArgs); -static sqInt prevInstIsPCAnnotated(void); -static sqInt receiverIsInReceiverResultReg(void); -static void NoDbgRegParms reinitializeFixupsFromthrough(sqInt start, sqInt end); -static sqInt NoDbgRegParms scanBlock(BlockStart *blockStart); -static sqInt scanMethod(void); -static sqInt NoDbgRegParms squeakV3orSistaV1PushNilSizenumInitialNils(sqInt aMethodObj, sqInt numInitialNils); -static sqInt NoDbgRegParms squeakV3orSistaV1NumPushNils(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static void NoDbgRegParms ssAllocateRequiredRegMaskupThroughupThroughNative(sqInt requiredRegsMask, sqInt stackPtr, sqInt nativeStackPtr); -static void NoDbgRegParms ssFlushUpThroughReceiverVariable(sqInt slotIndex); -static void NoDbgRegParms ssFlushUpThroughTemporaryVariable(sqInt tempIndex); -static void NoDbgRegParms ssPop(sqInt n); -static sqInt NoDbgRegParms ssPushAnnotatedConstant(sqInt literal); -static sqInt NoDbgRegParms ssPushBaseoffset(sqInt reg, sqInt offset); -static sqInt NoDbgRegParms ssPushConstant(sqInt literal); -static sqInt NoDbgRegParms ssPushDesc(SimStackEntry simStackEntry); -static sqInt NoDbgRegParms ssPushRegister(sqInt reg); -static void NoDbgRegParms ssPush(sqInt n); -static SimStackEntry ssSelfDescriptor(void); -static void NoDbgRegParms ssStoreAndReplacePoptoReg(sqInt popBoolean, sqInt reg); -static sqInt NoDbgRegParms ssStorePoptoPreferredReg(sqInt popBoolean, sqInt preferredReg); -static void NoDbgRegParms ssStorePoptoReg(sqInt popBoolean, sqInt reg); -static CogSimStackEntry * ssTop(void); -static CogSimStackEntry * NoDbgRegParms ssValue(sqInt n); -static sqInt NoDbgRegParms stackEntryIsBoolean(CogSimStackEntry *simStackEntry); -static sqInt tempsValidAndVolatileEntriesSpilled(void); -static sqInt NoDbgRegParms tryCollapseTempVectorInitializationOfSize(sqInt slots); -static sqInt violatesEnsureSpilledSpillAssert(void); -static void voidReceiverResultRegContainsSelf(void); - - -/*** Variables ***/ -static AbstractInstruction * abstractOpcodes; -static usqInt baseAddress; -static sqInt blockCount; -static AbstractInstruction * blockEntryLabel; -static AbstractInstruction * blockEntryNoContextSwitch; -static BlockStart * blockStarts; -static sqInt breakBlock; -static sqInt breakMethod; -static sqInt byte0; -static sqInt byte1; -static sqInt byte2; -static sqInt byte3; -static sqInt bytecodePC; -static sqInt bytecodeSetOffset; -static sqInt ceByteSizeOfTrampoline; -static sqInt ceCPICMissTrampoline; -static sqInt ceFetchContextInstVarTrampoline; -static sqInt ceFFICalloutTrampoline; -static sqInt ceFloatObjectOfTrampoline; -static sqInt ceFloatValueOfTrampoline; -static sqInt ceFlushICache; -static sqInt ceFreeTrampoline; -static sqInt ceInlineNewHashTrampoline; -static sqInt ceInstantiateClassIndexableSizeTrampoline; -static sqInt ceInstantiateClassTrampoline; -static sqInt ceLargeActiveContextInBlockTrampoline; -static sqInt ceLargeActiveContextInFullBlockTrampoline; -static sqInt ceLargeActiveContextInMethodTrampoline; -static sqInt ceMallocTrampoline; -static sqInt ceMethodAbortTrampoline; -static sqInt ceNewHashTrampoline; -static sqInt ceNonLocalReturnTrampoline; -static sqInt cePICAbortTrampoline; -static sqInt cePositive32BitIntegerTrampoline; -static sqInt cePositive32BitValueOfTrampoline; -static sqInt cePositive64BitIntegerTrampoline; -static sqInt cePositive64BitValueOfTrampoline; -static sqInt cePrimReturnEnterCogCode; -static sqInt cePrimReturnEnterCogCodeProfiling; -static sqInt ceReapAndResetErrorCodeTrampoline; -static sqInt ceScheduleScavengeTrampoline; -static sqInt ceSendMustBeBooleanAddFalseTrampoline; -static sqInt ceSendMustBeBooleanAddTrueTrampoline; -static sqInt ceSigned32BitIntegerTrampoline; -static sqInt ceSigned32BitValueOfTrampoline; -static sqInt ceSigned64BitIntegerTrampoline; -static sqInt ceSigned64BitValueOfTrampoline; -static sqInt ceSmallActiveContextInBlockTrampoline; -static sqInt ceSmallActiveContextInFullBlockTrampoline; -static sqInt ceSmallActiveContextInMethodTrampoline; -static sqInt ceStoreCheckContextReceiverTrampoline; -static sqInt ceStoreCheckTrampoline; -static sqInt ceStoreContextInstVarTrampoline; -static sqInt ceTraceBlockActivationTrampoline; -static sqInt ceTraceLinkedSendTrampoline; -static sqInt ceTraceStoreTrampoline; -static sqInt checkedEntryAlignment; -static sqInt closedPICSize; -static sqInt codeBase; -static sqInt codeModified; -static sqInt cogConstituentIndex; -static sqInt compactionInProgress; -static sqInt compilationPass; -static sqInt compilationTrace; -static sqInt cPICCaseSize; -static sqInt cPICEndOfCodeOffset; -static sqInt cPICEndSize; -static CogMethod * cPICPrototype; -static sqInt currentCallCleanUpSize; -static sqInt deadCode; -static sqInt debugBytecodePointers; -static sqInt debugFixupBreaks; -static sqInt debugOpcodeIndices; -static sqInt debugStackPointers; -static sqInt directedSendUsesBinding; -static sqInt directedSuperBindingSendTrampolines[NumSendTrampolines]; -static sqInt directedSuperSendTrampolines[NumSendTrampolines]; -static sqInt disassemblingMethod; -static AbstractInstruction * endCPICCase0; -static sqInt endPC; -static AbstractInstruction * entry; -static sqInt entryPointMask; -static CogMethod * enumeratingCogMethod; -static sqInt expectedFPAlignment; -static sqInt expectedSPAlignment; -static sqInt extA; -static sqInt extB; -static sqInt firstCPICCaseOffset; -static sqInt firstSend; -static BytecodeFixup * fixups; -static AbstractInstruction * fullBlockEntry; -static AbstractInstruction * fullBlockNoContextSwitchEntry; -static BytecodeDescriptor generatorTable[512] = { - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushReceiverBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantTrueBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantFalseBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantNilBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushQuickIntegerConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushQuickIntegerConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushQuickIntegerConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushQuickIntegerConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genReturnReceiver, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnTrue, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnFalse, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnNil, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnTopFromMethod, 0, needsFrameIfInBlock, -1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnTopFromBlock, 0, needsFrameNever, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { extendedPushBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { extendedStoreBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 0, 0 }, - { extendedStoreAndPopBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 0, 0 }, - { genExtendedSendBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { doubleExtendedDoAnythingBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genExtendedSuperBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0 }, - { genSecondExtendedSendBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genPopStackBytecode, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { duplicateTopBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushActiveContextBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushNewArrayBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genCallPrimitiveBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushClosureCopyCopiedValuesBytecode, v3BlockCodeSize, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongUnconditionalBackwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongUnconditionalBackwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongUnconditionalBackwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongUnconditionalBackwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongUnconditionalForwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genLongUnconditionalForwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genLongUnconditionalForwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genLongUnconditionalForwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genLongJumpIfTrue, v3LongForwardBranchDistance, 0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongJumpIfTrue, v3LongForwardBranchDistance, 0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongJumpIfTrue, v3LongForwardBranchDistance, 0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongJumpIfTrue, v3LongForwardBranchDistance, 0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongJumpIfFalse, v3LongForwardBranchDistance, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongJumpIfFalse, v3LongForwardBranchDistance, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongJumpIfFalse, v3LongForwardBranchDistance, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongJumpIfFalse, v3LongForwardBranchDistance, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, AddRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, SubRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpLess, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpGreater, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpLessOrEqual, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpGreaterOrEqual, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpZero, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpNonZero, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, AndRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, OrRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorEqualsEquals, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorClass, 0, needsFrameIfStackGreaterThanOne, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorNotEqualsEquals, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariable16CasesBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushReceiverBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantTrueBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantFalseBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantNilBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantZeroBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantOneBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtPushPseudoVariable, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { duplicateTopBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genReturnReceiver, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnTrue, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnFalse, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnNil, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnTopFromMethod, 0, needsFrameIfInBlock, -1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnNilFromBlock, 0, needsFrameNever, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, - { genReturnTopFromBlock, 0, needsFrameNever, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, - { genExtNopBytecode, 0, needsFrameNever, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, AddRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, SubRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpLess, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpGreater, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpLessOrEqual, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpGreaterOrEqual, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpZero, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpNonZero, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, AndRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, OrRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorEqualsEquals, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorClass, 0, needsFrameIfStackGreaterThanOne, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorNotEqualsEquals, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfTrue, v3ShortForwardBranchDistance, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPopStackBytecode, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genUnconditionalTrapBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { extABytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { extBBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genExtPushReceiverVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genExtPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtPushLiteralBytecode, 0, needsFrameNever, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genLongPushTemporaryVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushNewArrayBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtPushIntegerBytecode, 0, needsFrameNever, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtPushCharacterBytecode, 0, needsFrameNever, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtSendBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genExtSendSuperBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genCallMappedInlinedPrimitive, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 }, - { genExtUnconditionalJump, v4LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genExtJumpIfTrue, v4LongBranchDistance, 0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genExtJumpIfFalse, v4LongBranchDistance, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genExtStoreAndPopReceiverVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 0, 0 }, - { genExtStoreAndPopLiteralVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 0, 0, 0 }, - { genLongStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtStoreReceiverVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 0, 0 }, - { genExtStoreLiteralVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 0, 0, 0 }, - { genLongStoreTemporaryVariableBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genCallPrimitiveBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, - { genExtPushFullClosureBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genExtPushClosureBytecode, v4BlockCodeSize, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genPushRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 } -}; -static sqInt guardPageSize; -static sqInt hasMovableLiteral; -static sqInt hasYoungReferent; -static sqInt inBlock; -static sqInt initialPC; -static sqInt introspectionData; -static sqInt introspectionDataIndex; -static int labelCounter; -static sqInt lastSend; -static usqInt limitAddress; -static sqInt maxLitIndex; -static sqInt methodAbortTrampolines[4]; -static sqInt methodBytesFreedSinceLastCompaction; -static sqInt methodCount; -static sqInt methodHeader; -static sqInt methodObj; -static sqInt methodOrBlockNumArgs; -static sqInt methodOrBlockNumTemps; -static usqIntptr_t minValidCallAddress; -static usqInt mzFreeStart; -static sqInt needsFrame; -static AbstractInstruction * noCheckEntry; -static sqInt numAbstractOpcodes; -static sqInt numExtB; -static usqInt objectReferencesInRuntime[NumObjRefsInRuntime+1]; -static sqInt opcodeIndex; -static CogMethod *openPICList = 0; -static sqInt openPICSize; -static sqInt ordinarySendTrampolines[NumSendTrampolines]; -static sqInt picAbortTrampolines[4]; -static AbstractInstruction * picInterpretAbort; -static sqInt picMissTrampolines[4]; -static AbstractInstruction * picMNUAbort; -static BytecodeDescriptor * prevBCDescriptor; -static PrimitiveDescriptor primitiveGeneratorTable[MaxCompiledPrimitiveIndex+1] = { - { 0, -1 }, - { genPrimitiveAdd, 1 }, - { genPrimitiveSubtract, 1 }, - { genPrimitiveLessThan, 1 }, - { genPrimitiveGreaterThan, 1 }, - { genPrimitiveLessOrEqual, 1 }, - { genPrimitiveGreaterOrEqual, 1 }, - { genPrimitiveEqual, 1 }, - { genPrimitiveNotEqual, 1 }, - { genPrimitiveMultiply, 1 }, - { genPrimitiveDivide, 1 }, - { genPrimitiveMod, 1 }, - { genPrimitiveDiv, 1 }, - { genPrimitiveQuo, 1 }, - { genPrimitiveBitAnd, 1 }, - { genPrimitiveBitOr, 1 }, - { genPrimitiveBitXor, 1 }, - { genPrimitiveBitShift, 1 }, - { genPrimitiveMakePoint, 1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveAt, 1 }, - { genPrimitiveAtPut, 2 }, - { genPrimitiveSize, 0 }, - { genPrimitiveStringAt, 1 }, - { genPrimitiveStringAtPut, 2 }, - { genFastPrimFail, -1 }, - { genFastPrimFail, -1 }, - { genFastPrimFail, -1 }, - { genPrimitiveObjectAt, 1 }, - { 0, -1 }, - { genPrimitiveNew, 0 }, - { genPrimitiveNewWithArg, 1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveIdentityHash, 0 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveNewMethod, 2 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitivePerform, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveStringReplace, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveIdentical, 1 }, - { genPrimitiveClass, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveShallowCopy, 0 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveStringCompareWith, 1 }, - { genPrimitiveHashMultiply, 0 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveIntegerAt, 1 }, - { genPrimitiveIntegerAtPut, 2 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveNotIdentical, 1 }, - { genPrimitiveAsCharacter, -1 }, - { genPrimitiveImmediateAsInteger, 0 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveIdentityHash, 0 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genFastPrimFail, -1 }, - { genFastPrimFail, -1 }, - { 0, -1 }, - { genPrimitiveClosureValue, 0 }, - { genPrimitiveClosureValue, 1 }, - { genPrimitiveClosureValue, 2 }, - { genPrimitiveClosureValue, 3 }, - { genPrimitiveClosureValue, 4 }, - { 0, -1 }, - { genPrimitiveFullClosureValue, -1 }, - { 0, -1 }, - { genPrimitiveFullClosureValue, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveClosureValue, 0 }, - { genPrimitiveClosureValue, 1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveHighBit, 0 } -}; -static sqInt primitiveIndex; -static sqInt processorLock; -static sqInt receiverTags; -static sqInt regArgsHaveBeenPushed; -static sqInt runtimeObjectRefIndex; -static AbstractInstruction * sendMiss; -static sqInt simNativeStackPtr; -static sqInt simSpillBase; -static SimStackEntry simStack[70]; -static sqInt simStackPtr; -static AbstractInstruction * stackCheckLabel; -static AbstractInstruction * stackOverflowCall; -static sqInt superSendTrampolines[NumSendTrampolines]; -static sqInt tempOop; -static char *trampolineAddresses[NumTrampolines*2]; -static sqInt trampolineTableIndex; -static sqInt uncheckedEntryAlignment; -static usqInt unpairedMethodList; -static sqInt useTwoPaths; -static sqInt varBaseAddress; -static usqInt youngReferrers; -static AbstractInstruction aMethodLabel; -static AbstractInstruction * const backEnd = &aMethodLabel; -#if DUAL_MAPPED_CODE_ZONE -static void (*ceFlushDCache)(usqIntptr_t from, usqIntptr_t to); -#endif -#if IMMUTABILITY -static sqInt ceStoreTrampolines[5];; -#endif -#if DUAL_MAPPED_CODE_ZONE -static sqInt codeToDataDelta; -#else -# define codeToDataDelta 0 -#endif -static AbstractInstruction * const methodLabel = &aMethodLabel; -sqInt blockNoContextSwitchOffset; -sqInt breakPC; -sqInt cbEntryOffset; -sqInt cbNoSwitchEntryOffset; -sqInt ceBaseFrameReturnTrampoline; -sqInt ceCannotResumeTrampoline; -sqInt ceCheckForInterruptTrampoline; -sqInt ceReturnToInterpreterTrampoline; -sqInt cFramePointerInUse; -sqInt cmEntryOffset; -sqInt cmNoCheckEntryOffset; -usqInt methodZoneBase; -sqInt missOffset; -int traceFlags = 8 /* prim trace log on by default */; -sqInt traceStores; -void (*ceCall0ArgsPIC)(void); -void (*ceCall1ArgsPIC)(void); -void (*ceCall2ArgsPIC)(void); -void (*ceCallCogCodePopReceiverAndClassRegs)(void); -void (*ceCallCogCodePopReceiverArg0Regs)(void); -void (*ceCallCogCodePopReceiverArg1Arg0Regs)(void); -void (*ceCallCogCodePopReceiverReg)(void); -void (*ceCaptureCStackPointers)(void); -void (*ceEnterCogCodePopReceiverReg)(void); -usqIntptr_t (*ceGetFP)(void); -usqIntptr_t (*ceGetSP)(void); -void (*ceInvokeInterpret)(void); -#if COGMTVM -usqIntptr_t (*ceTryLockVMOwner)(usqIntptr_t); -#endif -void (*realCECallCogCodePopReceiverAndClassRegs)(void); -void (*realCECallCogCodePopReceiverArg0Regs)(void); -void (*realCECallCogCodePopReceiverArg1Arg0Regs)(void); -void (*realCECallCogCodePopReceiverReg)(void); -void (*realCEEnterCogCodePopReceiverReg)(void); - - -/*** Macros ***/ -#define inlineCacheValueForSelectorin(backEnd,selector,aCogMethod) (selector) -#define roundUpToMethodAlignment(ignored,numBytes) ((numBytes) + 7 & -8) -#define cPICNumCases stackCheckOffset -#define cPICNumCasesHack hack hack hack i.e. the getter macro does all the work -#define abstractInstructionAt(index) (&abstractOpcodes[index]) -#define addressIsInInstructions(address) (!((usqInt)(address) & (BytesPerWord-1)) \ - && (address) >= &abstractOpcodes[0] \ - && (address) < &abstractOpcodes[opcodeIndex]) -#define allocateBlockStarts(numBlocks) do { \ - blockStarts = (numBlocks) ? alloca(sizeof(BlockStart) * (numBlocks)) : 0; \ -} while (0) -#define assertValidDualZoneReadAddress(address) 0 -#define assertValidDualZoneWriteAddress(address) 0 -#define backEnd() backEnd -#define blockAlignment() 8 -#define blockStartAt(index) (&blockStarts[index]) -#define breakOnImplicitReceiver() (traceFlags & 64) -#define ceBaseFrameReturnPC() ceBaseFrameReturnTrampoline -#define ceCannotResumePC() ((usqInt)ceCannotResumeTrampoline) -#define ceCheckForInterruptTrampoline() ceCheckForInterruptTrampoline -#define ceReturnToInterpreterPC() ((usqInt)ceReturnToInterpreterTrampoline) -#define codeByteAtput(address,value) byteAtput((address) + codeToDataDelta, value) -#define codeLong32Atput(address,value) long32Atput((address) + codeToDataDelta, value) -#define codeLong64Atput(address,value) long64Atput((address) + codeToDataDelta, value) -#define codeLongAtput(address,value) longAtput((address) + codeToDataDelta, value) -#define codeMemcpy(dest,src,bytes) memcpy(dest,src,bytes) -#define codeMemmove(dest,src,bytes) memmove((char *)(dest)+codeToDataDelta,src,bytes) -#define cr() putchar('\n') -#define entryOffset() cmEntryOffset -#define generatorAt(index) (&generatorTable[index]) -#define getCodeToDataDelta() codeToDataDelta -#define getIsObjectReference() 2 -#define halt() warning("halt") -#define haltmsg(msg) warning("halt: " msg) -#define interpretOffset() missOffset -#define maxCogCodeSize() (16*1024*1024) -#define maybeBreakGeneratingFromto(address,end) 0 -#define maybeBreakGeneratingInstructionWithIndex(i) 0 -#define maybeHaltIfDebugPC() 0 -#define methodLabel() methodLabel -#define methodZoneBase() methodZoneBase -#define minCallAddress() minValidCallAddress -#define minCogMethodAddress() methodZoneBase -#define noCheckEntryOffset() cmNoCheckEntryOffset -#define noContextSwitchBlockEntryOffset() blockNoContextSwitchOffset -#define notYetImplemented() warning("not yet implemented") -#define null 0 -#define printNum(n) printf("%" PRIdSQINT, (sqInt) (n)) -#define printOnTrace() (traceFlags & 1) -#define print(aString) printf("%s", aString) -#define recordBlockTrace() (traceFlags & 4) -#define recordEventTrace() (traceFlags & 16) -#define recordFastCCallPrimTrace() (traceFlags & 512) -#define recordOverflowTrace() (traceFlags & 32) -#define recordPrimTrace() (traceFlags & 8) -#define recordSendTrace() (traceFlags & 2) -#define reportError(n) warning("compilation error") -#define setHasMovableLiteral(b) (hasMovableLiteral = (b)) -#define setHasYoungReferent(b) (hasYoungReferent = (b)) -#define tryLockVMOwnerTo(value) ceTryLockVMOwner(value) -#define varBaseAddress() varBaseAddress -#define nextOpenPIC methodObject -#define nextOpenPICHack hack hack hack i.e. the getter macro does all the work -#define freeStart() mzFreeStart -#define limitZony() ((CogMethod *)mzFreeStart) -#define methodBytesFreedSinceLastCompaction() methodBytesFreedSinceLastCompaction -#define youngReferrers() youngReferrers -#define flushDCacheFromto(me,startAddress,endAddress) 0 -#define flushICacheFromto(me,startAddress,endAddress) cacheflush((char*) startAddress, endAddress - startAddress, ICACHE) -#define maybeConstant(sse) ((sse)->constant) -#define fullBlockEntryOffset() cbEntryOffset -#define fullBlockNoContextSwitchEntryOffset() cbNoSwitchEntryOffset -#define fixupAtIndex(index) (&fixups[index]) -#define simNativeStackAt(index) (simNativeStack + (index)) -#define simSelf() simStack -#define simStackAt(index) (simStack + (index)) -#define traceDescriptor(ign) 0 -#define traceFixupmerge(igu,ana) 0 -#define traceMerge(ign) 0 -#define traceSimStack() 0 -#define traceSpill(ign) 0 -#define allocatype(numElements, elementType) alloca((numElements)*sizeof(elementType)) -#define numElementsIn(anArray) (sizeof(anArray)/sizeof(anArray[0])) -#define oopisGreaterThanOrEqualTo(anOop,otherOop) ((usqInt)(anOop) >= (usqInt)(otherOop)) -#define oopisGreaterThanOrEqualToandLessThanOrEqualTo(anOop,baseOop,limitOop) ((usqInt)(anOop) >= (usqInt)(baseOop) && (usqInt)(anOop) <= (usqInt)(limitOop)) -#define oopisGreaterThanOrEqualToandLessThan(anOop,baseOop,limitOop) ((usqInt)(anOop) >= (usqInt)(baseOop) && (usqInt)(anOop) < (usqInt)(limitOop)) -#define oopisGreaterThan(anOop,otherOop) ((usqInt)(anOop) > (usqInt)(otherOop)) -#define oopisGreaterThanandLessThan(anOop,baseOop,limitOop) ((usqInt)(anOop) > (usqInt)(baseOop) && (usqInt)(anOop) < (usqInt)(limitOop)) -#define oopisLessThanOrEqualTo(anOop,otherOop) ((usqInt)(anOop) <= (usqInt)(otherOop)) -#define oopisLessThan(anOop,otherOop) ((usqInt)(anOop) < (usqInt)(otherOop)) - - - /* CogAbstractInstruction>>#addDependent: */ -static AbstractInstruction * NoDbgRegParms -addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *anInstruction) -{ - if (!(((self_in_addDependent->dependent)) == null)) { - (anInstruction->dependent = (self_in_addDependent->dependent)); - } - return ((self_in_addDependent->dependent) = anInstruction); -} - - -/* Answer an unused abstract register in the liveRegMask. - Subclasses with more registers can override to answer them. */ - - /* CogAbstractInstruction>>#availableFloatRegisterOrNoneFor: */ -static sqInt NoDbgRegParms -availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask) -{ - if (!(((liveRegsMask & (1U << DPFPReg0)) != 0))) { - return DPFPReg0; - } - if (!(((liveRegsMask & (1U << DPFPReg1)) != 0))) { - return DPFPReg1; - } - if (!(((liveRegsMask & (1U << DPFPReg2)) != 0))) { - return DPFPReg2; - } - if (!(((liveRegsMask & (1U << DPFPReg3)) != 0))) { - return DPFPReg3; - } - if (!(((liveRegsMask & (1U << DPFPReg4)) != 0))) { - return DPFPReg4; - } - if (!(((liveRegsMask & (1U << DPFPReg5)) != 0))) { - return DPFPReg5; - } - if (!(((liveRegsMask & (1U << DPFPReg6)) != 0))) { - return DPFPReg6; - } - if (!(((liveRegsMask & (1U << DPFPReg7)) != 0))) { - return DPFPReg7; - } - return NoReg; -} - - -/* Answer an unused abstract register in the liveRegMask. - Subclasses with more registers can override to answer them. - N.B. Do /not/ allocate TempReg. */ - - /* CogAbstractInstruction>>#availableRegisterOrNoneFor: */ -static sqInt NoDbgRegParms -availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask) -{ - if (!(((liveRegsMask & (1U << Arg1Reg)) != 0))) { - return Arg1Reg; - } - if (!(((liveRegsMask & (1U << Arg0Reg)) != 0))) { - return Arg0Reg; - } - if (!(((liveRegsMask & (1U << SendNumArgsReg)) != 0))) { - return SendNumArgsReg; - } - if (!(((liveRegsMask & (1U << ClassReg)) != 0))) { - return ClassReg; - } - if (!(((liveRegsMask & (1U << ReceiverResultReg)) != 0))) { - return ReceiverResultReg; - } - return NoReg; -} - - -/* For out-of-line literal support, clone a literal from a literal. */ - - /* CogAbstractInstruction>>#cloneLiteralFrom: */ -static void NoDbgRegParms -cloneLiteralFrom(AbstractInstruction * self_in_cloneLiteralFrom, AbstractInstruction *existingLiteral) -{ - assert((((existingLiteral->opcode)) == Literal) - && ((((self_in_cloneLiteralFrom->dependent)) == null) - && (((self_in_cloneLiteralFrom->address)) == null))); - (self_in_cloneLiteralFrom->opcode) = Literal; - (self_in_cloneLiteralFrom->annotation) = (existingLiteral->annotation); - ((self_in_cloneLiteralFrom->operands))[0] = (((existingLiteral->operands))[0]); - ((self_in_cloneLiteralFrom->operands))[1] = (((existingLiteral->operands))[1]); - ((self_in_cloneLiteralFrom->operands))[2] = (((existingLiteral->operands))[2]); -} - - -/* Load the stack pointer register with that of the C stack, effecting - a switch to the C stack. Used when machine code calls into the - CoInterpreter run-time (e.g. to invoke interpreter primitives). */ - - /* CogAbstractInstruction>>#genLoadCStackPointer */ -static sqInt NoDbgRegParms -genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer) -{ - AbstractInstruction *anInstruction; - - /* begin checkLiteral:forInstruction: */ - cStackPointerAddress(); - anInstruction = genoperandoperand(MoveAwR, cStackPointerAddress(), NativeSPReg); - return 0; -} - - -/* Load the frame and stack pointer registers with those of the C stack, - effecting a switch to the C stack. Used when machine code calls into - the CoInterpreter run-time (e.g. to invoke interpreter primitives). - N.B. CoInterpreter stack layout dictates that the stack pointer should be - loaded first. - The stack zone is allocated on the C stack before the interpreter runs and - hence before CStackPointer and CFramePointer are captured. So when running - in machine - code the native stack pointer and frame pointer appear to be on a colder - part of the - stack to CStackPointer and CFramePointer. When CStackPointerhas been set - and the frame pointer is still in machine code the current frame looks - like it has lots of - stack. If the frame pointer was set to CFramePointer before hand then it - would be beyond the stack pointer for that one instruction. */ - - /* CogAbstractInstruction>>#genLoadCStackPointers */ -static sqInt NoDbgRegParms -genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkLiteral:forInstruction: */ - cStackPointerAddress(); - anInstruction = genoperandoperand(MoveAwR, cStackPointerAddress(), NativeSPReg); - /* begin checkLiteral:forInstruction: */ - cFramePointerAddress(); - anInstruction1 = genoperandoperand(MoveAwR, cFramePointerAddress(), FPReg); - return 0; -} - - -/* Switch back to the Smalltalk stack. Assign SPReg first - because typically it is used immediately afterwards. */ - - /* CogAbstractInstruction>>#genLoadStackPointers */ -static sqInt NoDbgRegParms -genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkLiteral:forInstruction: */ - stackPointerAddress(); - anInstruction = genoperandoperand(MoveAwR, stackPointerAddress(), SPReg); - /* begin checkLiteral:forInstruction: */ - framePointerAddress(); - anInstruction1 = genoperandoperand(MoveAwR, framePointerAddress(), FPReg); - return 0; -} - - -/* Switch back to the Smalltalk stack where there may be a C return address - on top of stack below - the last primitive argument. Assign SPReg first because typically it is - used immediately afterwards. - */ - - /* CogAbstractInstruction>>#genLoadStackPointersForFastPrimCall: */ -static sqInt NoDbgRegParms -genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg) -{ - genLoadStackPointers(self_in_genLoadStackPointersForFastPrimCall); - return 0; -} - - -/* Save the frame and stack pointer registers to the framePointer - and stackPointer variables. Used to save the machine code frame - for use by the run-time when calling into the CoInterpreter run-time. */ - - /* CogAbstractInstruction>>#genSaveStackPointers */ -static sqInt NoDbgRegParms -genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkLiteral:forInstruction: */ - framePointerAddress(); - anInstruction = genoperandoperand(MoveRAw, FPReg, framePointerAddress()); - /* begin checkLiteral:forInstruction: */ - stackPointerAddress(); - anInstruction1 = genoperandoperand(MoveRAw, SPReg, stackPointerAddress()); - return 0; -} - - -/* Generic register swap code. Subclasses for processors that have a true - exchange operation will override to use it. */ - - /* CogAbstractInstruction>>#genSwapR:R:Scratch: */ -static AbstractInstruction * NoDbgRegParms -genSwapRRScratch(AbstractInstruction * self_in_genSwapRRScratch, sqInt regA, sqInt regB, sqInt regTmp) -{ - AbstractInstruction *first; - - first = genoperandoperand(MoveRR, regA, regTmp); - genoperandoperand(MoveRR, regB, regA); - genoperandoperand(MoveRR, TempReg, regB); - return first; -} - - /* CogAbstractInstruction>>#genWriteCResultIntoReg: */ -static void NoDbgRegParms -genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister) -{ - if ((abstractRegister != NoReg) - && (abstractRegister != ABIResultReg)) { - genoperandoperand(MoveRR, ABIResultReg, abstractRegister); - } -} - - -/* For out-of-line literal support, initialize a sharable literal. */ - - /* CogAbstractInstruction>>#initializeSharableLiteral: */ -static void NoDbgRegParms -initializeSharableLiteral(AbstractInstruction * self_in_initializeSharableLiteral, sqInt literal) -{ - (self_in_initializeSharableLiteral->opcode) = Literal; - - /* separate := nil for Slang */ - (self_in_initializeSharableLiteral->annotation) = null; - (self_in_initializeSharableLiteral->address) = null; - (self_in_initializeSharableLiteral->dependent) = null; - ((self_in_initializeSharableLiteral->operands))[0] = literal; - ((self_in_initializeSharableLiteral->operands))[1] = (1 + (((sqInt)((usqInt)(BytesPerOop) << 1)))); - ((self_in_initializeSharableLiteral->operands))[2] = -1; -} - - -/* For out-of-line literal support, initialize an unsharable literal. */ - - /* CogAbstractInstruction>>#initializeUniqueLiteral: */ -static void NoDbgRegParms -initializeUniqueLiteral(AbstractInstruction * self_in_initializeUniqueLiteral, sqInt literal) -{ - (self_in_initializeUniqueLiteral->opcode) = Literal; - - /* separate := nil for Slang */ - (self_in_initializeUniqueLiteral->annotation) = null; - (self_in_initializeUniqueLiteral->address) = null; - (self_in_initializeUniqueLiteral->dependent) = null; - ((self_in_initializeUniqueLiteral->operands))[0] = literal; - ((self_in_initializeUniqueLiteral->operands))[1] = (0 + (((sqInt)((usqInt)(BytesPerOop) << 1)))); - ((self_in_initializeUniqueLiteral->operands))[2] = -1; -} - - -/* Answer if an address can be accessed using the offset in a MoveMw:r:R: or - similar instruction. - We assume this is true for 32-bit processors and expect 64-bit processors - to answer false - for values in the interpreter or the object memory. */ - - /* CogAbstractInstruction>>#isWithinMwOffsetRange: */ -static sqInt NoDbgRegParms -isWithinMwOffsetRange(AbstractInstruction * self_in_isWithinMwOffsetRange, sqInt anAddress) -{ - return 1; -} - - -/* Set the target of a jump instruction. These all have the target in the - first operand. */ - - /* CogAbstractInstruction>>#jmpTarget: */ -static AbstractInstruction * NoDbgRegParms -jmpTarget(AbstractInstruction * self_in_jmpTarget, AbstractInstruction *anAbstractInstruction) -{ - ((self_in_jmpTarget->operands))[0] = (((usqInt)anAbstractInstruction)); - return anAbstractInstruction; -} - - /* CogAbstractInstruction>>#resolveJumpTarget */ -static void NoDbgRegParms -resolveJumpTarget(AbstractInstruction * self_in_resolveJumpTarget) -{ - BytecodeFixup *fixup; - - assert(isJump(self_in_resolveJumpTarget)); - fixup = ((BytecodeFixup *) (((self_in_resolveJumpTarget->operands))[0])); - if (addressIsInFixups(fixup)) { - assert(addressIsInInstructions((fixup->targetInstruction))); - jmpTarget(self_in_resolveJumpTarget, (fixup->targetInstruction)); - } -} - - -/* Rewrite a CallFull instruction to call a different target. This variant is - used to rewrite cached primitive calls. - Answer the extent of the code change which is used to compute the range of - the icache to flush. - This defaults to rewriteCallAt:target:; processors that differentiate - between Call and CallFull will override. */ - - /* CogAbstractInstruction>>#rewriteCallFullAt:target: */ -static sqInt NoDbgRegParms -rewriteCallFullAttarget(AbstractInstruction * self_in_rewriteCallFullAttarget, sqInt callSiteReturnAddress, sqInt callTargetAddress) -{ - return rewriteCallAttarget(self_in_rewriteCallFullAttarget, callSiteReturnAddress, callTargetAddress); -} - - -/* Rewrite a JumpFull instruction to jump to a different target. This variant - is used to rewrite cached primitive calls. - Answer the extent of the code change which is used to compute the range of - the icache to flush. - This defaults to rewriteJumpLongAt:target:; processors that differentiate - between Jump and JumpFull will override. */ - - /* CogAbstractInstruction>>#rewriteJumpFullAt:target: */ -static sqInt NoDbgRegParms -rewriteJumpFullAttarget(AbstractInstruction * self_in_rewriteJumpFullAttarget, sqInt callSiteReturnAddress, sqInt callTargetAddress) -{ - return rewriteJumpLongAttarget(self_in_rewriteJumpFullAttarget, callSiteReturnAddress, callTargetAddress); -} - - /* CogBlockMethod>>#cmHomeMethod */ -static CogMethod * NoDbgRegParms -cmHomeMethod(CogBlockMethod * self_in_cmHomeMethod) -{ - return ((self_in_cmHomeMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? ((CogMethod *) self_in_cmHomeMethod) - : ((CogMethod *) ((((usqInt)self_in_cmHomeMethod)) - ((self_in_cmHomeMethod->homeOffset))))); -} - - /* CogBytecodeDescriptor>>#isBranch */ -static sqInt NoDbgRegParms -isBranch(BytecodeDescriptor * self_in_isBranch) -{ - return (((self_in_isBranch->spanFunction)) != null) - && (!((self_in_isBranch->isBlockCreation))); -} - - /* Cogit>>#AddCq:R: */ -static AbstractInstruction * NoDbgRegParms -gAddCqR(sqInt quickConstant, sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, quickConstant, reg); - return anInstruction; -} - - -/* N.B. if the condition codes don't require setting and three address - arithmetic is unavailable, then LoadEffectiveAddressMw:r:R: can be used - instead. - */ - - /* Cogit>>#AddCq:R:R: */ -static AbstractInstruction * NoDbgRegParms -gAddCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction * first; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(AddCqRR, quickConstant, srcReg, destReg); - return anInstruction2; - if (srcReg == destReg) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, quickConstant, destReg); - return anInstruction; - } - first = genoperandoperand(MoveRR, srcReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AddCqR, quickConstant, destReg); - return first; -} - - /* Cogit>>#AndCq:R: */ -static AbstractInstruction * NoDbgRegParms -gAndCqR(sqInt quickConstant, sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, quickConstant, reg); - return anInstruction; -} - - /* Cogit>>#AndCq:R:R: */ -static AbstractInstruction * NoDbgRegParms -gAndCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction * first; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(AndCqRR, quickConstant, srcReg, destReg); - return anInstruction2; - if (srcReg == destReg) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, quickConstant, destReg); - return anInstruction; - } - first = genoperandoperand(MoveRR, srcReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, quickConstant, destReg); - return first; -} - - -/* destReg := (signed)srcReg >> quickConstant */ - - /* Cogit>>#ArithmeticShiftRightCq:R:R: */ -static AbstractInstruction * NoDbgRegParms -gArithmeticShiftRightCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) -{ - AbstractInstruction * first; - - return genoperandoperandoperand(ArithmeticShiftRightCqRR, quickConstant, srcReg, destReg); - first = genoperandoperand(MoveRR, srcReg, destReg); - genoperandoperand(ArithmeticShiftRightCqR, quickConstant, destReg); - return first; -} - - /* Cogit>>#abortOffset */ -sqInt -abortOffset(void) -{ - return missOffset; -} - - /* Cogit>>#addCleanBlockStarts */ -static void -addCleanBlockStarts(void) -{ - sqInt i; - sqInt iLimiT; - sqInt lit; - sqInt startPCOrNil; - - for (i = 1, iLimiT = (literalCountOf(methodObj)); i <= iLimiT; i += 1) { - lit = fetchPointerofObject(i, methodObj); - startPCOrNil = startPCOrNilOfLiteralin(lit, methodObj); - if (!(startPCOrNil == null)) { - maxLitIndex = ((maxLitIndex < i) ? i : maxLitIndex); - addBlockStartAtnumArgsnumCopiedspan(startPCOrNil - 1, argumentCountOfClosure(lit), copiedValueCountOfClosure(lit), spanForCleanBlockStartingAt(startPCOrNil - 1)); - } - } -} - - -/* Perform an integrity/leak check using the heapMap. - Set a bit at each cog method's header. */ - - /* Cogit>>#addCogMethodsToHeapMap */ -void -addCogMethodsToHeapMap(void) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - heapMapAtWordPut(cogMethod, 1); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* Cogit>>#addressIsInCurrentCompilation: */ -static sqInt NoDbgRegParms -addressIsInCurrentCompilation(sqInt address) -{ - return ((((usqInt)address)) >= ((methodLabel->address))) - && ((((usqInt)address)) < ((((youngReferrers()) < (((methodLabel->address)) + MaxMethodSize)) ? (youngReferrers()) : (((methodLabel->address)) + MaxMethodSize)))); -} - - /* Cogit>>#addressIsInFixups: */ -static sqInt NoDbgRegParms -addressIsInFixups(BytecodeFixup *address) -{ - return (BytecodeFixup *)address >= fixups && (BytecodeFixup *)address < (fixups + numAbstractOpcodes); -} - - -/* calculate the end of the n'th case statement - which is complicated - because we have case 1 right at the top of our CPIC and then build up from - the last one. Yes I know this sounds strange, but trust me - I'm an - Engineer, we do things backwards all the emit - */ - - /* Cogit>>#addressOfEndOfCase:inCPIC: */ -static sqInt NoDbgRegParms -addressOfEndOfCaseinCPIC(sqInt n, CogMethod *cPIC) -{ - assert((n >= 1) - && (n <= MaxCPICCases)); - return (n == 1 - ? (((sqInt)cPIC)) + firstCPICCaseOffset - : ((((sqInt)cPIC)) + firstCPICCaseOffset) + (((MaxCPICCases + 1) - n) * cPICCaseSize)); -} - - -/* Align methodZoneBase to that for the start of a method. */ - - /* Cogit>>#alignMethodZoneBase */ -static void -alignMethodZoneBase(void) -{ - usqInt oldBase; - - oldBase = methodZoneBase; - methodZoneBase = roundUpToMethodAlignment(backEnd(), methodZoneBase); - stopsFromto(backEnd, oldBase, methodZoneBase - 1); -} - - /* Cogit>>#alignUptoRoutineBoundary: */ -static sqInt NoDbgRegParms -alignUptoRoutineBoundary(sqInt anAddress) -{ - return (((anAddress + 7) | 7) - 7); -} - - -/* Check that all methods have valid selectors, and that all linked sends are - to valid targets and have valid cache tags - */ - - /* Cogit>>#allMachineCodeObjectReferencesValid */ -static sqInt -allMachineCodeObjectReferencesValid(void) -{ - CogMethod *cogMethod; - sqInt ok; - - ok = 1; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - if (!(asserta(checkValidOopReference((cogMethod->selector))))) { - ok = 0; - } - if (!(asserta((cogMethodDoesntLookKosher(cogMethod)) == 0))) { - ok = 0; - } - } - if ((((cogMethod->cmType)) == CMMethod) - || (((cogMethod->cmType)) == CMOpenPIC)) { - if (!(asserta((mapForperformUntilarg(cogMethod, checkIfValidOopRefAndTargetpccogMethod, cogMethod)) == 0))) { - ok = 0; - } - } - if (((cogMethod->cmType)) == CMClosedPIC) { - if (!(asserta(noTargetsFreeInClosedPIC(cogMethod)))) { - ok = 0; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return ok; -} - - /* Cogit>>#allMethodsHaveCorrectHeader */ -static sqInt -allMethodsHaveCorrectHeader(void) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - if (!(((cogMethod->objectHeader)) == (nullHeaderForMachineCodeMethod()))) { - return 0; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return 1; -} - - /* Cogit>>#annotateAbsolutePCRef: */ -static AbstractInstruction * NoDbgRegParms -annotateAbsolutePCRef(AbstractInstruction *abstractInstruction) -{ - (abstractInstruction->annotation = IsAbsPCReference); - return abstractInstruction; -} - - /* Cogit>>#annotateBytecode: */ -static AbstractInstruction * NoDbgRegParms -annotateBytecode(AbstractInstruction *abstractInstruction) -{ - (abstractInstruction->annotation = HasBytecodePC); - return abstractInstruction; -} - - /* Cogit>>#annotate:objRef: */ -static AbstractInstruction * NoDbgRegParms -annotateobjRef(AbstractInstruction *abstractInstruction, sqInt anOop) -{ - if (shouldAnnotateObjectReference(anOop)) { - setHasMovableLiteral(1); - if (isYoungObject(anOop)) { - setHasYoungReferent(1); - } - (abstractInstruction->annotation = IsObjectReference); - } - return abstractInstruction; -} - - /* Cogit>>#assertSaneJumpTarget: */ -static void NoDbgRegParms -assertSaneJumpTarget(AbstractInstruction *jumpTarget) -{ - assert((closedPICSize == null) - || ((openPICSize == null) - || ((addressIsInInstructions(jumpTarget)) - || ((((((usqInt)jumpTarget)) >= codeBase) && ((((usqInt)jumpTarget)) <= ((((sqInt)(limitZony()))) + (((closedPICSize < openPICSize) ? openPICSize : closedPICSize))))))))); -} - - -/* {self firstInvalidDualZoneAddress. self firstInvalidDualZoneAddress + - codeToDataDelta } - */ -/* {self firstInvalidDualZoneAddress hex. (self firstInvalidDualZoneAddress + - codeToDataDelta) hex } - */ -/* {(objectMemory longAt: self firstInvalidDualZoneAddress) hex. - (objectMemory longAt: self firstInvalidDualZoneAddress + codeToDataDelta) - hex } - */ -/* self armDisassembleDualZoneAnomalies */ -/* self armPrintDualZoneAnomalies */ - - /* Cogit>>#assertValidDualZone */ -static void -assertValidDualZone(void) -{ -} - - -/* Answer an unused abstract register in the registerMask, or NoReg if none. */ - - /* Cogit>>#availableRegisterOrNoneIn: */ -static sqInt NoDbgRegParms -availableRegisterOrNoneIn(sqInt liveRegsMask) -{ - sqInt reg; - - if (liveRegsMask != 0) { - for (reg = 0; reg <= 0x1F; reg += 1) { - if (((liveRegsMask & (1U << reg)) != 0)) { - return reg; - } - } - } - return NoReg; -} - - -/* Evaluate binaryFunction with the block start mcpc and supplied arg for - each entry in the block dispatch. If the function answers non-zero answer - the value - it answered. Used to update back-references to the home method in - compaction. */ - - /* Cogit>>#blockDispatchTargetsFor:perform:arg: */ -static sqInt NoDbgRegParms -blockDispatchTargetsForperformarg(CogMethod *cogMethod, usqInt (*binaryFunction)(sqInt mcpc, sqInt arg), sqInt arg) -{ - sqInt blockEntry; - usqInt end; - sqInt pc; - sqInt result; - usqInt targetpc; - - if (((cogMethod->blockEntryOffset)) == 0) { - return null; - } - blockEntry = ((cogMethod->blockEntryOffset)) + (((sqInt)cogMethod)); - pc = blockEntry; - end = (mapEndFor(cogMethod)) - 1; - while (pc < end) { - if (isJumpAt(backEnd, pc)) { - targetpc = jumpTargetPCAt(backEnd, pc); - if (targetpc < blockEntry) { - result = binaryFunction(targetpc, arg); - if (result != 0) { - return result; - } - } - } - pc += 4 /* instructionSizeAt: */; - } - return 0; -} - - -/* Answer the zero-relative bytecode pc matching the machine code pc argument - in cogMethod, given the start of the bytecodes for cogMethod's block or - method object. */ - - /* Cogit>>#bytecodePCFor:startBcpc:in: */ -sqInt -bytecodePCForstartBcpcin(sqInt mcpc, sqInt startbcpc, CogBlockMethod *cogMethod) -{ - sqInt aMethodHeader; - sqInt aMethodHeader1; - sqInt aMethodObj; - sqInt annotation; - sqInt bcpc; - sqInt bsOffset; - sqInt byte; - BytecodeDescriptor *descriptor; - sqInt distance; - sqInt endbcpc; - CogMethod *homeMethod; - sqInt isBackwardBranch; - sqInt isInBlock; - sqInt latestContinuation; - usqInt map; - sqInt mapByte; - usqInt mcpc1; - sqInt nExts; - sqInt nextBcpc; - sqInt result; - sqInt targetPC; - - latestContinuation = 0; - /* begin mapFor:bcpc:performUntil:arg: */ - assert(((cogMethod->stackCheckOffset)) > 0); - - /* The stack check maps to the start of the first bytecode, - the first bytecode being effectively after frame build. */ - mcpc1 = (((usqInt)cogMethod)) + ((cogMethod->stackCheckOffset)); - result = findIsBackwardBranchMcpcBcpcMatchingMcpc(null, (0 + (((int)((usqInt)(HasBytecodePC) << 1)))), (((char *) mcpc1)), startbcpc, (((void *)mcpc))); - if (result != 0) { - return result; - } - - /* In both CMMethod and CMBlock cases find the start of the map and - skip forward to the bytecode pc map entry for the stack check. */ - bcpc = startbcpc; - if (((cogMethod->cmType)) == CMMethod) { - /* begin cmIsFullBlock */ - isInBlock = (cogMethod->cpicHasMNUCaseOrCMIsFullBlock); - homeMethod = ((CogMethod *) cogMethod); - assert(startbcpc == (startPCOfMethodHeader((homeMethod->methodHeader)))); - map = ((((usqInt)homeMethod)) + ((homeMethod->blockSize))) - 1; - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert((annotation == IsAbsPCReference) - || ((annotation == IsObjectReference) - || ((annotation == IsRelativeCall) - || (annotation == IsDisplacementX2N)))); - latestContinuation = startbcpc; - aMethodObj = (homeMethod->methodObject); - endbcpc = (numBytesOf(aMethodObj)) - 1; - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader) - ? 0x100 - : 0) -# else - 0 -# endif - ; - bcpc += deltaToSkipPrimAndErrorStoreInheader(aMethodObj, (homeMethod->methodHeader)); - } - else { - isInBlock = 1; - assert(bcpc == ((cogMethod->startpc))); - homeMethod = cmHomeMethod(cogMethod); - map = findMapLocationForMcpcinMethod((((usqInt)cogMethod)) + (sizeof(CogBlockMethod)), homeMethod); - assert(map != 0); - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert(((((usqInt)(annotation)) >> AnnotationShift) == HasBytecodePC) - || ((((usqInt)(annotation)) >> AnnotationShift) == IsDisplacementX2N)); - while (((annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift)) != HasBytecodePC) { - map -= 1; - } - - /* skip fiducial; i.e. the map entry for the pc immediately following the method header. */ - map -= 1; - aMethodObj = (homeMethod->methodObject); - bcpc = startbcpc - ( -#if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet((homeMethod->methodHeader)) - ? AltBlockCreationBytecodeSize - : BlockCreationBytecodeSize) -#else // MULTIPLEBYTECODESETS - BlockCreationBytecodeSize -#endif - ); - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader1 = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader1) - ? 0x100 - : 0) -# else - 0 -# endif - ; - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - endbcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, -1, aMethodObj)) - : 0)); - bcpc = startbcpc; - } - nExts = 0; - while ((((usqInt)((byteAt(map)))) >> AnnotationShift) != HasBytecodePC) { - map -= 1; - } - map -= 1; - while (((mapByte = byteAt(map))) != MapEnd) { - - /* defensive; we exit on bcpc */ - if (mapByte >= FirstAnnotation) { - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - mcpc1 += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if (annotation >= HasBytecodePC) { - if ((annotation == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - while (1) { - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - if (isInBlock) { - if (bcpc >= endbcpc) { - return 0; - } - } - else { - if (((descriptor->isReturn)) - && (bcpc >= latestContinuation)) { - return 0; - } - if ((isBranch(descriptor)) - || ((descriptor->isBlockCreation))) { - /* begin latestContinuationPCFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj); - targetPC = (bcpc + ((descriptor->numBytes))) + (((distance < 0) ? 0 : distance)); - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - /* latestContinuation = */ latestContinuation; - } - nextBcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) - : 0)); - if (((descriptor->isMapped)) - || (isInBlock - && ((descriptor->isMappedInBlock)))) break; - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - isBackwardBranch = (isBranch(descriptor)) - && ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) < 0)); - result = findIsBackwardBranchMcpcBcpcMatchingMcpc(descriptor, ((isBackwardBranch - ? (((sqInt)((usqInt)(annotation) << 1))) + 1 - : ((sqInt)((usqInt)(annotation) << 1)))), (((char *) mcpc1)), ((isBackwardBranch - ? bcpc - (2 * nExts) - : bcpc)), (((void *)mcpc))); - if (result != 0) { - return result; - } - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - } - else { - assert(((((usqInt)(mapByte)) >> AnnotationShift) == IsDisplacementX2N) - || ((((usqInt)(mapByte)) >> AnnotationShift) == IsAnnotationExtension)); - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc1 += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - return 0; -} - - /* Cogit>>#CallRT:registersToBeSavedMask: */ -static AbstractInstruction * NoDbgRegParms -CallRTregistersToBeSavedMask(sqInt callTarget, sqInt registersToBeSaved) -{ - AbstractInstruction *abstractInstruction; - sqInt callerSavedRegsToBeSaved; - AbstractInstruction *lastInst; - sqInt reg; - sqInt registersToBePushed; - - reg = 0; - callerSavedRegsToBeSaved = CallerSavedRegisterMask & registersToBeSaved; - registersToBePushed = callerSavedRegsToBeSaved; - reg = 0; - while (registersToBePushed != 0) { - if (((registersToBePushed & 1) != 0)) { - genoperand(PushR, reg); - } - reg += 1; - registersToBePushed = (registersToBePushed) >> 1; - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, callTarget); - (abstractInstruction->annotation = IsRelativeCall); - lastInst = abstractInstruction; - while (reg > 0) { - reg -= 1; - if (((callerSavedRegsToBeSaved & (1U << reg)) != 0)) { - lastInst = genoperand(PopR, reg); - } - } - return lastInst; -} - - /* Cogit>>#Call: */ -static AbstractInstruction * NoDbgRegParms -gCall(sqInt callTarget) -{ - return genoperand(Call, callTarget); -} - - /* Cogit>>#CmpCq:R: */ -static AbstractInstruction * NoDbgRegParms -gCmpCqR(sqInt quickConstant, sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, quickConstant, reg); - return anInstruction; -} - - -/* This is a static version of ceCallCogCodePopReceiverReg - for break-pointing when debugging in C. */ -/* This exists only for break-pointing. */ - - /* Cogit>>#callCogCodePopReceiver */ -void -callCogCodePopReceiver(void) -{ - realCECallCogCodePopReceiverReg(); - error("what??"); -} - - -/* This is a static version of ceCallCogCodePopReceiverAndClassRegs - for break-pointing when debugging in C. */ -/* This exists only for break-pointing. */ - - /* Cogit>>#callCogCodePopReceiverAndClassRegs */ -void -callCogCodePopReceiverAndClassRegs(void) -{ - realCECallCogCodePopReceiverAndClassRegs(); -} - - -/* Code entry closed PIC miss. A send has fallen - through a closed (finite) polymorphic inline cache. - Either extend it or patch the send site to an open PIC. - The stack looks like: - receiver - args - sp=> sender return address */ - - /* Cogit>>#ceCPICMiss:receiver: */ -static sqInt NoDbgRegParms -ceCPICMissreceiver(CogMethod *cPIC, sqInt receiver) -{ - sqInt cacheTag; - sqInt errorSelectorOrNil; - sqInt methodOrSelectorIndex; - sqInt newTargetMethodOrNil; - sqInt outerReturn; - sqInt result; - sqInt selector; - - if (isOopForwarded(receiver)) { - return ceSendFromInLineCacheMiss(cPIC); - } - outerReturn = stackTop(); - assert(!(((inlineCacheTagAt(backEnd, outerReturn)) == (picAbortDiscriminatorValue())))); - if (((cPIC->cPICNumCases)) < MaxCPICCases) { - /* begin lookup:for:methodAndErrorSelectorInto: */ - selector = (cPIC->selector); - methodOrSelectorIndex = lookupOrdinaryreceiver(selector, receiver); - if ((((usqInt)methodOrSelectorIndex)) > (maxLookupNoMNUErrorCode())) { - if (!(isOopCompiledMethod(methodOrSelectorIndex))) { - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = SelectorCannotInterpret; - goto l1; - } - if ((!(methodHasCogMethod(methodOrSelectorIndex))) - && (methodShouldBeCogged(methodOrSelectorIndex))) { - - /* We assume cog:selector: will *not* reclaim the method zone */ - cogselector(methodOrSelectorIndex, selector); - } - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = null; - goto l1; - } - if (methodOrSelectorIndex == SelectorDoesNotUnderstand) { - methodOrSelectorIndex = lookupMNUreceiver(splObj(SelectorDoesNotUnderstand), receiver); - if ((((usqInt)methodOrSelectorIndex)) > (maxLookupNoMNUErrorCode())) { - assert(isOopCompiledMethod(methodOrSelectorIndex)); - if ((!(methodHasCogMethod(methodOrSelectorIndex))) - && (methodShouldBeCogged(methodOrSelectorIndex))) { - - /* We assume cog:selector: will *not* reclaim the method zone */ - cogselector(methodOrSelectorIndex, splObj(SelectorDoesNotUnderstand)); - } - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = SelectorDoesNotUnderstand; - goto l1; - } - newTargetMethodOrNil = null; - errorSelectorOrNil = SelectorDoesNotUnderstand; - goto l1; - } - newTargetMethodOrNil = null; - errorSelectorOrNil = methodOrSelectorIndex; - l1: /* end lookup:for:methodAndErrorSelectorInto: */; - } - else { - newTargetMethodOrNil = (errorSelectorOrNil = null); - } - assert(outerReturn == (stackTop())); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - cacheTag = inlineCacheTagForInstance(receiver); - if ((((cPIC->cPICNumCases)) >= MaxCPICCases) - || (((errorSelectorOrNil != null) - && (errorSelectorOrNil != SelectorDoesNotUnderstand)) - || ((newTargetMethodOrNil == null) - || (isYoung(newTargetMethodOrNil))))) { - result = patchToOpenPICFornumArgsreceiver((cPIC->selector), (cPIC->cmNumArgs), receiver); - assert(!result); - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - return ceSendFromInLineCacheMiss(cPIC); - } - cogExtendPICCaseNMethodtagisMNUCase(cPIC, newTargetMethodOrNil, cacheTag, errorSelectorOrNil == SelectorDoesNotUnderstand); - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - executeCogPICfromLinkedSendWithReceiverandCacheTag(cPIC, receiver, inlineCacheTagAt(backEnd, outerReturn)); - return null; -} - - /* Cogit>>#ceFree: */ -void -ceFree(void *pointer) -{ - free(pointer); -} - - /* Cogit>>#ceMalloc: */ -static void* NoDbgRegParms -ceMalloc(size_t size) -{ - return malloc(size); -} - - -/* An in-line cache check in a method has failed. The failing entry check has - jumped to the ceMethodAbort abort call at the start of the method which - has called this routine. - If possible allocate a closed PIC for the current and existing classes. - The stack looks like: - receiver - args - sender return address - sp=> ceMethodAbort call return address - So we can find the method that did the failing entry check at - ceMethodAbort call return address - missOffset - and we can find the send site from the outer return address. */ - - /* Cogit>>#ceSICMiss: */ -static sqInt NoDbgRegParms -ceSICMiss(sqInt receiver) -{ - sqInt cacheTag; - usqInt entryPoint; - sqInt errorSelectorOrNil; - sqInt extent; - usqInt innerReturn; - sqInt methodOrSelectorIndex; - sqInt newTargetMethodOrNil; - usqInt outerReturn; - CogMethod *pic; - sqInt result; - sqInt selector; - CogMethod *targetMethod; - - - /* Whether we can relink to a PIC or not we need to pop off the inner return and identify the target method. */ - innerReturn = ((usqInt)(popStack())); - targetMethod = ((CogMethod *) (innerReturn - missOffset)); - if (isOopForwarded(receiver)) { - return ceSendFromInLineCacheMiss(targetMethod); - } - outerReturn = ((usqInt)(stackTop())); - assert(((outerReturn >= methodZoneBase) && (outerReturn <= (freeStart())))); - entryPoint = callTargetFromReturnAddress(backEnd, outerReturn); - assert(((targetMethod->selector)) != (nilObject())); - assert(((((sqInt)targetMethod)) + cmEntryOffset) == entryPoint); - /* begin lookup:for:methodAndErrorSelectorInto: */ - selector = (targetMethod->selector); - methodOrSelectorIndex = lookupOrdinaryreceiver(selector, receiver); - if ((((usqInt)methodOrSelectorIndex)) > (maxLookupNoMNUErrorCode())) { - if (!(isOopCompiledMethod(methodOrSelectorIndex))) { - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = SelectorCannotInterpret; - goto l1; - } - if ((!(methodHasCogMethod(methodOrSelectorIndex))) - && (methodShouldBeCogged(methodOrSelectorIndex))) { - - /* We assume cog:selector: will *not* reclaim the method zone */ - cogselector(methodOrSelectorIndex, selector); - } - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = null; - goto l1; - } - if (methodOrSelectorIndex == SelectorDoesNotUnderstand) { - methodOrSelectorIndex = lookupMNUreceiver(splObj(SelectorDoesNotUnderstand), receiver); - if ((((usqInt)methodOrSelectorIndex)) > (maxLookupNoMNUErrorCode())) { - assert(isOopCompiledMethod(methodOrSelectorIndex)); - if ((!(methodHasCogMethod(methodOrSelectorIndex))) - && (methodShouldBeCogged(methodOrSelectorIndex))) { - - /* We assume cog:selector: will *not* reclaim the method zone */ - cogselector(methodOrSelectorIndex, splObj(SelectorDoesNotUnderstand)); - } - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = SelectorDoesNotUnderstand; - goto l1; - } - newTargetMethodOrNil = null; - errorSelectorOrNil = SelectorDoesNotUnderstand; - goto l1; - } - newTargetMethodOrNil = null; - errorSelectorOrNil = methodOrSelectorIndex; - l1: /* end lookup:for:methodAndErrorSelectorInto: */; - assert(outerReturn == (stackTop())); - cacheTag = inlineCacheTagForInstance(receiver); - if (((errorSelectorOrNil != null) - && (errorSelectorOrNil != SelectorDoesNotUnderstand)) - || (((inlineCacheTagAt(backEnd, outerReturn)) == 0 /* picAbortDiscriminatorValue */) - || ((newTargetMethodOrNil == null) - || (isYoung(newTargetMethodOrNil))))) { - result = patchToOpenPICFornumArgsreceiver((targetMethod->selector), (targetMethod->cmNumArgs), receiver); - assert(!result); - return ceSendFromInLineCacheMiss(targetMethod); - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - pic = openPICWithSelector((targetMethod->selector)); - if ((pic == null) - || (!1)) { - - /* otherwise attempt to create a closed PIC for the two cases. */ - pic = cogPICSelectornumArgsCase0MethodCase1MethodtagisMNUCase((targetMethod->selector), (targetMethod->cmNumArgs), targetMethod, newTargetMethodOrNil, cacheTag, errorSelectorOrNil == SelectorDoesNotUnderstand); - if ((((((sqInt)pic)) >= MaxNegativeErrorCode) && ((((sqInt)pic)) <= -1))) { - - /* For some reason the PIC couldn't be generated, most likely a lack of code memory. - Continue as if this is an unlinked send. */ - if ((((sqInt)pic)) == InsufficientCodeSpace) { - callForCogCompiledCodeCompaction(); - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - return ceSendFromInLineCacheMiss(targetMethod); - } - } - extent = (((pic->cmType)) == CMOpenPIC - ? rewriteInlineCacheAttagtarget(backEnd, outerReturn, inlineCacheValueForSelectorin(backEnd, (targetMethod->selector), mframeHomeMethodExport()), (((sqInt)pic)) + cmEntryOffset) - : rewriteCallAttarget(backEnd, outerReturn, (((sqInt)pic)) + cmEntryOffset)); - /* begin assertValidDualZoneFrom:to: */ - (((usqInt)pic)) + closedPICSize; -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, (((usqInt)pic)) + cmNoCheckEntryOffset, codeToDataDelta); -# endif - flushICacheFromto(backEnd, ((usqInt)pic), (((usqInt)pic)) + closedPICSize); - flushICacheFromto(backEnd, (((usqInt)outerReturn)) - extent, ((usqInt)outerReturn)); - executeCogPICfromLinkedSendWithReceiverandCacheTag(pic, receiver, inlineCacheTagAt(backEnd, outerReturn)); - return null; -} - - -/* Check for a valid object reference, if any, at a map entry. Answer a code - unique to each error for debugging. */ - - /* Cogit>>#checkIfValidOopRefAndTarget:pc:cogMethod: */ -static sqInt NoDbgRegParms -checkIfValidOopRefAndTargetpccogMethod(sqInt annotation, char *mcpc, CogMethod *cogMethod) -{ - usqInt cacheTag1; - sqInt entryPoint; - usqInt entryPoint1; - usqInt literal; - sqInt offset1; - sqInt *sendTable1; - sqInt tagCouldBeObj; - CogMethod *targetMethod1; - - if (annotation == IsObjectReference) { - literal = literalBeforeFollowingAddress(backEnd, ((usqInt)mcpc)); - if (!(asserta(checkValidOopReference(literal)))) { - return 1; - } - if ((couldBeObject(literal)) - && (isReallyYoungObject(literal))) { - if (!(asserta(((((CogMethod *) cogMethod))->cmRefersToYoung)))) { - return 2; - } - } - } - if (annotation >= IsSendCall) { - if (!(asserta((((((CogMethod *) cogMethod))->cmType)) == CMMethod))) { - return 3; - } - /* begin entryCacheTagAndCouldBeObjectAt:annotation:into: */ - cacheTag1 = inlineCacheTagAt(backEnd, ((sqInt)mcpc)); - - /* in-line cache tags are the selectors of sends if sends are unlinked, - the selectors of super sends (entry offset = cmNoCheckEntryOffset), - the selectors of open PIC sends (entry offset = cmEntryOffset, target is an Open PIC) - or in-line cache tags (classes, class indices, immediate bit patterns, etc). - Note that selectors can be immediate so there is no guarantee that they - are markable/remappable objects. */ - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - tagCouldBeObj = entryPointTagIsSelector(entryPoint1); - entryPoint = entryPoint1; - if (tagCouldBeObj) { - if (couldBeObject(cacheTag1)) { - if (!(asserta(checkValidOopReference(cacheTag1)))) { - return 4; - } - } - else { - if (!(asserta(validInlineCacheTag(cacheTag1)))) { - return 5; - } - } - if ((couldBeObject(cacheTag1)) - && (isReallyYoungObject(cacheTag1))) { - if (!(asserta(((((CogMethod *) cogMethod))->cmRefersToYoung)))) { - return 6; - } - } - } - else { - if (!(asserta(validInlineCacheTag(cacheTag1)))) { - return 9; - } - } - if (entryPoint > methodZoneBase) { - - /* It's a linked send; find which kind. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (!(asserta((((targetMethod1->cmType)) == CMMethod) - || ((((targetMethod1->cmType)) == CMClosedPIC) - || (((targetMethod1->cmType)) == CMOpenPIC))))) { - return 10; - } - } - } - return 0; -} - - -/* Check for a valid object reference, if any, at a map entry. Answer a code - unique to each error for debugging. */ - - /* Cogit>>#checkIfValidOopRef:pc:cogMethod: */ -static sqInt NoDbgRegParms -checkIfValidOopRefpccogMethod(sqInt annotation, char *mcpc, CogMethod *cogMethod) -{ - usqInt entryPoint; - usqInt literal; - usqInt offset; - sqInt offset1; - usqInt selectorOrCacheTag; - sqInt *sendTable; - - if (annotation == IsObjectReference) { - literal = literalBeforeFollowingAddress(backEnd, ((usqInt)mcpc)); - if (!(checkValidOopReference(literal))) { - print("object ref leak in CM "); - printHex(((sqInt)cogMethod)); - print(" @ "); - printHex(((sqInt)mcpc)); - cr(); - return 1; - } - } - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint <= methodZoneBase) { - offset = entryPoint; - } - else { - /* begin offsetAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable = superSendTrampolines; - } - } - } - offset = offset1; - } - selectorOrCacheTag = inlineCacheTagAt(backEnd, ((sqInt)mcpc)); - if ((entryPoint > methodZoneBase) - && ((offset != cmNoCheckEntryOffset) - && ((((((CogMethod *) (entryPoint - offset)))->cmType)) != CMOpenPIC))) { - - /* linked non-super send, cacheTag is a cacheTag */ - if (!(validInlineCacheTag(selectorOrCacheTag))) { - print("cache tag leak in CM "); - printHex(((sqInt)cogMethod)); - print(" @ "); - printHex(((sqInt)mcpc)); - cr(); - return 1; - } - } - else { - - /* unlinked send or super send; cacheTag is a selector unless 64-bit, in which case it is an index. */ - if (!(checkValidOopReference(selectorOrCacheTag))) { - print("selector leak in CM "); - printHex(((sqInt)cogMethod)); - print(" @ "); - printHex(((sqInt)mcpc)); - cr(); - return 1; - } - } - } - return 0; -} - - -/* Answer if all references to objects in machine-code are valid. */ - - /* Cogit>>#checkIntegrityOfObjectReferencesInCode: */ -sqInt -checkIntegrityOfObjectReferencesInCode(sqInt gcModes) -{ - CogMethod *cogMethod; - sqInt count; - sqInt ok; - - cogMethod = ((CogMethod *) methodZoneBase); - ok = 1; - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - if ((cogMethod->cmRefersToYoung)) { - if (((count = occurrencesInYoungReferrers(cogMethod))) != 1) { - print("young referrer CM "); - printHex(((sqInt)cogMethod)); - if (count == 0) { - print(" is not in youngReferrers"); - cr(); - } - else { - print(" is in youngReferrers "); - printNum(count); - print(" times!"); - cr(); - } - ok = 0; - } - } - if (!(checkValidOopReference((cogMethod->selector)))) { - print("object leak in CM "); - printHex(((sqInt)cogMethod)); - print(" selector"); - cr(); - ok = 0; - } - if (((cogMethod->cmType)) == CMMethod) { - assert(((cogMethod->objectHeader)) == (nullHeaderForMachineCodeMethod())); - if (!(checkValidObjectReference((cogMethod->methodObject)))) { - print("object leak in CM "); - printHex(((sqInt)cogMethod)); - print(" methodObject"); - cr(); - ok = 0; - } - if (!(isOopCompiledMethod((cogMethod->methodObject)))) { - print("non-method in CM "); - printHex(((sqInt)cogMethod)); - print(" methodObject"); - cr(); - ok = 0; - } - if ((mapForperformUntilarg(cogMethod, checkIfValidOopRefpccogMethod, cogMethod)) != 0) { - ok = 0; - } - if (((isYoungObject((cogMethod->methodObject))) - || (isYoung((cogMethod->selector)))) - && (!((cogMethod->cmRefersToYoung)))) { - print("CM "); - printHex(((sqInt)cogMethod)); - print(" refers to young but not marked as such"); - cr(); - ok = 0; - } - } - else { - if (((cogMethod->cmType)) == CMClosedPIC) { - if (!(checkValidObjectReferencesInClosedPIC(cogMethod))) { - ok = 0; - } - } - else { - if (((cogMethod->cmType)) == CMOpenPIC) { - if ((mapForperformUntilarg(cogMethod, checkIfValidOopRefpccogMethod, cogMethod)) != 0) { - ok = 0; - } - } - } - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return ok; -} - - /* Cogit>>#checkMaybeObjRefInClosedPIC: */ -static sqInt NoDbgRegParms -checkMaybeObjRefInClosedPIC(sqInt maybeObject) -{ - if (maybeObject == 0) { - return 1; - } - if (!(couldBeObject(maybeObject))) { - return 1; - } - return checkValidObjectReference(maybeObject); -} - - /* Cogit>>#checkValidObjectReferencesInClosedPIC: */ -static sqInt NoDbgRegParms -checkValidObjectReferencesInClosedPIC(CogMethod *cPIC) -{ - sqInt i; - sqInt ok; - sqInt pc; - - ok = 1; - - /* first we check the obj ref at the beginning of the CPIC */ - pc = (((sqInt)cPIC)) + firstCPICCaseOffset; - if (!(checkMaybeObjRefInClosedPIC(literalBeforeFollowingAddress(backEnd, pc - (jumpLongByteSize(backEnd)))))) { - print("object leak in CPIC "); - printHex(((sqInt)cPIC)); - print(" @ "); - printHex(pc - (jumpLongByteSize(backEnd))); - cr(); - ok = 0; - } - - /* For each case we check any object reference at the end address - sizeof(conditional instruction) and then increment the end address by case size */ - pc = addressOfEndOfCaseinCPIC((cPIC->cPICNumCases), cPIC); - for (i = 2; i <= ((cPIC->cPICNumCases)); i += 1) { - if (!(checkMaybeObjRefInClosedPIC(literalBeforeFollowingAddress(backEnd, (pc - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */)))) { - print("object leak in CPIC "); - printHex(((sqInt)cPIC)); - print(" @ "); - printHex(pc - 16 /* jumpLongConditionalByteSize */); - cr(); - ok = 0; - } - pc += cPICCaseSize; - } - return ok; -} - - -/* i.e. this should never be called, so keep it out of the main path. */ - - /* Cogit>>#cleanUpFailingCogCodeConstituents: */ -static sqInt NoDbgRegParms NeverInline -cleanUpFailingCogCodeConstituents(CogMethod *cogMethodArg) -{ - CogMethod *cogMethod; - - cogMethod = cogMethodArg; - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMClosedPIC) { - (cogMethod->methodObject = 0); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - popRemappableOop(); - return null; -} - - -/* Answer if the ClosedPIC refers to any unmarked objects or freed/freeable - target methods, - applying markAndTraceOrFreeCogMethod:firstVisit: to those targets to - determine if freed/freeable. - */ - - /* Cogit>>#closedPICRefersToUnmarkedObject: */ -static sqInt NoDbgRegParms -closedPICRefersToUnmarkedObject(CogMethod *cPIC) -{ - sqInt i; - usqInt object; - sqInt pc; - - if (!((isImmediate((cPIC->selector))) - || (isMarked((cPIC->selector))))) { - return 1; - } - pc = addressOfEndOfCaseinCPIC(1, cPIC); - if (couldBeObject((object = literalBeforeFollowingAddress(backEnd, pc - (jumpLongByteSize(backEnd)))))) { - if (!(isMarked(object))) { - return 1; - } - } - if (markAndTraceOrFreePICTargetin(jumpLongTargetBeforeFollowingAddress(backEnd, pc), cPIC)) { - return 1; - } - for (i = 2; i <= ((cPIC->cPICNumCases)); i += 1) { - pc = addressOfEndOfCaseinCPIC(i, cPIC); - if (couldBeObject((object = literalBeforeFollowingAddress(backEnd, (pc - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */)))) { - if (!(isMarked(object))) { - return 1; - } - } - if (markAndTraceOrFreePICTargetin(jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc), cPIC)) { - return 1; - } - } - return 0; -} - - /* Cogit>>#codeEntryFor: */ -char * -codeEntryFor(char *address) -{ - sqInt i; - - for (i = 0; i <= (trampolineTableIndex - 3); i += 2) { - if (((address >= (trampolineAddresses[i + 1])) && (address <= ((trampolineAddresses[i + 3]) - 1)))) { - return trampolineAddresses[i + 1]; - } - } - return null; -} - - /* Cogit>>#codeEntryNameFor: */ -char * -codeEntryNameFor(char *address) -{ - sqInt i; - - for (i = 0; i <= (trampolineTableIndex - 3); i += 2) { - if (((address >= (trampolineAddresses[i + 1])) && (address <= ((trampolineAddresses[i + 3]) - 1)))) { - return trampolineAddresses[i]; - } - } - return null; -} - - /* Cogit>>#cogCodeBase */ -sqInt -cogCodeBase(void) -{ - return codeBase; -} - - -/* Answer the contents of the code zone as an array of pair-wise element, - address in ascending address order. - Answer a string for a runtime routine or abstract label (beginning, end, - etc), a CompiledMethod for a CMMethod, - or a selector (presumably a Symbol) for a PIC. - If withDetails is true - - answer machine-code to bytecode pc mapping information for methods - - answer class, target pair information for closed PIC - N.B. Since the class tag for the first case of a closed PIC is stored at - the send site, it must be collected - by scanning methods (see - collectCogConstituentFor:Annotation:Mcpc:Bcpc:Method:). Since closed PICs - are never shared they always come after the method that references them, - so we don't need an extra pass - to collect the first case class tags, which are (temporarily) assigned to - each closed PIC's methodObject field. - But we do need to reset the methodObject fields to zero. This is done in - createPICData:, unless memory - runs out, in which case it is done by cleanUpFailingCogCodeConstituents:. */ - - /* Cogit>>#cogCodeConstituents: */ -sqInt -cogCodeConstituents(sqInt withDetails) -{ - CogMethod *cogMethod; - sqInt constituents; - sqInt count; - sqInt i; - sqInt label; - sqInt profileData; - sqInt value; - - - /* + 3 for start, freeStart and end */ - count = (trampolineTableIndex / 2) + 3; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - count += 1; - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - constituents = instantiateClassindexableSize(classArray(), count * 2); - if (!constituents) { - return constituents; - } - pushRemappableOop(constituents); - if ((((label = stringForCString("CogCode"))) == null) - || (((value = positive32BitIntegerFor(codeBase))) == null)) { - popRemappableOop(); - return null; - } - storePointerUncheckedofObjectwithValue(0, constituents, label); - storePointerUncheckedofObjectwithValue(1, constituents, value); - for (i = 0; i < trampolineTableIndex; i += 2) { - if ((((label = stringForCString(trampolineAddresses[i]))) == null) - || (((value = positive32BitIntegerFor(((usqInt)(trampolineAddresses[i + 1]))))) == null)) { - popRemappableOop(); - return null; - } - storePointerUncheckedofObjectwithValue(2 + i, constituents, label); - storePointerUncheckedofObjectwithValue(3 + i, constituents, value); - } - count = trampolineTableIndex + 2; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - profileData = (((cogMethod->cmType)) == CMMethod - ? (cogMethod->methodObject) - : (withDetails - && (((cogMethod->cmType)) == CMClosedPIC) - ? createCPICData(cogMethod) - : (cogMethod->selector))); - if (!profileData) { - return cleanUpFailingCogCodeConstituents(cogMethod); - } - storePointerUncheckedofObjectwithValue(count, constituents, profileData); - if (withDetails) { - value = collectCogMethodConstituent(cogMethod); - } - else { - value = positive32BitIntegerFor(((usqInt)cogMethod)); - } - if (!value) { - return cleanUpFailingCogCodeConstituents(cogMethod); - } - storePointerUncheckedofObjectwithValue(count + 1, constituents, value); - count += 2; - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if ((((label = stringForCString("CCFree"))) == null) - || (((value = positive32BitIntegerFor(mzFreeStart))) == null)) { - popRemappableOop(); - return null; - } - storePointerUncheckedofObjectwithValue(count, constituents, label); - storePointerUncheckedofObjectwithValue(count + 1, constituents, value); - if ((((label = stringForCString("CCEnd"))) == null) - || (((value = positive32BitIntegerFor(limitAddress))) == null)) { - popRemappableOop(); - return null; - } - storePointerUncheckedofObjectwithValue(count + 2, constituents, label); - storePointerUncheckedofObjectwithValue(count + 3, constituents, value); - constituents = popRemappableOop(); - beRootIfOld(constituents); - return constituents; -} - - -/* Extend the cPIC with the supplied case. If caseNMethod is cogged dispatch - direct to - its unchecked entry-point. If caseNMethod is not cogged, jump to the fast - interpreter dispatch, and if isMNUCase then dispatch to fast MNU - invocation and mark the cPIC as - having the MNU case for cache flushing. */ - - /* Cogit>>#cogExtendPIC:CaseNMethod:tag:isMNUCase: */ -static void NoDbgRegParms -cogExtendPICCaseNMethodtagisMNUCase(CogMethod *cPIC, sqInt caseNMethod, sqInt caseNTag, sqInt isMNUCase) -{ - sqInt address; - sqInt operand; - CogBlockMethod * self_in_cpicHasMNUCase; - sqInt target; - - compilationBreakpointclassTagisMNUCase((cPIC->selector), caseNTag, isMNUCase); - assert(!(inlineCacheTagIsYoung(caseNTag))); - assert((caseNMethod != null) - && (!(isYoung(caseNMethod)))); - if ((!isMNUCase) - && (methodHasCogMethod(caseNMethod))) { - - /* this isn't an MNU and we have an already cogged method to jump to */ - operand = 0; - target = (((sqInt)(cogMethodOf(caseNMethod)))) + cmNoCheckEntryOffset; - } - else { - operand = caseNMethod; - if (isMNUCase) { - - /* this is an MNU so tag the CPIC header and setup a jump to the MNUAbort */ - /* begin cpicHasMNUCase: */ - self_in_cpicHasMNUCase = ((CogBlockMethod *) (((CogMethod *) ((((usqInt)cPIC)) + codeToDataDelta)))); - (self_in_cpicHasMNUCase->cpicHasMNUCaseOrCMIsFullBlock) = 1; - target = (((sqInt)cPIC)) + (sizeof(CogMethod)); - } - else { - - /* setup a jump to the interpretAborth so we can cog the target method */ - target = (((sqInt)cPIC)) + (picInterpretAbortOffset()); - } - } - address = addressOfEndOfCaseinCPIC(((cPIC->cPICNumCases)) + 1, cPIC); - rewriteCPICCaseAttagobjReftarget(address, caseNTag, operand, target); - /* begin rewriteCPIC:caseJumpTo: */ - rewriteCPICJumpAttarget(backEnd, (((((sqInt)cPIC)) + firstCPICCaseOffset) - (jumpLongByteSize(backEnd))) - 8 /* loadLiteralByteSize */, address - cPICCaseSize); - ((((CogMethod *) ((((usqInt)cPIC)) + codeToDataDelta)))->cPICNumCases = ((cPIC->cPICNumCases)) + 1); - flushICacheFromto(backEnd, ((usqInt)cPIC), (((usqInt)cPIC)) + closedPICSize); - /* begin assertValidDualZoneFrom:to: */ - (((usqInt)cPIC)) + closedPICSize; -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, (((usqInt)cPIC)) + cmNoCheckEntryOffset, codeToDataDelta); -# endif -} - - -/* Attempt to produce a machine code method for the bytecode method - object aMethodObj. N.B. If there is no code memory available do *NOT* - attempt to reclaim the method zone. Certain clients (e.g. ceSICMiss:) - depend on the zone remaining constant across method generation. */ - - /* Cogit>>#cogFullBlockMethod:numCopied: */ -CogMethod * -cogFullBlockMethodnumCopied(sqInt aMethodObj, sqInt numCopied) -{ - CogMethod *cogMethod; - - - /* inline exclude: */ - assert(!((methodHasCogMethod(aMethodObj)))); - assert(isOopCompiledMethod(ultimateLiteralOf(aMethodObj))); - if (aMethodObj == breakMethod) { - haltmsg("Compilation of breakMethod"); - } - if (methodUsesAlternateBytecodeSet(aMethodObj)) { - if ((numElementsIn(generatorTable)) <= 0x100) { - return null; - } - bytecodeSetOffset = 0x100; - } - else { - bytecodeSetOffset = 0; - } - ensureNoForwardedLiteralsIn(aMethodObj); - methodObj = aMethodObj; - methodHeader = methodHeaderOf(aMethodObj); - receiverTags = receiverTagBitsForMethod(methodObj); - cogMethod = compileCogFullBlockMethod(numCopied); - if ((((((sqInt)cogMethod)) >= MaxNegativeErrorCode) && ((((sqInt)cogMethod)) <= -1))) { - if ((((sqInt)cogMethod)) == InsufficientCodeSpace) { - callForCogCompiledCodeCompaction(); - } - return null; - } - return cogMethod; -} - - /* Cogit>>#cogitPostGCAction: */ -void -cogitPostGCAction(sqInt gcMode) -{ - -# if SPURVM - if (gcMode == GCModeBecome) { - followForwardedLiteralsInOpenPICList(); - } -# endif - assert(allMethodsHaveCorrectHeader()); - assert(((!(gcMode & (GCModeFull + GCModeNewSpace)))) - || (kosherYoungReferrers())); - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - -/* Check that the header fields onf a non-free method are consistent with - the type. Answer 0 if it is ok, otherwise answer a code for the error. */ - - /* Cogit>>#cogMethodDoesntLookKosher: */ -sqInt -cogMethodDoesntLookKosher(CogMethod *cogMethod) -{ - if (((((cogMethod->blockSize)) & (BytesPerWord - 1)) != 0) - || ((((cogMethod->blockSize)) < (sizeof(CogMethod))) - || (((cogMethod->blockSize)) >= 0x8000))) { - return 1; - } - if (((cogMethod->cmType)) == CMFree) { - return 2; - } - if (((cogMethod->cmType)) == CMMethod) { - if (!((((cogMethod->methodHeader)) & 1))) { - return 11; - } - if (!(couldBeObject((cogMethod->methodObject)))) { - return 12; - } - if ((((cogMethod->stackCheckOffset)) > 0) - && (((cogMethod->stackCheckOffset)) < cmNoCheckEntryOffset)) { - return 13; - } - return 0; - } - if (((cogMethod->cmType)) == CMOpenPIC) { - if (((cogMethod->blockSize)) != openPICSize) { - return 21; - } - if (((cogMethod->methodHeader)) != 0) { - return 22; - } - if (((cogMethod->objectHeader)) >= 0) { - if (!((((cogMethod->methodObject)) == 0) - || (compactionInProgress - || (((cogMethod->methodObject)) == (((usqInt)(methodFor(((void *)((cogMethod->methodObject))))))))))) { - return 23; - } - } - if (((cogMethod->stackCheckOffset)) != 0) { - return 24; - } - return 0; - } - if (((cogMethod->cmType)) == CMClosedPIC) { - if (((cogMethod->blockSize)) != closedPICSize) { - return 0x1F; - } - if (!(((((cogMethod->cPICNumCases)) >= 1) && (((cogMethod->cPICNumCases)) <= MaxCPICCases)))) { - return 32; - } - if (((cogMethod->methodHeader)) != 0) { - return 33; - } - if (((cogMethod->methodObject)) != 0) { - return 34; - } - return 0; - } - return 9; -} - - -/* Attempt to create a one-case PIC for an MNU. - The tag for the case is at the send site and so doesn't need to be - generated. - */ - - /* Cogit>>#cogMNUPICSelector:receiver:methodOperand:numArgs: */ -CogMethod * -cogMNUPICSelectorreceivermethodOperandnumArgs(sqInt selector, sqInt rcvr, sqInt methodOperand, sqInt numArgs) -{ - CogMethod * actualPIC; - usqInt startAddress; - CogMethod * writablePIC; - - if ((isYoung(selector)) - || ((inlineCacheTagForInstance(rcvr)) == 0 /* picAbortDiscriminatorValue */)) { - return 0; - } - compilationBreakpointclassTagisMNUCase(selector, fetchClassTagOf(rcvr), 1); - assert(endCPICCase0 != null); - startAddress = allocate(closedPICSize); - if (startAddress == 0) { - callForCogCompiledCodeCompaction(); - return 0; - } - maybeBreakGeneratingFromto(startAddress, startAddress + closedPICSize); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - - /* memcpy the prototype across to our allocated space; because anything else would be silly */ - writablePIC = ((CogMethod *) ((((usqInt)startAddress)) + codeToDataDelta)); - codeMemcpy(writablePIC, cPICPrototype, closedPICSize); - /* begin fillInCPICHeader:numArgs:numCases:hasMNUCase:selector: */ - assert(!(isYoung(selector))); - (writablePIC->cmType = CMClosedPIC); - (writablePIC->objectHeader = 0); - (writablePIC->blockSize = closedPICSize); - (writablePIC->methodObject = 0); - (writablePIC->methodHeader = 0); - (writablePIC->selector = selector); - (writablePIC->cmNumArgs = numArgs); - (writablePIC->cmHasMovableLiteral = 0); - (writablePIC->cmRefersToYoung = 0); - (writablePIC->cmUsageCount = initialClosedPICUsageCount()); - /* begin cpicHasMNUCase: */ - ((((CogBlockMethod *) writablePIC))->cpicHasMNUCaseOrCMIsFullBlock) = 1; - (writablePIC->cPICNumCases = 1); - (writablePIC->blockEntryOffset = 0); - assert(((writablePIC->cmType)) == CMClosedPIC); - assert(((writablePIC->selector)) == selector); - assert(((writablePIC->cmNumArgs)) == numArgs); - assert(((writablePIC->cPICNumCases)) == 1); - assert(closedPICSize == (roundUpLength(closedPICSize))); - /* begin maybeEnableSingleStep */ - configureMNUCPICmethodOperandnumArgsdelta((actualPIC = ((CogMethod *) startAddress)), methodOperand, numArgs, startAddress - (((usqInt)cPICPrototype))); - flushICacheFromto(backEnd, startAddress, startAddress + closedPICSize); - assert((callTargetFromReturnAddress(backEnd, startAddress + missOffset)) == (picAbortTrampolineFor(numArgs))); - /* begin assertValidDualZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, startAddress + cmNoCheckEntryOffset, codeToDataDelta); -# endif - return actualPIC; -} - - -/* Create an Open PIC. Temporarily create a direct call of - ceSendFromOpenPIC:. Should become a probe of the first-level method lookup - cache followed by a - call of ceSendFromOpenPIC: if the probe fails. */ - - /* Cogit>>#cogOpenPICSelector:numArgs: */ -static CogMethod * NoDbgRegParms -cogOpenPICSelectornumArgs(sqInt selector, sqInt numArgs) -{ - sqInt codeSize; - sqInt end; - sqInt fixupSize; - sqInt mapSize; - sqInt opcodeSize; - CogMethod *pic; - usqInt startAddress; - - compilationBreakpointisMNUCase(selector, 0); - startAddress = allocate(openPICSize); - if (startAddress == 0) { - return ((CogMethod *) InsufficientCodeSpace); - } - (methodLabel->address = startAddress); - (methodLabel->dependent = null); - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 100; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - compileOpenPICnumArgs(selector, numArgs); - computeMaximumSizes(); - concretizeAt(methodLabel, startAddress); - codeSize = generateInstructionsAt(startAddress + (sizeof(CogMethod))); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - mapSize = generateMapAtstart((startAddress + openPICSize) - 1, startAddress + cmNoCheckEntryOffset); - assert((((entry->address)) - startAddress) == cmEntryOffset); - assert(((roundUpLength((sizeof(CogMethod)) + codeSize)) + (roundUpLength(mapSize))) <= openPICSize); - end = outputInstructionsAt(startAddress + (sizeof(CogMethod))); - /* begin fillInOPICHeader:numArgs:selector: */ - pic = ((CogMethod *) ((((usqInt)startAddress)) + codeToDataDelta)); - (pic->cmType = CMOpenPIC); - (pic->objectHeader = 0); - (pic->blockSize = openPICSize); - addToOpenPICList(pic); - (pic->methodHeader = 0); - (pic->selector = selector); - (pic->cmNumArgs = numArgs); - (pic->cmHasMovableLiteral = isNonImmediate(selector)); - if ((pic->cmRefersToYoung = isYoung(selector))) { - addToYoungReferrers(pic); - } - (pic->cmUsageCount = initialOpenPICUsageCount()); - /* begin cpicHasMNUCase: */ - ((((CogBlockMethod *) pic))->cpicHasMNUCaseOrCMIsFullBlock) = 0; - (pic->cPICNumCases = 0); - (pic->blockEntryOffset = 0); - flushICacheFromto(backEnd, (((usqInt)pic)) - codeToDataDelta, ((((usqInt)pic)) - codeToDataDelta) + openPICSize); - assert(((pic->cmType)) == CMOpenPIC); - assert(((pic->selector)) == selector); - assert(((pic->cmNumArgs)) == numArgs); - assert((callTargetFromReturnAddress(backEnd, ((((sqInt)pic)) - codeToDataDelta) + missOffset)) == (picAbortTrampolineFor(numArgs))); - assert(openPICSize == (roundUpLength(openPICSize))); - /* begin assertValidDualZoneFrom:to: */ - ((((usqInt)pic)) - codeToDataDelta) + openPICSize; -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, ((((usqInt)pic)) - codeToDataDelta) + cmNoCheckEntryOffset, codeToDataDelta); -# endif - /* begin maybeEnableSingleStep */ - return ((CogMethod *) startAddress); -} - - -/* Attempt to create a two-case PIC for case0CogMethod and - case1Method,case1Tag. The tag for case0CogMethod is at the send site and - so doesn't need to be generated. - case1Method may be any of - - a Cog method; link to its unchecked entry-point - - a CompiledMethod; link to ceInterpretMethodFromPIC: - - a CompiledMethod; link to ceMNUFromPICMNUMethod:receiver: */ - - /* Cogit>>#cogPICSelector:numArgs:Case0Method:Case1Method:tag:isMNUCase: */ -static CogMethod * NoDbgRegParms -cogPICSelectornumArgsCase0MethodCase1MethodtagisMNUCase(sqInt selector, sqInt numArgs, CogMethod *case0CogMethod, sqInt case1MethodOrNil, sqInt case1Tag, sqInt isMNUCase) -{ - CogMethod * actualPIC; - usqInt startAddress; - CogMethod * writablePIC; - - if (isYoung(selector)) { - return ((CogMethod *) YoungSelectorInPIC); - } - compilationBreakpointclassTagisMNUCase(selector, case1Tag, isMNUCase); - startAddress = allocate(closedPICSize); - if (startAddress == 0) { - return ((CogMethod *) InsufficientCodeSpace); - } - maybeBreakGeneratingFromto(startAddress, startAddress + closedPICSize); - - /* memcpy the prototype across to our allocated space; because anything else would be silly */ - writablePIC = ((CogMethod *) ((((usqInt)startAddress)) + codeToDataDelta)); - codeMemcpy(writablePIC, cPICPrototype, closedPICSize); - /* begin fillInCPICHeader:numArgs:numCases:hasMNUCase:selector: */ - assert(!(isYoung(selector))); - (writablePIC->cmType = CMClosedPIC); - (writablePIC->objectHeader = 0); - (writablePIC->blockSize = closedPICSize); - (writablePIC->methodObject = 0); - (writablePIC->methodHeader = 0); - (writablePIC->selector = selector); - (writablePIC->cmNumArgs = numArgs); - (writablePIC->cmHasMovableLiteral = 0); - (writablePIC->cmRefersToYoung = 0); - (writablePIC->cmUsageCount = initialClosedPICUsageCount()); - /* begin cpicHasMNUCase: */ - ((((CogBlockMethod *) writablePIC))->cpicHasMNUCaseOrCMIsFullBlock) = isMNUCase; - (writablePIC->cPICNumCases = 2); - (writablePIC->blockEntryOffset = 0); - assert(((writablePIC->cmType)) == CMClosedPIC); - assert(((writablePIC->selector)) == selector); - assert(((writablePIC->cmNumArgs)) == numArgs); - assert(((writablePIC->cPICNumCases)) == 2); - assert(closedPICSize == (roundUpLength(closedPICSize))); - /* begin maybeEnableSingleStep */ - configureCPICCase0Case1MethodtagisMNUCasenumArgsdelta((actualPIC = ((CogMethod *) startAddress)), case0CogMethod, case1MethodOrNil, case1Tag, isMNUCase, numArgs, startAddress - (((usqInt)cPICPrototype))); - assert((callTargetFromReturnAddress(backEnd, startAddress + missOffset)) == (picAbortTrampolineFor(numArgs))); - return actualPIC; -} - - -/* Attempt to produce a machine code method for the bytecode method - object aMethodObj. N.B. If there is no code memory available do *NOT* - attempt to reclaim the method zone. Certain clients (e.g. ceSICMiss:) - depend on the zone remaining constant across method generation. */ - - /* Cogit>>#cog:selector: */ -CogMethod * -cogselector(sqInt aMethodObj, sqInt aSelectorOop) -{ - CogMethod *cogMethod; - sqInt selector; - - - /* inline exclude:selector: */ - assert(!((methodHasCogMethod(aMethodObj)))); - assert(!((isOopCompiledMethod(ultimateLiteralOf(aMethodObj))))); - - /* coInterpreter stringOf: selector */ - selector = (aSelectorOop == (nilObject()) - ? maybeSelectorOfMethod(aMethodObj) - : aSelectorOop); - if (!(selector == null)) { - compilationBreakpointisMNUCase(selector, 0); - } - if (aMethodObj == breakMethod) { - haltmsg("Compilation of breakMethod"); - } - if (methodUsesAlternateBytecodeSet(aMethodObj)) { - if ((numElementsIn(generatorTable)) <= 0x100) { - return null; - } - bytecodeSetOffset = 0x100; - } - else { - bytecodeSetOffset = 0; - } - ensureNoForwardedLiteralsIn(aMethodObj); - methodObj = aMethodObj; - methodHeader = methodHeaderOf(aMethodObj); - receiverTags = receiverTagBitsForMethod(methodObj); - cogMethod = compileCogMethod(aSelectorOop); - if ((((((sqInt)cogMethod)) >= MaxNegativeErrorCode) && ((((sqInt)cogMethod)) <= -1))) { - if ((((sqInt)cogMethod)) == InsufficientCodeSpace) { - callForCogCompiledCodeCompaction(); - } - return null; - } - return cogMethod; -} - - /* Cogit>>#collectCogConstituentFor:Annotation:Mcpc:Bcpc:Method: */ -static sqInt NoDbgRegParms -collectCogConstituentForAnnotationMcpcBcpcMethod(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *cogMethodArg) -{ - sqInt address; - sqInt annotation; - usqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - - if (!descriptor) { - return 0; - } - if (!((descriptor->isMapped))) { - return 0; - } - address = positive32BitIntegerFor(((usqInt)mcpc)); - if (!address) { - return PrimErrNoMemory; - } - storePointerUncheckedofObjectwithValue(cogConstituentIndex, topRemappableOop(), address); - storePointerUncheckedofObjectwithValue(cogConstituentIndex + 1, topRemappableOop(), (((usqInt)bcpc << 1) | 1)); - - /* Collect any first case classTags for closed PICs. */ - cogConstituentIndex += 2; - if (((!(isBackwardBranchAndAnnotation & 1))) - && (((((usqInt)(isBackwardBranchAndAnnotation)) >> 1) >= IsSendCall) - || (0))) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* send is linked */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - annotation = ((usqInt)(isBackwardBranchAndAnnotation)) >> 1; - /* begin offsetAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (((targetMethod1->cmType)) == CMClosedPIC) { - (targetMethod1->methodObject = classForInlineCacheTag(inlineCacheTagAt(backEnd, mcpc))); - } - } - } - return 0; -} - - -/* Answer a description of the mapping between machine code pointers and - bytecode pointers for the Cog Method. - First value is the address of the cog method. - Following values are pairs of machine code pc and bytecode pc */ - - /* Cogit>>#collectCogMethodConstituent: */ -static sqInt NoDbgRegParms -collectCogMethodConstituent(CogMethod *cogMethod) -{ - sqInt address; - sqInt aMethodHeader; - sqInt aMethodHeader1; - sqInt aMethodObj; - sqInt annotation; - sqInt bcpc; - sqInt bsOffset; - sqInt byte; - sqInt cm; - CogBlockMethod *cogBlockMethod; - sqInt data; - BytecodeDescriptor *descriptor; - sqInt distance; - sqInt endbcpc; - sqInt errCode; - CogMethod *homeMethod; - sqInt isBackwardBranch; - sqInt isInBlock; - sqInt latestContinuation; - usqInt map; - sqInt mapByte; - usqInt mcpc; - sqInt nExts; - sqInt nextBcpc; - sqInt nSlots; - sqInt result; - sqInt startbcpc; - sqInt targetPC; - - latestContinuation = 0; - if (!(((cogMethod->cmType)) == CMMethod)) { - return positive32BitIntegerFor(((usqInt)cogMethod)); - } - cogBlockMethod = ((CogBlockMethod *) cogMethod); - if (((cogBlockMethod->stackCheckOffset)) == 0) { - - /* isFrameless ? */ - return positive32BitIntegerFor(((usqInt)cogMethod)); - } - cm = (cogMethod->methodObject); - - /* +1 for first address */ - nSlots = ((((byteSizeOf(cm)) - (startPCOfMethod(cm))) * 2) + (minSlotsForShortening())) + 1; - data = instantiateClassindexableSize(splObj(ClassArray), nSlots); - if (!data) { - return null; - } - pushRemappableOop(data); - address = positive32BitIntegerFor(((usqInt)cogMethod)); - if (!address) { - popRemappableOop(); - return null; - } - storePointerUncheckedofObjectwithValue(0, topRemappableOop(), address); - cogConstituentIndex = 1; - /* begin mapFor:bcpc:performUntil:arg: */ - startbcpc = startPCOfMethod((cogMethod->methodObject)); - assert(((cogBlockMethod->stackCheckOffset)) > 0); - - /* The stack check maps to the start of the first bytecode, - the first bytecode being effectively after frame build. */ - mcpc = (((usqInt)cogBlockMethod)) + ((cogBlockMethod->stackCheckOffset)); - result = collectCogConstituentForAnnotationMcpcBcpcMethod(null, (0 + (((int)((usqInt)(HasBytecodePC) << 1)))), (((char *) mcpc)), startbcpc, (((void *)cogMethod))); - if (result != 0) { - errCode = result; - goto l7; - } - - /* In both CMMethod and CMBlock cases find the start of the map and - skip forward to the bytecode pc map entry for the stack check. */ - bcpc = startbcpc; - if (((cogBlockMethod->cmType)) == CMMethod) { - /* begin cmIsFullBlock */ - isInBlock = (cogBlockMethod->cpicHasMNUCaseOrCMIsFullBlock); - homeMethod = ((CogMethod *) cogBlockMethod); - assert(startbcpc == (startPCOfMethodHeader((homeMethod->methodHeader)))); - map = ((((usqInt)homeMethod)) + ((homeMethod->blockSize))) - 1; - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert((annotation == IsAbsPCReference) - || ((annotation == IsObjectReference) - || ((annotation == IsRelativeCall) - || (annotation == IsDisplacementX2N)))); - latestContinuation = startbcpc; - aMethodObj = (homeMethod->methodObject); - endbcpc = (numBytesOf(aMethodObj)) - 1; - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader) - ? 0x100 - : 0) -# else - 0 -# endif - ; - bcpc += deltaToSkipPrimAndErrorStoreInheader(aMethodObj, (homeMethod->methodHeader)); - } - else { - isInBlock = 1; - assert(bcpc == ((cogBlockMethod->startpc))); - homeMethod = cmHomeMethod(cogBlockMethod); - map = findMapLocationForMcpcinMethod((((usqInt)cogBlockMethod)) + (sizeof(CogBlockMethod)), homeMethod); - assert(map != 0); - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert(((((usqInt)(annotation)) >> AnnotationShift) == HasBytecodePC) - || ((((usqInt)(annotation)) >> AnnotationShift) == IsDisplacementX2N)); - while (((annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift)) != HasBytecodePC) { - map -= 1; - } - - /* skip fiducial; i.e. the map entry for the pc immediately following the method header. */ - map -= 1; - aMethodObj = (homeMethod->methodObject); - bcpc = startbcpc - ( -#if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet((homeMethod->methodHeader)) - ? AltBlockCreationBytecodeSize - : BlockCreationBytecodeSize) -#else // MULTIPLEBYTECODESETS - BlockCreationBytecodeSize -#endif - ); - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader1 = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader1) - ? 0x100 - : 0) -# else - 0 -# endif - ; - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - endbcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, -1, aMethodObj)) - : 0)); - bcpc = startbcpc; - } - nExts = 0; - while ((((usqInt)((byteAt(map)))) >> AnnotationShift) != HasBytecodePC) { - map -= 1; - } - map -= 1; - while (((mapByte = byteAt(map))) != MapEnd) { - - /* defensive; we exit on bcpc */ - if (mapByte >= FirstAnnotation) { - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if (annotation >= HasBytecodePC) { - if ((annotation == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - while (1) { - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - if (isInBlock) { - if (bcpc >= endbcpc) { - errCode = 0; - goto l7; - } - } - else { - if (((descriptor->isReturn)) - && (bcpc >= latestContinuation)) { - errCode = 0; - goto l7; - } - if ((isBranch(descriptor)) - || ((descriptor->isBlockCreation))) { - /* begin latestContinuationPCFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj); - targetPC = (bcpc + ((descriptor->numBytes))) + (((distance < 0) ? 0 : distance)); - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - /* latestContinuation = */ latestContinuation; - } - nextBcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) - : 0)); - if (((descriptor->isMapped)) - || (isInBlock - && ((descriptor->isMappedInBlock)))) break; - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - isBackwardBranch = (isBranch(descriptor)) - && ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) < 0)); - result = collectCogConstituentForAnnotationMcpcBcpcMethod(descriptor, ((isBackwardBranch - ? (((sqInt)((usqInt)(annotation) << 1))) + 1 - : ((sqInt)((usqInt)(annotation) << 1)))), (((char *) mcpc)), ((isBackwardBranch - ? bcpc - (2 * nExts) - : bcpc)), (((void *)cogMethod))); - if (result != 0) { - errCode = result; - goto l7; - } - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - } - else { - assert(((((usqInt)(mapByte)) >> AnnotationShift) == IsDisplacementX2N) - || ((((usqInt)(mapByte)) >> AnnotationShift) == IsAnnotationExtension)); - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - errCode = 0; - l7: /* end mapFor:bcpc:performUntil:arg: */; - if (errCode != 0) { - popRemappableOop(); - return null; - } - if (cogConstituentIndex < nSlots) { - shortentoIndexableSize(topRemappableOop(), cogConstituentIndex); - } - return popRemappableOop(); -} - - /* Cogit>>#compactCogCompiledCode */ -void -compactCogCompiledCode(void) -{ - assertValidDualZone(); - assert(noCogMethodsMaximallyMarked()); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - markActiveMethodsAndReferents(); - freeOlderMethodsForCompaction(); - compactPICsWithFreedTargets(); - planCompaction(); - updateStackZoneReferencesToCompiledCodePreCompaction(); - relocateMethodsPreCompaction(); - assertValidDualZone(); - compactCompiledCode(); - stopsFromto(backEnd, freeStart(), (youngReferrers()) - 1); - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), ((usqInt)(youngReferrers()))); - assert(allMethodsHaveCorrectHeader()); - assert(kosherYoungReferrers()); - assertValidDualZone(); -} - - /* Cogit>>#compactPICsWithFreedTargets */ -static void -compactPICsWithFreedTargets(void) -{ - CogMethod *cogMethod; - sqInt count; - - cogMethod = ((CogMethod *) methodZoneBase); - count = 0; - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) == CMClosedPIC) - && (cPICCompactAndIsNowEmpty(cogMethod))) { - ((((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)))->cmType = CMFree); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - count += 1; - } - assert(count == (numMethods())); -} - - -/* The start of a CogMethod has a call to a run-time abort routine that - either handles an in-line cache failure or a stack overflow. The routine - selects the - path depending on ReceiverResultReg; if zero it takes the stack overflow - path; if nonzero the in-line cache miss path. Neither of these paths - returns. The abort routine must be called; In the callee the method is - located by - adding the relevant offset to the return address of the call. - - N.B. This code must match that in compilePICAbort: so that the offset of - the return address of the call is the same in methods and closed PICs. */ - - /* Cogit>>#compileAbort */ -static AbstractInstruction * -compileAbort(void) -{ - AbstractInstruction *anInstruction; - sqInt callTarget; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 0, ReceiverResultReg); - stackOverflowCall = anInstruction; - - /* If there is a link register it must be saved (pushed onto the stack) before it - is smashed by the abort call, and hence needs to be manually handled here */ - sendMiss = genoperand(PushR, LinkReg); - /* begin Call: */ - callTarget = methodAbortTrampolineFor(methodOrBlockNumArgs); - return genoperand(Call, callTarget); -} - - /* Cogit>>#compileBlockDispatchFrom:to: */ -static sqInt NoDbgRegParms -compileBlockDispatchFromto(sqInt lowBlockStartIndex, sqInt highBlockStartIndex) -{ - AbstractInstruction *anInstruction; - BlockStart *blockStart; - sqInt halfWay; - AbstractInstruction *jmp; - - if (lowBlockStartIndex == highBlockStartIndex) { - blockStart = blockStartAt(lowBlockStartIndex); - genoperand(Jump, ((sqInt)((blockStart->entryLabel)))); - return null; - } - halfWay = (highBlockStartIndex + lowBlockStartIndex) / 2; - assert(((halfWay >= lowBlockStartIndex) && (halfWay <= highBlockStartIndex))); - - /* N.B. FLAGS := TempReg - startpc */ - blockStart = blockStartAt(halfWay); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)(((blockStart->startpc)) + 1) << 1) | 1); - anInstruction = genoperandoperand(CmpCqR, (((usqInt)(((blockStart->startpc)) + 1) << 1) | 1), TempReg); - if (lowBlockStartIndex == halfWay) { - genConditionalBranchoperand(JumpLessOrEqual, ((sqInt)((blockStart->entryLabel)))); - compileBlockDispatchFromto(halfWay + 1, highBlockStartIndex); - return null; - } - if ((halfWay + 1) == highBlockStartIndex) { - blockStart = blockStartAt(highBlockStartIndex); - genConditionalBranchoperand(JumpGreater, ((sqInt)((blockStart->entryLabel)))); - return compileBlockDispatchFromto(lowBlockStartIndex, halfWay); - } - jmp = genConditionalBranchoperand(JumpGreater, ((sqInt)0)); - compileBlockDispatchFromto(lowBlockStartIndex, halfWay); - if (halfWay == highBlockStartIndex) { - blockStart = blockStartAt(highBlockStartIndex); - jmpTarget(jmp, (blockStart->entryLabel)); - } - else { - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileBlockDispatchFromto(halfWay + 1, highBlockStartIndex); - } - return 0; -} - - -/* Compile a block's entry. This looks like a dummy CogBlockMethod header - (for frame parsing) - followed by either a frame build, if a frame is required, or nothing. The - CogMethodHeader's objectHeader field is a back pointer to the method, but - this can't be filled in until code generation. */ - - /* Cogit>>#compileBlockEntry: */ -static void NoDbgRegParms -compileBlockEntry(BlockStart *blockStart) -{ - AbstractInstruction *abstractInstruction; - sqInt alignment; - - /* begin AlignmentNops: */ - alignment = blockAlignment(); - genoperand(AlignmentNops, alignment); - (blockStart->fakeHeader = genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - switch (sizeof(CogBlockMethod)) { - case 8: - genoperand(Fill32, 0); - genoperand(Fill32, 0); - break; - case 12: - genoperand(Fill32, 0); - genoperand(Fill32, 0); - genoperand(Fill32, 0); - break; - case 16: - genoperand(Fill32, 0); - genoperand(Fill32, 0); - genoperand(Fill32, 0); - genoperand(Fill32, 0); - break; - default: - error("Case not found and no otherwise clause"); - } - (blockStart->entryLabel = genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (needsFrame) { - compileBlockFrameBuild(blockStart); - if (recordBlockTrace()) { - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceTraceBlockActivationTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - } - } - else { - compileBlockFramelessEntry(blockStart); - } -} - - -/* Generate a call to aRoutine with up to 4 arguments. If resultRegOrNone is - not NoReg assign the C result to resultRegOrNone. If saveRegs, save all - registers. Hack: a negative arg value indicates an abstract register, a - non-negative value - indicates a constant. */ - - /* Cogit>>#compileCallFor:numArgs:arg:arg:arg:arg:resultReg:regsToSave: */ -static void NoDbgRegParms -compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt resultRegOrNone, sqInt regMask) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - const int cStackAlignment = STACK_ALIGN_BYTES; - sqInt delta; - sqInt numRegsPushed; - usqInt regMaskCopy; - sqInt regsToSave; - sqInt wordsPushedModAlignment; - - regsToSave = (resultRegOrNone == NoReg - ? regMask - : ((regMask | (1U << resultRegOrNone)) - (1U << resultRegOrNone))); - if (cStackAlignment > BytesPerWord) { - /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ - regMaskCopy = ((usqInt)regsToSave); - numRegsPushed = 0; - while (regMaskCopy != 0) { - numRegsPushed += regMaskCopy & 1; - regMaskCopy = ((regMaskCopy) >> 1); - } - if ((numRegsPushed == 0) - && ((numIntRegArgs(((AbstractInstruction *) backEnd))) >= numArgs)) { - goto l1; - } - wordsPushedModAlignment = (numRegsPushed + ((((numArgs - (numIntRegArgs(((AbstractInstruction *) backEnd)))) < 0) ? 0 : (numArgs - (numIntRegArgs(((AbstractInstruction *) backEnd))))))) % (cStackAlignment / BytesPerWord); - if (wordsPushedModAlignment != 0) { - delta = (cStackAlignment / BytesPerWord) - wordsPushedModAlignment; - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, delta * BytesPerWord, SPReg); - } - l1: /* end genAlignCStackSavingRegisters:numArgs:wordAlignment: */; - } - genSaveRegs(backEnd, regsToSave); - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - if (numArgs == 0) { - goto l13; - } - if (regOrConst0 < NoReg) { - /* begin MoveCq:R: */ - anInstruction4 = genoperandoperand(MoveCqR, -2 - regOrConst0, A0); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, regOrConst0, A0); - } - if (numArgs == 1) { - goto l13; - } - if (regOrConst1 < NoReg) { - /* begin MoveCq:R: */ - anInstruction11 = genoperandoperand(MoveCqR, -2 - regOrConst1, A1); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, regOrConst1, A1); - } - if (numArgs == 2) { - goto l13; - } - if (regOrConst2 < NoReg) { - /* begin MoveCq:R: */ - anInstruction21 = genoperandoperand(MoveCqR, -2 - regOrConst2, A2); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, regOrConst2, A2); - } - if (numArgs == 3) { - goto l13; - } - if (regOrConst3 < NoReg) { - /* begin MoveCq:R: */ - anInstruction3 = genoperandoperand(MoveCqR, -2 - regOrConst3, A3); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, regOrConst3, A3); - } - l13: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin checkLiteral:forInstruction: */ - anInstruction2 = genoperand(CallFull, ((usqInt)aRoutine)); - genWriteCResultIntoReg(backEnd, resultRegOrNone); - assert(numArgs <= 4); - genRestoreRegs(backEnd, regsToSave); -} - - -/* Compile the cache tag computation and the first comparison. Answer the - address of that comparison. */ - - /* Cogit>>#compileCPICEntry */ -static AbstractInstruction * -compileCPICEntry(void) -{ - entry = genGetInlineCacheClassTagFromintoforEntry(ReceiverResultReg, TempReg, 1); - /* begin CmpR:R: */ - assert(!((ClassReg == SPReg))); - genoperandoperand(CmpRR, ClassReg, TempReg); - return genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -} - - -/* Compile the abstract instructions for the entire full block method. */ - - /* Cogit>>#compileEntireFullBlockMethod: */ -static sqInt NoDbgRegParms -compileEntireFullBlockMethod(sqInt numCopied) -{ - sqInt result; - - /* begin preenMethodLabel */ - (((((AbstractInstruction *) methodLabel))->operands))[1] = 0; - compileFullBlockEntry(); - compileFullBlockMethodFrameBuild(numCopied); - if (((result = compileMethodBody())) < 0) { - return result; - } - assert(blockCount == 0); - return 0; -} - - -/* The entry code to a method checks that the class of the current receiver - matches that in the inline cache. Other non-obvious elements are that its - alignment must be - different from the alignment of the noCheckEntry so that the method map - machinery can distinguish normal and super sends (super sends bind to the - noCheckEntry). */ - - /* Cogit>>#compileEntry */ -static void -compileEntry(void) -{ - AbstractInstruction *anInstruction1; - AbstractInstruction * inst; - - entry = genGetInlineCacheClassTagFromintoforEntry(ReceiverResultReg, TempReg, 1); - /* begin CmpR:R: */ - assert(!((ClassReg == SPReg))); - genoperandoperand(CmpRR, ClassReg, TempReg); - genConditionalBranchoperand(JumpNonZero, ((sqInt)sendMiss)); - noCheckEntry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - if (((traceFlags & 0x100) == 0x100)) { - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - /* begin checkLiteral:forInstruction: */ - anInstruction1 = genoperand(CallFull, ceTraceLinkedSendTrampoline); - /* begin PopR: */ - genoperand(PopR, LinkReg); - } -} - - -/* Compile the abstract instructions for the entire method, including blocks. */ -/* Abort for stack overflow on full block activation (no inline cache miss - possible). The flag is SendNumArgsReg. */ - - /* Cogit>>#compileFullBlockEntry */ -static sqInt -compileFullBlockEntry(void) -{ - sqInt alignment; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt callTarget; - AbstractInstruction * jumpNoContextSwitch; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 0, ReceiverResultReg); - stackOverflowCall = anInstruction; - /* begin PushR: */ - genoperand(PushR, LinkReg); - /* begin Call: */ - callTarget = methodAbortTrampolineFor(methodOrBlockNumArgs); - genoperand(Call, callTarget); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, 0, SendNumArgsReg); - fullBlockNoContextSwitchEntry = anInstruction1; - jumpNoContextSwitch = genoperand(Jump, ((sqInt)0)); - /* begin AlignmentNops: */ - alignment = ((BytesPerWord < 8) ? 8 : BytesPerWord); - genoperand(AlignmentNops, alignment); - fullBlockEntry = genoperandoperand(MoveRR, ReceiverResultReg, SendNumArgsReg); - jmpTarget(jumpNoContextSwitch, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - -/* Compile the top-level method body. */ - - /* Cogit>>#compileMethodBody */ -static sqInt -compileMethodBody(void) -{ - if (endPC < initialPC) { - return 0; - } - return compileAbstractInstructionsFromthrough(initialPC + (deltaToSkipPrimAndErrorStoreInheader(methodObj, methodHeader)), endPC); -} - - -/* The start of a PIC has a call to a run-time abort routine that either - handles a dispatch to an - interpreted method or a dispatch of an MNU case. The routine selects the - path by testing - ClassReg, which holds the inline cache tag; if equal to the - picAbortDiscriminatorValue (zero) - it takes the MNU path; if nonzero the dispatch to interpreter path. - Neither of these paths - returns. The abort routine must be called; In the callee the PIC is - located by adding the - relevant offset to the return address of the call. - - N.B. This code must match that in compileAbort so that the offset of the - return address of - the call is the same in methods and closed PICs. */ - - /* Cogit>>#compilePICAbort: */ -static sqInt NoDbgRegParms -compilePICAbort(sqInt numArgs) -{ - AbstractInstruction *anInstruction; - sqInt callTarget; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 0 /* picAbortDiscriminatorValue */, ClassReg); - picMNUAbort = anInstruction; - - /* If there is a link register it must be saved (pushed onto the stack) before it - is smashed by the abort call, and hence needs to be manually handled here */ - picInterpretAbort = genoperand(PushR, LinkReg); - /* begin Call: */ - callTarget = picAbortTrampolineFor(numArgs); - genoperand(Call, callTarget); - return 0; -} - - -/* Compile the compare of stackLimit against the stack pointer, jumping to - the stackOverflowCall if - the stack pointer is below the limit. Answer a bytecode annotated label - that follows the sequence. - - The stack check functions both as a genuine stack limit check to prevent - calls overflowing stack pages, - and as an event/context-switch break out. To cause an event check - (including a check for a required - context switch), stackLimit is set to the highest possible value, and - hence all stack limit checks will - fail. A path in the stack overflow abort then arranges to call event - checking if it has been requested. - - Certain block activations (e.g. valueNoContextSwitch:) must not context - switch, and in that - case, SendNumArgs is set to zero to communicate to the stack overflow - abort that it should - not perform event/context-switch (yet). */ - - /* Cogit>>#compileStackOverflowCheck: */ -static AbstractInstruction * NoDbgRegParms -compileStackOverflowCheck(sqInt canContextSwitch) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction * jumpSkip; - AbstractInstruction * label; - - /* begin checkLiteral:forInstruction: */ - stackLimitAddress(); - anInstruction1 = genoperandoperand(MoveAwR, stackLimitAddress(), TempReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, SPReg); - if (canContextSwitch) { - genConditionalBranchoperand(JumpBelow, ((sqInt)stackOverflowCall)); - label = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - else { - jumpSkip = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 0, SendNumArgsReg); - genoperand(Jump, ((sqInt)stackOverflowCall)); - jmpTarget(jumpSkip, (label = genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - } - /* begin annotateBytecode: */ - (label->annotation = HasBytecodePC); - return label; -} - - -/* Generate a trampoline with up to four arguments. Generate either a call or - a jump to aRoutine - as requested by callJumpBar. If generating a call and resultRegOrNone is - not NoReg pass the C - result back in resultRegOrNone. - Hack: a negative value indicates an abstract register, a non-negative - value indicates a constant. */ - - /* Cogit>>#compileTrampolineFor:numArgs:arg:arg:arg:arg:regsToSave:pushLinkReg:resultReg: */ -static void NoDbgRegParms -compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone) -{ - genSmalltalkToCStackSwitch(pushLinkReg); - compileCallFornumArgsargargargargresultRegregsToSave(aRoutine, numArgs, regOrConst0, regOrConst1, regOrConst2, regOrConst3, resultRegOrNone, regMask); - genLoadStackPointers(backEnd); - genTrampolineReturn(pushLinkReg); -} - - -/* Generate the entry code for a method to determine cmEntryOffset and - cmNoCheckEntryOffset. We - need cmNoCheckEntryOffset up front to be able to generate the map starting - from cmNoCheckEntryOffset */ -/* stack allocate the various collections so that they - are effectively garbage collected on return. */ - - /* Cogit>>#computeEntryOffsets */ -static void -computeEntryOffsets(void) -{ - sqInt fixupSize; - sqInt opcodeSize; - AbstractInstruction *sendMissCall; - - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 24; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - methodOrBlockNumArgs = 0; - sendMissCall = compileAbort(); - compileEntry(); - computeMaximumSizes(); - generateInstructionsAt(methodZoneBase + (sizeof(CogMethod))); - cmEntryOffset = ((entry->address)) - methodZoneBase; - cmNoCheckEntryOffset = ((noCheckEntry->address)) - methodZoneBase; - missOffset = (((sendMissCall->address)) + ((sendMissCall->machineCodeSize))) - methodZoneBase; - entryPointMask = BytesPerWord - 1; - while ((cmEntryOffset & entryPointMask) == (cmNoCheckEntryOffset & entryPointMask)) { - entryPointMask = (entryPointMask + entryPointMask) + 1; - } - if (entryPointMask >= (roundUpToMethodAlignment(backEnd(), 1))) { - error("cannot differentiate checked and unchecked entry-points with current cog method alignment"); - } - checkedEntryAlignment = cmEntryOffset & entryPointMask; - uncheckedEntryAlignment = cmNoCheckEntryOffset & entryPointMask; - assert(checkedEntryAlignment != uncheckedEntryAlignment); -} - - -/* Generate the entry code for a method to determine cmEntryOffset and - cmNoCheckEntryOffset. We - need cmNoCheckEntryOffset up front to be able to generate the map starting - from cmNoCheckEntryOffset */ -/* stack allocate the various collections so that they - are effectively garbage collected on return. */ - - /* Cogit>>#computeFullBlockEntryOffsets */ -static void -computeFullBlockEntryOffsets(void) -{ - sqInt fixupSize; - sqInt opcodeSize; - - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 24; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - methodOrBlockNumArgs = 0; - compileFullBlockEntry(); - computeMaximumSizes(); - generateInstructionsAt(methodZoneBase + (sizeof(CogMethod))); - cbEntryOffset = ((fullBlockEntry->address)) - methodZoneBase; - cbNoSwitchEntryOffset = ((fullBlockNoContextSwitchEntry->address)) - methodZoneBase; -} - - -/* While we order variables in the CoInterpreter in order of dynamic - frequency, and hence - expect that stackPointer will be output first, C optimizers and linkers - may get their own - ideas and ``improve upon'' this ordering. So we cannot depend on - stackPointer being - at the lowest address of the variables we want to access through - VarBaseReg. Here we - choose the minimum amongst a set to try to choose a varBaseAddress that is - just less - than but iwht in range of all variables we want to access through it. */ - - /* Cogit>>#computeGoodVarBaseAddress */ -static usqInt -computeGoodVarBaseAddress(void) -{ - usqInt minAddress; - - - /* stackLimit is e.g. lowest using the clang toolchain on MacOS X */ - minAddress = stackLimitAddress(); - if ((stackPointerAddress()) < minAddress) { - minAddress = stackPointerAddress(); - } - if ((framePointerAddress()) < minAddress) { - minAddress = framePointerAddress(); - } - if ((instructionPointerAddress()) < minAddress) { - minAddress = instructionPointerAddress(); - } - if ((argumentCountAddress()) < minAddress) { - minAddress = argumentCountAddress(); - } - if ((primFailCodeAddress()) < minAddress) { - minAddress = primFailCodeAddress(); - } - return minAddress; -} - - -/* This pass assigns maximum sizes to all abstract instructions and - eliminates jump fixups. - It hence assigns the maximum address an instruction will occur at which - allows the next - pass to conservatively size jumps. */ - - /* Cogit>>#computeMaximumSizes */ -static void -computeMaximumSizes(void) -{ - AbstractInstruction *abstractInstruction; - sqInt i; - sqInt relativeAddress; - - relativeAddress = 0; - for (i = 0; i < opcodeIndex; i += 1) { - maybeBreakGeneratingInstructionWithIndex(i); - abstractInstruction = abstractInstructionAt(i); - (abstractInstruction->address = relativeAddress); - (abstractInstruction->maxSize = computeMaximumSize(abstractInstruction)); - relativeAddress += (abstractInstruction->maxSize); - } -} - - -/* Configure a copy of the prototype CPIC for a two-case PIC for - case0CogMethod and - case1Method - case1Tag. - The tag for case0CogMethod is at the send site and so doesn't need to be - generated. case1Method may be any of - - a Cog method; jump to its unchecked entry-point - - a CompiledMethod; jump to the ceInterpretFromPIC trampoline - - nil; call ceMNUFromPIC - addDelta is the address change from the prototype to the new CPIC - location, needed - because the loading of the CPIC label at the end may use a literal instead - of a pc relative load. */ -/* self disassembleFrom: cPIC asInteger + (self sizeof: CogMethod) to: cPIC - asInteger + closedPICSize - */ - - /* Cogit>>#configureCPIC:Case0:Case1Method:tag:isMNUCase:numArgs:delta: */ -static sqInt NoDbgRegParms -configureCPICCase0Case1MethodtagisMNUCasenumArgsdelta(CogMethod *cPIC, CogMethod *case0CogMethod, sqInt case1Method, sqInt case1Tag, sqInt isMNUCase, sqInt numArgs, sqInt addrDelta) -{ - sqInt caseEndAddress; - int operand; - sqInt targetEntry; - - assert(case1Method != null); - rewriteCallAttarget(backEnd, (((sqInt)cPIC)) + missOffset, picAbortTrampolineFor(numArgs)); - assert(!(inlineCacheTagIsYoung(case1Tag))); - if ((!isMNUCase) - && (methodHasCogMethod(case1Method))) { - operand = 0; - targetEntry = (((sqInt)(cogMethodOf(case1Method)))) + cmNoCheckEntryOffset; - } - else { - - /* We do not scavenge PICs, hence we cannot cache the MNU method if it is in new space. */ - operand = ((case1Method == null) - || (isYoungObject(case1Method)) - ? 0 - : case1Method); - targetEntry = (case1Method == null - ? (((sqInt)cPIC)) + (sizeof(CogMethod)) - : (((sqInt)cPIC)) + (picInterpretAbortOffset())); - } - rewriteJumpLongAttarget(backEnd, (((sqInt)cPIC)) + firstCPICCaseOffset, (((sqInt)case0CogMethod)) + cmNoCheckEntryOffset); - - /* update the cpic case */ - caseEndAddress = addressOfEndOfCaseinCPIC(2, cPIC); - rewriteCPICCaseAttagobjReftarget(caseEndAddress, case1Tag, operand, ((sqInt)((isMNUCase - ? (((sqInt)cPIC)) + (sizeof(CogMethod)) - : targetEntry)))); - relocateMethodReferenceBeforeAddressby(backEnd, ((((sqInt)cPIC)) + cPICEndOfCodeOffset) - (jumpLongByteSize(backEnd)), addrDelta); - rewriteJumpLongAttarget(backEnd, (((sqInt)cPIC)) + cPICEndOfCodeOffset, cPICMissTrampolineFor(numArgs)); - return 0; -} - - -/* Configure a copy of the prototype CPIC for a one-case MNU CPIC that calls - ceMNUFromPIC for - case0Tag The tag for case0 is at the send site and so doesn't need to be - generated. addDelta is the address change from the prototype to the new - CPIC location, needed - because the loading of the CPIC label at the end may be a literal instead - of a pc-relative load. */ -/* adjust the jump at missOffset, the ceAbortXArgs */ - - /* Cogit>>#configureMNUCPIC:methodOperand:numArgs:delta: */ -static sqInt NoDbgRegParms -configureMNUCPICmethodOperandnumArgsdelta(CogMethod *cPIC, sqInt methodOperand, sqInt numArgs, sqInt addrDelta) -{ - int operand; - sqInt target; - - rewriteCallAttarget(backEnd, (((sqInt)cPIC)) + missOffset, picAbortTrampolineFor(numArgs)); - - /* set the jump to the case0 method */ - operand = ((methodOperand == null) - || (isYoungObject(methodOperand)) - ? 0 - : methodOperand); - rewriteJumpLongAttarget(backEnd, (((sqInt)cPIC)) + firstCPICCaseOffset, (((sqInt)cPIC)) + (sizeof(CogMethod))); - storeLiteralbeforeFollowingAddress(backEnd, operand, ((((sqInt)cPIC)) + firstCPICCaseOffset) - (jumpLongByteSize(backEnd))); - rewriteJumpLongAttarget(backEnd, (((sqInt)cPIC)) + cPICEndOfCodeOffset, cPICMissTrampolineFor(numArgs)); - relocateMethodReferenceBeforeAddressby(backEnd, ((((sqInt)cPIC)) + cPICEndOfCodeOffset) - (jumpLongByteSize(backEnd)), addrDelta); - /* begin rewriteCPIC:caseJumpTo: */ - target = addressOfEndOfCaseinCPIC(2, cPIC); - rewriteCPICJumpAttarget(backEnd, (((((sqInt)cPIC)) + firstCPICCaseOffset) - (jumpLongByteSize(backEnd))) - 8 /* loadLiteralByteSize */, target); - return 0; -} - - -/* Scan the CPIC for target methods that have been freed and eliminate them. - Since the first entry cannot be eliminated, answer that the PIC should be - freed if the first entry is to a free target. Answer if the PIC is now - empty or should be freed. */ - - /* Cogit>>#cPICCompactAndIsNowEmpty: */ -static sqInt NoDbgRegParms -cPICCompactAndIsNowEmpty(CogMethod *cPIC) -{ - usqInt entryPoint; - sqInt followingAddress; - sqInt i; - sqInt methods[MaxCPICCases]; - sqInt pc; - int tags[MaxCPICCases]; - CogMethod *targetMethod; - sqInt targets[MaxCPICCases]; - sqInt used; - sqInt valid; - - used = 0; - for (i = 1; i <= ((cPIC->cPICNumCases)); i += 1) { - pc = addressOfEndOfCaseinCPIC(i, cPIC); - entryPoint = (i == 1 - ? jumpLongTargetBeforeFollowingAddress(backEnd, pc) - : jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc)); - - /* Collect all target triples except for triples whose entry-point is a freed method */ - valid = 1; - if (!(((((usqInt)cPIC)) <= (((usqInt)entryPoint))) - && (((((usqInt)cPIC)) + ((cPIC->blockSize))) >= (((usqInt)entryPoint))))) { - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - assert((((targetMethod->cmType)) == CMMethod) - || (((targetMethod->cmType)) == CMFree)); - if (((targetMethod->cmType)) == CMFree) { - if (i == 1) { - return 1; - } - valid = 0; - } - } - if (valid) { - tags[used] = ((i > 1 - ? (/* begin literal32BeforeFollowingAddress: */ - (followingAddress = pc - 16 /* jumpLongConditionalByteSize */), - literalBeforeFollowingAddress(((AbstractInstruction *) backEnd), followingAddress)) - : 0)); - targets[used] = entryPoint; - methods[used] = (literalBeforeFollowingAddress(backEnd, pc - ((i == 1 - ? jumpLongByteSize(backEnd) - : 24)))); - used += 1; - } - } - if (used == ((cPIC->cPICNumCases))) { - return 0; - } - if (used == 0) { - return 1; - } - ((((CogMethod *) ((((usqInt)cPIC)) + codeToDataDelta)))->cPICNumCases = used); - if (used == 1) { - pc = addressOfEndOfCaseinCPIC(2, cPIC); - /* begin rewriteCPIC:caseJumpTo: */ - rewriteCPICJumpAttarget(backEnd, (((((sqInt)cPIC)) + firstCPICCaseOffset) - (jumpLongByteSize(backEnd))) - 8 /* loadLiteralByteSize */, pc); - return 0; - } - for (i = 1; i < used; i += 1) { - pc = addressOfEndOfCaseinCPIC(i + 1, cPIC); - rewriteCPICCaseAttagobjReftarget(pc, tags[i], methods[i], targets[i]); - } - /* begin rewriteCPIC:caseJumpTo: */ - rewriteCPICJumpAttarget(backEnd, (((((sqInt)cPIC)) + firstCPICCaseOffset) - (jumpLongByteSize(backEnd))) - 8 /* loadLiteralByteSize */, pc - cPICCaseSize); - return 0; -} - - -/* The first case in a CPIC doesn't have a class reference so we need only - step over actually usd subsequent cases. - */ - - /* Cogit>>#cPICHasForwardedClass: */ -static sqInt NoDbgRegParms -cPICHasForwardedClass(CogMethod *cPIC) -{ - usqInt classIndex; - sqInt i; - sqInt pc; - - - /* start by finding the address of the topmost case, the cPICNumCases'th one */ - pc = (addressOfEndOfCaseinCPIC((cPIC->cPICNumCases), cPIC)) - 16 /* jumpLongConditionalByteSize */; - for (i = 2; i <= ((cPIC->cPICNumCases)); i += 1) { - /* begin literal32BeforeFollowingAddress: */ - classIndex = literalBeforeFollowingAddress(((AbstractInstruction *) backEnd), pc); - if (isForwardedClassIndex(classIndex)) { - return 1; - } - pc += cPICCaseSize; - } - return 0; -} - - -/* scan the CPIC for target methods that have been freed. */ - - /* Cogit>>#cPICHasFreedTargets: */ -static sqInt NoDbgRegParms -cPICHasFreedTargets(CogMethod *cPIC) -{ - sqInt entryPoint; - sqInt i; - sqInt pc; - CogMethod *targetMethod; - - for (i = 1; i <= ((cPIC->cPICNumCases)); i += 1) { - pc = addressOfEndOfCaseinCPIC(i, cPIC); - - /* Find target from jump. Ignore jumps to the interpret and MNU calls within this PIC */ - entryPoint = (i == 1 - ? jumpLongTargetBeforeFollowingAddress(backEnd, pc) - : jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc)); - if (!(((((usqInt)cPIC)) <= (((usqInt)entryPoint))) - && (((((usqInt)cPIC)) + ((cPIC->blockSize))) >= (((usqInt)entryPoint))))) { - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - assert((((targetMethod->cmType)) == CMMethod) - || (((targetMethod->cmType)) == CMFree)); - if (((targetMethod->cmType)) == CMFree) { - return 1; - } - } - } - return 0; -} - - -/* Whimsey; we want 16rCA5E10 + cPICPrototypeCaseOffset to be somewhere in - the middle of the zone. - */ - - /* Cogit>>#cPICPrototypeCaseOffset */ -static usqInt -cPICPrototypeCaseOffset(void) -{ - return ((methodZoneBase + (youngReferrers())) / 2) - 13262352; -} - - -/* Are any of the jumps from this CPIC to targetMethod? */ - - /* Cogit>>#cPIC:HasTarget: */ -static sqInt NoDbgRegParms -cPICHasTarget(CogMethod *cPIC, CogMethod *targetMethod) -{ - sqInt i; - sqInt pc; - sqInt target; - - target = (((usqInt)targetMethod)) + cmNoCheckEntryOffset; - - /* Since this is a fast test doing simple compares we don't need to care that some - cases have nonsense addresses in there. Just zip on through. */ - /* First jump is unconditional; subsequent ones are conditional */ - pc = (((sqInt)cPIC)) + firstCPICCaseOffset; - if (target == (jumpLongTargetBeforeFollowingAddress(backEnd, pc))) { - return 1; - } - for (i = 2; i <= MaxCPICCases; i += 1) { - pc += cPICCaseSize; - if (target == (jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc))) { - return 1; - } - } - return 0; -} - - -/* Answer an Array of the PIC's selector, followed by class and - targetMethod/doesNotUnderstand: for each entry in the PIC. - */ - - /* Cogit>>#createCPICData: */ -static sqInt NoDbgRegParms -createCPICData(CogMethod *cPIC) -{ - sqInt class; - usqInt entryPoint; - sqInt i; - sqInt pc; - sqInt picData; - sqInt target; - CogMethod *targetMethod; - - assert((((cPIC->methodObject)) == 0) - || (addressCouldBeOop((cPIC->methodObject)))); - picData = instantiateClassindexableSize(classArray(), (((cPIC->cPICNumCases)) * 2) + 1); - if (!picData) { - return picData; - } - storePointerUncheckedofObjectwithValue(0, picData, (cPIC->selector)); - for (i = 1; i <= ((cPIC->cPICNumCases)); i += 1) { - pc = addressOfEndOfCaseinCPIC(i, cPIC); - if (i == 1) { - - /* first case may have been collected and stored here by collectCogConstituentFor:Annotation:Mcpc:Bcpc:Method: */ - class = (cPIC->methodObject); - if (class == 0) { - class = nilObject(); - } - entryPoint = jumpLongTargetBeforeFollowingAddress(backEnd, pc); - } - else { - class = classForInlineCacheTag(literalBeforeFollowingAddress(backEnd, pc - 16 /* jumpLongConditionalByteSize */)); - entryPoint = jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc); - } - if (((((usqInt)cPIC)) <= (((usqInt)entryPoint))) - && (((((usqInt)cPIC)) + ((cPIC->blockSize))) >= (((usqInt)entryPoint)))) { - target = splObj(SelectorDoesNotUnderstand); - } - else { - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - assert(((targetMethod->cmType)) == CMMethod); - target = (targetMethod->methodObject); - } - storePointerUncheckedofObjectwithValue((i * 2) - 1, picData, class); - storePointerUncheckedofObjectwithValue(i * 2, picData, target); - } - beRootIfOld(picData); - (cPIC->methodObject = 0); - return picData; -} - - -/* Division is a little weird on some processors. Defer to the backEnd - to allow it to generate any special code it may need to. */ - - /* Cogit>>#DivR:R:Quo:Rem: */ -static AbstractInstruction * NoDbgRegParms -gDivRRQuoRem(sqInt rDivisor, sqInt rDividend, sqInt rQuotient, sqInt rRemainder) -{ - genDivRRQuoRem(backEnd, rDivisor, rDividend, rQuotient, rRemainder); - return abstractInstructionAt(opcodeIndex - 1); -} - - -/* Return the default number of bytes to allocate for native code at startup. - The actual value can be set via vmParameterAt: and/or a preference in the - ini file. */ - - /* Cogit>>#defaultCogCodeSize */ -sqInt -defaultCogCodeSize(void) -{ - return 0x180000; -} - - -/* Answer the number of bytecodes to skip to get to the first bytecode - past the primitive call and any store of the error code. */ - - /* Cogit>>#deltaToSkipPrimAndErrorStoreIn:header: */ -static sqInt NoDbgRegParms -deltaToSkipPrimAndErrorStoreInheader(sqInt aMethodObj, sqInt aMethodHeader) -{ - return (((primitiveIndexOfMethodheader(aMethodObj, aMethodHeader)) > 0) - && ((longStoreBytecodeForHeader(aMethodHeader)) == (fetchByteofObject((startPCOfMethod(aMethodObj)) + (sizeOfCallPrimitiveBytecode(aMethodHeader)), aMethodObj))) - ? (sizeOfCallPrimitiveBytecode(aMethodHeader)) + (sizeOfLongStoreTempBytecode(aMethodHeader)) - : 0); -} - - /* Cogit>>#endPCOf: */ -static sqInt NoDbgRegParms -endPCOf(sqInt aMethod) -{ - sqInt bsOffset; - sqInt byte; - BytecodeDescriptor *descriptor; - sqInt distance; - sqInt end; - sqInt latestContinuation; - sqInt nExts; - sqInt pc; - sqInt prim; - sqInt targetPC; - - pc = (latestContinuation = startPCOfMethod(aMethod)); - if (((prim = primitiveIndexOf(aMethod))) > 0) { - if (isQuickPrimitiveIndex(prim)) { - return pc - 1; - } - } - /* begin bytecodeSetOffsetFor: */ - bsOffset = -# if MULTIPLEBYTECODESETS - (methodUsesAlternateBytecodeSet(aMethod) - ? 0x100 - : 0) -# else - (assert(!((methodUsesAlternateBytecodeSet(aMethod)))), - 0) -# endif - ; - nExts = 0; - end = numBytesOf(aMethod); - while (pc <= end) { - byte = fetchByteofObject(pc, aMethod); - descriptor = generatorAt(byte + bsOffset); - if (((descriptor->isReturn)) - && (pc >= latestContinuation)) { - end = pc; - } - if ((isBranch(descriptor)) - || ((descriptor->isBlockCreation))) { - distance = ((descriptor->spanFunction))(descriptor, pc, nExts, aMethod); - targetPC = (pc + ((descriptor->numBytes))) + distance; - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - if ((descriptor->isBlockCreation)) { - pc += distance; - } - } - else { - /* latestContinuation = */ latestContinuation; - } - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - pc += (descriptor->numBytes); - } - return end; -} - - -/* This is a static version of ceEnterCogCodePopReceiverReg - for break-pointing when debugging in C. */ -/* This exists only for break-pointing. */ - - /* Cogit>>#enterCogCodePopReceiver */ -void -enterCogCodePopReceiver(void) -{ - realCEEnterCogCodePopReceiverReg(); - error("what??"); -} - - -/* Answer if the entryPoint's tag is expected to be a selector reference, as - opposed to a class tag. - */ - - /* Cogit>>#entryPointTagIsSelector: */ -static sqInt NoDbgRegParms -entryPointTagIsSelector(sqInt entryPoint) -{ - return (entryPoint < methodZoneBase) - || (((entryPoint & entryPointMask) == uncheckedEntryAlignment) - || (((entryPoint & entryPointMask) == checkedEntryAlignment) - && ((((((CogMethod *) (entryPoint - cmEntryOffset)))->cmType)) == CMOpenPIC))); -} - - -/* Use asserts to check if the ClosedPICPrototype is as expected from - compileClosedPICPrototype, and can be updated as required via - rewriteCPICCaseAt:tag:objRef:target:. If all asserts pass, answer - 0, otherwise answer a bit mask identifying all the errors. */ -/* self disassembleFrom: methodZoneBase + (self sizeof: CogMethod) to: - methodZoneBase + closedPICSize - */ - - /* Cogit>>#expectedClosedPICPrototype: */ -static sqInt NoDbgRegParms -expectedClosedPICPrototype(CogMethod *cPIC) -{ - usqInt classTag; - sqInt classTagPC; - usqInt entryPoint; - sqInt errors; - sqInt i; - sqInt methodObjPC; - usqInt object; - sqInt pc; - - errors = 0; - - /* First jump is unconditional; subsequent ones are conditional */ - pc = (((usqInt)cPIC)) + firstCPICCaseOffset; - object = literalBeforeFollowingAddress(backEnd, pc - (jumpLongByteSize(backEnd))); - if (!(asserta(object == (firstPrototypeMethodOop())))) { - errors = 1; - } - entryPoint = jumpLongTargetBeforeFollowingAddress(backEnd, pc); - if (!(asserta(entryPoint == ((cPICPrototypeCaseOffset()) + 13262352)))) { - errors += 2; - } - for (i = 1; i < MaxCPICCases; i += 1) { - - /* verify information in case is as expected. */ - pc += cPICCaseSize; - methodObjPC = (pc - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */; - object = literalBeforeFollowingAddress(backEnd, methodObjPC); - if (!(asserta(object == ((subsequentPrototypeMethodOop()) + i)))) { - errors = errors | 4; - } - classTagPC = pc - 16 /* jumpLongConditionalByteSize */; - /* begin literal32BeforeFollowingAddress: */ - classTag = literalBeforeFollowingAddress(((AbstractInstruction *) backEnd), classTagPC); - if (!(asserta(classTag == (3133021973U + i)))) { - errors = errors | 8; - } - entryPoint = jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc); - if (!(asserta(entryPoint == (((cPICPrototypeCaseOffset()) + 13262352) + (i * 16))))) { - errors = errors | 16; - } - rewriteCPICCaseAttagobjReftarget(pc, classTag ^ 0x5A5A5A5A, object ^ 0xA5A5A5A5U, entryPoint ^ 0x55AA50); - object = literalBeforeFollowingAddress(backEnd, methodObjPC); - if (!(asserta(object == (((subsequentPrototypeMethodOop()) + i) ^ 0xA5A5A5A5U)))) { - errors = errors | 32; - } - /* begin literal32BeforeFollowingAddress: */ - classTag = literalBeforeFollowingAddress(((AbstractInstruction *) backEnd), classTagPC); - if (!(asserta(classTag == ((3133021973U + i) ^ 0x5A5A5A5A)))) { - errors = errors | 64; - } - entryPoint = jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc); - if (!(asserta(entryPoint == ((((cPICPrototypeCaseOffset()) + 13262352) + (i * 16)) ^ 0x55AA50)))) { - errors = errors | 128; - } - rewriteCPICCaseAttagobjReftarget(pc, classTag ^ 0x5A5A5A5A, object ^ 0xA5A5A5A5U, entryPoint ^ 0x55AA50); - } - entryPoint = jumpLongTargetBeforeFollowingAddress(backEnd, (((usqInt)cPIC)) + cPICEndOfCodeOffset); - if (!(asserta(entryPoint == (cPICMissTrampolineFor(0))))) { - errors += 0x100; - } - return errors; -} - - -/* 224 11100000 aaaaaaaa Extend A (Ext A = Ext A prev * 256 + Ext A) */ - - /* Cogit>>#extABytecode */ -static sqInt -extABytecode(void) -{ - extA = ((((sqInt)((usqInt)(extA) << 8)))) + byte1; - return 0; -} - - -/* 225 11100001 sbbbbbbb Extend B (Ext B = Ext B prev * 256 + Ext B) */ - - /* Cogit>>#extBBytecode */ -static sqInt -extBBytecode(void) -{ - extB = ((numExtB == 0) - && (byte1 > 0x7F) - ? byte1 - 0x100 - : ((((sqInt)((usqInt)(extB) << 8)))) + byte1); - numExtB += 1; - return 0; -} - - -/* Fill in the block headers now we know the exact layout of the code. */ - - /* Cogit>>#fillInBlockHeadersAt: */ -static sqInt NoDbgRegParms -fillInBlockHeadersAt(sqInt startAddress) -{ - sqInt aCogMethodOrInteger; - CogBlockMethod *blockHeader; - BlockStart *blockStart; - sqInt i; - - if (!(needsFrame - && (blockCount > 0))) { - return null; - } - if (blockNoContextSwitchOffset == null) { - blockNoContextSwitchOffset = ((blockEntryLabel->address)) - ((blockEntryNoContextSwitch->address)); - } - else { - assert(blockNoContextSwitchOffset == (((blockEntryLabel->address)) - ((blockEntryNoContextSwitch->address)))); - } - for (i = 0; i < blockCount; i += 1) { - blockStart = blockStartAt(i); - /* begin writableBlockMethodFor: */ - aCogMethodOrInteger = (((blockStart->fakeHeader))->address); - blockHeader = ((CogBlockMethod *) ((((usqInt)aCogMethodOrInteger)) + codeToDataDelta)); - (blockHeader->homeOffset = ((((blockStart->fakeHeader))->address)) - startAddress); - (blockHeader->startpc = (blockStart->startpc)); - (blockHeader->cmType = CMBlock); - (blockHeader->cmNumArgs = (blockStart->numArgs)); - (blockHeader->cbUsesInstVars = (blockStart->hasInstVarRef)); - (blockHeader->stackCheckOffset = (((blockStart->stackCheckLabel)) == null - ? 0 - : ((((blockStart->stackCheckLabel))->address)) - ((((blockStart->fakeHeader))->address)))); - } - return 0; -} - - -/* Fill in the header for theCogMehtod method. This may be located at the - writable mapping. */ - - /* Cogit>>#fillInMethodHeader:size:selector: */ -static void NoDbgRegParms -fillInMethodHeadersizeselector(CogMethod *method, sqInt size, sqInt selector) -{ - sqInt actualMethodLocation; - CogMethod *originalMethod; - sqInt rawHeader; - - actualMethodLocation = (((usqInt)method)) - codeToDataDelta; - (method->cmType = CMMethod); - (method->objectHeader = nullHeaderForMachineCodeMethod()); - (method->blockSize = size); - (method->methodObject = methodObj); - - /* If the method has already been cogged (e.g. Newspeak accessors) then - leave the original method attached to its cog method, but get the right header. */ - rawHeader = rawHeaderOf(methodObj); - if (isCogMethodReference(rawHeader)) { - originalMethod = ((CogMethod *) rawHeader); - assert(((originalMethod->blockSize)) == size); - assert(methodHeader == ((originalMethod->methodHeader))); - } - else { - rawHeaderOfput(methodObj, actualMethodLocation); - } - (method->methodHeader = methodHeader); - (method->selector = selector); - (method->cmNumArgs = argumentCountOfMethodHeader(methodHeader)); - (method->cmHasMovableLiteral = hasMovableLiteral); - if ((method->cmRefersToYoung = hasYoungReferent)) { - addToYoungReferrers(method); - } - (method->cmUsageCount = initialMethodUsageCount()); - /* begin cpicHasMNUCase: */ - ((((CogBlockMethod *) method))->cpicHasMNUCaseOrCMIsFullBlock) = 0; - (method->cmUsesPenultimateLit = maxLitIndex >= ((literalCountOfMethodHeader(methodHeader)) - 2)); - (method->blockEntryOffset = (blockEntryLabel != null - ? ((blockEntryLabel->address)) - actualMethodLocation - : 0)); - if (needsFrame) { - if (!((((stackCheckLabel->address)) - actualMethodLocation) <= MaxStackCheckOffset)) { - error("too much code for stack check offset"); - } - } - (method->stackCheckOffset = (needsFrame - ? ((stackCheckLabel->address)) - actualMethodLocation - : 0)); - assert((callTargetFromReturnAddress(backEnd, actualMethodLocation + missOffset)) == (methodAbortTrampolineFor((method->cmNumArgs)))); - assert(size == (roundUpLength(size))); - /* begin assertValidDualZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, actualMethodLocation + cmNoCheckEntryOffset, codeToDataDelta); -# endif - /* begin maybeEnableSingleStep */ -} - - /* Cogit>>#findBackwardBranch:IsBackwardBranch:Mcpc:Bcpc:MatchingBcpc: */ -static sqInt NoDbgRegParms -findBackwardBranchIsBackwardBranchMcpcBcpcMatchingBcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *targetBcpc) -{ - return ((((isBackwardBranchAndAnnotation & 1) != 0)) - && ((((sqInt)targetBcpc)) == bcpc) - ? ((sqInt)mcpc) - : 0); -} - - /* Cogit>>#findBlockMethodWithEntry:startBcpc: */ -static usqInt NoDbgRegParms -findBlockMethodWithEntrystartBcpc(sqInt blockEntryMcpc, sqInt startBcpc) -{ - CogBlockMethod *cogBlockMethod; - - cogBlockMethod = ((CogBlockMethod *) (blockEntryMcpc - (sizeof(CogBlockMethod)))); - if (((cogBlockMethod->startpc)) == startBcpc) { - return ((usqInt)cogBlockMethod); - } - return 0; -} - - /* Cogit>>#findMapLocationForMcpc:inMethod: */ -static usqInt NoDbgRegParms -findMapLocationForMcpcinMethod(usqInt targetMcpc, CogMethod *cogMethod) -{ - sqInt annotation; - usqInt map; - sqInt mapByte; - sqInt mcpc; - - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - if (mcpc == targetMcpc) { - return map; - } - while (((mapByte = byteAt(map))) != MapEnd) { - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - if (annotation != IsAnnotationExtension) { - mcpc += 4 /* codeGranularity */ * ((annotation == IsDisplacementX2N - ? ((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift)) - : mapByte & DisplacementMask)); - } - if (mcpc >= targetMcpc) { - assert(mcpc == targetMcpc); - if (annotation == IsDisplacementX2N) { - map -= 1; - mapByte = byteAt(map); - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - assert(annotation > IsAnnotationExtension); - } - return map; - } - map -= 1; - } - return 0; -} - - -/* Find the CMMethod or CMBlock that has zero-relative startbcpc as its first - bytecode pc. - As this is for cannot resume processing and/or conversion to machine-code - on backward - branch, it doesn't have to be fast. Enumerate block returns and map to - bytecode pcs. */ - - /* Cogit>>#findMethodForStartBcpc:inHomeMethod: */ -CogBlockMethod * -findMethodForStartBcpcinHomeMethod(sqInt startbcpc, CogMethod *cogMethod) -{ - assert(((cogMethod->cmType)) == CMMethod); - if (startbcpc == (startPCOfMethodHeader((cogMethod->methodHeader)))) { - return ((CogBlockMethod *) cogMethod); - } - assert(((cogMethod->blockEntryOffset)) != 0); - return ((CogBlockMethod *) (blockDispatchTargetsForperformarg(cogMethod, findBlockMethodWithEntrystartBcpc, startbcpc))); -} - - -/* Machine code addresses map to the following bytecode for all bytecodes - except backward branches, where they map to the backward branch itself. - This is so that loops continue, rather than terminate prematurely. */ - - /* Cogit>>#find:IsBackwardBranch:Mcpc:Bcpc:MatchingMcpc: */ -static sqInt NoDbgRegParms -findIsBackwardBranchMcpcBcpcMatchingMcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *targetMcpc) -{ - return (targetMcpc == mcpc - ? ((descriptor == null) - || (((isBackwardBranchAndAnnotation & 1) != 0)) - ? bcpc - : bcpc + ((descriptor->numBytes))) - : 0); -} - - /* Cogit>>#firstMappedPCFor: */ -static sqInt NoDbgRegParms -firstMappedPCFor(CogMethod *cogMethod) -{ - return ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); -} - - -/* Answer a fake value for the first method oop in the PIC prototype. - Since we use MoveUniqueCw:R: it must not be confused with a - method-relative address. */ - - /* Cogit>>#firstPrototypeMethodOop */ -static sqInt -firstPrototypeMethodOop(void) -{ - return (addressIsInCurrentCompilation(99282957) - ? 212332557 - : 99282957); -} - - /* Cogit>>#fixupAt: */ -static BytecodeFixup * NoDbgRegParms -fixupAt(sqInt fixupPC) -{ - return fixupAtIndex(fixupPC - initialPC); -} - - /* Cogit>>#followForwardedLiteralsIn: */ -void -followForwardedLiteralsIn(CogMethod *cogMethod) -{ - sqInt annotation; - sqInt hasYoungObj; - sqInt hasYoungObjPtr; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - CogMethod * writableCogMethod; - - assert((((cogMethod->cmType)) != CMMethod) - || (!(isForwarded((cogMethod->methodObject))))); - writableCogMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - hasYoungObj = isYoung((cogMethod->methodObject)); - if (shouldRemapOop((cogMethod->selector))) { - (writableCogMethod->selector = remapObj((cogMethod->selector))); - if (isYoung((cogMethod->selector))) { - hasYoungObj = 1; - } - } - hasYoungObjPtr = ((sqInt)((&hasYoungObj))); - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = remapIfObjectRefpchasYoung(annotation, (((char *) mcpc)), (((void *)hasYoungObjPtr))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - if (hasYoungObj) { - ensureInYoungReferrers(cogMethod); - } - else { - (writableCogMethod->cmRefersToYoung = 0); - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - /* Cogit>>#followForwardedMethods */ -void -followForwardedMethods(void) -{ - CogMethod * cogMethod; - sqInt freedPIC; - - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - freedPIC = 0; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - if (isForwarded((cogMethod->methodObject))) { - (cogMethod->methodObject = followForwarded((cogMethod->methodObject))); - if (isYoungObject((cogMethod->methodObject))) { - ensureInYoungReferrers(cogMethod); - } - } - } - if (((cogMethod->cmType)) == CMClosedPIC) { - if (followMethodReferencesInClosedPIC(cogMethod)) { - freedPIC = 1; - freeMethod(cogMethod); - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (freedPIC) { - unlinkSendsToFree(); - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - -/* Follow a potential object reference from a closed PIC. - This may be a method reference or null. - Answer if the followed literal is young. - 'mcpc' refers to the jump/branch instruction at the end of - each cpic case */ - - /* Cogit>>#followMaybeObjRefInClosedPICAt: */ -static sqInt NoDbgRegParms -followMaybeObjRefInClosedPICAt(sqInt mcpc) -{ - usqInt object; - sqInt subject; - - object = literalBeforeFollowingAddress(backEnd, mcpc); - if (!(couldBeObject(object))) { - return 0; - } - if (!(isForwarded(object))) { - return isYoungObject(object); - } - subject = followForwarded(object); - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - storeLiteralbeforeFollowingAddress(backEnd, subject, mcpc); - return isYoungObject(subject); -} - - -/* Remap all object references in the closed PIC. Answer if any references - are young. - Set codeModified if any modifications are made. */ - - /* Cogit>>#followMethodReferencesInClosedPIC: */ -static sqInt NoDbgRegParms -followMethodReferencesInClosedPIC(CogMethod *cPIC) -{ - sqInt i; - sqInt pc; - sqInt refersToYoung; - - - /* first we check the potential method oop load at the beginning of the CPIC */ - pc = addressOfEndOfCaseinCPIC(1, cPIC); - - /* We find the end address of the cPICNumCases'th case and can then just step forward by the case size thereafter */ - refersToYoung = followMaybeObjRefInClosedPICAt(pc - (jumpLongByteSize(backEnd))); - - /* Next we check the potential potential method oop load for each case. */ - pc = addressOfEndOfCaseinCPIC((cPIC->cPICNumCases), cPIC); - for (i = 2; i <= ((cPIC->cPICNumCases)); i += 1) { - if (followMaybeObjRefInClosedPICAt((pc - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */)) { - refersToYoung = 1; - } - pc += cPICCaseSize; - } - return refersToYoung; -} - - -/* To avoid runtime checks on literal variable and literal accesses in == and - ~~, - we follow literals in methods having movable literals in the postBecome - action. To avoid scanning every method, we annotate cogMethods with the - cmHasMovableLiteral flag. */ - - /* Cogit>>#followMovableLiteralsAndUpdateYoungReferrers */ -void -followMovableLiteralsAndUpdateYoungReferrers(void) -{ - CogMethod *cogMethod; - - assert(kosherYoungReferrers()); - codeModified = 0; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - if ((cogMethod->cmHasMovableLiteral)) { - followForwardedLiteralsIn(cogMethod); - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - pruneYoungReferrers(); - if (codeModified) { - - /* After updating oops in inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)codeBase), freeStart()); - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - /* Cogit>>#freeCogMethod: */ -void -freeCogMethod(CogMethod *cogMethod) -{ - freeMethod(cogMethod); - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - -/* Free machine-code methods whose compiled methods are unmarked - and open PICs whose selectors are not marked, and closed PICs that - refer to unmarked objects. */ - - /* Cogit>>#freeUnmarkedMachineCode */ -void -freeUnmarkedMachineCode(void) -{ - CogMethod *cogMethod; - sqInt freedMethod; - - freedMethod = 0; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) == CMMethod) - && (!(isMarked((cogMethod->methodObject))))) { - freedMethod = 1; - freeMethod(cogMethod); - } - if ((((cogMethod->cmType)) == CMOpenPIC) - && ((!(isImmediate((cogMethod->selector)))) - && (!(isMarked((cogMethod->selector)))))) { - freedMethod = 1; - freeMethod(cogMethod); - } - if ((((cogMethod->cmType)) == CMClosedPIC) - && (closedPICRefersToUnmarkedObject(cogMethod))) { - freedMethod = 1; - freeMethod(cogMethod); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (freedMethod) { - unlinkSendsToFree(); - } -} - - -/* Call ceSendMustBeBooleanTo: via the relevant trampoline. */ - - /* Cogit>>#genCallMustBeBooleanFor: */ -static AbstractInstruction * NoDbgRegParms -genCallMustBeBooleanFor(sqInt boolean) -{ - AbstractInstruction *abstractInstruction; - sqInt callTarget; - - /* begin CallRT: */ - callTarget = (boolean == (falseObject()) - ? ceSendMustBeBooleanAddFalseTrampoline - : ceSendMustBeBooleanAddTrueTrampoline); - /* begin annotateCall: */ - abstractInstruction = genoperand(Call, callTarget); - (abstractInstruction->annotation = IsRelativeCall); - return abstractInstruction; -} - - /* Cogit>>#genConditionalBranch:operand: */ -static AbstractInstruction * NoDbgRegParms -genConditionalBranchoperand(sqInt opcode, sqInt operandOne) -{ - return noteFollowingConditionalBranch(previousInstruction(), genoperand(opcode, operandOne)); -} - - -/* An enilopmart (the reverse of a trampoline) is a piece of code that makes - the system-call-like transition from the C runtime into generated machine - code. The desired arguments and entry-point are pushed on a stackPage's - stack. The enilopmart pops off the values to be loaded into registers and - then executes a return instruction to pop off the entry-point and jump to - it. - BEFORE AFTER (stacks grow down) - whatever stackPointer -> whatever - target address => reg1 = reg1val, etc - reg1val pc = target address - reg2val - stackPointer -> reg3val */ - - /* Cogit>>#genEnilopmartFor:and:and:forCall:called: */ -static void (*genEnilopmartForandandforCallcalled(sqInt regArg1, sqInt regArg2OrNone, sqInt regArg3OrNone, sqInt forCall, char *trampolineName))(void) - -{ - AbstractInstruction *anInstruction; - sqInt endAddress; - usqInt enilopmart; - sqInt quickConstant; - sqInt size; - - zeroOpcodeIndex(); - /* begin MoveCq:R: */ - quickConstant = varBaseAddress(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - genLoadStackPointers(backEnd); - if (regArg3OrNone != NoReg) { - genoperand(PopR, regArg3OrNone); - } - if (regArg2OrNone != NoReg) { - genoperand(PopR, regArg2OrNone); - } - genoperand(PopR, regArg1); - genEnilopmartReturn(forCall); - computeMaximumSizes(); - size = generateInstructionsAt(methodZoneBase); - endAddress = outputInstructionsAt(methodZoneBase); - assert((methodZoneBase + size) == endAddress); - enilopmart = methodZoneBase; - methodZoneBase = alignUptoRoutineBoundary(endAddress); - stopsFromto(backEnd, endAddress, methodZoneBase - 1); - recordGeneratedRunTimeaddress(trampolineName, enilopmart); - return ((void (*)(void)) enilopmart); -} - - -/* An enilopmart (the reverse of a trampoline) is a piece of code that makes - the system-call-like transition from the C runtime into generated machine - code. At the point the enilopmart enters machine code via a return - instruction, any argument registers have been loaded with their values and - the stack, if - for call, looks like - ret pc - stackPointer -> target address - - and if not for call, looks like - whatever - stackPointer -> target address - - If forCall and running on a CISC, ret pc must be left on the stack. If - forCall and - running on a RISC, ret pc must be popped into LinkReg. In either case, - target address must be removed from the stack and jumped/returned to. */ - - /* Cogit>>#genEnilopmartReturn: */ -static void NoDbgRegParms -genEnilopmartReturn(sqInt forCall) -{ - if (forCall) { - genoperand(PopR, RISCTempReg); - genoperand(PopR, LinkReg); - genoperand(JumpR, RISCTempReg); - } - else { - genoperand(PopR, RISCTempReg); - genoperand(JumpR, RISCTempReg); - } -} - - -/* Generate the routine that writes the current values of the C frame and - stack pointers into - variables. These are used to establish the C stack in trampolines back - into the C run-time. - This routine assumes the system's frame pointer is the same as that used - in generated code. */ - - /* Cogit>>#generateCaptureCStackPointers: */ -static void NoDbgRegParms NeverInline -generateCaptureCStackPointers(sqInt captureFramePointer) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - sqInt callerSavedReg; - sqInt fixupSize; - sqInt offset; - sqInt opcodeSize; - sqInt pushedVarBaseReg; - sqInt quickConstant; - usqInt startAddress; - - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 32; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - - /* Must happen first; value may be used in accessing any of the following addresses */ - startAddress = methodZoneBase; - callerSavedReg = 0; - pushedVarBaseReg = 0; - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { - - /* VarBaseReg is not caller-saved; must save and restore it, either by using an available caller-saved reg or push/pop. */ - - /* TempReg used below */ - callerSavedReg = availableRegisterOrNoneIn(((ABICallerSavedRegisterMask | (1U << TempReg)) - (1U << TempReg))); - if (callerSavedReg == NoReg) { - gNativePushR(VarBaseReg); - pushedVarBaseReg = 1; - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, VarBaseReg, callerSavedReg); - } - } - /* begin MoveCq:R: */ - quickConstant = varBaseAddress(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - if (captureFramePointer) { - /* begin checkLiteral:forInstruction: */ - cFramePointerAddress(); - anInstruction1 = genoperandoperand(MoveRAw, FPReg, cFramePointerAddress()); - } - if (pushedVarBaseReg) { - /* begin LoadEffectiveAddressMw:r:R: */ - offset = (pushedVarBaseReg - ? 0 /* leafCallStackPointerDelta */ + BytesPerWord - : 0 /* leafCallStackPointerDelta */); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(LoadEffectiveAddressMwrR, offset, NativeSPReg, TempReg); - /* begin checkLiteral:forInstruction: */ - cStackPointerAddress(); - anInstruction3 = genoperandoperand(MoveRAw, TempReg, cStackPointerAddress()); - } - else { - /* begin checkLiteral:forInstruction: */ - cStackPointerAddress(); - anInstruction4 = genoperandoperand(MoveRAw, NativeSPReg, cStackPointerAddress()); - } - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { - if (pushedVarBaseReg) { - gNativePopR(VarBaseReg); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, callerSavedReg, VarBaseReg); - } - } - gNativeRetN(0); - outputInstructionsForGeneratedRuntimeAt(startAddress); - flushICacheFromto(backEnd, ((usqInt)startAddress), ((usqInt)methodZoneBase)); - recordGeneratedRunTimeaddress("ceCaptureCStackPointers", startAddress); - ceCaptureCStackPointers = ((void (*)(void)) startAddress); -} - - -/* Generate the prototype ClosedPIC to determine how much space a full closed - PIC takes. - When we first allocate a closed PIC it only has one or two cases and we - want to grow it. - So we have to determine how big a full one is before hand. */ -/* stack allocate the various collections so that they - are effectively garbage collected on return. */ - - /* Cogit>>#generateClosedPICPrototype */ -static void -generateClosedPICPrototype(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - CogMethod * cPIC; - AbstractInstruction * cPICEndOfCodeLabel; - sqInt endAddress; - AbstractInstruction * endCPICCase1; - sqInt fixupSize; - sqInt h; - AbstractInstruction *jumpNext; - sqInt jumpTarget; - sqInt jumpTarget1; - sqInt jumpTarget2; - sqInt numArgs; - sqInt opcode; - sqInt opcodeSize; - sqInt wordConstant; - sqInt wordConstant1; - - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = MaxCPICCases * 9; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - (methodLabel->address = methodZoneBase); - (methodLabel->dependent = null); - /* begin compileClosedPICPrototype */ - compilePICAbort((numArgs = 0)); - - /* At the end of the entry code we need to jump to the first case code, which is actually the last chunk. - On each entension we must update this jump to move back one case. */ - jumpNext = compileCPICEntry(); - /* begin MoveUniqueCw:R: */ - wordConstant1 = firstPrototypeMethodOop(); - /* begin uniqueLiteral:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCwR, wordConstant1, SendNumArgsReg); - /* begin JumpLong: */ - jumpTarget1 = (((methodZoneBase + (youngReferrers())) / 2) - 13262352) + 13262352; - genoperand(JumpLong, jumpTarget1); - endCPICCase0 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - for (h = 1; h < MaxCPICCases; h += 1) { - if (h == (MaxCPICCases - 1)) { - jmpTarget(jumpNext, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - /* begin MoveUniqueCw:R: */ - wordConstant = (subsequentPrototypeMethodOop()) + h; - /* begin uniqueLiteral:forInstruction: */ - anInstruction = genoperandoperand(MoveCwR, wordConstant, SendNumArgsReg); - /* begin gen:literal32:operand: */ - opcode = CmpCwR; - /* begin checkLiteral32:forInstruction: */ - anInstruction1 = genoperandoperand(opcode, 3133021973U + h, TempReg); - /* begin JumpLongZero: */ - jumpTarget = ((((methodZoneBase + (youngReferrers())) / 2) - 13262352) + 13262352) + (h * 16); - genConditionalBranchoperand(JumpLongZero, ((sqInt)jumpTarget)); - if (h == 1) { - endCPICCase1 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - } - /* begin checkLiteral:forInstruction: */ - (methodLabel->address); - anInstruction3 = genoperandoperand(MoveCwR, (methodLabel->address), ClassReg); - /* begin JumpLong: */ - jumpTarget2 = cPICMissTrampolineFor(numArgs); - genoperand(JumpLong, jumpTarget2); - cPICEndOfCodeLabel = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - computeMaximumSizes(); - cPIC = ((CogMethod *) methodZoneBase); - closedPICSize = (sizeof(CogMethod)) + (generateInstructionsAt(methodZoneBase + (sizeof(CogMethod)))); - endAddress = outputInstructionsAt(methodZoneBase + (sizeof(CogMethod))); - assert((methodZoneBase + closedPICSize) == endAddress); - firstCPICCaseOffset = ((endCPICCase0->address)) - methodZoneBase; - cPICEndOfCodeOffset = ((cPICEndOfCodeLabel->address)) - methodZoneBase; - cPICCaseSize = ((endCPICCase1->address)) - ((endCPICCase0->address)); - cPICEndSize = closedPICSize - (((MaxCPICCases - 1) * cPICCaseSize) + firstCPICCaseOffset); - closedPICSize = roundUpToMethodAlignment(backEnd(), closedPICSize); - assert(((picInterpretAbort->address)) == (((methodLabel->address)) + (picInterpretAbortOffset()))); - assert((expectedClosedPICPrototype(cPIC)) == 0); - storeLiteralbeforeFollowingAddress(backEnd, 0, ((endCPICCase0->address)) - (jumpLongByteSize(backEnd))); - methodZoneBase = alignUptoRoutineBoundary(endAddress); - cPICPrototype = cPIC; -} - - -/* We handle jump sizing simply. First we make a pass that asks each - instruction to compute its maximum size. Then we make a pass that - sizes jumps based on the maxmimum sizes. Then we make a pass - that fixes up jumps. When fixing up a jump the jump is not allowed to - choose a smaller offset but must stick to the size set in the second pass. */ - - /* Cogit>>#generateCogFullBlock */ -static CogMethod * -generateCogFullBlock(void) -{ - sqInt codeSize; - usqIntptr_t headerSize; - sqInt mapSize; - CogMethod *method; - sqInt result; - usqInt startAddress; - sqInt totalSize; - - headerSize = sizeof(CogMethod); - (methodLabel->address = freeStart()); - computeMaximumSizes(); - concretizeAt(methodLabel, freeStart()); - codeSize = generateInstructionsAt(((methodLabel->address)) + headerSize); - mapSize = generateMapAtstart(null, ((methodLabel->address)) + cbNoSwitchEntryOffset); - totalSize = roundUpToMethodAlignment(backEnd(), (headerSize + codeSize) + mapSize); - if (totalSize > MaxMethodSize) { - return ((CogMethod *) MethodTooBig); - } - startAddress = allocate(totalSize); - if (startAddress == 0) { - return ((CogMethod *) InsufficientCodeSpace); - } - assert((startAddress + cbEntryOffset) == ((fullBlockEntry->address))); - assert((startAddress + cbNoSwitchEntryOffset) == ((fullBlockNoContextSwitchEntry->address))); - result = outputInstructionsAt(startAddress + headerSize); - assert(((startAddress + headerSize) + codeSize) == result); - padIfPossibleWithStopsFromto(backEnd, result, ((startAddress + totalSize) - mapSize) - 1); - generateMapAtstart((startAddress + totalSize) - 1, startAddress + cbNoSwitchEntryOffset); - flag("TOCHECK"); - method = ((CogMethod *) ((((usqInt)startAddress)) + codeToDataDelta)); - fillInMethodHeadersizeselector(method, totalSize, nilObject()); - (method->cpicHasMNUCaseOrCMIsFullBlock = 1); - flushICacheFromto(backEnd, startAddress, startAddress + totalSize); - return ((CogMethod *) startAddress); -} - - -/* We handle jump sizing simply. First we make a pass that asks each - instruction to compute its maximum size. Then we make a pass that - sizes jumps based on the maxmimum sizes. Then we make a pass - that fixes up jumps. When fixing up a jump the jump is not allowed to - choose a smaller offset but must stick to the size set in the second pass. */ - - /* Cogit>>#generateCogMethod: */ -static CogMethod * NoDbgRegParms -generateCogMethod(sqInt selector) -{ - sqInt codeSize; - usqIntptr_t headerSize; - sqInt mapSize; - sqInt result; - usqInt startAddress; - sqInt totalSize; - - headerSize = sizeof(CogMethod); - (methodLabel->address = freeStart()); - computeMaximumSizes(); - concretizeAt(methodLabel, freeStart()); - codeSize = generateInstructionsAt(((methodLabel->address)) + headerSize); - mapSize = generateMapAtstart(null, ((methodLabel->address)) + cmNoCheckEntryOffset); - totalSize = roundUpToMethodAlignment(backEnd(), (headerSize + codeSize) + mapSize); - if (totalSize > MaxMethodSize) { - return ((CogMethod *) MethodTooBig); - } - startAddress = allocate(totalSize); - if (startAddress == 0) { - return ((CogMethod *) InsufficientCodeSpace); - } - assert((startAddress + cmEntryOffset) == ((entry->address))); - assert((startAddress + cmNoCheckEntryOffset) == ((noCheckEntry->address))); - result = outputInstructionsAt(startAddress + headerSize); - assert(((startAddress + headerSize) + codeSize) == result); - padIfPossibleWithStopsFromto(backEnd, result, ((startAddress + totalSize) - mapSize) - 1); - generateMapAtstart((startAddress + totalSize) - 1, startAddress + cmNoCheckEntryOffset); - fillInBlockHeadersAt(startAddress); - fillInMethodHeadersizeselector(((CogMethod *) ((((usqInt)startAddress)) + codeToDataDelta)), totalSize, selector); - flushICacheFromto(backEnd, startAddress, startAddress + totalSize); - return ((CogMethod *) startAddress); -} - - -/* Generate the method map at addressrNull (or compute it if addressOrNull is - null). Answer the length of the map in byes. Each entry in the map is in - two parts. In the - least signficant bits are a displacement of how far from the start or - previous entry, - unless it is an IsAnnotationExtension byte, in which case those bits are - the extension. - In the most signficant bits are the type of annotation at the point - reached. A null - byte ends the map. */ - - /* Cogit>>#generateMapAt:start: */ -static sqInt NoDbgRegParms -generateMapAtstart(usqInt addressOrNull, usqInt startAddress) -{ - unsigned char annotation; - sqInt delta; - sqInt i; - AbstractInstruction *instruction; - sqInt length; - usqInt location; - sqInt mapEntry; - sqInt maxDelta; - usqInt mcpc; - - length = 0; - location = startAddress; - for (i = 0; i < opcodeIndex; i += 1) { - instruction = abstractInstructionAt(i); - annotation = (instruction->annotation); - if (!(annotation == null)) { - /* begin mapEntryAddress */ - mcpc = ((instruction->address)) + ((instruction->machineCodeSize)); - while (((delta = (mcpc - location) / 4 /* codeGranularity */)) > DisplacementMask) { - maxDelta = (((((delta < MaxX2NDisplacement) ? delta : MaxX2NDisplacement)) | DisplacementMask) - DisplacementMask); - assert((((usqInt)(maxDelta)) >> AnnotationShift) <= DisplacementMask); - if (!(addressOrNull == null)) { - /* begin addToMap:instruction:byte:at:for: */ - codeByteAtput(addressOrNull - length, (((usqInt)(maxDelta)) >> AnnotationShift) + DisplacementX2N); - } - location += maxDelta * 4 /* codeGranularity */; - length += 1; - } - if (!(addressOrNull == null)) { - mapEntry = delta + (((sqInt)((usqInt)((((annotation < IsSendCall) ? annotation : IsSendCall))) << AnnotationShift))); - /* begin addToMap:instruction:byte:at:for: */ - codeByteAtput(addressOrNull - length, mapEntry); - } - location += delta * 4 /* codeGranularity */; - length += 1; - if (annotation > IsSendCall) { - - /* Add the necessary IsAnnotationExtension */ - if (!(addressOrNull == null)) { - mapEntry = (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift))) + (annotation - IsSendCall); - /* begin addToMap:instruction:byte:at:for: */ - codeByteAtput(addressOrNull - length, mapEntry); - } - length += 1; - } - } - } - if (!(addressOrNull == null)) { - /* begin addToMap:instruction:byte:at:for: */ - codeByteAtput(addressOrNull - length, MapEnd); - } - return length + 1; -} - - -/* Generate the prototype OpenPIC to determine how much space an open PIC - takes. - */ -/* stack allocate the various collections so that they - are effectively garbage collected on return. */ - - /* Cogit>>#generateOpenPICPrototype */ -static void -generateOpenPICPrototype(void) -{ - sqInt codeSize; - sqInt fixupSize; - sqInt mapSize; - sqInt opcodeSize; - - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 100; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - (methodLabel->address = methodZoneBase); - (methodLabel->dependent = null); - compileOpenPICnumArgs(specialSelector(0), 2 /* numRegArgs */); - computeMaximumSizes(); - concretizeAt(methodLabel, methodZoneBase); - codeSize = generateInstructionsAt(methodZoneBase + (sizeof(CogMethod))); - mapSize = generateMapAtstart(null, methodZoneBase + cmNoCheckEntryOffset); - openPICSize = (roundUpLength((sizeof(CogMethod)) + codeSize)) + (roundUpToMethodAlignment(backEnd(), mapSize)); -} - - -/* Generate the run-time entries at the base of the native code zone and - update the base. - */ - - /* Cogit>>#generateRunTimeTrampolines */ -static void -generateRunTimeTrampolines(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction2; - - ceSendMustBeBooleanAddFalseTrampoline = genMustBeBooleanTrampolineForcalled(falseObject(), "ceSendMustBeBooleanAddFalseTrampoline"); - ceSendMustBeBooleanAddTrueTrampoline = genMustBeBooleanTrampolineForcalled(trueObject(), "ceSendMustBeBooleanAddTrueTrampoline"); - /* begin genNonLocalReturnTrampoline */ - zeroOpcodeIndex(); - /* begin checkLiteral:forInstruction: */ - instructionPointerAddress(); - anInstruction2 = genoperandoperand(MoveRAw, LinkReg, instructionPointerAddress()); - ceNonLocalReturnTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNonLocalReturn, "ceNonLocalReturnTrampoline", 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 0, NoReg, 1); - /* begin genCheckForInterruptsTrampoline */ - zeroOpcodeIndex(); - /* begin checkLiteral:forInstruction: */ - instructionPointerAddress(); - anInstruction = genoperandoperand(MoveRAw, LinkReg, instructionPointerAddress()); - ceCheckForInterruptTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceCheckForInterrupt, "ceCheckForInterruptTrampoline", 0, null, null, null, null, 0 /* emptyRegisterMask */, 0, NoReg, 1); - ceFetchContextInstVarTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceContextinstVar, "ceFetchContextInstVarTrampoline", 2, ReceiverResultReg, SendNumArgsReg, null, null, 0 /* emptyRegisterMask */, 1, SendNumArgsReg, 0); - ceStoreContextInstVarTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceContextinstVarvalue, "ceStoreContextInstVarTrampoline", 3, ReceiverResultReg, SendNumArgsReg, ClassReg, null, 0 /* emptyRegisterMask */, 1, ReceiverResultReg, 0); - - /* ceInvokeInterpreter is an optimization and a work-around. Historically we used setjmp/longjmp to reenter the - interpreter at the current C stack base. The C stack base is set at start-up and on each callback enter and - callback return. The interpreter must be invoked whenever a non-machine-code method must be run. That might - be when invoking an interpreter method from one of the send linking routines (ceSend:...), or on continuing from - an evaluation primitive such as primitiveExecuteMethod. The problem here is that such primitives could have - been invoked by the interpreter or by machine code. So some form of non-local jump is required. But at least as - early as MSVC Community 2017, the Microshaft longjmp performs stack unwinding which gets hoplessly confused - (bless its little heart) by any stack switch between machine code and C stack, and raises a spurious - Stack cookie instrumentation code detected a stack-based buffer overrun - error from the bowels of gs_report.c _GSHandlerCheck. - Since the CoInterpreter maintains the base of the C stack in CFramePointer & CStackPointer, it is straight-forward - for us to simply call interpret after doing the switch to the C stack, avoiding the stack unwind issue altogether. */ - ceCannotResumeTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceCannotResume, "ceCannotResumeTrampoline", 0, null, null, null, null, 0 /* emptyRegisterMask */, 1, NoReg, 0); - - /* These two are unusual; they are reached by return instructions. */ - ceInvokeInterpret = genInvokeInterpretTrampoline(); - ceReturnToInterpreterTrampoline = genReturnToInterpreterTrampoline(); - ceBaseFrameReturnTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceBaseFrameReturn, "ceBaseFrameReturnTrampoline", 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 0, NoReg, 0); - } - - -/* Generate a routine ceCaptureCStackPointers that will capture the C stack - pointer, and, if it is in use, the C frame pointer. These are used in - trampolines to call - run-time routines in the interpreter from machine-code. */ - - /* Cogit>>#generateStackPointerCapture */ -static void -generateStackPointerCapture(void) -{ - usqInt oldMethodZoneBase; - sqInt oldTrampolineTableIndex; - - - /* For the benefit of the following assert, assume the minimum at first. */ - cFramePointerInUse = 0; - assertCStackWellAligned(); - oldMethodZoneBase = methodZoneBase; - oldTrampolineTableIndex = trampolineTableIndex; - generateCaptureCStackPointers(1); - ceCaptureCStackPointers(); - if (!((cFramePointerInUse = checkIfCFramePointerInUse()))) { - methodZoneBase = oldMethodZoneBase; - trampolineTableIndex = oldTrampolineTableIndex; - generateCaptureCStackPointers(0); - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - assertCStackWellAligned(); -} - - -/* Generate the run-time entries and exits at the base of the native code - zone and update the base. - Read the class-side method trampolines for documentation on the various - trampolines - */ - - /* Cogit>>#generateTrampolines */ -static void -generateTrampolines(void) -{ - sqInt fixupSize; - usqInt methodZoneStart; - sqInt opcodeSize; - - methodZoneStart = methodZoneBase; - (methodLabel->address = methodZoneStart); - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 80; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - setHasYoungReferent(0); - generateSendTrampolines(); - generateMissAbortTrampolines(); - generateObjectRepresentationTrampolines(); - generateRunTimeTrampolines(); - generateEnilopmarts(); - generateTracingTrampolines(); - recordGeneratedRunTimeaddress("methodZoneBase", methodZoneBase); -} - - /* Cogit>>#generatorForPC: */ -static BytecodeDescriptor * NoDbgRegParms -generatorForPC(sqInt pc) -{ - return generatorAt(bytecodeSetOffset + (fetchByteofObject(pc, methodObj))); -} - - -/* Generate a pair of routines that answer the frame pointer, and the stack - pointer immediately - after a leaf call, used for checking stack pointer alignment, frame - pointer usage, etc. N.B. - these are exported to the CoInterpreter et al via Cogit - class>>mustBeGlobal:. - */ - - /* Cogit>>#genGetLeafCallStackPointers */ -static void -genGetLeafCallStackPointers(void) -{ - sqInt fixupSize; - sqInt opcodeSize; - usqInt startAddress; - - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 4; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - startAddress = methodZoneBase; - genoperandoperand(MoveRR, FPReg, ABIResultReg); - genoperand(RetN, 0); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress("ceGetFP", startAddress); - ceGetFP = ((usqIntptr_t (*)(void)) startAddress); - startAddress = methodZoneBase; - zeroOpcodeIndex(); - genoperandoperand(MoveRR, NativeSPReg, ABIResultReg); - genoperand(RetN, 0); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress("ceGetSP", startAddress); - ceGetSP = ((usqIntptr_t (*)(void)) startAddress); -} - - -/* Generate the abort for a PIC. This abort performs either a call of - ceInterpretMethodFromPIC:receiver: to handle invoking an uncogged target - or a call of ceMNUFromPICMNUMethod:receiver: to handle an MNU dispatch - in a closed PIC. It distinguishes the two by testing ClassReg. If the - register is zero then this is an MNU. - - This poses a problem in 32-bit Spur, where zero is the cache tag for - immediate characters (tag pattern 2r10) because SmallIntegers have tag - patterns 2r11 - and 2r01, so anding with 1 reduces these to 0 & 1. We solve the ambiguity - by patching send sites with a 0 cache tag to open PICs instead of closed - PICs. */ - - /* Cogit>>#genInnerPICAbortTrampoline: */ -static usqInt NoDbgRegParms -genInnerPICAbortTrampoline(char *name) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *jumpMNUCase; - - /* begin CmpCq:R: */ - anInstruction = genoperandoperand(CmpCqR, 0 /* picAbortDiscriminatorValue */, ClassReg); - jumpMNUCase = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(ceInterpretMethodFromPICreceiver, 2, SendNumArgsReg, ReceiverResultReg, null, null, 0 /* emptyRegisterMask */, 0, NoReg); - jmpTarget(jumpMNUCase, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceMNUFromPICMNUMethodreceiver, name, 2, SendNumArgsReg, ReceiverResultReg, null, null, 0 /* emptyRegisterMask */, 0, NoReg, 1); -} - - -/* Switch to the C stack (do *not* save the Smalltalk stack pointers; - this is the caller's responsibility), and invoke interpret PDQ. */ - - /* Cogit>>#genInvokeInterpretTrampoline */ -static void (*genInvokeInterpretTrampoline(void))(void) - -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - sqInt quickConstant; - usqInt startAddress; - - startAddress = methodZoneBase; - zeroOpcodeIndex(); - /* begin MoveCq:R: */ - quickConstant = varBaseAddress(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - if (cFramePointerInUse) { - genLoadCStackPointers(backEnd); - } - else { - genLoadCStackPointer(backEnd); - } - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l16; - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction5 = genoperandoperand(MoveCqR, -2 - null, A0); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A0); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction11 = genoperandoperand(MoveCqR, -2 - null, A1); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A1); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction21 = genoperandoperand(MoveCqR, -2 - null, A2); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A2); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction31 = genoperandoperand(MoveCqR, -2 - null, A3); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A3); - } - l16: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin checkLiteral:forInstruction: */ - cReturnAddressAddress(); - anInstruction1 = genoperandoperand(MoveAwR, cReturnAddressAddress(), LinkReg); - /* begin checkLiteral:forInstruction: */ - ((sqInt)(((usqInt)interpret))); - anInstruction4 = genoperand(JumpFull, ((sqInt)(((usqInt)interpret)))); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress("ceInvokeInterpret", startAddress); - return ((void (*)(void)) startAddress); -} - - -/* The in-line cache for a send is implemented as a constant load into - ClassReg. We always use a 32-bit load, even in 64-bits. - - In the initial (unlinked) state the in-line cache is notionally loaded - with the selector. - But since in 64-bits an arbitrary selector oop won't fit in a 32-bit - constant load, we - instead load the cache with the selector's index, either into the literal - frame of the - current method, or into the special selector array. Negative values are - 1-relative indices into the special selector array. - - When a send is linked, the load of the selector, or selector index, is - overwritten with a - load of the receiver's class, or class tag. Hence, the 64-bit VM is - currently constrained - to use class indices as cache tags. If out-of-line literals are used, - distinct caches /must - not/ share acche locations, for if they do, send cacheing will be confused - by the sharing. - Hence we use the MoveUniqueC32:R: instruction that will not share literal - locations. */ - - /* Cogit>>#genLoadInlineCacheWithSelector: */ -static void NoDbgRegParms -genLoadInlineCacheWithSelector(sqInt selectorIndex) -{ - AbstractInstruction *anInstruction; - sqInt cacheValue; - sqInt opcode; - sqInt selector; - - assert((selectorIndex < 0 - ? (((-selectorIndex) >= 1) && ((-selectorIndex) <= (numSpecialSelectors()))) - : ((selectorIndex >= 0) && (selectorIndex <= ((literalCountOf(methodObj)) - 1))))); - selector = (selectorIndex < 0 - ? specialSelector(-1 - selectorIndex) - : getLiteral(selectorIndex)); - assert(addressCouldBeOop(selector)); - if (isNonImmediate(selector)) { - setHasMovableLiteral(1); - } - if (isYoung(selector)) { - setHasYoungReferent(1); - } - cacheValue = selector; - /* begin gen:uniqueLiteral32:operand: */ - opcode = MoveCwR; - /* begin uniqueLiteral32:forInstruction: */ - anInstruction = genoperandoperand(opcode, cacheValue, ClassReg); -} - - /* Cogit>>#genReturnToInterpreterTrampoline */ -static usqInt -genReturnToInterpreterTrampoline(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - usqInt startAddress; - - startAddress = methodZoneBase; - zeroOpcodeIndex(); - genoperand(PushR, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperandoperand(MoveMwrR, FoxIFSavedIP, FPReg, TempReg); - /* begin checkLiteral:forInstruction: */ - instructionPointerAddress(); - anInstruction5 = genoperandoperand(MoveRAw, TempReg, instructionPointerAddress()); - genSmalltalkToCStackSwitch(0); - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l17; - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction6 = genoperandoperand(MoveCqR, -2 - null, A0); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A0); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction11 = genoperandoperand(MoveCqR, -2 - null, A1); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A1); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction21 = genoperandoperand(MoveCqR, -2 - null, A2); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A2); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction31 = genoperandoperand(MoveCqR, -2 - null, A3); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A3); - } - l17: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin checkLiteral:forInstruction: */ - cReturnAddressAddress(); - anInstruction = genoperandoperand(MoveAwR, cReturnAddressAddress(), LinkReg); - /* begin checkLiteral:forInstruction: */ - ((sqInt)(((usqInt)interpret))); - anInstruction3 = genoperand(JumpFull, ((sqInt)(((usqInt)interpret)))); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress("ceReturnToInterpreterTrampoline", startAddress); - return startAddress; -} - - -/* If the client requires, then on an ARM-like RISC processor, the return - address needs to - be pushed to the stack so that the interpreter sees the same stack layout - as on CISC. - */ - - /* Cogit>>#genSmalltalkToCStackSwitch: */ -static sqInt NoDbgRegParms -genSmalltalkToCStackSwitch(sqInt pushLinkReg) -{ - if (pushLinkReg) { - genoperand(PushR, LinkReg); - } - genSaveStackPointers(backEnd); - if (cFramePointerInUse) { - genLoadCStackPointers(backEnd); - } - else { - genLoadCStackPointer(backEnd); - } - return 0; -} - - -/* Generate a trampoline with up to four arguments. Generate either a call or - a jump to aRoutineOrNil - as requested by callJumpBar. If generating a call and resultRegOrNone is - not NoReg pass the C result - back in resultRegOrNone. - Hack: a negative value indicates an abstract register, a non-negative - value indicates a constant. */ - - /* Cogit>>#genTrampolineFor:called:numArgs:arg:arg:arg:arg:regsToSave:pushLinkReg:resultReg:appendOpcodes: */ -static usqInt NoDbgRegParms -genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(void *aRoutine, char *trampolineName, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone, sqInt appendBoolean) -{ - usqInt startAddress; - - startAddress = methodZoneBase; - if (!appendBoolean) { - zeroOpcodeIndex(); - } - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(aRoutine, numArgs, regOrConst0, regOrConst1, regOrConst2, regOrConst3, regMask, pushLinkReg, resultRegOrNone); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress(trampolineName, startAddress); - recordRunTimeObjectReferences(); - /* begin assertValidDualZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, codeBase + cmNoCheckEntryOffset, codeToDataDelta); -# endif - return startAddress; -} - - -/* To return from a trampoline call we have to take the return address off - the stack, - iof it has been saved */ - - /* Cogit>>#genTrampolineReturn: */ -static void NoDbgRegParms -genTrampolineReturn(sqInt lnkRegWasPushed) -{ - if (lnkRegWasPushed - && (1)) { - genoperand(PopR, LinkReg); - genoperand(RetN, 0); - } - else { - genoperand(RetN, 0); - } -} - - -/* */ - - /* Cogit>>#gen: */ -static AbstractInstruction * NoDbgRegParms -gen(sqInt opcode) -{ - AbstractInstruction *abstractInstruction; - - assert(opcodeIndex < numAbstractOpcodes); - abstractInstruction = abstractInstructionAt(opcodeIndex); - opcodeIndex += 1; - (abstractInstruction->opcode = opcode); - return abstractInstruction; -} - - -/* */ -/* */ - - /* Cogit>>#gen:operand: */ -static AbstractInstruction * NoDbgRegParms -genoperand(sqInt opcode, sqInt operand) -{ - AbstractInstruction *abstractInstruction; - - assert(opcodeIndex < numAbstractOpcodes); - abstractInstruction = abstractInstructionAt(opcodeIndex); - opcodeIndex += 1; - (abstractInstruction->opcode = opcode); - ((abstractInstruction->operands))[0] = operand; - return abstractInstruction; -} - - -/* */ -/* */ -/* */ - - /* Cogit>>#gen:operand:operand: */ -static AbstractInstruction * NoDbgRegParms -genoperandoperand(sqInt opcode, sqInt operandOne, sqInt operandTwo) -{ - AbstractInstruction *abstractInstruction; - - assert(opcodeIndex < numAbstractOpcodes); - abstractInstruction = abstractInstructionAt(opcodeIndex); - opcodeIndex += 1; - (abstractInstruction->opcode = opcode); - ((abstractInstruction->operands))[0] = operandOne; - ((abstractInstruction->operands))[1] = operandTwo; - return abstractInstruction; -} - - -/* */ -/* */ -/* */ -/* */ - - /* Cogit>>#gen:operand:operand:operand: */ -static AbstractInstruction * NoDbgRegParms -genoperandoperandoperand(sqInt opcode, sqInt operandOne, sqInt operandTwo, sqInt operandThree) -{ - AbstractInstruction *abstractInstruction; - - assert(opcodeIndex < numAbstractOpcodes); - abstractInstruction = abstractInstructionAt(opcodeIndex); - opcodeIndex += 1; - (abstractInstruction->opcode = opcode); - ((abstractInstruction->operands))[0] = operandOne; - ((abstractInstruction->operands))[1] = operandTwo; - ((abstractInstruction->operands))[2] = operandThree; - return abstractInstruction; -} - - /* Cogit>>#getLiteral: */ -static sqInt NoDbgRegParms -getLiteral(sqInt litIndex) -{ - if (maxLitIndex < litIndex) { - maxLitIndex = litIndex; - } - return literalofMethod(litIndex, methodObj); -} - - /* Cogit>>#incrementUsageOfTargetIfLinkedSend:mcpc:ignored: */ -static sqInt NoDbgRegParms -incrementUsageOfTargetIfLinkedSendmcpcignored(sqInt annotation, char *mcpc, sqInt superfluity) -{ - sqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - - if (annotation >= IsSendCall) { - assert(annotation != IsNSSendCall); - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (((targetMethod1->cmUsageCount)) < (CMMaxUsageCount / 2)) { - ((((CogMethod *) ((((usqInt)targetMethod1)) + codeToDataDelta)))->cmUsageCount = ((targetMethod1->cmUsageCount)) + 1); - } - } - } - return 0; -} - - -/* Answer a usage count that reflects likely long-term usage. */ - - /* Cogit>>#initialClosedPICUsageCount */ -static sqInt -initialClosedPICUsageCount(void) -{ - return CMMaxUsageCount / 2; -} - - /* Cogit>>#initializeBackend */ -static void -initializeBackend(void) -{ - (methodLabel->machineCodeSize = 0); - (methodLabel->opcode = Label); - ((methodLabel->operands))[0] = 0; - ((methodLabel->operands))[1] = 0; - assert((!((registerMaskFor(VarBaseReg)) & CallerSavedRegisterMask))); - varBaseAddress = computeGoodVarBaseAddress(); - assert((stackLimitAddress()) >= varBaseAddress); - assert((cStackPointerAddress()) >= varBaseAddress); - assert((cFramePointerAddress()) >= varBaseAddress); - assert((cReturnAddressAddress()) >= varBaseAddress); - assert((nextProfileTickAddress()) >= varBaseAddress); - } - - /* Cogit>>#initializeCodeZoneFrom:upTo: */ -void -initializeCodeZoneFromupTo(sqInt startAddress, sqInt endAddress) -{ - sqInt fixupSize; - sqInt numberOfAbstractOpcodes; - sqInt opcodeSize; - usqInt startAddress1; - - initializeBackend(); - sqMakeMemoryExecutableFromToCodeToDataDelta(startAddress, endAddress, -# if DUAL_MAPPED_CODE_ZONE - (&codeToDataDelta) -# else - null -# endif - ); - stopsFromto(backEnd, startAddress, endAddress - 1); - codeBase = (methodZoneBase = startAddress); - minValidCallAddress = (((((codeBase < (interpretAddress())) ? codeBase : (interpretAddress()))) < (primitiveFailAddress())) ? (((codeBase < (interpretAddress())) ? codeBase : (interpretAddress()))) : (primitiveFailAddress())); - /* begin manageFrom:to: */ - mzFreeStart = (baseAddress = methodZoneBase); - youngReferrers = (limitAddress = endAddress); - openPICList = null; - methodBytesFreedSinceLastCompaction = 0; - methodCount = 0; - assertValidDualZone(); - /* begin maybeGenerateCacheFlush */ - /* begin generateVMOwnerLockFunctions */ -# if COGMTVM - /* begin allocateOpcodes:bytecodes: */ - numberOfAbstractOpcodes = numLowLevelLockOpcodes(backEnd); - numAbstractOpcodes = numberOfAbstractOpcodes; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - zeroOpcodeIndex(); - startAddress1 = methodZoneBase; - generateLowLevelTryLock(backEnd, vmOwnerAddress()); - outputInstructionsForGeneratedRuntimeAt(startAddress1); - recordGeneratedRunTimeaddress("ceTryLockVMOwner", startAddress1); - ceTryLockVMOwner = ((usqIntptr_t (*)(usqIntptr_t)) startAddress1); -# endif // COGMTVM - genGetLeafCallStackPointers(); - generateStackPointerCapture(); - generateTrampolines(); - computeEntryOffsets(); - computeFullBlockEntryOffsets(); - generateClosedPICPrototype(); - alignMethodZoneBase(); - flushICacheFromto(backEnd, startAddress, ((usqInt)methodZoneBase)); - /* begin maybeFlushWritableZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - if (codeToDataDelta > 0) { - flushDCacheFromto(backEnd, startAddress, ((usqInt)methodZoneBase)); - } -# endif - /* begin manageFrom:to: */ - mzFreeStart = (baseAddress = methodZoneBase); - youngReferrers = (limitAddress = endAddress); - openPICList = null; - methodBytesFreedSinceLastCompaction = 0; - methodCount = 0; - generateOpenPICPrototype(); -} - - -/* Answer a usage count that reflects likely long-term usage. - Answer 1 for non-primitives or quick primitives (inst var accessors), - 2 for methods with interpreter primitives, and 3 for compiled primitives. */ - - /* Cogit>>#initialMethodUsageCount */ -static sqInt -initialMethodUsageCount(void) -{ - if ((primitiveIndex == 1) - || (isQuickPrimitiveIndex(primitiveIndex))) { - return 1; - } - if (!(primitiveGeneratorOrNil())) { - return 2; - } - return 3; -} - - -/* Answer a usage count that reflects likely long-term usage. */ - - /* Cogit>>#initialOpenPICUsageCount */ -static sqInt -initialOpenPICUsageCount(void) -{ - return CMMaxUsageCount - 1; -} - - /* Cogit>>#inverseBranchFor: */ -static sqInt NoDbgRegParms -inverseBranchFor(sqInt opcode) -{ - switch (opcode) { - case JumpLongZero: - return JumpLongNonZero; - - case JumpLongNonZero: - return JumpLongZero; - - case JumpZero: - return JumpNonZero; - - case JumpNonZero: - return JumpZero; - - case JumpNegative: - return JumpNonNegative; - - case JumpNonNegative: - return JumpNegative; - - case JumpOverflow: - return JumpNoOverflow; - - case JumpNoOverflow: - return JumpOverflow; - - case JumpCarry: - return JumpNoCarry; - - case JumpNoCarry: - return JumpCarry; - - case JumpLess: - return JumpGreaterOrEqual; - - case JumpGreaterOrEqual: - return JumpLess; - - case JumpGreater: - return JumpLessOrEqual; - - case JumpLessOrEqual: - return JumpGreater; - - case JumpBelow: - return JumpAboveOrEqual; - - case JumpAboveOrEqual: - return JumpBelow; - - case JumpAbove: - return JumpBelowOrEqual; - - case JumpBelowOrEqual: - return JumpAbove; - - default: - error("Case not found and no otherwise clause"); - } - error("invalid opcode for inverse"); - return 0; -} - - -/* See Cogit class>>initializeAnnotationConstants */ - - /* Cogit>>#isPCMappedAnnotation: */ -static sqInt NoDbgRegParms -isPCMappedAnnotation(sqInt annotation) -{ - return annotation >= HasBytecodePC; -} - - /* Cogit>>#isPCWithinMethodZone: */ -sqInt -isPCWithinMethodZone(void *address) -{ - return (((((usqInt)address)) >= methodZoneBase) && ((((usqInt)address)) <= (freeStart()))); -} - - -/* Answer if the instruction preceding retpc is a call instruction. */ - - /* Cogit>>#isSendReturnPC: */ -sqInt -isSendReturnPC(sqInt retpc) -{ - usqInt target; - - if (!(isCallPrecedingReturnPC(backEnd, retpc))) { - return 0; - } - target = callTargetFromReturnAddress(backEnd, retpc); - return (((target >= firstSend) && (target <= lastSend))) - || (((target >= methodZoneBase) && (target <= (freeStart())))); -} - - -/* Floating-point jumps are a little weird on some processors. Defer to - the backEnd to allow it to generate any special code it may need to. */ - - /* Cogit>>#JumpFPEqual: */ -static AbstractInstruction * NoDbgRegParms -gJumpFPEqual(void *jumpTarget) -{ - /* begin genJumpFPEqual: */ - return genoperand(JumpFPEqual, ((sqInt)jumpTarget)); -} - - -/* Floating-point jumps are a little weird on some processors. Defer to - the backEnd to allow it to generate any special code it may need to. */ - - /* Cogit>>#JumpFPGreaterOrEqual: */ -static AbstractInstruction * NoDbgRegParms -gJumpFPGreaterOrEqual(void *jumpTarget) -{ - /* begin genJumpFPGreaterOrEqual: */ - return genoperand(JumpFPGreaterOrEqual, ((sqInt)jumpTarget)); -} - - -/* Floating-point jumps are a little weird on some processors. Defer to - the backEnd to allow it to generate any special code it may need to. */ - - /* Cogit>>#JumpFPGreater: */ -static AbstractInstruction * NoDbgRegParms -gJumpFPGreater(void *jumpTarget) -{ - /* begin genJumpFPGreater: */ - return genoperand(JumpFPGreater, ((sqInt)jumpTarget)); -} - - -/* Floating-point jumps are a little weird on some processors. Defer to - the backEnd to allow it to generate any special code it may need to. */ - - /* Cogit>>#JumpFPNotEqual: */ -static AbstractInstruction * NoDbgRegParms -gJumpFPNotEqual(void *jumpTarget) -{ - /* begin genJumpFPNotEqual: */ - return genoperand(JumpFPNotEqual, ((sqInt)jumpTarget)); -} - - /* Cogit>>#LogicalShiftLeftCq:R: */ -static AbstractInstruction * NoDbgRegParms -gLogicalShiftLeftCqR(sqInt quickConstant, sqInt reg) -{ - return genoperandoperand(LogicalShiftLeftCqR, quickConstant, reg); -} - - -/* destReg := srcReg << quickConstant */ - - /* Cogit>>#LogicalShiftLeftCq:R:R: */ -static AbstractInstruction * NoDbgRegParms -gLogicalShiftLeftCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) -{ - AbstractInstruction * first; - - return genoperandoperandoperand(LogicalShiftLeftCqRR, quickConstant, srcReg, destReg); - first = genoperandoperand(MoveRR, srcReg, destReg); - genoperandoperand(LogicalShiftLeftCqR, quickConstant, destReg); - return first; -} - - -/* destReg := (unsigned)srcReg >> quickConstant */ - - /* Cogit>>#LogicalShiftRightCq:R:R: */ -static AbstractInstruction * NoDbgRegParms -gLogicalShiftRightCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) -{ - AbstractInstruction * first; - - return genoperandoperandoperand(LogicalShiftRightCqRR, quickConstant, srcReg, destReg); - first = genoperandoperand(MoveRR, srcReg, destReg); - genoperandoperand(LogicalShiftRightCqR, quickConstant, destReg); - return first; -} - - /* Cogit>>#lastOpcode */ -static AbstractInstruction * -lastOpcode(void) -{ - assert(opcodeIndex > 0); - return abstractInstructionAt(opcodeIndex - 1); -} - - /* Cogit>>#linkSendAt:in:to:offset:receiver: */ -void -linkSendAtintooffsetreceiver(sqInt callSiteReturnAddress, CogMethod *sendingMethod, CogMethod *targetMethod, sqInt theEntryOffset, sqInt receiver) -{ - sqInt extent; - sqInt inlineCacheTag; - - assert((theEntryOffset == cmEntryOffset) - || (theEntryOffset == cmNoCheckEntryOffset)); - assert(((callSiteReturnAddress >= methodZoneBase) && (callSiteReturnAddress <= (freeStart())))); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - if (theEntryOffset == cmNoCheckEntryOffset) { - - /* no need to change selector cache tag */ - extent = rewriteCallAttarget(backEnd, callSiteReturnAddress, (((sqInt)targetMethod)) + cmNoCheckEntryOffset); - } - else { - inlineCacheTag = inlineCacheTagForInstance(receiver); - extent = rewriteInlineCacheAttagtarget(backEnd, callSiteReturnAddress, inlineCacheTag, (((sqInt)targetMethod)) + theEntryOffset); - } - flushICacheFromto(backEnd, (((usqInt)callSiteReturnAddress)) - extent, ((usqInt)callSiteReturnAddress)); -} - - /* Cogit>>#loadBytesAndGetDescriptor */ -static BytecodeDescriptor * -loadBytesAndGetDescriptor(void) -{ - BytecodeDescriptor *descriptor; - - byte0 = (fetchByteofObject(bytecodePC, methodObj)) + bytecodeSetOffset; - descriptor = generatorAt(byte0); - loadSubsequentBytesForDescriptorat(descriptor, bytecodePC); - return descriptor; -} - - /* Cogit>>#loadSubsequentBytesForDescriptor:at: */ -static void NoDbgRegParms -loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc) -{ - if (((descriptor->numBytes)) > 1) { - byte1 = fetchByteofObject(pc + 1, methodObj); - if (((descriptor->numBytes)) > 2) { - byte2 = fetchByteofObject(pc + 2, methodObj); - if (((descriptor->numBytes)) > 3) { - byte3 = fetchByteofObject(pc + 3, methodObj); - if (((descriptor->numBytes)) > 4) { - notYetImplemented(); - } - } - } - } -} - - /* Cogit>>#MoveCw:R: */ -static AbstractInstruction * NoDbgRegParms -gMoveCwR(sqInt wordConstant, sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkLiteral:forInstruction: */ - anInstruction = genoperandoperand(MoveCwR, wordConstant, reg); - return anInstruction; -} - - -/* Answer the address of the null byte at the end of the method map. */ - - /* Cogit>>#mapEndFor: */ -static usqInt NoDbgRegParms -mapEndFor(CogMethod *cogMethod) -{ - usqInt end; - - end = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while ((byteAt(end)) != MapEnd) { - end -= 1; - assert(end > (firstMappedPCFor(cogMethod))); - } - return end; -} - - -/* Unlinking/GC/Disassembly support */ -/* most of the time arg is a CogMethod... */ - - /* Cogit>>#mapFor:performUntil:arg: */ -static sqInt NoDbgRegParms -mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg) -{ - sqInt annotation; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - - /* begin firstMappedPCFor: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = functionSymbol(annotation, (((char *) mcpc)), arg); - if (result != 0) { - return result; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - return 0; -} - - -/* Remap all object references in the closed PIC. Answer if any references - are young. - Set codeModified if any modifications are made. */ - - /* Cogit>>#mapObjectReferencesInClosedPIC: */ -static sqInt NoDbgRegParms -mapObjectReferencesInClosedPIC(CogMethod *cPIC) -{ - sqInt i; - sqInt pc; - sqInt refersToYoung; - - - /* first we check the potential method oop load at the beginning of the CPIC */ - pc = addressOfEndOfCaseinCPIC(1, cPIC); - - /* We find the end address of the cPICNumCases'th case and can then just step forward by the case size thereafter */ - refersToYoung = remapMaybeObjRefInClosedPICAt(pc - (jumpLongByteSize(backEnd))); - - /* Next we check the potential class ref in the compare instruction, and the potential method oop load for each case. */ - pc = addressOfEndOfCaseinCPIC((cPIC->cPICNumCases), cPIC); - for (i = 2; i <= ((cPIC->cPICNumCases)); i += 1) { - if (remapMaybeObjRefInClosedPICAt((pc - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */)) { - refersToYoung = 1; - } - pc += cPICCaseSize; - } - return refersToYoung; -} - - -/* Update all references to objects in the generated runtime. */ - - /* Cogit>>#mapObjectReferencesInGeneratedRuntime */ -static void -mapObjectReferencesInGeneratedRuntime(void) -{ - sqInt i; - usqInt literal; - sqInt mappedLiteral; - usqInt mcpc; - - for (i = 0; i < runtimeObjectRefIndex; i += 1) { - mcpc = objectReferencesInRuntime[i]; - literal = literalBeforeFollowingAddress(backEnd, mcpc); - mappedLiteral = remapObject(literal); - if (mappedLiteral != literal) { - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - storeLiteralbeforeFollowingAddress(backEnd, mappedLiteral, mcpc); - } - } -} - - -/* Update all references to objects in machine code for a become. - Unlike incrementalGC or fullGC a method that does not refer to young may - refer to young as a result of the become operation. Unlike incrementalGC - or fullGC the reference from a Cog method to its methodObject *must not* - change since the two are two halves of the same object. */ - - /* Cogit>>#mapObjectReferencesInMachineCodeForBecome */ -static void -mapObjectReferencesInMachineCodeForBecome(void) -{ - sqInt annotation; - CogMethod * cogMethod; - sqInt freedPIC; - sqInt hasYoungObj; - sqInt hasYoungObjPtr; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt remappedMethod; - sqInt result; - CogMethod * writableCogMethod; - - hasYoungObj = 0; - hasYoungObjPtr = ((sqInt)((&hasYoungObj))); - codeModified = (freedPIC = 0); - mapObjectReferencesInGeneratedRuntime(); - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - assert(!hasYoungObj); - if (((cogMethod->cmType)) != CMFree) { - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - writableCogMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - (writableCogMethod->selector = remapOop((cogMethod->selector))); - if (((cogMethod->cmType)) == CMClosedPIC) { - if ((isYoung((cogMethod->selector))) - || (mapObjectReferencesInClosedPIC(cogMethod))) { - freedPIC = 1; - freeMethod(cogMethod); - } - } - else { - if (isYoung((cogMethod->selector))) { - hasYoungObj = 1; - } - if (((cogMethod->cmType)) == CMMethod) { - assert(((cogMethod->objectHeader)) == (nullHeaderForMachineCodeMethod())); - remappedMethod = remapOop((cogMethod->methodObject)); - if (remappedMethod != ((cogMethod->methodObject))) { - if (methodHasCogMethod(remappedMethod)) { - error("attempt to become two cogged methods"); - } - if (!(withoutForwardingOnandwithsendToCogit((cogMethod->methodObject), remappedMethod, (cogMethod->cmUsesPenultimateLit), methodhasSameCodeAscheckPenultimate))) { - error("attempt to become cogged method into different method"); - } - if ((rawHeaderOf((cogMethod->methodObject))) == (((sqInt)cogMethod))) { - rawHeaderOfput((cogMethod->methodObject), (cogMethod->methodHeader)); - (writableCogMethod->methodHeader = rawHeaderOf(remappedMethod)); - (writableCogMethod->methodObject = remappedMethod); - rawHeaderOfput(remappedMethod, ((sqInt)cogMethod)); - } - else { - assert((noAssertMethodClassAssociationOf((cogMethod->methodObject))) == (nilObject())); - (writableCogMethod->methodHeader = rawHeaderOf(remappedMethod)); - (writableCogMethod->methodObject = remappedMethod); - } - } - if (isYoung((cogMethod->methodObject))) { - hasYoungObj = 1; - } - } - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = remapIfObjectRefpchasYoung(annotation, (((char *) mcpc)), (((CogMethod *) hasYoungObjPtr))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - if (hasYoungObj) { - ensureInYoungReferrers(cogMethod); - hasYoungObj = 0; - } - else { - (cogMethod->cmRefersToYoung = 0); - } - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - pruneYoungReferrers(); - if (freedPIC) { - unlinkSendsToFree(); - } - if (codeModified) { - - /* After updating oops in inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)codeBase), freeStart()); - } -} - - -/* Update all references to objects in machine code for a full gc. Since - the current (New)ObjectMemory GC makes everything old in a full GC - a method not referring to young will not refer to young afterwards */ - - /* Cogit>>#mapObjectReferencesInMachineCodeForFullGC */ -static void -mapObjectReferencesInMachineCodeForFullGC(void) -{ - sqInt annotation; - CogMethod * cogMethod; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - CogMethod * writableCogMethod; - - codeModified = 0; - mapObjectReferencesInGeneratedRuntime(); - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - writableCogMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - (writableCogMethod->selector = remapOop((cogMethod->selector))); - if (((cogMethod->cmType)) == CMClosedPIC) { - assert(!((cogMethod->cmRefersToYoung))); - mapObjectReferencesInClosedPIC(cogMethod); - } - else { - if (((cogMethod->cmType)) == CMMethod) { - assert(((cogMethod->objectHeader)) == (nullHeaderForMachineCodeMethod())); - (writableCogMethod->methodObject = remapOop((cogMethod->methodObject))); - } - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = remapIfObjectRefpchasYoung(annotation, (((char *) mcpc)), 0); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - pruneYoungReferrers(); - if (codeModified) { - - /* After updating oops in inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)codeBase), freeStart()); - } -} - - -/* Update all references to objects in machine code for either a Spur - scavenging gc - or a Squeak V3 incremental GC. Avoid scanning all code by using the - youngReferrers list. In a young gc a method referring to young may no - longer refer to young, but a - method not referring to young cannot and will not refer to young - afterwards. */ - - /* Cogit>>#mapObjectReferencesInMachineCodeForYoungGC */ -static void -mapObjectReferencesInMachineCodeForYoungGC(void) -{ - sqInt annotation; - CogMethod * cogMethod; - sqInt hasYoungObj; - sqInt hasYoungObjPtr; - usqInt map; - sqInt mapByte; - sqInt mcpc; - usqInt pointer; - sqInt result; - CogMethod * writableCogMethod; - sqInt zoneIsWritable; - - codeModified = (zoneIsWritable = (hasYoungObj = 0)); - hasYoungObjPtr = ((sqInt)((&hasYoungObj))); - pointer = youngReferrers(); - while (pointer < limitAddress) { - assert(!hasYoungObj); - cogMethod = ((CogMethod *) (longAt(pointer))); - if (((cogMethod->cmType)) == CMFree) { - assert(!((cogMethod->cmRefersToYoung))); - } - else { - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - if ((cogMethod->cmRefersToYoung)) { - assert((((cogMethod->cmType)) == CMMethod) - || (((cogMethod->cmType)) == CMOpenPIC)); - if (!zoneIsWritable) { - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - zoneIsWritable = 1; - } - writableCogMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - (writableCogMethod->selector = remapOop((cogMethod->selector))); - if (isYoung((cogMethod->selector))) { - hasYoungObj = 1; - } - if (((cogMethod->cmType)) == CMMethod) { - assert(((cogMethod->objectHeader)) == (nullHeaderForMachineCodeMethod())); - (writableCogMethod->methodObject = remapOop((cogMethod->methodObject))); - if (isYoung((cogMethod->methodObject))) { - hasYoungObj = 1; - } - } - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = remapIfObjectRefpchasYoung(annotation, (((char *) mcpc)), (((void *)hasYoungObjPtr))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - if (hasYoungObj) { - hasYoungObj = 0; - } - else { - (writableCogMethod->cmRefersToYoung = 0); - } - } - } - pointer += BytesPerWord; - } - pruneYoungReferrers(); - if (codeModified) { - - /* After updating oops in inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } -} - - -/* Update all references to objects in machine code. */ - - /* Cogit>>#mapObjectReferencesInMachineCode: */ -void -mapObjectReferencesInMachineCode(sqInt gcMode) -{ - switch (gcMode) { - case GCModeNewSpace: - - /* N.B. do *not* ensureWritableCodeZone for every scavenge. */ - mapObjectReferencesInMachineCodeForYoungGC(); - break; - case GCModeFull: - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - mapObjectReferencesInMachineCodeForFullGC(); - break; - case GCModeBecome: - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - mapObjectReferencesInMachineCodeForBecome(); - break; - default: - error("Case not found and no otherwise clause"); - } - if (!(asserta((freeStart()) <= (youngReferrers())))) { - error("youngReferrers list overflowed"); - } -} - - -/* Mark objects in machine-code of marked methods (or open PICs with marked - selectors). - */ - - /* Cogit>>#markAndTraceMachineCodeOfMarkedMethods */ -void -markAndTraceMachineCodeOfMarkedMethods(void) -{ - sqInt annotation; - sqInt annotation1; - CogMethod *cogMethod; - usqInt map; - usqInt map1; - sqInt mapByte; - sqInt mapByte1; - sqInt mcpc; - sqInt mcpc1; - sqInt result; - sqInt result1; - - if (leakCheckFullGC()) { - asserta(allMachineCodeObjectReferencesValid()); - } - codeModified = 0; - markAndTraceObjectReferencesInGeneratedRuntime(); - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) == CMMethod) - && (isMarked((cogMethod->methodObject)))) { - /* begin markAndTraceLiteralsIn: */ - assert(((((cogMethod->cmType)) == CMMethod) - && (isMarked((cogMethod->methodObject)))) - || ((((cogMethod->cmType)) == CMOpenPIC) - && ((isImmediate((cogMethod->selector))) - || (isMarked((cogMethod->selector)))))); - markAndTraceLiteralinat((cogMethod->selector), cogMethod, (&((cogMethod->selector)))); - /* begin maybeMarkIRCsIn: */ - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = markLiteralspcmethod(annotation, (((char *) mcpc)), cogMethod); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - if ((((cogMethod->cmType)) == CMOpenPIC) - && ((isImmediate((cogMethod->selector))) - || (isMarked((cogMethod->selector))))) { - /* begin markAndTraceLiteralsIn: */ - assert(((((cogMethod->cmType)) == CMMethod) - && (isMarked((cogMethod->methodObject)))) - || ((((cogMethod->cmType)) == CMOpenPIC) - && ((isImmediate((cogMethod->selector))) - || (isMarked((cogMethod->selector)))))); - markAndTraceLiteralinat((cogMethod->selector), cogMethod, (&((cogMethod->selector)))); - /* begin maybeMarkIRCsIn: */ - /* begin mapFor:performUntil:arg: */ - mcpc1 = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map1 = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte1 = byteAt(map1))) != MapEnd) { - if (mapByte1 >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc1 += (mapByte1 & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation1 = ((usqInt)(mapByte1)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte1 = byteAt(map1 - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation1 += mapByte1 & DisplacementMask; - map1 -= 1; - } - result1 = markLiteralspcmethod(annotation1, (((char *) mcpc1)), cogMethod); - if (result1 != 0) { - goto l4; - } - } - else { - if (mapByte1 < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc1 += (((sqInt)((usqInt)((mapByte1 - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map1 -= 1; - } - l4: /* end mapFor:performUntil:arg: */; - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (leakCheckFullGC()) { - asserta(allMachineCodeObjectReferencesValid()); - } - if (codeModified) { - - /* After updating oops in inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } -} - - -/* Mark and trace any object references in the generated run-time. */ - - /* Cogit>>#markAndTraceObjectReferencesInGeneratedRuntime */ -static void -markAndTraceObjectReferencesInGeneratedRuntime(void) -{ - sqInt i; - usqInt literal; - usqInt mcpc; - - for (i = 0; i < runtimeObjectRefIndex; i += 1) { - mcpc = objectReferencesInRuntime[i]; - literal = literalBeforeFollowingAddress(backEnd, mcpc); - markAndTraceLiteralinatpc(literal, ((CogMethod *) null), ((usqInt)mcpc)); - } -} - - -/* Mark and trace objects in the argument and free if it is appropriate. - Answer if the method has been freed. firstVisit is a hint used to avoid - scanning methods we've already seen. False positives are fine. - For a CMMethod this - frees if the bytecode method isnt marked, - marks and traces object literals and selectors, - unlinks sends to targets that should be freed. - For a CMClosedPIC this - frees if it refers to anything that should be freed or isn't marked. - For a CMOpenPIC this - frees if the selector isn't marked. */ -/* this recurses at most one level down */ - - /* Cogit>>#markAndTraceOrFreeCogMethod:firstVisit: */ -static sqInt NoDbgRegParms -markAndTraceOrFreeCogMethodfirstVisit(CogMethod *cogMethod, sqInt firstVisit) -{ - sqInt annotation; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - - if (((cogMethod->cmType)) == CMFree) { - return 1; - } - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - if (((cogMethod->cmType)) == CMMethod) { - if (!(isMarked((cogMethod->methodObject)))) { - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - freeMethod(cogMethod); - return 1; - } - if (firstVisit) { - /* begin markLiteralsAndUnlinkUnmarkedSendsIn: */ - assert(((cogMethod->cmType)) == CMMethod); - assert(isMarked((cogMethod->methodObject))); - markAndTraceLiteralinat((cogMethod->selector), cogMethod, (&((cogMethod->selector)))); - /* begin maybeMarkIRCsIn: */ - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = markLiteralsAndUnlinkIfUnmarkedSendpcmethod(annotation, (((char *) mcpc)), cogMethod); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - return 0; - } - if (((cogMethod->cmType)) == CMClosedPIC) { - if (!(closedPICRefersToUnmarkedObject(cogMethod))) { - return 0; - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - freeMethod(cogMethod); - return 1; - } - if (((cogMethod->cmType)) == CMOpenPIC) { - if (isMarked((cogMethod->selector))) { - return 0; - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - freeMethod(cogMethod); - return 1; - } - assert((((cogMethod->cmType)) == CMMethod) - || ((((cogMethod->cmType)) == CMClosedPIC) - || (((cogMethod->cmType)) == CMOpenPIC))); - return 0; -} - - -/* If entryPoint is that of some method, then mark and trace objects in it - and free if it is appropriate. - Answer if the method has been freed. */ - - /* Cogit>>#markAndTraceOrFreePICTarget:in: */ -static sqInt NoDbgRegParms -markAndTraceOrFreePICTargetin(sqInt entryPoint, CogMethod *cPIC) -{ - CogMethod *targetMethod; - - assert((entryPoint > methodZoneBase) - && (entryPoint < (freeStart()))); - if (((((usqInt)cPIC)) <= (((usqInt)entryPoint))) - && (((((usqInt)cPIC)) + ((cPIC->blockSize))) >= (((usqInt)entryPoint)))) { - return 0; - } - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - assert((((targetMethod->cmType)) == CMMethod) - || (((targetMethod->cmType)) == CMFree)); - return markAndTraceOrFreeCogMethodfirstVisit(targetMethod, (((usqInt)targetMethod)) > (((usqInt)cPIC))); -} - - -/* Mark and trace literals. Unlink sends that have unmarked cache tags or - targets. - */ - - /* Cogit>>#markLiteralsAndUnlinkIfUnmarkedSend:pc:method: */ -static sqInt NoDbgRegParms -markLiteralsAndUnlinkIfUnmarkedSendpcmethod(sqInt annotation, char *mcpc, sqInt cogMethod) -{ - usqInt cacheTag1; - sqInt cacheTagMarked; - usqInt entryPoint1; - usqInt literal; - sqInt offset1; - sqInt *sendTable1; - sqInt tagCouldBeObj1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - literal = 0; - if (annotation == IsObjectReference) { - literal = literalBeforeFollowingAddress(backEnd, ((usqInt)mcpc)); - if (markAndTraceLiteralinatpc(literal, ((CogMethod *) cogMethod), ((usqInt)mcpc))) { - codeModified = 1; - } - } - if (annotation >= IsSendCall) { - /* begin entryCacheTagAndCouldBeObjectAt:annotation:into: */ - cacheTag1 = inlineCacheTagAt(backEnd, ((sqInt)mcpc)); - - /* in-line cache tags are the selectors of sends if sends are unlinked, - the selectors of super sends (entry offset = cmNoCheckEntryOffset), - the selectors of open PIC sends (entry offset = cmEntryOffset, target is an Open PIC) - or in-line cache tags (classes, class indices, immediate bit patterns, etc). - Note that selectors can be immediate so there is no guarantee that they - are markable/remappable objects. */ - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - tagCouldBeObj1 = entryPointTagIsSelector(entryPoint1); - cacheTagMarked = tagCouldBeObj1 - && (1); - if (entryPoint1 > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint1 - offset1)); - if ((!cacheTagMarked) - || (markAndTraceOrFreeCogMethodfirstVisit(targetMethod1, (((usqInt)targetMethod1)) > (((usqInt)mcpc))))) { - - /* Either the cacheTag is unmarked (e.g. new class) or the target - has been freed (because it is unmarked), so unlink the send. */ - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - markAndTraceLiteralinat((targetMethod1->selector), targetMethod1, (&((targetMethod1->selector)))); - } - } - else { - - /* cacheTag is selector */ - if (markAndTraceCacheTagLiteralinatpc(cacheTag1, ((CogMethod *) cogMethod), ((usqInt)mcpc))) { - codeModified = 1; - } - } - } - return 0; -} - - -/* Mark and trace literals. - Additionally in Newspeak, void push implicits that have unmarked classes. */ - - /* Cogit>>#markLiterals:pc:method: */ -static sqInt NoDbgRegParms -markLiteralspcmethod(sqInt annotation, char *mcpc, CogMethod *cogMethod) -{ - usqInt cacheTag1; - usqInt entryPoint1; - usqInt literal; - sqInt tagCouldBeObj1; - - literal = 0; - if (annotation == IsObjectReference) { - literal = literalBeforeFollowingAddress(backEnd, ((usqInt)mcpc)); - if (markAndTraceLiteralinatpc(literal, cogMethod, ((usqInt)mcpc))) { - codeModified = 1; - } - } - if (annotation >= IsSendCall) { - /* begin entryCacheTagAndCouldBeObjectAt:annotation:into: */ - cacheTag1 = inlineCacheTagAt(backEnd, ((sqInt)mcpc)); - - /* in-line cache tags are the selectors of sends if sends are unlinked, - the selectors of super sends (entry offset = cmNoCheckEntryOffset), - the selectors of open PIC sends (entry offset = cmEntryOffset, target is an Open PIC) - or in-line cache tags (classes, class indices, immediate bit patterns, etc). - Note that selectors can be immediate so there is no guarantee that they - are markable/remappable objects. */ - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - tagCouldBeObj1 = entryPointTagIsSelector(entryPoint1); - if (tagCouldBeObj1 - && (markAndTraceCacheTagLiteralinatpc(cacheTag1, cogMethod, ((usqInt)mcpc)))) { - - /* cacheTag is selector */ - codeModified = 1; - } - } - return 0; -} - - /* Cogit>>#markMethodAndReferents: */ -void -markMethodAndReferents(CogBlockMethod *aCogMethod) -{ - sqInt annotation; - CogMethod * cogMethod; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - CogMethod * writableMethod; - - assert((((aCogMethod->cmType)) == CMMethod) - || (((aCogMethod->cmType)) == CMBlock)); - cogMethod = (((aCogMethod->cmType)) == CMMethod - ? ((CogMethod *) aCogMethod) - : cmHomeMethod(aCogMethod)); - writableMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - (writableMethod->cmUsageCount = CMMaxUsageCount); - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = incrementUsageOfTargetIfLinkedSendmcpcignored(annotation, (((char *) mcpc)), 0); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; -} - - /* Cogit>>#maxCogMethodAddress */ -usqInt -maxCogMethodAddress(void) -{ - return ((usqInt)(limitZony())); -} - - -/* If this is the Newspeak VM and the objectRepresentation supports pinning - then allocate space for the implicit receiver caches on the heap. */ - - /* Cogit>>#maybeAllocAndInitIRCs */ -static sqInt -maybeAllocAndInitIRCs(void) -{ - return 1; -} - - -/* Check that the header fields are consistent with the type. - Answer 0 if it is ok, otherwise answer a code for the error. */ - - /* Cogit>>#maybeFreeCogMethodDoesntLookKosher: */ -static sqInt NoDbgRegParms -maybeFreeCogMethodDoesntLookKosher(CogMethod *cogMethod) -{ - sqInt result; - - result = cogMethodDoesntLookKosher(cogMethod); - return (result == 2 - ? 0 - : result); -} - - /* Cogit>>#mclassIsSmallInteger */ -static sqInt -mclassIsSmallInteger(void) -{ - return (receiverTags & 1); -} - - -/* Answer the absolute machine code pc matching the zero-relative - bytecode pc of a backward branch in cogMethod, given the start - of the bytecodes for cogMethod's block or method object. */ - - /* Cogit>>#mcPCForBackwardBranch:startBcpc:in: */ -usqInt -mcPCForBackwardBranchstartBcpcin(sqInt bcpc, sqInt startbcpc, CogBlockMethod *cogMethod) -{ - sqInt aMethodHeader; - sqInt aMethodHeader1; - sqInt aMethodObj; - sqInt annotation; - sqInt bcpc1; - sqInt bsOffset; - sqInt byte; - BytecodeDescriptor *descriptor; - sqInt distance; - sqInt endbcpc; - CogMethod *homeMethod; - sqInt isBackwardBranch; - sqInt isInBlock; - sqInt latestContinuation; - usqInt map; - sqInt mapByte; - usqInt mcpc; - sqInt nExts; - sqInt nextBcpc; - sqInt result; - sqInt targetPC; - - latestContinuation = 0; - /* begin mapFor:bcpc:performUntil:arg: */ - assert(((cogMethod->stackCheckOffset)) > 0); - - /* The stack check maps to the start of the first bytecode, - the first bytecode being effectively after frame build. */ - mcpc = (((usqInt)cogMethod)) + ((cogMethod->stackCheckOffset)); - result = (((((0 + (((int)((usqInt)(HasBytecodePC) << 1)))) & 1) != 0)) - && ((((sqInt)(((void *)bcpc)))) == startbcpc) - ? ((sqInt)(((char *) mcpc))) - : 0); - if (result != 0) { - return result; - } - - /* In both CMMethod and CMBlock cases find the start of the map and - skip forward to the bytecode pc map entry for the stack check. */ - bcpc1 = startbcpc; - if (((cogMethod->cmType)) == CMMethod) { - /* begin cmIsFullBlock */ - isInBlock = (cogMethod->cpicHasMNUCaseOrCMIsFullBlock); - homeMethod = ((CogMethod *) cogMethod); - assert(startbcpc == (startPCOfMethodHeader((homeMethod->methodHeader)))); - map = ((((usqInt)homeMethod)) + ((homeMethod->blockSize))) - 1; - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert((annotation == IsAbsPCReference) - || ((annotation == IsObjectReference) - || ((annotation == IsRelativeCall) - || (annotation == IsDisplacementX2N)))); - latestContinuation = startbcpc; - aMethodObj = (homeMethod->methodObject); - endbcpc = (numBytesOf(aMethodObj)) - 1; - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader) - ? 0x100 - : 0) -# else - 0 -# endif - ; - bcpc1 += deltaToSkipPrimAndErrorStoreInheader(aMethodObj, (homeMethod->methodHeader)); - } - else { - isInBlock = 1; - assert(bcpc1 == ((cogMethod->startpc))); - homeMethod = cmHomeMethod(cogMethod); - map = findMapLocationForMcpcinMethod((((usqInt)cogMethod)) + (sizeof(CogBlockMethod)), homeMethod); - assert(map != 0); - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert(((((usqInt)(annotation)) >> AnnotationShift) == HasBytecodePC) - || ((((usqInt)(annotation)) >> AnnotationShift) == IsDisplacementX2N)); - while (((annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift)) != HasBytecodePC) { - map -= 1; - } - - /* skip fiducial; i.e. the map entry for the pc immediately following the method header. */ - map -= 1; - aMethodObj = (homeMethod->methodObject); - bcpc1 = startbcpc - ( -#if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet((homeMethod->methodHeader)) - ? AltBlockCreationBytecodeSize - : BlockCreationBytecodeSize) -#else // MULTIPLEBYTECODESETS - BlockCreationBytecodeSize -#endif - ); - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader1 = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader1) - ? 0x100 - : 0) -# else - 0 -# endif - ; - byte = (fetchByteofObject(bcpc1, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - endbcpc = (bcpc1 + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc1, -1, aMethodObj)) - : 0)); - bcpc1 = startbcpc; - } - nExts = 0; - while ((((usqInt)((byteAt(map)))) >> AnnotationShift) != HasBytecodePC) { - map -= 1; - } - map -= 1; - while (((mapByte = byteAt(map))) != MapEnd) { - - /* defensive; we exit on bcpc */ - if (mapByte >= FirstAnnotation) { - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if (annotation >= HasBytecodePC) { - if ((annotation == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - while (1) { - byte = (fetchByteofObject(bcpc1, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - if (isInBlock) { - if (bcpc1 >= endbcpc) { - return 0; - } - } - else { - if (((descriptor->isReturn)) - && (bcpc1 >= latestContinuation)) { - return 0; - } - if ((isBranch(descriptor)) - || ((descriptor->isBlockCreation))) { - /* begin latestContinuationPCFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, bcpc1, nExts, aMethodObj); - targetPC = (bcpc1 + ((descriptor->numBytes))) + (((distance < 0) ? 0 : distance)); - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - /* latestContinuation = */ latestContinuation; - } - nextBcpc = (bcpc1 + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc1, nExts, aMethodObj)) - : 0)); - if (((descriptor->isMapped)) - || (isInBlock - && ((descriptor->isMappedInBlock)))) break; - bcpc1 = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - isBackwardBranch = (isBranch(descriptor)) - && ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, bcpc1, nExts, aMethodObj)) < 0)); - result = findBackwardBranchIsBackwardBranchMcpcBcpcMatchingBcpc(descriptor, ((isBackwardBranch - ? (((sqInt)((usqInt)(annotation) << 1))) + 1 - : ((sqInt)((usqInt)(annotation) << 1)))), (((char *) mcpc)), ((isBackwardBranch - ? bcpc1 - (2 * nExts) - : bcpc1)), (((void *)bcpc))); - if (result != 0) { - return result; - } - bcpc1 = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - } - else { - assert(((((usqInt)(mapByte)) >> AnnotationShift) == IsDisplacementX2N) - || ((((usqInt)(mapByte)) >> AnnotationShift) == IsAnnotationExtension)); - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - return 0; -} - - -/* For the purposes of become: see if the two methods are similar, i.e. can - be safely becommed. - This is pretty strict. All literals and bytecodes must be identical. Only - trailer bytes and header - flags can differ. */ - - /* Cogit>>#method:hasSameCodeAs:checkPenultimate: */ -static sqInt NoDbgRegParms -methodhasSameCodeAscheckPenultimate(sqInt methodA, sqInt methodB, sqInt comparePenultimateLiteral) -{ - sqInt bi; - sqInt endPCA; - sqInt headerA; - sqInt headerB; - sqInt li; - sqInt numLitsA; - - headerA = methodHeaderOf(methodA); - headerB = methodHeaderOf(methodB); - numLitsA = literalCountOfMethodHeader(headerA); - endPCA = endPCOf(methodA); - if (((argumentCountOfMethodHeader(headerA)) != (argumentCountOfMethodHeader(headerB))) - || (((temporaryCountOfMethodHeader(headerA)) != (temporaryCountOfMethodHeader(headerB))) - || (((primitiveIndexOfMethodheader(methodA, headerA)) != (primitiveIndexOfMethodheader(methodB, headerB))) - || ((numLitsA != (literalCountOfMethodHeader(headerB))) - || (endPCA > (numBytesOf(methodB))))))) { - return 0; - } - for (li = 1; li < numLitsA; li += 1) { - if ((fetchPointerofObject(li, methodA)) != (fetchPointerofObject(li, methodB))) { - if ((li < (numLitsA - 1)) - || (comparePenultimateLiteral)) { - return 0; - } - } - } - for (bi = (startPCOfMethod(methodA)); bi <= endPCA; bi += 1) { - if ((fetchByteofObject(bi, methodA)) != (fetchByteofObject(bi, methodB))) { - return 0; - } - } - return 1; -} - - /* Cogit>>#mnuOffset */ -sqInt -mnuOffset(void) -{ - return missOffset; -} - - /* Cogit>>#NativePopR: */ -static AbstractInstruction * NoDbgRegParms -gNativePopR(sqInt reg) -{ - return genoperand(PopR, reg); -} - - /* Cogit>>#NativePushR: */ -static AbstractInstruction * NoDbgRegParms -gNativePushR(sqInt reg) -{ - return genoperand(PushR, reg); -} - - /* Cogit>>#NativeRetN: */ -static AbstractInstruction * NoDbgRegParms -gNativeRetN(sqInt offset) -{ - return genoperand(RetN, offset); -} - - /* Cogit>>#needsFrameIfImmutability: */ -static sqInt NoDbgRegParms -needsFrameIfImmutability(sqInt stackDelta) -{ - return IMMUTABILITY; -} - - /* Cogit>>#needsFrameIfInBlock: */ -static sqInt NoDbgRegParms -needsFrameIfInBlock(sqInt stackDelta) -{ - return inBlock > 0; -} - - /* Cogit>>#needsFrameNever: */ -static sqInt NoDbgRegParms -needsFrameNever(sqInt stackDelta) -{ - return 0; -} - - /* Cogit>>#noAssertMethodClassAssociationOf: */ -static sqInt NoDbgRegParms -noAssertMethodClassAssociationOf(sqInt methodPointer) -{ - return literalofMethod((literalCountOfMethodHeader(noAssertHeaderOf(methodPointer))) - 1, methodPointer); -} - - -/* Check that no method is maximally marked. A maximal mark is an indication - the method has been scanned to increase the usage count of its referent - methods. */ - - /* Cogit>>#noCogMethodsMaximallyMarked */ -static sqInt -noCogMethodsMaximallyMarked(void) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) != CMFree) - && (((cogMethod->cmUsageCount)) == CMMaxUsageCount)) { - return 0; - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return 1; -} - - -/* Answer if all targets in the PIC are in-use methods. */ - - /* Cogit>>#noTargetsFreeInClosedPIC: */ -static sqInt NoDbgRegParms -noTargetsFreeInClosedPIC(CogMethod *cPIC) -{ - return !(cPICHasFreedTargets(cPIC)); -} - - /* Cogit>>#OrCq:R:R: */ -static AbstractInstruction * NoDbgRegParms -gOrCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction * first; - - /* begin gen:quickConstant:operand:operand: */ - anInstruction = genoperandoperandoperand(OrCqRR, quickConstant, srcReg, destReg); - return anInstruction; - if (srcReg == destReg) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(OrCqR, quickConstant, destReg); - return anInstruction1; - } - first = genoperandoperand(MoveRR, srcReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(OrCqR, quickConstant, destReg); - return first; -} - - -/* Store the generated machine code, answering the last address */ - - /* Cogit>>#outputInstructionsAt: */ -static sqInt NoDbgRegParms -outputInstructionsAt(sqInt startAddress) -{ - sqInt absoluteAddress; - AbstractInstruction * abstractInstruction; - sqInt i; - sqInt j; - - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - absoluteAddress = startAddress; - for (i = 0; i < opcodeIndex; i += 1) { - maybeBreakGeneratingInstructionWithIndex(i); - abstractInstruction = abstractInstructionAt(i); - assert(((abstractInstruction->address)) == absoluteAddress); - /* begin outputMachineCodeAt: */ - for (j = 0; j < ((abstractInstruction->machineCodeSize)); j += 4) { - longAtput(absoluteAddress + j, ((abstractInstruction->machineCode))[j / 4]); - } - absoluteAddress += (abstractInstruction->machineCodeSize); - } - return absoluteAddress; -} - - -/* Output instructions generated for one of the generated run-time routines, - a trampoline, etc - */ - - /* Cogit>>#outputInstructionsForGeneratedRuntimeAt: */ -static sqInt NoDbgRegParms -outputInstructionsForGeneratedRuntimeAt(sqInt startAddress) -{ - sqInt endAddress; - sqInt size; - - computeMaximumSizes(); - (methodLabel->address = startAddress); - size = generateInstructionsAt(startAddress); - endAddress = outputInstructionsAt(startAddress); - assert((startAddress + size) == endAddress); - methodZoneBase = alignUptoRoutineBoundary(endAddress); - stopsFromto(backEnd, endAddress, methodZoneBase - 1); - return startAddress; -} - - /* Cogit>>#PushCw: */ -static AbstractInstruction * NoDbgRegParms -gPushCw(sqInt wordConstant) -{ - AbstractInstruction *anInstruction; - - /* begin checkLiteral:forInstruction: */ - anInstruction = genoperand(PushCw, wordConstant); - return anInstruction; -} - - -/* Code entry closed PIC full or miss to an instance of a young class or to a - young target method. - Attempt to patch the send site to an open PIC. Answer if the attempt - succeeded; in fact it will - only return if the attempt failed. - The stack looks like: - receiver - args - sp=> sender return address */ - - /* Cogit>>#patchToOpenPICFor:numArgs:receiver: */ -sqInt -patchToOpenPICFornumArgsreceiver(sqInt selector, sqInt numArgs, sqInt receiver) -{ - sqInt extent; - CogMethod *oPIC; - sqInt outerReturn; - - - /* See if an Open PIC is already available. */ - outerReturn = stackTop(); - oPIC = openPICWithSelector(selector); - if (!oPIC) { - - /* otherwise attempt to create an Open PIC. */ - oPIC = cogOpenPICSelectornumArgs(selector, numArgs); - if ((((((sqInt)oPIC)) >= MaxNegativeErrorCode) && ((((sqInt)oPIC)) <= -1))) { - - /* For some reason the PIC couldn't be generated, most likely a lack of code memory. */ - if ((((sqInt)oPIC)) == InsufficientCodeSpace) { - callForCogCompiledCodeCompaction(); - } - return 0; - } - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - extent = rewriteInlineCacheAttagtarget(backEnd, outerReturn, inlineCacheValueForSelectorin(backEnd, selector, mframeHomeMethodExport()), (((sqInt)oPIC)) + cmEntryOffset); - flushICacheFromto(backEnd, (((usqInt)outerReturn)) - extent, ((usqInt)outerReturn)); - flushICacheFromto(backEnd, ((usqInt)oPIC), (((usqInt)oPIC)) + openPICSize); - executeCogMethodfromLinkedSendWithReceiver(oPIC, receiver); - return 1; -} - - -/* This value is used to decide between MNU processing - or interpretation in the closed PIC aborts. */ - - /* Cogit>>#picAbortDiscriminatorValue */ -static sqInt -picAbortDiscriminatorValue(void) -{ - return 0; -} - - -/* Answer the start of the abort sequence for invoking the interpreter in a - closed PIC. - */ - - /* Cogit>>#picInterpretAbortOffset */ -static sqInt -picInterpretAbortOffset(void) -{ - return (interpretOffset()) - (8 /* pushLinkRegisterByteSize */ + (callInstructionByteSize(backEnd))); -} - - /* Cogit>>#previousInstruction */ -static AbstractInstruction * -previousInstruction(void) -{ - assert(opcodeIndex > 0); - return abstractInstructionAt(opcodeIndex - 1); -} - - /* Cogit>>#printCogMethodFor: */ -void -printCogMethodFor(void *address) -{ - CogMethod * cogMethod; - - cogMethod = methodFor(address); - if (cogMethod == null) { - if ((codeEntryFor(address)) == null) { - print("not a method"); - cr(); - } - else { - print("trampoline "); - print(codeEntryNameFor(address)); - cr(); - } - } - else { - printCogMethod(cogMethod); - } -} - - /* Cogit>>#printTrampolineTable */ -void -printTrampolineTable(void) -{ - sqInt i; - - for (i = 0; i < trampolineTableIndex; i += 2) { - printHex(((sqInt)(trampolineAddresses[i + 1]))); - print(": "); - print(((char *) (trampolineAddresses[i]))); - cr(); - } -} - - /* Cogit>>#processorHasDivQuoRemAndMClassIsSmallInteger */ -static sqInt -processorHasDivQuoRemAndMClassIsSmallInteger(void) -{ - return mclassIsSmallInteger(); -} - - /* Cogit>>#processorHasMultiplyAndMClassIsSmallInteger */ -static sqInt -processorHasMultiplyAndMClassIsSmallInteger(void) -{ - return 0; -} - - /* Cogit>>#recordGeneratedRunTime:address: */ -static void NoDbgRegParms -recordGeneratedRunTimeaddress(char *aString, sqInt address) -{ - assert((trampolineTableIndex + 2) <= (NumTrampolines * 2)); - trampolineAddresses[trampolineTableIndex] = aString; - trampolineAddresses[trampolineTableIndex + 1] = (((char *) address)); - - /* self printTrampolineTable */ - trampolineTableIndex += 2; -} - - -/* This one for C support code. */ - - /* Cogit>>#recordPrimTraceFunc */ -sqInt -recordPrimTraceFunc(void) -{ - return recordPrimTrace(); -} - - /* Cogit>>#recordRunTimeObjectReferences */ -static void -recordRunTimeObjectReferences(void) -{ - sqInt i; - AbstractInstruction *instruction; - - for (i = 0; i < opcodeIndex; i += 1) { - instruction = abstractInstructionAt(i); - if (((instruction->annotation)) == IsObjectReference) { - assert(runtimeObjectRefIndex < NumObjRefsInRuntime); - assert(!hasYoungReferent); - if (hasYoungReferent) { - error("attempt to generate run-time routine containing young object reference. Cannot initialize Cogit run-time."); - } - objectReferencesInRuntime[runtimeObjectRefIndex] = (((usqInt)(((instruction->address)) + ((instruction->machineCodeSize))))); - runtimeObjectRefIndex += 1; - } - } -} - - /* Cogit>>#registerMaskFor: */ -static sqInt NoDbgRegParms -registerMaskFor(sqInt reg) -{ - return 1U << reg; -} - - /* Cogit>>#registerMaskFor:and:and: */ -static sqInt NoDbgRegParms -registerMaskForandand(sqInt reg1, sqInt reg2, sqInt reg3) -{ - return ((1U << reg1) | (1U << reg2)) | (1U << reg3); -} - - /* Cogit>>#relocateCallsAndSelfReferencesInMethod: */ -static void NoDbgRegParms -relocateCallsAndSelfReferencesInMethod(CogMethod *cogMethod) -{ - sqInt annotation; - sqInt callDelta; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqLong refDelta; - sqInt result; - - refDelta = (cogMethod->objectHeader); - callDelta = 0; - assert((((cogMethod->cmType)) == CMMethod) - || (((cogMethod->cmType)) == CMOpenPIC)); - assert((callTargetFromReturnAddress(backEnd, (((sqInt)cogMethod)) + missOffset)) == ((((cogMethod->cmType)) == CMMethod - ? methodAbortTrampolineFor((cogMethod->cmNumArgs)) - : picAbortTrampolineFor((cogMethod->cmNumArgs))))); - relocateCallBeforeReturnPCby(backEnd, (((sqInt)cogMethod)) + missOffset, -callDelta); - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = relocateIfCallOrMethodReferencemcpcdelta(annotation, (((char *) mcpc)), (((void *)refDelta))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; -} - - /* Cogit>>#relocateCallsInClosedPIC: */ -static void NoDbgRegParms -relocateCallsInClosedPIC(CogMethod *cPIC) -{ - sqInt callDelta; - sqInt entryPoint; - sqInt i; - sqInt pc; - sqLong refDelta; - CogMethod *targetMethod; - - refDelta = (cPIC->objectHeader); - callDelta = 0; - assert((callTargetFromReturnAddress(backEnd, (((sqInt)cPIC)) + missOffset)) == (picAbortTrampolineFor((cPIC->cmNumArgs)))); - relocateCallBeforeReturnPCby(backEnd, (((sqInt)cPIC)) + missOffset, -callDelta); - pc = (((sqInt)cPIC)) + firstCPICCaseOffset; - for (i = 1; i <= ((cPIC->cPICNumCases)); i += 1) { - pc = addressOfEndOfCaseinCPIC(i, cPIC); - entryPoint = (i == 1 - ? jumpLongTargetBeforeFollowingAddress(backEnd, pc) - : jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc)); - if (((((usqInt)cPIC)) <= (((usqInt)entryPoint))) - && (((((usqInt)cPIC)) + ((cPIC->blockSize))) >= (((usqInt)entryPoint)))) { - - /* Interpret/MNU */ - if (i == 1) { - relocateJumpLongBeforeFollowingAddressby(backEnd, pc, refDelta); - } - else { - relocateJumpLongConditionalBeforeFollowingAddressby(backEnd, pc, refDelta); - } - } - else { - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - assert(((targetMethod->cmType)) == CMMethod); - if (i == 1) { - relocateJumpLongBeforeFollowingAddressby(backEnd, pc, -(callDelta - ((targetMethod->objectHeader)))); - } - else { - relocateJumpLongConditionalBeforeFollowingAddressby(backEnd, pc, -(callDelta - ((targetMethod->objectHeader)))); - } - } - } - assert(((cPIC->cPICNumCases)) > 0); - relocateMethodReferenceBeforeAddressby(backEnd, (addressOfEndOfCaseinCPIC(2, cPIC)) + 8 /* loadLiteralByteSize */, refDelta); - relocateJumpLongBeforeFollowingAddressby(backEnd, (((sqInt)cPIC)) + cPICEndOfCodeOffset, -callDelta); -} - - -/* To placate the C static type system... */ - - /* Cogit>>#relocateIfCallOrMethodReference:mcpc:delta: */ -static sqInt NoDbgRegParms -relocateIfCallOrMethodReferencemcpcdelta(sqInt annotation, char *mcpc, CogMethod *refDeltaArg) -{ - sqInt callDelta; - sqInt entryPoint; - sqInt offset1; - sqInt refDelta; - sqInt *sendTable1; - CogMethod *targetMethod; - sqInt unlinkedRoutine; - - refDelta = ((sqInt) refDeltaArg); - callDelta = 0; - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint <= methodZoneBase) { - - /* send is not linked; just relocate */ - relocateCallBeforeReturnPCby(backEnd, ((sqInt)mcpc), -callDelta); - return 0; - } - /* begin offsetAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod = ((CogMethod *) (entryPoint - offset1)); - if (((targetMethod->cmType)) != CMFree) { - - /* send target not freed; just relocate. */ - relocateCallBeforeReturnPCby(backEnd, ((sqInt)mcpc), -(callDelta - ((targetMethod->objectHeader)))); - return 0; - } - unlinkedRoutine = sendTable1[((((targetMethod->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod->cmNumArgs)) : (NumSendTrampolines - 1))]; - unlinkedRoutine -= callDelta; - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod->selector), enumeratingCogMethod), unlinkedRoutine); - return 0; - } - if (annotation == IsRelativeCall) { - relocateCallBeforeReturnPCby(backEnd, ((sqInt)mcpc), -callDelta); - return 0; - } - if (annotation == IsAbsPCReference) { - relocateMethodReferenceBeforeAddressby(backEnd, ((sqInt)mcpc), refDelta); - } - return 0; -} - - -/* to placate the C static type system... */ - - /* Cogit>>#remapIfObjectRef:pc:hasYoung: */ -static sqInt NoDbgRegParms -remapIfObjectRefpchasYoung(sqInt annotation, char *mcpc, CogMethod *hasYoungPtr) -{ - usqInt cacheTag1; - usqInt entryPoint1; - usqInt literal; - sqInt mappedCacheTag; - sqInt mappedLiteral; - sqInt offset1; - sqInt *sendTable1; - sqInt tagCouldBeObj1; - CogMethod *targetMethod1; - - if (annotation == IsObjectReference) { - literal = literalBeforeFollowingAddress(backEnd, ((usqInt)mcpc)); - if (couldBeObject(literal)) { - mappedLiteral = remapObject(literal); - if (literal != mappedLiteral) { - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - storeLiteralbeforeFollowingAddress(backEnd, mappedLiteral, ((usqInt)mcpc)); - } - if ((hasYoungPtr != 0) - && (isYoung(mappedLiteral))) { - (*((sqInt *) hasYoungPtr) = 1); - } - } - } - if (annotation >= IsSendCall) { - /* begin entryCacheTagAndCouldBeObjectAt:annotation:into: */ - cacheTag1 = inlineCacheTagAt(backEnd, ((sqInt)mcpc)); - - /* in-line cache tags are the selectors of sends if sends are unlinked, - the selectors of super sends (entry offset = cmNoCheckEntryOffset), - the selectors of open PIC sends (entry offset = cmEntryOffset, target is an Open PIC) - or in-line cache tags (classes, class indices, immediate bit patterns, etc). - Note that selectors can be immediate so there is no guarantee that they - are markable/remappable objects. */ - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - tagCouldBeObj1 = entryPointTagIsSelector(entryPoint1); - if (tagCouldBeObj1 - && (couldBeObject(cacheTag1))) { - mappedCacheTag = remapObject(cacheTag1); - if (cacheTag1 != mappedCacheTag) { - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheTagat(backEnd, mappedCacheTag, ((usqInt)mcpc)); - } - if ((hasYoungPtr != 0) - && (isYoung(mappedCacheTag))) { - (*((sqInt *) hasYoungPtr) = 1); - } - } - if (hasYoungPtr != 0) { - - /* Since the unlinking routines may rewrite the cacheTag to the send's selector, and - since they don't have the cogMethod to hand and can't add it to youngReferrers, - the method must remain in youngReferrers if the targetMethod's selector is young. */ - if (entryPoint1 > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint1 - offset1)); - if (isYoung((targetMethod1->selector))) { - (*((sqInt *) hasYoungPtr) = 1); - } - } - } - } - return 0; -} - - -/* Remap a potential object reference from a closed PIC. - This may be an object reference, an inline cache tag or null. - Answer if the updated literal is young. - mcpc is the address of the next instruction following either - the load of the method literal or the compare of the class tag. */ - - /* Cogit>>#remapMaybeObjRefInClosedPICAt: */ -static sqInt NoDbgRegParms -remapMaybeObjRefInClosedPICAt(sqInt mcpc) -{ - usqInt object; - sqInt subject; - - object = literalBeforeFollowingAddress(backEnd, mcpc); - if (!(couldBeObject(object))) { - return 0; - } - subject = remapOop(object); - if (object != subject) { - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - storeLiteralbeforeFollowingAddress(backEnd, subject, mcpc); - } - return isYoungObject(subject); -} - - -/* Rewrite the three values involved in a CPIC case. Used by the initialize & - extend CPICs. - c.f. expectedClosedPICPrototype: */ -/* write the obj ref/operand via the second ldr */ - - /* Cogit>>#rewriteCPICCaseAt:tag:objRef:target: */ -static void NoDbgRegParms -rewriteCPICCaseAttagobjReftarget(sqInt followingAddress, sqInt newTag, sqInt newObjRef, sqInt newTarget) -{ - sqInt classTagPC; - sqInt methodObjPC; - - methodObjPC = (followingAddress - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */; - storeLiteralbeforeFollowingAddress(backEnd, newObjRef, methodObjPC); - - /* rewite the tag via the first ldr */ - classTagPC = followingAddress - 16 /* jumpLongConditionalByteSize */; - /* begin storeLiteral32:beforeFollowingAddress: */ - storeLiteralbeforeFollowingAddress(((AbstractInstruction *) backEnd), newTag, classTagPC); - rewriteConditionalJumpLongAttarget(backEnd, followingAddress, newTarget); -} - - -/* destReg := fromReg - subReg */ - - /* Cogit>>#SubR:R:R: */ -static AbstractInstruction * NoDbgRegParms -gSubRRR(sqInt subReg, sqInt fromReg, sqInt destReg) -{ - AbstractInstruction * first; - - return genoperandoperandoperand(SubRRR, subReg, fromReg, destReg); - assert(subReg != destReg); - first = genoperandoperand(MoveRR, fromReg, destReg); - genoperandoperand(SubRR, subReg, destReg); - return first; -} - - -/* Answer the number of clean blocks found in the literal frame */ - - /* Cogit>>#scanForCleanBlocks */ -static sqInt -scanForCleanBlocks(void) -{ - sqInt i; - sqInt iLimiT; - sqInt lit; - sqInt numCleanBlocks; - sqInt startPCOrNil; - - numCleanBlocks = 0; - for (i = 1, iLimiT = (literalCountOf(methodObj)); i <= iLimiT; i += 1) { - lit = fetchPointerofObject(i, methodObj); - startPCOrNil = startPCOrNilOfLiteralin(lit, methodObj); - if (!(startPCOrNil == null)) { - numCleanBlocks += 1; - } - } - return numCleanBlocks; -} - - /* Cogit>>#setBreakMethod: */ -void -setBreakMethod(sqInt anObj) -{ - breakMethod = anObj; -} - - -/* If a method is compiled to machine code via a block entry it won't have a - selector. A subsequent send can find the method and hence fill in the - selector. - */ -/* self disassembleMethod: cogMethod */ - - /* Cogit>>#setSelectorOf:to: */ -void -setSelectorOfto(CogMethod *cogMethod, sqInt aSelectorOop) -{ - compilationBreakpointisMNUCase(aSelectorOop, 0); - assert(((cogMethod->cmType)) == CMMethod); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - ((((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)))->selector = aSelectorOop); - if (isYoung(aSelectorOop)) { - ensureInYoungReferrers(cogMethod); - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - /* Cogit>>#spanForCleanBlockStartingAt: */ -static sqInt NoDbgRegParms -spanForCleanBlockStartingAt(sqInt startPC) -{ - BytecodeDescriptor *descriptor; - sqInt end; - sqInt pc; - - pc = startPC; - end = numBytesOf(methodObj); - while (pc <= end) { - /* begin generatorForPC: */ - descriptor = generatorAt(bytecodeSetOffset + (fetchByteofObject(pc, methodObj))); - pc += (descriptor->numBytes); - if ((descriptor->isReturn)) { - return pc - startPC; - } - } - error("couldn't locate end of clean block"); - return 0; -} - - /* Cogit>>#stackCheckOffsetOfBlockAt:isMcpc: */ -static usqInt NoDbgRegParms -stackCheckOffsetOfBlockAtisMcpc(sqInt blockEntryMcpc, sqInt mcpc) -{ - CogBlockMethod *cogBlockMethod; - - cogBlockMethod = ((CogBlockMethod *) (blockEntryMcpc - (sizeof(CogBlockMethod)))); - if (((((sqInt)cogBlockMethod)) + ((cogBlockMethod->stackCheckOffset))) == mcpc) { - return ((usqInt)cogBlockMethod); - } - return 0; -} - - -/* Answer a fake value for the method oop in other than the first case in the - PIC prototype. - Since we use MoveUniqueCw:R: it must not be confused with a - method-relative address. - */ - - /* Cogit>>#subsequentPrototypeMethodOop */ -static sqInt -subsequentPrototypeMethodOop(void) -{ - return (addressIsInCurrentCompilation(0xBADA550) - ? 0xDEADEAD - : 0xBADA550); -} - - /* Cogit>>#traceLinkedSendOffset */ -sqInt -traceLinkedSendOffset(void) -{ - return (cmNoCheckEntryOffset + (callFullInstructionByteSize(backEnd))) + (8 /* pushLinkRegisterByteSize */); -} - - -/* Encode true and false and 0 to N such that they can't be confused for - register numbers (including NoReg) - and can be tested for by isTrampolineArgConstant: and decoded by - trampolineArgValue: - */ - - /* Cogit>>#trampolineArgConstant: */ -static sqInt NoDbgRegParms -trampolineArgConstant(sqInt booleanOrInteger) -{ - assert(booleanOrInteger >= 0); - return -2 - booleanOrInteger; -} - - /* Cogit>>#trampolineName:numArgs: */ -static char * NoDbgRegParms -trampolineNamenumArgs(char *routinePrefix, sqInt numArgs) -{ - char *theString; - - /* begin trampolineName:numArgs:limit: */ - theString = malloc((strlen(routinePrefix)) + 6); - sprintf(theString, "%s%cArgs", routinePrefix, (numArgs <= (NumSendTrampolines - 2) - ? '0' + numArgs - : 'N')); - return theString; -} - - -/* Malloc a string with the contents for the trampoline table */ - - /* Cogit>>#trampolineName:numArgs:limit: */ -static char * NoDbgRegParms -trampolineNamenumArgslimit(char *routinePrefix, int numArgs, sqInt argsLimit) -{ - char *theString; - - theString = malloc((strlen(routinePrefix)) + 6); - sprintf(theString, "%s%cArgs", routinePrefix, (numArgs <= argsLimit - ? '0' + numArgs - : 'N')); - return theString; -} - - /* Cogit>>#trampolineName:numRegArgs: */ -static char * NoDbgRegParms -trampolineNamenumRegArgs(char *routinePrefix, sqInt numArgs) -{ - sqInt argsLimit; - char *theString; - - /* begin trampolineName:numArgs:limit: */ - argsLimit = 2 /* numRegArgs */; - theString = malloc((strlen(routinePrefix)) + 6); - sprintf(theString, "%s%cArgs", routinePrefix, (numArgs <= argsLimit - ? '0' + numArgs - : 'N')); - return theString; -} - - /* Cogit>>#unknownBytecode */ -static sqInt -unknownBytecode(void) -{ - return EncounteredUnknownBytecode; -} - - -/* Unlink all sends in cog methods. */ - - /* Cogit>>#unlinkAllSends */ -void -unlinkAllSends(void) -{ - sqInt annotation; - CogMethod *cogMethod; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - - if (!methodZoneBase) { - return; - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - cogMethod = ((CogMethod *) methodZoneBase); - voidOpenPICList(); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfLinkedSendpcignored(annotation, (((char *) mcpc)), 0); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - else { - if (((cogMethod->cmType)) != CMFree) { - freeMethod(cogMethod); - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); -} - - -/* To placate the C static type system... */ - - /* Cogit>>#unlinkIfFreeOrLinkedSend:pc:of: */ -static sqInt NoDbgRegParms -unlinkIfFreeOrLinkedSendpcof(sqInt annotation, char *mcpc, CogMethod *theSelector) -{ - sqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if ((((targetMethod1->cmType)) == CMFree) - || (((targetMethod1->selector)) == (((sqInt) theSelector)))) { - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - } - return 0; -} - - /* Cogit>>#unlinkIfInvalidClassSend:pc:ignored: */ -static sqInt NoDbgRegParms -unlinkIfInvalidClassSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity) -{ - usqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send, but maybe a super send or linked to an OpenPIC, in which case the cache tag will be a selector.... */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (!(((annotation == IsSuperSend) - || (((annotation >= IsDirectedSuperSend) && (annotation <= IsDirectedSuperBindingSend)))) - || (((targetMethod1->cmType)) == CMOpenPIC))) { - if (!(isValidClassTag(inlineCacheTagAt(backEnd, ((sqInt)mcpc))))) { - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - } - } - return 0; -} - - /* Cogit>>#unlinkIfLinkedSendToFree:pc:ignored: */ -static sqInt NoDbgRegParms -unlinkIfLinkedSendToFreepcignored(sqInt annotation, char *mcpc, sqInt superfluity) -{ - sqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (((targetMethod1->cmType)) == CMFree) { - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - } - return 0; -} - - -/* To placate the C static type system... */ - - /* Cogit>>#unlinkIfLinkedSend:pc:if: */ -static sqInt NoDbgRegParms -unlinkIfLinkedSendpcif(sqInt annotation, char *mcpc, CogMethod *criterionArg) -{ - sqInt (*criterion)(CogMethod *); - sqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - criterion = ((void *)criterionArg); - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (criterion(targetMethod1)) { - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - } - return 0; -} - - /* Cogit>>#unlinkIfLinkedSend:pc:ignored: */ -static sqInt NoDbgRegParms -unlinkIfLinkedSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity) -{ - usqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - return 0; -} - - /* Cogit>>#unlinkIfLinkedSend:pc:to: */ -static sqInt NoDbgRegParms -unlinkIfLinkedSendpcto(sqInt annotation, char *mcpc, sqInt theCogMethod) -{ - sqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - if (annotation == IsDirectedSuperSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperSendTrampolines; - } - else { - if (annotation == IsDirectedSuperBindingSend) { - offset1 = cmNoCheckEntryOffset; - sendTable1 = directedSuperBindingSendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - } - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if ((((sqInt)targetMethod1)) == theCogMethod) { - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - } - return 0; -} - - -/* Unlink all sends in cog methods whose class tag is that of a forwarded - class. - */ - - /* Cogit>>#unlinkSendsLinkedForInvalidClasses */ -void -unlinkSendsLinkedForInvalidClasses(void) -{ - sqInt annotation; - CogMethod *cogMethod; - sqInt freedPIC; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - - if (!methodZoneBase) { - return; - } - cogMethod = ((CogMethod *) methodZoneBase); - codeModified = (freedPIC = 0); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfInvalidClassSendpcignored(annotation, (((char *) mcpc)), 0); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - else { - if ((((cogMethod->cmType)) == CMClosedPIC) - && (cPICHasForwardedClass(cogMethod))) { - freeMethod(cogMethod); - freedPIC = 1; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (freedPIC) { - unlinkSendsToFree(); - } - else { - if (codeModified) { - - /* After possibly updating inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } - } -} - - -/* Unlink all sends in cog methods. Free all Closed PICs with the selector, - or with an MNU case if isMNUSelector. First check if any method actually - has the selector; if not there can't be any linked send to it. This - routine (including descendents) is performance critical. It contributes - perhaps 30% of entire execution time in Compiler recompileAll. */ - - /* Cogit>>#unlinkSendsOf:isMNUSelector: */ -void -unlinkSendsOfisMNUSelector(sqInt selector, sqInt isMNUSelector) -{ - sqInt annotation; - CogMethod *cogMethod; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt mustScanAndUnlink; - sqInt result; - - if (!methodZoneBase) { - return; - } - cogMethod = ((CogMethod *) methodZoneBase); - mustScanAndUnlink = 0; - if (isMNUSelector) { - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - if (((cogMethod->cpicHasMNUCaseOrCMIsFullBlock)) - && (((cogMethod->cmType)) == CMClosedPIC)) { - assert(((cogMethod->cmType)) == CMClosedPIC); - freeMethod(cogMethod); - mustScanAndUnlink = 1; - } - else { - if (((cogMethod->selector)) == selector) { - mustScanAndUnlink = 1; - if (((cogMethod->cmType)) == CMClosedPIC) { - freeMethod(cogMethod); - } - } - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - } - else { - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) != CMFree) - && (((cogMethod->selector)) == selector)) { - mustScanAndUnlink = 1; - if (((cogMethod->cmType)) == CMClosedPIC) { - freeMethod(cogMethod); - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - } - if (!mustScanAndUnlink) { - return; - } - codeModified = 0; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfFreeOrLinkedSendpcof(annotation, (((char *) mcpc)), (((CogMethod *) selector))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (codeModified) { - - /* After possibly updating inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - -/* Unlink all sends in cog methods to free methods and/or pics. */ - - /* Cogit>>#unlinkSendsToFree */ -void -unlinkSendsToFree(void) -{ - sqInt annotation; - CogMethod *cogMethod; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - - if (!methodZoneBase) { - return; - } - codeModified = 0; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfLinkedSendToFreepcignored(annotation, (((char *) mcpc)), 0); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - else { - if (((cogMethod->cmType)) == CMClosedPIC) { - assert(noTargetsFreeInClosedPIC(cogMethod)); - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (codeModified) { - - /* After possibly updating inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } -} - - -/* Unlink all sends in cog methods to methods with a machine code - primitive, and free machine code primitive methods if freeIfTrue. - To avoid having to scan PICs, free any and all PICs */ - - /* Cogit>>#unlinkSendsToMethodsSuchThat:AndFreeIf: */ -void -unlinkSendsToMethodsSuchThatAndFreeIf(sqInt (*criterion)(CogMethod *), sqInt freeIfTrue) -{ - sqInt annotation; - CogMethod *cogMethod; - sqInt freedSomething; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - - if (!methodZoneBase) { - return; - } - codeModified = (freedSomething = 0); - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - if (freeIfTrue - && (criterion(cogMethod))) { - freeMethod(cogMethod); - freedSomething = 1; - } - else { - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfLinkedSendpcif(annotation, (((char *) mcpc)), (((CogMethod *) criterion))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - } - else { - if (((cogMethod->cmType)) == CMClosedPIC) { - freeMethod(cogMethod); - freedSomething = 1; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (freedSomething) { - unlinkSendsToFree(); - } - else { - if (codeModified) { - - /* After possibly updating inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } - } -} - - -/* Unlink all sends in cog methods to a particular target method. - If targetMethodObject isn't actually a method (perhaps being - used via invokeAsMethod) then there's nothing to do. */ - - /* Cogit>>#unlinkSendsTo:andFreeIf: */ -void -unlinkSendsToandFreeIf(sqInt targetMethodObject, sqInt freeIfTrue) -{ - sqInt annotation; - CogMethod *cogMethod; - sqInt freedPIC; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - CogMethod *targetMethod; - - if (!((isOopCompiledMethod(targetMethodObject)) - && (methodHasCogMethod(targetMethodObject)))) { - return; - } - targetMethod = cogMethodOf(targetMethodObject); - if (!methodZoneBase) { - return; - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - codeModified = (freedPIC = 0); - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - /* begin mapFor:performUntil:arg: */ - mcpc = ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock) - ? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset - : (((usqInt)cogMethod)) + cmNoCheckEntryOffset); - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfLinkedSendpcto(annotation, (((char *) mcpc)), targetMethod); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - else { - if ((((cogMethod->cmType)) == CMClosedPIC) - && (cPICHasTarget(cogMethod, targetMethod))) { - freeMethod(cogMethod); - freedPIC = 1; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (freeIfTrue) { - freeMethod(targetMethod); - } - if (freedPIC) { - unlinkSendsToFree(); - } - else { - if (codeModified) { - - /* After possibly updating inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - /* Cogit>>#voidCogCompiledCode */ -void -voidCogCompiledCode(void) -{ - CogMethod *cogMethod; - - /* begin clearCogCompiledCode */ - cogMethod = ((CogMethod *) baseAddress); - while ((((usqInt)cogMethod)) < mzFreeStart) { - if (((cogMethod->cmType)) == CMMethod) { - freeMethod(cogMethod); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - /* begin manageFrom:to: */ - mzFreeStart = (/* baseAddress = */ baseAddress); - youngReferrers = (/* limitAddress = */ limitAddress); - openPICList = null; - methodBytesFreedSinceLastCompaction = 0; - methodCount = 0; - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - -/* Access for the object representations when they need to prepend code to - trampolines. - */ -/* Eliminate stale dependent info. */ - - /* Cogit>>#zeroOpcodeIndex */ -static void -zeroOpcodeIndex(void) -{ - sqInt i; - - for (i = 0; i < opcodeIndex; i += 1) { - ((abstractOpcodes[i]).dependent = null); - } - zeroOpcodeIndexForNewOpcodes(); -} - - -/* Access for the object representations when they need to prepend code to - trampolines. - */ - - /* Cogit>>#zeroOpcodeIndexForNewOpcodes */ -static void -zeroOpcodeIndexForNewOpcodes(void) -{ - opcodeIndex = 0; -} - - /* CogMethod>>#counters */ -static sqInt NoDbgRegParms -counters(CogMethod * self_in_counters) -{ - return 0; -} - - /* CogMethodZone>>#addToOpenPICList: */ -static void NoDbgRegParms -addToOpenPICList(CogMethod *anOpenPIC) -{ - assert(((anOpenPIC->cmType)) == CMOpenPIC); - assert((openPICList == null) - || (((openPICList->cmType)) == CMOpenPIC)); - assertValidDualZoneWriteAddress(anOpenPIC); - (anOpenPIC->nextOpenPIC = ((usqInt)openPICList)); - openPICList = ((CogMethod *) ((((usqInt)anOpenPIC)) - (getCodeToDataDelta()))); -} - - /* CogMethodZone>>#addToYoungReferrers: */ -static void NoDbgRegParms -addToYoungReferrers(CogMethod *cogMethod) -{ - assertValidDualZoneWriteAddress(cogMethod); - assert((occurrencesInYoungReferrers(cogMethod)) == 0); - assert((cogMethod->cmRefersToYoung)); - assert((youngReferrers <= limitAddress) - && (youngReferrers >= (limitAddress - (methodCount * BytesPerWord)))); - if (!(asserta((limitAddress - (methodCount * BytesPerWord)) >= mzFreeStart))) { - error("no room on youngReferrers list"); - } - youngReferrers -= BytesPerWord; - codeLongAtput(youngReferrers, (((usqInt)cogMethod)) - (getCodeToDataDelta())); -} - - /* CogMethodZone>>#allocate: */ -static usqInt NoDbgRegParms -allocate(sqInt numBytes) -{ - usqInt allocation; - sqInt roundedBytes; - - roundedBytes = (numBytes + 7) & -8; - if ((mzFreeStart + roundedBytes) >= (limitAddress - (methodCount * BytesPerWord))) { - return 0; - } - allocation = mzFreeStart; - mzFreeStart += roundedBytes; - methodCount += 1; - return allocation; -} - - -/* Answer the method containing mcpc for the purposes of code zone - compaction, where mcpc is actually the value of instructionPointer at the - time of a compaction. */ - - /* CogMethodZone>>#cogMethodContaining: */ -CogMethod * -cogMethodContaining(usqInt mcpc) -{ - CogMethod * cogMethod; - CogMethod * prevMethod; - - if (mcpc > limitAddress) { - return null; - } - if (mcpc < baseAddress) { - /* begin assertMcpcIsPrimReturn: */ - assert((mcpc == cePrimReturnEnterCogCode) - || (mcpc == cePrimReturnEnterCogCodeProfiling)); - return null; - } - assert(mcpc < (freeStart())); - cogMethod = ((CogMethod *) baseAddress); - while ((((usqInt)cogMethod)) < mcpc) { - prevMethod = cogMethod; - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - assert((prevMethod != null) - && ((mcpc == ((((usqInt)prevMethod)) + ((prevMethod->stackCheckOffset)))) - || ((mcpcisAtStackCheckOfBlockMethodIn(mcpc, prevMethod)) - || (((primitiveIndexOfMethodheader((prevMethod->methodObject), (prevMethod->methodHeader))) > 0) - || ((isCallPrecedingReturnPC(backEnd(), mcpc)) - && ((callTargetFromReturnAddress(backEnd(), mcpc)) == (ceCheckForInterruptTrampoline()))))))); - return prevMethod; -} - - /* CogMethodZone>>#compactCompiledCode */ -static void -compactCompiledCode(void) -{ - unsigned short bytes; - CogMethod *dest; - sqLong objectHeaderValue; - CogMethod *source; - CogMethod * writableVersion; - - compactionInProgress = 1; - methodCount = 0; - objectHeaderValue = nullHeaderForMachineCodeMethod(); - source = ((CogMethod *) baseAddress); - voidOpenPICList(); - voidUnpairedMethodList(); - while ((source < (limitZony())) - && (((source->cmType)) != CMFree)) { - assert((cogMethodDoesntLookKosher(source)) == 0); - /* begin writableMethodFor: */ - writableVersion = ((CogMethod *) ((((usqInt)source)) + codeToDataDelta)); - (writableVersion->objectHeader = objectHeaderValue); - if (((source->cmUsageCount)) > 0) { - (writableVersion->cmUsageCount = ((source->cmUsageCount)) / 2); - } - /* begin maybeLinkOnUnpairedMethodList: */ - /* begin clearSavedPICUsageCount: */ - if (((source->cmType)) == CMOpenPIC) { - addToOpenPICList(writableVersion); - } - methodCount += 1; - source = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)source)) + ((source->blockSize))))); - } - if (source >= (limitZony())) { - haltmsg("no free methods; cannot compact."); - return; - } - dest = source; - while (source < (limitZony())) { - assert((maybeFreeCogMethodDoesntLookKosher(source)) == 0); - bytes = (source->blockSize); - if (((source->cmType)) != CMFree) { - methodCount += 1; - codeMemmove(dest, source, bytes); - /* begin maybeFlushWritableZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - if (codeToDataDelta > 0) { - flushDCacheFromto(backEnd, ((usqInt)dest), (((usqInt)dest)) + bytes); - } -# endif - ((writableVersion = ((CogMethod *) ((((usqInt)dest)) + codeToDataDelta)))->objectHeader = objectHeaderValue); - if (((dest->cmType)) == CMMethod) { - - /* For non-Newspeak there should be a one-to-one mapping between bytecoded and - cog methods. For Newspeak not necessarily, but only for anonymous accessors. */ - /* Only update the original method's header if it is referring to this CogMethod. */ - if ((((sqInt)(rawHeaderOf((dest->methodObject))))) == (((sqInt)source))) { - rawHeaderOfput((dest->methodObject), ((sqInt)dest)); - } - else { - assert((noAssertMethodClassAssociationOf((dest->methodObject))) == (nilObject())); - /* begin linkOnUnpairedMethodList: */ - } - } - else { - /* begin clearSavedPICUsageCount: */ - if (((dest->cmType)) == CMOpenPIC) { - addToOpenPICList(writableVersion); - } - } - if (((dest->cmUsageCount)) > 0) { - (writableVersion->cmUsageCount = ((dest->cmUsageCount)) / 2); - } - /* begin maybeFlushWritableZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - if (codeToDataDelta > 0) { - flushDCacheFromto(backEnd, ((usqInt)dest), ((usqInt)(dest + 1))); - } -# endif - dest = ((CogMethod *) ((((usqInt)dest)) + bytes)); - } - source = ((CogMethod *) ((((usqInt)source)) + bytes)); - } - mzFreeStart = ((usqInt)dest); - methodBytesFreedSinceLastCompaction = 0; - compactionInProgress = 0; -} - - /* CogMethodZone>>#ensureInYoungReferrers: */ -static void NoDbgRegParms -ensureInYoungReferrers(CogMethod *cogMethod) -{ - CogMethod * writableMethod; - - assertValidDualZoneReadAddress(cogMethod); - if (!((cogMethod->cmRefersToYoung))) { - assert((occurrencesInYoungReferrers(cogMethod)) == 0); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - ((writableMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)))->cmRefersToYoung = 1); - addToYoungReferrers(writableMethod); - } -} - - /* CogMethodZone>>#followForwardedLiteralsInOpenPICList */ -static void -followForwardedLiteralsInOpenPICList(void) -{ - CogMethod *openPIC; - - openPIC = openPICList; - while (openPIC != null) { - followForwardedLiteralsIn(openPIC); - openPIC = ((CogMethod *) ((openPIC->nextOpenPIC))); - } - pruneYoungReferrers(); -} - - /* CogMethodZone>>#freeMethod: */ -static void NoDbgRegParms -freeMethod(CogMethod *cogMethod) -{ - CogMethod * writableMethod; - - assert(((cogMethod->cmType)) != CMFree); - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - if (((cogMethod->cmType)) == CMMethod) { - - /* For non-Newspeak there should be a one-to-one mapping between bytecoded and - cog methods. For Newspeak not necessarily, but only for anonymous accessors. */ - /* Only reset the original method's header if it is referring to this CogMethod. */ - if ((((sqInt)(rawHeaderOf((cogMethod->methodObject))))) == (((sqInt)cogMethod))) { - rawHeaderOfput((cogMethod->methodObject), (cogMethod->methodHeader)); - } - else { - assert((noAssertMethodClassAssociationOf((cogMethod->methodObject))) == (nilObject())); - } - } - if (((cogMethod->cmType)) == CMOpenPIC) { - removeFromOpenPICList(cogMethod); - } - /* begin writableMethodFor: */ - writableMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - (writableMethod->cmRefersToYoung = 0); - (writableMethod->cmType = CMFree); - methodBytesFreedSinceLastCompaction += (cogMethod->blockSize); -} - - -/* Free methods, preferring older methods for compaction, up to some - fraction, currently a quarter. - */ - - /* CogMethodZone>>#freeOlderMethodsForCompaction */ -static void -freeOlderMethodsForCompaction(void) -{ - sqInt amountToFree; - CogMethod *cogMethod; - sqInt freeableUsage; - sqInt freedSoFar; - sqInt initialFreeSpace; - sqInt zoneSize; - - zoneSize = limitAddress - baseAddress; - initialFreeSpace = (limitAddress - mzFreeStart) + methodBytesFreedSinceLastCompaction; - freedSoFar = initialFreeSpace; - - /* 4 needs to be e.g. a start-up parameter */ - amountToFree = zoneSize / 4; - freeableUsage = 0; - do { - cogMethod = ((CogMethod *) baseAddress); - while (((((usqInt)cogMethod)) < mzFreeStart) - && (freedSoFar < amountToFree)) { - if ((((cogMethod->cmType)) != CMFree) - && (((cogMethod->cmUsageCount)) <= freeableUsage)) { - freeMethod(cogMethod); - freedSoFar += (cogMethod->blockSize); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - } while((freedSoFar < amountToFree) - && (((freeableUsage += 1)) < CMMaxUsageCount)); -} - - -/* Answer that all entries in youngReferrers are in-use and have the - cmRefersToYoung flag set. - Used to check that the youngreferrers pruning routines work correctly. */ - - /* CogMethodZone>>#kosherYoungReferrers */ -sqInt -kosherYoungReferrers(void) -{ - CogMethod * cogMethod; - usqInt pointer; - CogMethod * prevMethod; - - if ((youngReferrers > limitAddress) - || (youngReferrers < mzFreeStart)) { - return 0; - } - pointer = youngReferrers; - while (pointer < limitAddress) { - cogMethod = ((CogMethod *) (longAt(pointer))); - if (((cogMethod->cmType)) != CMFree) { - if (!((cogMethod->cmRefersToYoung))) { - return 0; - } - if ((occurrencesInYoungReferrers(cogMethod)) != 1) { - return 0; - } - } - pointer += BytesPerWord; - } - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - prevMethod = cogMethod; - if (((cogMethod->cmType)) != CMFree) { - if ((occurrencesInYoungReferrers(cogMethod)) != (((cogMethod->cmRefersToYoung) - ? 1 - : 0))) { - return 0; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - if (cogMethod == prevMethod) { - return 0; - } - } - return 1; -} - - -/* For assert checking... */ - - /* CogMethodZone>>#mcpc:isAtStackCheckOfBlockMethodIn: */ -static sqInt NoDbgRegParms -mcpcisAtStackCheckOfBlockMethodIn(sqInt mcpc, CogMethod *cogMethod) -{ - if (((cogMethod->blockEntryOffset)) == 0) { - return 0; - } - return (blockDispatchTargetsForperformarg(cogMethod, stackCheckOffsetOfBlockAtisMcpc, mcpc)) != 0; -} - - /* CogMethodZone>>#methodFor: */ -CogMethod * -methodFor(void *address) -{ - CogMethod * cogMethod; - CogMethod * nextMethod; - - cogMethod = ((CogMethod *) baseAddress); - while ((cogMethod < (limitZony())) - && ((((usqInt)cogMethod)) <= (((usqInt)address)))) { - /* begin methodAfter: */ - nextMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - if (nextMethod == cogMethod) { - return null; - } - if (((((usqInt)address)) >= (((usqInt)cogMethod))) - && ((((usqInt)address)) < (((usqInt)nextMethod)))) { - return cogMethod; - } - cogMethod = nextMethod; - } - return null; -} - - /* CogMethodZone>>#methodsCompiledToMachineCodeInto: */ -sqInt -methodsCompiledToMachineCodeInto(sqInt arrayObj) -{ - CogMethod *cogMethod; - sqInt methodIndex; - - methodIndex = 0; - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - storePointerUncheckedofObjectwithValue(methodIndex, arrayObj, (cogMethod->methodObject)); - methodIndex += 1; - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return methodIndex; -} - - /* CogMethodZone>>#numMethods */ -sqInt -numMethods(void) -{ - return methodCount; -} - - /* CogMethodZone>>#numMethodsOfType: */ -sqInt -numMethodsOfType(sqInt cogMethodType) -{ - CogMethod *cogMethod; - sqInt n; - - n = 0; - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == cogMethodType) { - n += 1; - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return n; -} - - /* CogMethodZone>>#occurrencesInYoungReferrers: */ -static sqInt NoDbgRegParms -occurrencesInYoungReferrers(CogMethod *cogMethod) -{ - sqInt count; - usqInt pointer; - - assert(youngReferrers <= limitAddress); - count = 0; - pointer = youngReferrers; - while (pointer < limitAddress) { - if ((((sqInt)cogMethod)) == (longAt(pointer))) { - count += 1; - } - pointer += BytesPerWord; - } - return count; -} - - /* CogMethodZone>>#openPICWithSelector: */ -static CogMethod * NoDbgRegParms -openPICWithSelector(sqInt aSelector) -{ - CogMethod *openPIC; - - openPIC = openPICList; - do { - if ((openPIC == null) - || (((openPIC->selector)) == aSelector)) { - return openPIC; - } - openPIC = ((CogMethod *) ((openPIC->nextOpenPIC))); - } while(1); - return 0; -} - - -/* Some methods have been freed. Compute how much each survivor needs to - move during the ensuing compaction and record it in the objectHeader - field. - For Sista, where we want PICs to last so they can be observed, we need to - keep PICs unless - they are definitely unused. So we need to identify unused PICs. So in - planCompact, zero the - usage counts of all PICs, saving the actual usage count in - blockEntryOffset. Then in - relocateMethodsPreCompaction (actually in - relocateIfCallOrMethodReference:mcpc:delta:) restore the usage counts of - used PICs. Finally in compactCompiledCode, clear the blockEntryOffset - of the unused PICs; they will then have a zero count and be reclaimed in - the next code compaction. */ - - /* CogMethodZone>>#planCompaction */ -static void -planCompaction(void) -{ - CogMethod *cogMethod; - sqInt delta; - - delta = 0; - cogMethod = ((CogMethod *) baseAddress); - while ((((usqInt)cogMethod)) < mzFreeStart) { - if (((cogMethod->cmType)) == CMFree) { - delta -= (cogMethod->blockSize); - } - else { - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - ((((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)))->objectHeader = delta); - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* CogMethodZone>>#printCogMethods */ -void -printCogMethods(void) -{ - CogMethod *cogMethod; - sqInt nc; - sqInt nf; - sqInt nm; - sqInt no; - sqInt nu; - - /* begin printCogMethodsSummarizing: */ - nm = (nc = (no = (nf = (nu = 0)))); - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - printCogMethod(cogMethod); - switch ((cogMethod->cmType)) { - case CMFree: - nf += 1; - break; - case CMMethod: - nm += 1; - break; - case CMClosedPIC: - nc += 1; - break; - case CMOpenPIC: - no += 1; - break; - default: - nu += 1; - - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - print("CMMethod "); - printNum(nm); - print(" CMClosedPIC "); - printNum(nc); - print(" CMOpenPIC "); - printNum(no); - print(" CMFree "); - printNum(nf); - if (nu > 0) { - print(" UNKNOWN "); - printNum(nu); - } - print(" total "); - printNum((((nm + nc) + no) + nf) + nu); - cr(); -} - - /* CogMethodZone>>#printCogMethodsOfType: */ -void -printCogMethodsOfType(sqInt cmType) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == cmType) { - printCogMethod(cogMethod); - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* CogMethodZone>>#printCogMethodsWithMethod: */ -void -printCogMethodsWithMethod(sqInt methodOop) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) != CMFree) - && (((cogMethod->methodObject)) == methodOop)) { - printCogMethod(cogMethod); - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* CogMethodZone>>#printCogMethodsWithPrimitive: */ -void -printCogMethodsWithPrimitive(sqInt primIdx) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) == CMMethod) - && (primIdx == (primitiveIndexOfMethodheader((cogMethod->methodObject), (cogMethod->methodHeader))))) { - printCogMethod(cogMethod); - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* CogMethodZone>>#printCogMethodsWithSelector: */ -void -printCogMethodsWithSelector(sqInt selectorOop) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) != CMFree) - && (((cogMethod->selector)) == selectorOop)) { - printCogMethod(cogMethod); - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* CogMethodZone>>#printCogYoungReferrers */ -void -printCogYoungReferrers(void) -{ - CogMethod *cogMethod; - usqInt pointer; - - pointer = youngReferrers; - while (pointer < limitAddress) { - cogMethod = ((CogMethod *) (longAt(pointer))); - if (!((cogMethod->cmRefersToYoung))) { - print("*"); - } - if (((cogMethod->cmType)) == CMFree) { - print("!"); - } - if (!(((cogMethod->cmRefersToYoung)) - && (((cogMethod->cmType)) != CMFree))) { - print(" "); - } - printCogMethod(cogMethod); - pointer += BytesPerWord; - } -} - - /* CogMethodZone>>#printOpenPICList */ -sqInt -printOpenPICList(void) -{ - sqInt n; - CogMethod *openPIC; - - /* begin printOpenPICListSummarizing: */ - n = 0; - openPIC = openPICList; - while (!(openPIC == null)) { - n += 1; - printCogMethod(openPIC); - openPIC = ((CogMethod *) ((openPIC->nextOpenPIC))); - } - return n; -} - - /* CogMethodZone>>#pruneYoungReferrers */ -sqInt -pruneYoungReferrers(void) -{ - usqInt dest; - usqInt next; - usqInt source; - - assert(youngReferrers <= limitAddress); - if (youngReferrers == limitAddress) { - return null; - } - dest = limitAddress; - while (1) { - next = dest - BytesPerWord; - if (!((next >= youngReferrers) - && (((((CogMethod *) (longAt(next))))->cmRefersToYoung)))) break; - dest = next; - } - assert(dest >= youngReferrers); - source = dest - BytesPerWord; - while (source >= youngReferrers) { - if (((((CogMethod *) (longAt(source))))->cmRefersToYoung)) { - assert(source < (dest - BytesPerWord)); - if (!(next == null)) { - - /* convenient first-time flag */ - next = null; - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - } - codeLongAtput((dest -= BytesPerWord), longAt(source)); - } - source -= BytesPerWord; - } - youngReferrers = dest; - assert(kosherYoungReferrers()); - return 0; -} - - /* CogMethodZone>>#relocateAndPruneYoungReferrers */ -static sqInt -relocateAndPruneYoungReferrers(void) -{ - CogMethod *cogMethod; - usqInt dest; - usqInt next; - usqInt source; - - assert(youngReferrers <= limitAddress); - if (youngReferrers == limitAddress) { - return null; - } - dest = limitAddress; - while (1) { - next = dest - BytesPerWord; - if (!((next >= youngReferrers) - && (((((cogMethod = ((CogMethod *) (longAt(next))))->cmType)) != CMFree) - && ((cogMethod->cmRefersToYoung))))) break; - if (((cogMethod->objectHeader)) != 0) { - codeLongAtput(next, (((sqInt)cogMethod)) + ((cogMethod->objectHeader))); - } - dest = next; - } - assert(dest >= youngReferrers); - source = dest - BytesPerWord; - while (source >= youngReferrers) { - cogMethod = ((CogMethod *) (longAt(source))); - if ((((cogMethod->cmType)) != CMFree) - && ((cogMethod->cmRefersToYoung))) { - assert(source < (dest - BytesPerWord)); - if (((cogMethod->objectHeader)) != 0) { - cogMethod = ((CogMethod *) ((((sqInt)cogMethod)) + (((sqInt)((cogMethod->objectHeader)))))); - } - codeLongAtput((dest -= BytesPerWord), ((sqInt)cogMethod)); - } - source -= BytesPerWord; - } - youngReferrers = dest; - return 0; -} - - -/* All surviving methods have had the amount they are going to relocate by - stored in their objectHeader fields. Relocate all relative calls so that - after the compaction of both the method containing each call and the call - target the calls invoke the same target. */ - - /* CogMethodZone>>#relocateMethodsPreCompaction */ -static sqInt -relocateMethodsPreCompaction(void) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) baseAddress); - while ((((usqInt)cogMethod)) < mzFreeStart) { - if (((cogMethod->cmType)) != CMFree) { - if (((cogMethod->cmType)) == CMClosedPIC) { - relocateCallsInClosedPIC(cogMethod); - } - else { - relocateCallsAndSelfReferencesInMethod(cogMethod); - } - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - relocateAndPruneYoungReferrers(); - return 1; -} - - /* CogMethodZone>>#removeFromOpenPICList: */ -static sqInt NoDbgRegParms -removeFromOpenPICList(CogMethod *anOpenPIC) -{ - CogMethod *prevPIC; - - assert(((anOpenPIC->cmType)) == CMOpenPIC); - if (!openPICList) { - return null; - } - assert((((openPICList->cmType)) == CMOpenPIC) - && ((((openPICList->nextOpenPIC)) == null) - || ((((((CogMethod *) ((openPICList->nextOpenPIC))))->cmType)) == CMOpenPIC))); - if (anOpenPIC == openPICList) { - - /* N.B. Use self rather than coInterpreter to avoid attempting to cast nil. - Conversion to CogMethod done in the nextOpenPIC accessor. */ - openPICList = ((CogMethod *) ((anOpenPIC->nextOpenPIC))); - return null; - } - prevPIC = openPICList; - do { - assert((prevPIC != null) - && (((prevPIC->cmType)) == CMOpenPIC)); - if (((prevPIC->nextOpenPIC)) == (((usqInt)anOpenPIC))) { - ((((CogMethod *) ((((usqInt)prevPIC)) + codeToDataDelta)))->nextOpenPIC = (anOpenPIC->nextOpenPIC)); - return null; - } - prevPIC = ((CogMethod *) ((prevPIC->nextOpenPIC))); - } while(1); - return 0; -} - - -/* Determine the default alignment for the start of a CogMethod, which in - turn determines the size of the mask used to distinguish the checked and - unchecked entry-points, used to distinguish normal and super sends on - method unlinking. - This is passed onto the backEnd to allow processors with coarse - instructions (ARM) to increase the alignment if required. */ - - /* CogMethodZone>>#roundUpLength: */ -static sqInt NoDbgRegParms -roundUpLength(sqInt numBytes) -{ - return roundUpToMethodAlignment(backEnd(), numBytes); -} - - /* CogMethodZone>>#voidOpenPICList */ -static void -voidOpenPICList(void) -{ - openPICList = null; -} - - /* CogMethodZone>>#voidUnpairedMethodList */ -static void -voidUnpairedMethodList(void) -{ - } - - /* CogMethodZone>>#voidYoungReferrersPostTenureAll */ -static void -voidYoungReferrersPostTenureAll(void) -{ - CogMethod *cogMethod; - usqInt pointer; - - assert(youngReferrers <= limitAddress); - pointer = youngReferrers; - while (pointer < limitAddress) { - cogMethod = ((CogMethod *) (longAt(pointer))); - if (((cogMethod->cmType)) != CMFree) { - (cogMethod->cmRefersToYoung = 0); - } - pointer += BytesPerWord; - } - youngReferrers = limitAddress; -} - - -/* useful for VM debugging; use export: so it will be accessible on win32 */ - - /* CogMethodZone>>#whereIsMaybeCodeThing: */ -EXPORT(char *) -whereIsMaybeCodeThing(sqInt anOop) -{ - if (oopisGreaterThanOrEqualToandLessThan(anOop, codeBase, limitAddress)) { - if (oopisLessThan(anOop, minCogMethodAddress())) { - return " is in generated runtime"; - } - if (oopisLessThan(anOop, mzFreeStart)) { - return " is in generated methods"; - } - if (oopisLessThan(anOop, youngReferrers)) { - return " is in code zone"; - } - return " is in young referrers"; - } - return null; -} - - /* CogMIPSELCompiler>>#addiuR:R:C: */ -static sqInt NoDbgRegParms -addiuRRC(AbstractInstruction * self_in_addiuRRC, sqInt destReg, sqInt srcReg, sqInt imm) -{ - return itypersrtsignedImmediate(self_in_addiuRRC, ADDIU, srcReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#adduR:R:R: */ -static sqInt NoDbgRegParms -adduRRR(AbstractInstruction * self_in_adduRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_adduRRR, SPECIAL, leftReg, rightReg, destReg, 0, ADDU); -} - - /* CogMIPSELCompiler>>#andiR:R:C: */ -static sqInt NoDbgRegParms -andiRRC(AbstractInstruction * self_in_andiRRC, sqInt destReg, sqInt srcReg, sqInt imm) -{ - return itypersrteitherImmediate(self_in_andiRRC, ANDI, srcReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#andR:R:R: */ -static sqInt NoDbgRegParms -andRRR(AbstractInstruction * self_in_andRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_andRRR, SPECIAL, leftReg, rightReg, destReg, 0, AND); -} - - /* CogMIPSELCompiler>>#beqR:R:offset: */ -static sqInt NoDbgRegParms -beqRRoffset(AbstractInstruction * self_in_beqRRoffset, sqInt leftReg, sqInt rightReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_beqRRoffset, BEQ, leftReg, rightReg, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#bgezR:offset: */ -static sqInt NoDbgRegParms -bgezRoffset(AbstractInstruction * self_in_bgezRoffset, sqInt cmpReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_bgezRoffset, REGIMM, cmpReg, BGEZ, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#bgtzR:offset: */ -static sqInt NoDbgRegParms -bgtzRoffset(AbstractInstruction * self_in_bgtzRoffset, sqInt cmpReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_bgtzRoffset, BGTZ, cmpReg, 0, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#blezR:offset: */ -static sqInt NoDbgRegParms -blezRoffset(AbstractInstruction * self_in_blezRoffset, sqInt cmpReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_blezRoffset, BLEZ, cmpReg, 0, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#bltzR:offset: */ -static sqInt NoDbgRegParms -bltzRoffset(AbstractInstruction * self_in_bltzRoffset, sqInt cmpReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_bltzRoffset, REGIMM, cmpReg, BLTZ, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#bneR:R:offset: */ -static sqInt NoDbgRegParms -bneRRoffset(AbstractInstruction * self_in_bneRRoffset, sqInt leftReg, sqInt rightReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_bneRRoffset, BNE, leftReg, rightReg, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#callInstructionByteSize */ -static sqInt NoDbgRegParms -callInstructionByteSize(AbstractInstruction * self_in_callInstructionByteSize) -{ - flag("todo"); - return 16; -} - - -/* csra - 16: lui t9, high - csra - 12: ori t9, low - csra - 8: jalr t9 - csra - 4: nop (delay slot) */ - - /* CogMIPSELCompiler>>#callTargetFromReturnAddress: */ -static usqInt NoDbgRegParms -callTargetFromReturnAddress(AbstractInstruction * self_in_callTargetFromReturnAddress, sqInt callSiteReturnAddress) -{ - assert((opcodeAtAddress(self_in_callTargetFromReturnAddress, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_callTargetFromReturnAddress, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_callTargetFromReturnAddress, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_callTargetFromReturnAddress, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_callTargetFromReturnAddress))); - return literalAtAddress(self_in_callTargetFromReturnAddress, callSiteReturnAddress - 12); -} - - -/* NOTE: the right reg (rt) MUST equal dest reg (rd) or behavior is undefined */ - - /* CogMIPSELCompiler>>#clzR:R:R: */ -static sqInt NoDbgRegParms -clzRRR(AbstractInstruction * self_in_clzRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_clzRRR, SPECIAL, leftReg, rightReg, destReg, 0, 32); -} - - /* CogMIPSELCompiler>>#cmpC32RTempByteSize */ -static sqInt NoDbgRegParms -cmpC32RTempByteSize(AbstractInstruction * self_in_cmpC32RTempByteSize) -{ - return 8; -} - - -/* Each MIPS instruction has 4 bytes. Many abstract opcodes need more than - one instruction. Instructions that refer to constants and/or literals - depend on literals - being stored in-line or out-of-line. - - N.B. The ^N forms are to get around the bytecode compiler's long branch - limits which are exceeded when each case jumps around the otherwise. */ - - /* CogMIPSELCompiler>>#computeMaximumSize */ -static sqInt NoDbgRegParms -computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize) -{ - switch ((self_in_computeMaximumSize->opcode)) { - case BrEqualRR: - case BrNotEqualRR: - case JumpR: - case Jump: - case JumpZero: - case JumpNonZero: - case JumpNegative: - case JumpNonNegative: - case JumpOverflow: - case JumpNoOverflow: - case JumpCarry: - case JumpNoCarry: - case JumpLess: - case JumpGreaterOrEqual: - case JumpGreater: - case JumpLessOrEqual: - case JumpBelow: - case JumpAboveOrEqual: - case JumpAbove: - case JumpBelowOrEqual: - case JumpFPEqual: - case JumpFPNotEqual: - case JumpFPLess: - case JumpFPGreaterOrEqual: - case JumpFPGreater: - case JumpFPLessOrEqual: - case JumpFPOrdered: - case JumpFPUnordered: - case RetN: - case MoveCwR: - case MoveXbrRR: - case MoveRXbrR: - case PopR: - case PushR: - case ConvertRRd: - return 8; - - case BrUnsignedLessRR: - case BrUnsignedLessEqualRR: - case BrUnsignedGreaterRR: - case BrUnsignedGreaterEqualRR: - case BrSignedLessRR: - case BrSignedLessEqualRR: - case BrSignedGreaterRR: - case BrSignedGreaterEqualRR: - case XorCqR: - case AddCwR: - case AndCwR: - case OrCwR: - case SubCwR: - case XorCwR: - case MoveXwrRR: - case MoveRXwrR: - case PrefetchAw: - return 12; - - case BrLongEqualRR: - case BrLongNotEqualRR: - case PushCw: - case PushCq: - return 16; - - case MulRR: - case DivRR: - case MoveLowR: - case MoveHighR: - case Literal: - case Fill32: - case Nop: - case Stop: - case AddRR: - case AndRR: - case OrRR: - case XorRR: - case SubRR: - case NegateR: - case AddRRR: - case SubRRR: - case LogicalShiftLeftCqR: - case LogicalShiftRightCqR: - case ArithmeticShiftRightCqR: - case LogicalShiftLeftRR: - case LogicalShiftRightRR: - case ArithmeticShiftRightRR: - case AddRdRd: - case CmpRdRd: - case SubRdRd: - case MulRdRd: - case DivRdRd: - case SqrtRd: - case ClzRR: - case MoveRR: - case MoveRdRd: - case MoveRMwr: - case MoveMbrR: - case MoveRMbr: - case MoveM16rR: - case MoveRM16r: - return 4; - - case Label: - return 0; - - case AlignmentNops: - return (((self_in_computeMaximumSize->operands))[0]) - 4; - - case Call: - case CallFull: - case JumpFull: - case JumpLong: - case JumpLongZero: - case JumpLongNonZero: - return 16; - - case AddCqR: - case OrCqR: - case OrCqRR: - case SubCqR: - case TstCqR: - case LoadEffectiveAddressMwrR: - return (isShortOffset(self_in_computeMaximumSize, ((self_in_computeMaximumSize->operands))[0]) - ? 4 - : 12); - - case AndCqR: - case AndCqRR: - return ((((((self_in_computeMaximumSize->operands))[0]) >= 0) && ((((self_in_computeMaximumSize->operands))[0]) <= 0xFFFF)) - ? 4 - : 12); - - case CmpCqR: - case CmpCwR: - case AddCheckOverflowCqR: - case SubCheckOverflowCqR: - return 28; - - case CmpRR: - case AddCheckOverflowRR: - case SubCheckOverflowRR: - case MulCheckOverflowRR: - return 20; - - case MoveCqR: - return (isShortOffset(self_in_computeMaximumSize, ((self_in_computeMaximumSize->operands))[0]) - ? 4 - : 8); - - case MoveAwR: - case MoveAbR: - return (((((self_in_computeMaximumSize->operands))[0]) != null) - && ((((varBaseAddress()) - (0x8000)) < (((self_in_computeMaximumSize->operands))[0])) - && ((((self_in_computeMaximumSize->operands))[0]) < ((varBaseAddress()) + (0x8000)))) - ? 4 - : 12); - - case MoveRAw: - case MoveRAb: - return (((((self_in_computeMaximumSize->operands))[1]) != null) - && ((((varBaseAddress()) - (0x8000)) < (((self_in_computeMaximumSize->operands))[1])) - && ((((self_in_computeMaximumSize->operands))[1]) < ((varBaseAddress()) + (0x8000)))) - ? 4 - : 12); - - case MoveRdM64r: - case MoveM64rRd: - return 12; - - case MoveMwrR: - return (isShortOffset(self_in_computeMaximumSize, ((self_in_computeMaximumSize->operands))[0]) - ? 4 - : 16); - - default: - error("Case not found and no otherwise clause"); - } - return 0; -} - - /* CogMIPSELCompiler>>#concretizeAddCheckOverflowCqR */ -static sqInt NoDbgRegParms -concretizeAddCheckOverflowCqR(AbstractInstruction * self_in_concretizeAddCheckOverflowCqR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - sqInt aWord4; - sqInt aWord5; - sqInt aWord6; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeAddCheckOverflowCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAddCheckOverflowCqR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeAddCheckOverflowCqR, AT, high16BitsOf(self_in_concretizeAddCheckOverflowCqR, rightImm)); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeAddCheckOverflowCqR, AT, AT, low16BitsOf(self_in_concretizeAddCheckOverflowCqR, rightImm)); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = adduRRR(self_in_concretizeAddCheckOverflowCqR, OverflowTemp1, leftReg, ZR); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = adduRRR(self_in_concretizeAddCheckOverflowCqR, destReg, leftReg, AT); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[12 / 4] = aWord3; - /* begin machineCodeAt:put: */ - aWord4 = xorRRR(self_in_concretizeAddCheckOverflowCqR, OverflowTemp2, destReg, AT); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[16 / 4] = aWord4; - /* begin machineCodeAt:put: */ - aWord5 = xorRRR(self_in_concretizeAddCheckOverflowCqR, OverflowTemp1, destReg, OverflowTemp1); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[20 / 4] = aWord5; - /* begin machineCodeAt:put: */ - aWord6 = andRRR(self_in_concretizeAddCheckOverflowCqR, Overflow, OverflowTemp1, OverflowTemp2); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[24 / 4] = aWord6; - return 28; -} - - /* CogMIPSELCompiler>>#concretizeAddCheckOverflowRR */ -static sqInt NoDbgRegParms -concretizeAddCheckOverflowRR(AbstractInstruction * self_in_concretizeAddCheckOverflowRR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - sqInt aWord4; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeAddCheckOverflowRR->operands))[0]; - - /* Save original LHS */ - destReg = (leftReg = ((self_in_concretizeAddCheckOverflowRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeAddCheckOverflowRR, OverflowTemp1, leftReg, ZR); - ((self_in_concretizeAddCheckOverflowRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = adduRRR(self_in_concretizeAddCheckOverflowRR, destReg, leftReg, rightReg); - ((self_in_concretizeAddCheckOverflowRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = xorRRR(self_in_concretizeAddCheckOverflowRR, OverflowTemp2, destReg, rightReg); - ((self_in_concretizeAddCheckOverflowRR->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = xorRRR(self_in_concretizeAddCheckOverflowRR, OverflowTemp1, destReg, OverflowTemp1); - ((self_in_concretizeAddCheckOverflowRR->machineCode))[12 / 4] = aWord3; - /* begin machineCodeAt:put: */ - aWord4 = andRRR(self_in_concretizeAddCheckOverflowRR, Overflow, OverflowTemp1, OverflowTemp2); - ((self_in_concretizeAddCheckOverflowRR->machineCode))[16 / 4] = aWord4; - return 20; -} - - /* CogMIPSELCompiler>>#concretizeAddCqR */ -static sqInt NoDbgRegParms -concretizeAddCqR(AbstractInstruction * self_in_concretizeAddCqR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeAddCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAddCqR->operands))[1]); - if (!(isShortOffset(self_in_concretizeAddCqR, rightImm))) { - return concretizeAddCwR(self_in_concretizeAddCqR); - } - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizeAddCqR, destReg, leftReg, rightImm); - ((self_in_concretizeAddCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeAddCwR */ -static sqInt NoDbgRegParms -concretizeAddCwR(AbstractInstruction * self_in_concretizeAddCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeAddCwR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAddCwR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeAddCwR, AT, high16BitsOf(self_in_concretizeAddCwR, rightImm)); - ((self_in_concretizeAddCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeAddCwR, AT, AT, low16BitsOf(self_in_concretizeAddCwR, rightImm)); - ((self_in_concretizeAddCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = adduRRR(self_in_concretizeAddCwR, destReg, leftReg, AT); - ((self_in_concretizeAddCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeAddRRDest: */ -static sqInt NoDbgRegParms -concretizeAddRRDest(AbstractInstruction * self_in_concretizeAddRRDest, sqInt destReg) -{ - sqInt aWord; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeAddRRDest->operands))[0]; - leftReg = ((self_in_concretizeAddRRDest->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeAddRRDest, destReg, leftReg, rightReg); - ((self_in_concretizeAddRRDest->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeAlignmentNops */ -static usqInt NoDbgRegParms -concretizeAlignmentNops(AbstractInstruction * self_in_concretizeAlignmentNops) -{ - sqInt p; - - assert((((self_in_concretizeAlignmentNops->machineCodeSize)) % 4) == 0); - for (p = 0; p < ((self_in_concretizeAlignmentNops->machineCodeSize)); p += 4) { - /* begin machineCodeAt:put: */ - ((self_in_concretizeAlignmentNops->machineCode))[p / 4] = 0 /* nop */; - } - return (self_in_concretizeAlignmentNops->machineCodeSize); -} - - /* CogMIPSELCompiler>>#concretizeAndCqR */ -static sqInt NoDbgRegParms -concretizeAndCqR(AbstractInstruction * self_in_concretizeAndCqR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeAndCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAndCqR->operands))[1]); - if (!(isShortOffset(self_in_concretizeAndCqR, rightImm))) { - return concretizeAndCwR(self_in_concretizeAndCqR); - } - /* begin machineCodeAt:put: */ - aWord = andiRRC(self_in_concretizeAndCqR, destReg, leftReg, rightImm); - ((self_in_concretizeAndCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeAndCqRDest: */ -static sqInt NoDbgRegParms -concretizeAndCqRDest(AbstractInstruction * self_in_concretizeAndCqRDest, sqInt destReg) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt srcReg; - usqInt value; - - value = ((self_in_concretizeAndCqRDest->operands))[0]; - srcReg = ((self_in_concretizeAndCqRDest->operands))[1]; - if (((value >= 0) && (value <= 0xFFFF))) { - /* begin machineCodeAt:put: */ - aWord = andiRRC(self_in_concretizeAndCqRDest, destReg, srcReg, value); - ((self_in_concretizeAndCqRDest->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeAndCqRDest, AT, high16BitsOf(self_in_concretizeAndCqRDest, value)); - ((self_in_concretizeAndCqRDest->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeAndCqRDest, AT, AT, low16BitsOf(self_in_concretizeAndCqRDest, value)); - ((self_in_concretizeAndCqRDest->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = andRRR(self_in_concretizeAndCqRDest, destReg, srcReg, AT); - ((self_in_concretizeAndCqRDest->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeAndCwR */ -static sqInt NoDbgRegParms -concretizeAndCwR(AbstractInstruction * self_in_concretizeAndCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeAndCwR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAndCwR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeAndCwR, AT, high16BitsOf(self_in_concretizeAndCwR, rightImm)); - ((self_in_concretizeAndCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeAndCwR, AT, AT, low16BitsOf(self_in_concretizeAndCwR, rightImm)); - ((self_in_concretizeAndCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = andRRR(self_in_concretizeAndCwR, destReg, leftReg, AT); - ((self_in_concretizeAndCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeAndRR */ -static sqInt NoDbgRegParms -concretizeAndRR(AbstractInstruction * self_in_concretizeAndRR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeAndRR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAndRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = andRRR(self_in_concretizeAndRR, destReg, leftReg, rightReg); - ((self_in_concretizeAndRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeArithmeticShiftRightCqR */ -static sqInt NoDbgRegParms -concretizeArithmeticShiftRightCqR(AbstractInstruction * self_in_concretizeArithmeticShiftRightCqR) -{ - sqInt aWord; - sqInt distance; - usqInt reg; - - distance = (((((self_in_concretizeArithmeticShiftRightCqR->operands))[0]) < 0x1F) ? (((self_in_concretizeArithmeticShiftRightCqR->operands))[0]) : 0x1F); - reg = ((self_in_concretizeArithmeticShiftRightCqR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = sraRRC(self_in_concretizeArithmeticShiftRightCqR, reg, reg, distance); - ((self_in_concretizeArithmeticShiftRightCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeArithmeticShiftRightRR */ -static sqInt NoDbgRegParms -concretizeArithmeticShiftRightRR(AbstractInstruction * self_in_concretizeArithmeticShiftRightRR) -{ - sqInt aWord; - usqInt destReg; - usqInt distReg; - - distReg = ((self_in_concretizeArithmeticShiftRightRR->operands))[0]; - destReg = ((self_in_concretizeArithmeticShiftRightRR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = sravRRR(self_in_concretizeArithmeticShiftRightRR, destReg, destReg, distReg); - ((self_in_concretizeArithmeticShiftRightRR->machineCode))[0 / 4] = aWord; - return 4; -} - - -/* Generate concrete machine code for the instruction at actualAddress, - setting machineCodeSize, and answer the following address. */ -/* Generate concrete machine code for the instruction at actualAddress, - setting machineCodeSize, and answer the following address. */ - - /* CogMIPSELCompiler>>#concretizeAt: */ -static sqInt NoDbgRegParms -concretizeAt(AbstractInstruction * self_in_concretizeAt, sqInt actualAddress) -{ - assert((actualAddress % 4) == 0); - (self_in_concretizeAt->address) = actualAddress; - (self_in_concretizeAt->machineCodeSize) = dispatchConcretize(self_in_concretizeAt); - assert((((self_in_concretizeAt->maxSize)) == null) - || (((self_in_concretizeAt->maxSize)) >= ((self_in_concretizeAt->machineCodeSize)))); - return actualAddress + ((self_in_concretizeAt->machineCodeSize)); -} - - /* CogMIPSELCompiler>>#concretizeBrEqualRR */ -static sqInt NoDbgRegParms -concretizeBrEqualRR(AbstractInstruction * self_in_concretizeBrEqualRR) -{ - sqInt aWord; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrEqualRR->address)) + 4))); - leftReg = ((self_in_concretizeBrEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrEqualRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = beqRRoffset(self_in_concretizeBrEqualRR, leftReg, rightReg, offset); - ((self_in_concretizeBrEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrEqualRR->machineCode))[4 / 4] = 0 /* nop */; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeBrLongEqualRR */ -static sqInt NoDbgRegParms -concretizeBrLongEqualRR(AbstractInstruction * self_in_concretizeBrLongEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - usqInt jumpTargetAddr; - AbstractInstruction *jumpTargetInstruction; - usqInt leftReg; - usqInt rightReg; - - /* begin longJumpTargetAddress */ - jumpTarget = ((AbstractInstruction *) (((self_in_concretizeBrLongEqualRR->operands))[0])); - if ((addressIsInInstructions(jumpTarget)) - || (jumpTarget == (methodLabel()))) { - jumpTarget = ((AbstractInstruction *) ((jumpTarget->address))); - } - assert(jumpTarget != 0); - jumpTargetInstruction = jumpTarget; - flag("todo"); - jumpTargetAddr = (((usqInt)jumpTargetInstruction)) & 0xFFFFFFF; - leftReg = ((self_in_concretizeBrLongEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrLongEqualRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = bneRRoffset(self_in_concretizeBrLongEqualRR, leftReg, rightReg, 12); - ((self_in_concretizeBrLongEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrLongEqualRR->machineCode))[4 / 4] = 0 /* nop */; - /* begin machineCodeAt:put: */ - aWord1 = jA(self_in_concretizeBrLongEqualRR, jumpTargetAddr); - ((self_in_concretizeBrLongEqualRR->machineCode))[8 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrLongEqualRR->machineCode))[12 / 4] = 0 /* nop */; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeBrLongNotEqualRR */ -static sqInt NoDbgRegParms -concretizeBrLongNotEqualRR(AbstractInstruction * self_in_concretizeBrLongNotEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - usqInt jumpTargetAddr; - AbstractInstruction *jumpTargetInstruction; - usqInt leftReg; - usqInt rightReg; - - /* begin longJumpTargetAddress */ - jumpTarget = ((AbstractInstruction *) (((self_in_concretizeBrLongNotEqualRR->operands))[0])); - if ((addressIsInInstructions(jumpTarget)) - || (jumpTarget == (methodLabel()))) { - jumpTarget = ((AbstractInstruction *) ((jumpTarget->address))); - } - assert(jumpTarget != 0); - jumpTargetInstruction = jumpTarget; - flag("todo"); - jumpTargetAddr = (((usqInt)jumpTargetInstruction)) & 0xFFFFFFF; - leftReg = ((self_in_concretizeBrLongNotEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrLongNotEqualRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = beqRRoffset(self_in_concretizeBrLongNotEqualRR, leftReg, rightReg, 12); - ((self_in_concretizeBrLongNotEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrLongNotEqualRR->machineCode))[4 / 4] = 0 /* nop */; - /* begin machineCodeAt:put: */ - aWord1 = jA(self_in_concretizeBrLongNotEqualRR, jumpTargetAddr); - ((self_in_concretizeBrLongNotEqualRR->machineCode))[8 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrLongNotEqualRR->machineCode))[12 / 4] = 0 /* nop */; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeBrNotEqualRR */ -static sqInt NoDbgRegParms -concretizeBrNotEqualRR(AbstractInstruction * self_in_concretizeBrNotEqualRR) -{ - sqInt aWord; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrNotEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrNotEqualRR->address)) + 4))); - leftReg = ((self_in_concretizeBrNotEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrNotEqualRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = bneRRoffset(self_in_concretizeBrNotEqualRR, leftReg, rightReg, offset); - ((self_in_concretizeBrNotEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrNotEqualRR->machineCode))[4 / 4] = 0 /* nop */; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeBrSignedGreaterEqualRR */ -static sqInt NoDbgRegParms -concretizeBrSignedGreaterEqualRR(AbstractInstruction * self_in_concretizeBrSignedGreaterEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrSignedGreaterEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrSignedGreaterEqualRR->address)) + 8))); - leftReg = ((self_in_concretizeBrSignedGreaterEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrSignedGreaterEqualRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltRRR(self_in_concretizeBrSignedGreaterEqualRR, BranchTemp, leftReg, rightReg); - ((self_in_concretizeBrSignedGreaterEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = beqRRoffset(self_in_concretizeBrSignedGreaterEqualRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrSignedGreaterEqualRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrSignedGreaterEqualRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrSignedGreaterRR */ -static sqInt NoDbgRegParms -concretizeBrSignedGreaterRR(AbstractInstruction * self_in_concretizeBrSignedGreaterRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrSignedGreaterRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrSignedGreaterRR->address)) + 8))); - leftReg = ((self_in_concretizeBrSignedGreaterRR->operands))[1]; - rightReg = ((self_in_concretizeBrSignedGreaterRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltRRR(self_in_concretizeBrSignedGreaterRR, BranchTemp, rightReg, leftReg); - ((self_in_concretizeBrSignedGreaterRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = bneRRoffset(self_in_concretizeBrSignedGreaterRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrSignedGreaterRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrSignedGreaterRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrSignedLessEqualRR */ -static sqInt NoDbgRegParms -concretizeBrSignedLessEqualRR(AbstractInstruction * self_in_concretizeBrSignedLessEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrSignedLessEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrSignedLessEqualRR->address)) + 8))); - leftReg = ((self_in_concretizeBrSignedLessEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrSignedLessEqualRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltRRR(self_in_concretizeBrSignedLessEqualRR, BranchTemp, rightReg, leftReg); - ((self_in_concretizeBrSignedLessEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = beqRRoffset(self_in_concretizeBrSignedLessEqualRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrSignedLessEqualRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrSignedLessEqualRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrSignedLessRR */ -static sqInt NoDbgRegParms -concretizeBrSignedLessRR(AbstractInstruction * self_in_concretizeBrSignedLessRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrSignedLessRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrSignedLessRR->address)) + 8))); - leftReg = ((self_in_concretizeBrSignedLessRR->operands))[1]; - rightReg = ((self_in_concretizeBrSignedLessRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltRRR(self_in_concretizeBrSignedLessRR, BranchTemp, leftReg, rightReg); - ((self_in_concretizeBrSignedLessRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = bneRRoffset(self_in_concretizeBrSignedLessRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrSignedLessRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrSignedLessRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrUnsignedGreaterEqualRR */ -static sqInt NoDbgRegParms -concretizeBrUnsignedGreaterEqualRR(AbstractInstruction * self_in_concretizeBrUnsignedGreaterEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrUnsignedGreaterEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrUnsignedGreaterEqualRR->address)) + 8))); - leftReg = ((self_in_concretizeBrUnsignedGreaterEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrUnsignedGreaterEqualRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltuRRR(self_in_concretizeBrUnsignedGreaterEqualRR, BranchTemp, leftReg, rightReg); - ((self_in_concretizeBrUnsignedGreaterEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = beqRRoffset(self_in_concretizeBrUnsignedGreaterEqualRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrUnsignedGreaterEqualRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrUnsignedGreaterEqualRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrUnsignedGreaterRR */ -static sqInt NoDbgRegParms -concretizeBrUnsignedGreaterRR(AbstractInstruction * self_in_concretizeBrUnsignedGreaterRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrUnsignedGreaterRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrUnsignedGreaterRR->address)) + 8))); - leftReg = ((self_in_concretizeBrUnsignedGreaterRR->operands))[1]; - rightReg = ((self_in_concretizeBrUnsignedGreaterRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltuRRR(self_in_concretizeBrUnsignedGreaterRR, BranchTemp, rightReg, leftReg); - ((self_in_concretizeBrUnsignedGreaterRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = bneRRoffset(self_in_concretizeBrUnsignedGreaterRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrUnsignedGreaterRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrUnsignedGreaterRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrUnsignedLessEqualRR */ -static sqInt NoDbgRegParms -concretizeBrUnsignedLessEqualRR(AbstractInstruction * self_in_concretizeBrUnsignedLessEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrUnsignedLessEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrUnsignedLessEqualRR->address)) + 8))); - leftReg = ((self_in_concretizeBrUnsignedLessEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrUnsignedLessEqualRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltuRRR(self_in_concretizeBrUnsignedLessEqualRR, BranchTemp, rightReg, leftReg); - ((self_in_concretizeBrUnsignedLessEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = beqRRoffset(self_in_concretizeBrUnsignedLessEqualRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrUnsignedLessEqualRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrUnsignedLessEqualRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrUnsignedLessRR */ -static sqInt NoDbgRegParms -concretizeBrUnsignedLessRR(AbstractInstruction * self_in_concretizeBrUnsignedLessRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrUnsignedLessRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrUnsignedLessRR->address)) + 8))); - leftReg = ((self_in_concretizeBrUnsignedLessRR->operands))[1]; - rightReg = ((self_in_concretizeBrUnsignedLessRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltuRRR(self_in_concretizeBrUnsignedLessRR, BranchTemp, leftReg, rightReg); - ((self_in_concretizeBrUnsignedLessRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = bneRRoffset(self_in_concretizeBrUnsignedLessRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrUnsignedLessRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrUnsignedLessRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - -/* Call is used only for calls within code-space, See CallFull for general - anywhere in address space calling - */ -/* Relative branches in MIPS have a displacement of +/- 131kB (signed 18 - bits), which is too small to cover - the method zone. */ - - /* CogMIPSELCompiler>>#concretizeCall */ -static sqInt NoDbgRegParms -concretizeCall(AbstractInstruction * self_in_concretizeCall) -{ - return concretizeCallFull(self_in_concretizeCall); -} - - /* CogMIPSELCompiler>>#concretizeCallFull */ -static sqInt NoDbgRegParms -concretizeCallFull(AbstractInstruction * self_in_concretizeCallFull) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - AbstractInstruction *jumpTarget; - usqInt jumpTargetAddr; - AbstractInstruction *jumpTargetInstruction; - - /* begin longJumpTargetAddress */ - jumpTarget = ((AbstractInstruction *) (((self_in_concretizeCallFull->operands))[0])); - if ((addressIsInInstructions(jumpTarget)) - || (jumpTarget == (methodLabel()))) { - jumpTarget = ((AbstractInstruction *) ((jumpTarget->address))); - } - assert(jumpTarget != 0); - jumpTargetInstruction = jumpTarget; - jumpTargetAddr = ((usqInt)jumpTargetInstruction); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeCallFull, TargetReg, high16BitsOf(self_in_concretizeCallFull, jumpTargetAddr)); - ((self_in_concretizeCallFull->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeCallFull, TargetReg, TargetReg, low16BitsOf(self_in_concretizeCallFull, jumpTargetAddr)); - ((self_in_concretizeCallFull->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = jalR(self_in_concretizeCallFull, TargetReg); - ((self_in_concretizeCallFull->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - ((self_in_concretizeCallFull->machineCode))[12 / 4] = 0 /* nop */; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeClzRR */ -static sqInt NoDbgRegParms -concretizeClzRR(AbstractInstruction * self_in_concretizeClzRR) -{ - sqInt aWord; - usqInt destReg; - usqInt maskReg; - usqInt rightReg; - - maskReg = ((self_in_concretizeClzRR->operands))[0]; - destReg = (rightReg = ((self_in_concretizeClzRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = clzRRR(self_in_concretizeClzRR, destReg, maskReg, rightReg); - ((self_in_concretizeClzRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeCmpCqR */ -static sqInt NoDbgRegParms -concretizeCmpCqR(AbstractInstruction * self_in_concretizeCmpCqR) -{ - return concretizeCmpCwR(self_in_concretizeCmpCqR); -} - - /* CogMIPSELCompiler>>#concretizeCmpCwR */ -static sqInt NoDbgRegParms -concretizeCmpCwR(AbstractInstruction * self_in_concretizeCmpCwR) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeCmpRR */ -static sqInt NoDbgRegParms -concretizeCmpRR(AbstractInstruction * self_in_concretizeCmpRR) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeDivRR */ -static sqInt NoDbgRegParms -concretizeDivRR(AbstractInstruction * self_in_concretizeDivRR) -{ - sqInt aWord; - usqInt dividendReg; - usqInt divisorReg; - - dividendReg = ((self_in_concretizeDivRR->operands))[0]; - divisorReg = ((self_in_concretizeDivRR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = divRR(self_in_concretizeDivRR, dividendReg, divisorReg); - ((self_in_concretizeDivRR->machineCode))[0 / 4] = aWord; - return 4; -} - - -/* fill with operand 0 according to the processor's endianness. - You might think this is bogus and we should fill with stop instrurctions - instead, but this is used to leave room for a CMBlock header before the - code for a block; - the gaps get filled in by fillInBlockHeadersAt: after code has been - generated. */ - - /* CogMIPSELCompiler>>#concretizeFill32 */ -static sqInt NoDbgRegParms -concretizeFill32(AbstractInstruction * self_in_concretizeFill32) -{ - sqInt aWord; - - /* begin machineCodeAt:put: */ - aWord = ((self_in_concretizeFill32->operands))[0]; - ((self_in_concretizeFill32->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeJump */ -static sqInt NoDbgRegParms -concretizeJump(AbstractInstruction * self_in_concretizeJump) -{ - sqInt aWord; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - sqInt offset; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeJump->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeJump->address)) + 4))); - flag("BranchRange"); - /* begin machineCodeAt:put: */ - aWord = beqRRoffset(self_in_concretizeJump, ZR, ZR, offset); - ((self_in_concretizeJump->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeJump->machineCode))[4 / 4] = 0 /* nop */; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeJumpFull */ -static sqInt NoDbgRegParms -concretizeJumpFull(AbstractInstruction * self_in_concretizeJumpFull) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - AbstractInstruction *jumpTarget; - usqInt jumpTargetAddr; - AbstractInstruction *jumpTargetInstruction; - - /* begin longJumpTargetAddress */ - jumpTarget = ((AbstractInstruction *) (((self_in_concretizeJumpFull->operands))[0])); - if ((addressIsInInstructions(jumpTarget)) - || (jumpTarget == (methodLabel()))) { - jumpTarget = ((AbstractInstruction *) ((jumpTarget->address))); - } - assert(jumpTarget != 0); - jumpTargetInstruction = jumpTarget; - jumpTargetAddr = ((usqInt)jumpTargetInstruction); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeJumpFull, TargetReg, high16BitsOf(self_in_concretizeJumpFull, jumpTargetAddr)); - ((self_in_concretizeJumpFull->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeJumpFull, TargetReg, TargetReg, low16BitsOf(self_in_concretizeJumpFull, jumpTargetAddr)); - ((self_in_concretizeJumpFull->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = jR(self_in_concretizeJumpFull, TargetReg); - ((self_in_concretizeJumpFull->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - ((self_in_concretizeJumpFull->machineCode))[12 / 4] = 0 /* nop */; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeJumpLong */ -static sqInt NoDbgRegParms -concretizeJumpLong(AbstractInstruction * self_in_concretizeJumpLong) -{ - return concretizeJumpFull(self_in_concretizeJumpLong); -} - - /* CogMIPSELCompiler>>#concretizeJumpLongNonZero */ -static sqInt NoDbgRegParms -concretizeJumpLongNonZero(AbstractInstruction * self_in_concretizeJumpLongNonZero) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpLongZero */ -static sqInt NoDbgRegParms -concretizeJumpLongZero(AbstractInstruction * self_in_concretizeJumpLongZero) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpNonZero */ -static sqInt NoDbgRegParms -concretizeJumpNonZero(AbstractInstruction * self_in_concretizeJumpNonZero) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpNoOverflow */ -static sqInt NoDbgRegParms -concretizeJumpNoOverflow(AbstractInstruction * self_in_concretizeJumpNoOverflow) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpOverflow */ -static sqInt NoDbgRegParms -concretizeJumpOverflow(AbstractInstruction * self_in_concretizeJumpOverflow) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpR */ -static sqInt NoDbgRegParms -concretizeJumpR(AbstractInstruction * self_in_concretizeJumpR) -{ - sqInt aWord; - usqInt reg; - - flag("OABI"); - reg = ((self_in_concretizeJumpR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = jR(self_in_concretizeJumpR, reg); - ((self_in_concretizeJumpR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeJumpR->machineCode))[4 / 4] = 0 /* nop */; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeJumpSignedGreaterEqual */ -static sqInt NoDbgRegParms -concretizeJumpSignedGreaterEqual(AbstractInstruction * self_in_concretizeJumpSignedGreaterEqual) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpSignedGreaterThan */ -static sqInt NoDbgRegParms -concretizeJumpSignedGreaterThan(AbstractInstruction * self_in_concretizeJumpSignedGreaterThan) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpSignedLessEqual */ -static sqInt NoDbgRegParms -concretizeJumpSignedLessEqual(AbstractInstruction * self_in_concretizeJumpSignedLessEqual) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpSignedLessThan */ -static sqInt NoDbgRegParms -concretizeJumpSignedLessThan(AbstractInstruction * self_in_concretizeJumpSignedLessThan) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpUnsignedGreaterEqual */ -static sqInt NoDbgRegParms -concretizeJumpUnsignedGreaterEqual(AbstractInstruction * self_in_concretizeJumpUnsignedGreaterEqual) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpUnsignedGreaterThan */ -static sqInt NoDbgRegParms -concretizeJumpUnsignedGreaterThan(AbstractInstruction * self_in_concretizeJumpUnsignedGreaterThan) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpUnsignedLessEqual */ -static sqInt NoDbgRegParms -concretizeJumpUnsignedLessEqual(AbstractInstruction * self_in_concretizeJumpUnsignedLessEqual) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpUnsignedLessThan */ -static sqInt NoDbgRegParms -concretizeJumpUnsignedLessThan(AbstractInstruction * self_in_concretizeJumpUnsignedLessThan) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpZero */ -static sqInt NoDbgRegParms -concretizeJumpZero(AbstractInstruction * self_in_concretizeJumpZero) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeLoadEffectiveAddressMwrR */ -static sqInt NoDbgRegParms -concretizeLoadEffectiveAddressMwrR(AbstractInstruction * self_in_concretizeLoadEffectiveAddressMwrR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt baseReg; - usqInt destReg; - sqInt offset; - - offset = ((self_in_concretizeLoadEffectiveAddressMwrR->operands))[0]; - baseReg = ((self_in_concretizeLoadEffectiveAddressMwrR->operands))[1]; - destReg = ((self_in_concretizeLoadEffectiveAddressMwrR->operands))[2]; - if (isShortOffset(self_in_concretizeLoadEffectiveAddressMwrR, offset)) { - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizeLoadEffectiveAddressMwrR, destReg, baseReg, offset); - ((self_in_concretizeLoadEffectiveAddressMwrR->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeLoadEffectiveAddressMwrR, AT, high16BitsOf(self_in_concretizeLoadEffectiveAddressMwrR, offset)); - ((self_in_concretizeLoadEffectiveAddressMwrR->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeLoadEffectiveAddressMwrR, AT, AT, low16BitsOf(self_in_concretizeLoadEffectiveAddressMwrR, offset)); - ((self_in_concretizeLoadEffectiveAddressMwrR->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = adduRRR(self_in_concretizeLoadEffectiveAddressMwrR, destReg, baseReg, AT); - ((self_in_concretizeLoadEffectiveAddressMwrR->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeLogicalShiftLeftCqR */ -static sqInt NoDbgRegParms -concretizeLogicalShiftLeftCqR(AbstractInstruction * self_in_concretizeLogicalShiftLeftCqR) -{ - sqInt aWord; - sqInt distance; - usqInt reg; - - distance = (((((self_in_concretizeLogicalShiftLeftCqR->operands))[0]) < 0x1F) ? (((self_in_concretizeLogicalShiftLeftCqR->operands))[0]) : 0x1F); - reg = ((self_in_concretizeLogicalShiftLeftCqR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = sllRRC(self_in_concretizeLogicalShiftLeftCqR, reg, reg, distance); - ((self_in_concretizeLogicalShiftLeftCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeLogicalShiftLeftRR */ -static sqInt NoDbgRegParms -concretizeLogicalShiftLeftRR(AbstractInstruction * self_in_concretizeLogicalShiftLeftRR) -{ - sqInt aWord; - usqInt destReg; - usqInt distReg; - - distReg = ((self_in_concretizeLogicalShiftLeftRR->operands))[0]; - destReg = ((self_in_concretizeLogicalShiftLeftRR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = sllvRRR(self_in_concretizeLogicalShiftLeftRR, destReg, destReg, distReg); - ((self_in_concretizeLogicalShiftLeftRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeLogicalShiftRightCqR */ -static sqInt NoDbgRegParms -concretizeLogicalShiftRightCqR(AbstractInstruction * self_in_concretizeLogicalShiftRightCqR) -{ - sqInt aWord; - sqInt distance; - usqInt reg; - - distance = (((((self_in_concretizeLogicalShiftRightCqR->operands))[0]) < 0x1F) ? (((self_in_concretizeLogicalShiftRightCqR->operands))[0]) : 0x1F); - reg = ((self_in_concretizeLogicalShiftRightCqR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = srlRRC(self_in_concretizeLogicalShiftRightCqR, reg, reg, distance); - ((self_in_concretizeLogicalShiftRightCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeLogicalShiftRightRR */ -static sqInt NoDbgRegParms -concretizeLogicalShiftRightRR(AbstractInstruction * self_in_concretizeLogicalShiftRightRR) -{ - sqInt aWord; - usqInt destReg; - usqInt distReg; - - distReg = ((self_in_concretizeLogicalShiftRightRR->operands))[0]; - destReg = ((self_in_concretizeLogicalShiftRightRR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = srlvRRR(self_in_concretizeLogicalShiftRightRR, destReg, destReg, distReg); - ((self_in_concretizeLogicalShiftRightRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveAbR */ -static sqInt NoDbgRegParms -concretizeMoveAbR(AbstractInstruction * self_in_concretizeMoveAbR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt destReg; - usqInt srcAddr; - - srcAddr = ((self_in_concretizeMoveAbR->operands))[0]; - destReg = ((self_in_concretizeMoveAbR->operands))[1]; - if ((srcAddr != null) - && ((((varBaseAddress()) - (0x8000)) < srcAddr) - && (srcAddr < ((varBaseAddress()) + (0x8000))))) { - /* begin machineCodeAt:put: */ - aWord = lwRbaseoffset(self_in_concretizeMoveAbR, destReg, ConcreteVarBaseReg, srcAddr - (varBaseAddress())); - ((self_in_concretizeMoveAbR->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeMoveAbR, AT, high16BitsOf(self_in_concretizeMoveAbR, srcAddr)); - ((self_in_concretizeMoveAbR->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeMoveAbR, AT, AT, low16BitsOf(self_in_concretizeMoveAbR, srcAddr)); - ((self_in_concretizeMoveAbR->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = lbuRbaseoffset(self_in_concretizeMoveAbR, destReg, AT, 0); - ((self_in_concretizeMoveAbR->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMoveAwR */ -static sqInt NoDbgRegParms -concretizeMoveAwR(AbstractInstruction * self_in_concretizeMoveAwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt destReg; - usqInt srcAddr; - - srcAddr = ((self_in_concretizeMoveAwR->operands))[0]; - destReg = ((self_in_concretizeMoveAwR->operands))[1]; - if ((srcAddr != null) - && ((((varBaseAddress()) - (0x8000)) < srcAddr) - && (srcAddr < ((varBaseAddress()) + (0x8000))))) { - /* begin machineCodeAt:put: */ - aWord = lwRbaseoffset(self_in_concretizeMoveAwR, destReg, ConcreteVarBaseReg, srcAddr - (varBaseAddress())); - ((self_in_concretizeMoveAwR->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeMoveAwR, AT, high16BitsOf(self_in_concretizeMoveAwR, srcAddr)); - ((self_in_concretizeMoveAwR->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeMoveAwR, AT, AT, low16BitsOf(self_in_concretizeMoveAwR, srcAddr)); - ((self_in_concretizeMoveAwR->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = lwRbaseoffset(self_in_concretizeMoveAwR, destReg, AT, 0); - ((self_in_concretizeMoveAwR->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMoveCqR */ -static sqInt NoDbgRegParms -concretizeMoveCqR(AbstractInstruction * self_in_concretizeMoveCqR) -{ - sqInt aWord; - usqInt reg; - sqInt word; - - word = ((self_in_concretizeMoveCqR->operands))[0]; - reg = ((self_in_concretizeMoveCqR->operands))[1]; - if (!(isShortOffset(self_in_concretizeMoveCqR, word))) { - return concretizeMoveCwR(self_in_concretizeMoveCqR); - } - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizeMoveCqR, reg, ZR, word); - ((self_in_concretizeMoveCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveCwR */ -static sqInt NoDbgRegParms -concretizeMoveCwR(AbstractInstruction * self_in_concretizeMoveCwR) -{ - sqInt aWord; - sqInt aWord1; - usqInt reg; - sqInt word; - - word = ((self_in_concretizeMoveCwR->operands))[0]; - reg = ((self_in_concretizeMoveCwR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeMoveCwR, reg, high16BitsOf(self_in_concretizeMoveCwR, word)); - ((self_in_concretizeMoveCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeMoveCwR, reg, reg, low16BitsOf(self_in_concretizeMoveCwR, word)); - ((self_in_concretizeMoveCwR->machineCode))[4 / 4] = aWord1; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeMoveHighR */ -static sqInt NoDbgRegParms -concretizeMoveHighR(AbstractInstruction * self_in_concretizeMoveHighR) -{ - sqInt aWord; - usqInt destReg; - - destReg = ((self_in_concretizeMoveHighR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = mfhiR(self_in_concretizeMoveHighR, destReg); - ((self_in_concretizeMoveHighR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveLowR */ -static sqInt NoDbgRegParms -concretizeMoveLowR(AbstractInstruction * self_in_concretizeMoveLowR) -{ - sqInt aWord; - usqInt destReg; - - destReg = ((self_in_concretizeMoveLowR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = mfloR(self_in_concretizeMoveLowR, destReg); - ((self_in_concretizeMoveLowR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveM16rR */ -static sqInt NoDbgRegParms -concretizeMoveM16rR(AbstractInstruction * self_in_concretizeMoveM16rR) -{ - sqInt aWord; - usqInt destReg; - sqInt offset; - usqInt srcReg; - - offset = ((self_in_concretizeMoveM16rR->operands))[0]; - srcReg = ((self_in_concretizeMoveM16rR->operands))[1]; - destReg = ((self_in_concretizeMoveM16rR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = lhuRbaseoffset(self_in_concretizeMoveM16rR, destReg, srcReg, offset); - ((self_in_concretizeMoveM16rR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveMbrR */ -static sqInt NoDbgRegParms -concretizeMoveMbrR(AbstractInstruction * self_in_concretizeMoveMbrR) -{ - sqInt aWord; - usqInt destReg; - sqInt offset; - usqInt srcReg; - - offset = ((self_in_concretizeMoveMbrR->operands))[0]; - srcReg = ((self_in_concretizeMoveMbrR->operands))[1]; - destReg = ((self_in_concretizeMoveMbrR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = lbuRbaseoffset(self_in_concretizeMoveMbrR, destReg, srcReg, offset); - ((self_in_concretizeMoveMbrR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveMwrR */ -static sqInt NoDbgRegParms -concretizeMoveMwrR(AbstractInstruction * self_in_concretizeMoveMwrR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - sqInt aWord4; - usqInt baseReg; - usqInt destReg; - sqInt offset; - - offset = ((self_in_concretizeMoveMwrR->operands))[0]; - baseReg = ((self_in_concretizeMoveMwrR->operands))[1]; - destReg = ((self_in_concretizeMoveMwrR->operands))[2]; - if (isShortOffset(self_in_concretizeMoveMwrR, offset)) { - /* begin machineCodeAt:put: */ - aWord = lwRbaseoffset(self_in_concretizeMoveMwrR, destReg, baseReg, offset); - ((self_in_concretizeMoveMwrR->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeMoveMwrR, AT, high16BitsOf(self_in_concretizeMoveMwrR, offset)); - ((self_in_concretizeMoveMwrR->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeMoveMwrR, AT, AT, low16BitsOf(self_in_concretizeMoveMwrR, offset)); - ((self_in_concretizeMoveMwrR->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = adduRRR(self_in_concretizeMoveMwrR, AT, baseReg, AT); - ((self_in_concretizeMoveMwrR->machineCode))[8 / 4] = aWord3; - /* begin machineCodeAt:put: */ - aWord4 = lwRbaseoffset(self_in_concretizeMoveMwrR, destReg, AT, 0); - ((self_in_concretizeMoveMwrR->machineCode))[12 / 4] = aWord4; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeMoveRAb */ -static sqInt NoDbgRegParms -concretizeMoveRAb(AbstractInstruction * self_in_concretizeMoveRAb) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt destAddr; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRAb->operands))[0]; - destAddr = ((self_in_concretizeMoveRAb->operands))[1]; - if ((destAddr != null) - && ((((varBaseAddress()) - (0x8000)) < destAddr) - && (destAddr < ((varBaseAddress()) + (0x8000))))) { - /* begin machineCodeAt:put: */ - aWord = swRbaseoffset(self_in_concretizeMoveRAb, srcReg, ConcreteVarBaseReg, destAddr - (varBaseAddress())); - ((self_in_concretizeMoveRAb->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeMoveRAb, AT, high16BitsOf(self_in_concretizeMoveRAb, destAddr)); - ((self_in_concretizeMoveRAb->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeMoveRAb, AT, AT, low16BitsOf(self_in_concretizeMoveRAb, destAddr)); - ((self_in_concretizeMoveRAb->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = sbRbaseoffset(self_in_concretizeMoveRAb, srcReg, AT, 0); - ((self_in_concretizeMoveRAb->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMoveRAw */ -static sqInt NoDbgRegParms -concretizeMoveRAw(AbstractInstruction * self_in_concretizeMoveRAw) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt destAddr; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRAw->operands))[0]; - destAddr = ((self_in_concretizeMoveRAw->operands))[1]; - if ((destAddr != null) - && ((((varBaseAddress()) - (0x8000)) < destAddr) - && (destAddr < ((varBaseAddress()) + (0x8000))))) { - /* begin machineCodeAt:put: */ - aWord = swRbaseoffset(self_in_concretizeMoveRAw, srcReg, ConcreteVarBaseReg, destAddr - (varBaseAddress())); - ((self_in_concretizeMoveRAw->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeMoveRAw, AT, high16BitsOf(self_in_concretizeMoveRAw, destAddr)); - ((self_in_concretizeMoveRAw->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeMoveRAw, AT, AT, low16BitsOf(self_in_concretizeMoveRAw, destAddr)); - ((self_in_concretizeMoveRAw->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = swRbaseoffset(self_in_concretizeMoveRAw, srcReg, AT, 0); - ((self_in_concretizeMoveRAw->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMoveRM16r */ -static sqInt NoDbgRegParms -concretizeMoveRM16r(AbstractInstruction * self_in_concretizeMoveRM16r) -{ - sqInt aWord; - usqInt destReg; - sqInt offset; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRM16r->operands))[0]; - offset = ((self_in_concretizeMoveRM16r->operands))[1]; - destReg = ((self_in_concretizeMoveRM16r->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = shRbaseoffset(self_in_concretizeMoveRM16r, srcReg, destReg, offset); - ((self_in_concretizeMoveRM16r->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveRMbr */ -static sqInt NoDbgRegParms -concretizeMoveRMbr(AbstractInstruction * self_in_concretizeMoveRMbr) -{ - sqInt aWord; - usqInt destReg; - sqInt offset; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRMbr->operands))[0]; - offset = ((self_in_concretizeMoveRMbr->operands))[1]; - destReg = ((self_in_concretizeMoveRMbr->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = sbRbaseoffset(self_in_concretizeMoveRMbr, srcReg, destReg, offset); - ((self_in_concretizeMoveRMbr->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveRMwr */ -static sqInt NoDbgRegParms -concretizeMoveRMwr(AbstractInstruction * self_in_concretizeMoveRMwr) -{ - sqInt aWord; - usqInt baseReg; - sqInt offset; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRMwr->operands))[0]; - offset = ((self_in_concretizeMoveRMwr->operands))[1]; - baseReg = ((self_in_concretizeMoveRMwr->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = swRbaseoffset(self_in_concretizeMoveRMwr, srcReg, baseReg, offset); - ((self_in_concretizeMoveRMwr->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveRR */ -static sqInt NoDbgRegParms -concretizeMoveRR(AbstractInstruction * self_in_concretizeMoveRR) -{ - sqInt aWord; - usqInt destReg; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRR->operands))[0]; - destReg = ((self_in_concretizeMoveRR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeMoveRR, destReg, srcReg, ZR); - ((self_in_concretizeMoveRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveRXbrR */ -static sqInt NoDbgRegParms -concretizeMoveRXbrR(AbstractInstruction * self_in_concretizeMoveRXbrR) -{ - sqInt aWord; - sqInt aWord1; - usqInt baseReg; - usqInt indexReg; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRXbrR->operands))[0]; - indexReg = ((self_in_concretizeMoveRXbrR->operands))[1]; - baseReg = ((self_in_concretizeMoveRXbrR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeMoveRXbrR, AT, baseReg, indexReg); - ((self_in_concretizeMoveRXbrR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = sbRbaseoffset(self_in_concretizeMoveRXbrR, srcReg, AT, 0); - ((self_in_concretizeMoveRXbrR->machineCode))[4 / 4] = aWord1; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeMoveRXwrR */ -static sqInt NoDbgRegParms -concretizeMoveRXwrR(AbstractInstruction * self_in_concretizeMoveRXwrR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt baseReg; - usqInt indexReg; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRXwrR->operands))[0]; - indexReg = ((self_in_concretizeMoveRXwrR->operands))[1]; - baseReg = ((self_in_concretizeMoveRXwrR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = sllRRC(self_in_concretizeMoveRXwrR, AT, indexReg, 2); - ((self_in_concretizeMoveRXwrR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = adduRRR(self_in_concretizeMoveRXwrR, AT, baseReg, AT); - ((self_in_concretizeMoveRXwrR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = swRbaseoffset(self_in_concretizeMoveRXwrR, srcReg, AT, 0); - ((self_in_concretizeMoveRXwrR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMoveXbrRR */ -static sqInt NoDbgRegParms -concretizeMoveXbrRR(AbstractInstruction * self_in_concretizeMoveXbrRR) -{ - sqInt aWord; - sqInt aWord1; - usqInt baseReg; - usqInt destReg; - usqInt indexReg; - - - /* index is number of *bytes* */ - indexReg = ((self_in_concretizeMoveXbrRR->operands))[0]; - baseReg = ((self_in_concretizeMoveXbrRR->operands))[1]; - destReg = ((self_in_concretizeMoveXbrRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeMoveXbrRR, AT, baseReg, indexReg); - ((self_in_concretizeMoveXbrRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = lbuRbaseoffset(self_in_concretizeMoveXbrRR, destReg, AT, 0); - ((self_in_concretizeMoveXbrRR->machineCode))[4 / 4] = aWord1; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeMoveXwrRR */ -static sqInt NoDbgRegParms -concretizeMoveXwrRR(AbstractInstruction * self_in_concretizeMoveXwrRR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt baseReg; - usqInt destReg; - usqInt indexReg; - - indexReg = ((self_in_concretizeMoveXwrRR->operands))[0]; - baseReg = ((self_in_concretizeMoveXwrRR->operands))[1]; - destReg = ((self_in_concretizeMoveXwrRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = sllRRC(self_in_concretizeMoveXwrRR, AT, indexReg, 2); - ((self_in_concretizeMoveXwrRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = adduRRR(self_in_concretizeMoveXwrRR, AT, baseReg, AT); - ((self_in_concretizeMoveXwrRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = lwRbaseoffset(self_in_concretizeMoveXwrRR, destReg, AT, 0); - ((self_in_concretizeMoveXwrRR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMulCheckOverflowRR */ -static sqInt NoDbgRegParms -concretizeMulCheckOverflowRR(AbstractInstruction * self_in_concretizeMulCheckOverflowRR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeMulCheckOverflowRR->operands))[0]; - - /* Overflow occured if the sign bit of the low part is different from the high part. */ - destReg = (leftReg = ((self_in_concretizeMulCheckOverflowRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = multRR(self_in_concretizeMulCheckOverflowRR, leftReg, rightReg); - ((self_in_concretizeMulCheckOverflowRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = mfloR(self_in_concretizeMulCheckOverflowRR, destReg); - ((self_in_concretizeMulCheckOverflowRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = sraRRC(self_in_concretizeMulCheckOverflowRR, OverflowTemp1, destReg, 0x1F); - ((self_in_concretizeMulCheckOverflowRR->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = mfhiR(self_in_concretizeMulCheckOverflowRR, OverflowTemp2); - ((self_in_concretizeMulCheckOverflowRR->machineCode))[12 / 4] = aWord3; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeNegateR */ -static sqInt NoDbgRegParms -concretizeNegateR(AbstractInstruction * self_in_concretizeNegateR) -{ - sqInt aWord; - usqInt reg; - - reg = ((self_in_concretizeNegateR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = subuRRR(self_in_concretizeNegateR, reg, ZR, reg); - ((self_in_concretizeNegateR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeNop */ -static sqInt NoDbgRegParms -concretizeNop(AbstractInstruction * self_in_concretizeNop) -{ - /* begin machineCodeAt:put: */ - ((self_in_concretizeNop->machineCode))[0 / 4] = 0 /* nop */; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeOrCqR */ -static sqInt NoDbgRegParms -concretizeOrCqR(AbstractInstruction * self_in_concretizeOrCqR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeOrCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeOrCqR->operands))[1]); - if (!(((rightImm >= 0) && (rightImm <= 0xFFFF)))) { - return concretizeOrCwR(self_in_concretizeOrCqR); - } - /* begin machineCodeAt:put: */ - aWord = oriRRC(self_in_concretizeOrCqR, destReg, leftReg, rightImm); - ((self_in_concretizeOrCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeOrCqRR */ -static sqInt NoDbgRegParms -concretizeOrCqRR(AbstractInstruction * self_in_concretizeOrCqRR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt dstReg; - usqInt srcReg; - usqInt value; - - value = ((self_in_concretizeOrCqRR->operands))[0]; - srcReg = ((self_in_concretizeOrCqRR->operands))[1]; - dstReg = ((self_in_concretizeOrCqRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeOrCqRR, AT, high16BitsOf(self_in_concretizeOrCqRR, value)); - ((self_in_concretizeOrCqRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeOrCqRR, AT, AT, low16BitsOf(self_in_concretizeOrCqRR, value)); - ((self_in_concretizeOrCqRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = orRRR(self_in_concretizeOrCqRR, dstReg, srcReg, AT); - ((self_in_concretizeOrCqRR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeOrCwR */ -static sqInt NoDbgRegParms -concretizeOrCwR(AbstractInstruction * self_in_concretizeOrCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeOrCwR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeOrCwR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeOrCwR, AT, high16BitsOf(self_in_concretizeOrCwR, rightImm)); - ((self_in_concretizeOrCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeOrCwR, AT, AT, low16BitsOf(self_in_concretizeOrCwR, rightImm)); - ((self_in_concretizeOrCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = orRRR(self_in_concretizeOrCwR, destReg, leftReg, AT); - ((self_in_concretizeOrCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeOrRR */ -static sqInt NoDbgRegParms -concretizeOrRR(AbstractInstruction * self_in_concretizeOrRR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeOrRR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeOrRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = orRRR(self_in_concretizeOrRR, destReg, leftReg, rightReg); - ((self_in_concretizeOrRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizePopR */ -static sqInt NoDbgRegParms -concretizePopR(AbstractInstruction * self_in_concretizePopR) -{ - sqInt aWord; - sqInt aWord1; - usqInt destReg; - - destReg = ((self_in_concretizePopR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = lwRbaseoffset(self_in_concretizePopR, destReg, SP, 0); - ((self_in_concretizePopR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = addiuRRC(self_in_concretizePopR, SP, SP, 4); - ((self_in_concretizePopR->machineCode))[4 / 4] = aWord1; - return 8; -} - - /* CogMIPSELCompiler>>#concretizePrefetchAw */ -static sqInt NoDbgRegParms -concretizePrefetchAw(AbstractInstruction * self_in_concretizePrefetchAw) -{ - usqInt addressOperand; - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - - addressOperand = ((self_in_concretizePrefetchAw->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizePrefetchAw, AT, high16BitsOf(self_in_concretizePrefetchAw, addressOperand)); - ((self_in_concretizePrefetchAw->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizePrefetchAw, AT, AT, low16BitsOf(self_in_concretizePrefetchAw, addressOperand)); - ((self_in_concretizePrefetchAw->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = prefRoffsethint(self_in_concretizePrefetchAw, AT, 0, HintLoad); - ((self_in_concretizePrefetchAw->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizePushCq */ -static sqInt NoDbgRegParms -concretizePushCq(AbstractInstruction * self_in_concretizePushCq) -{ - return concretizePushCw(self_in_concretizePushCq); -} - - /* CogMIPSELCompiler>>#concretizePushCw */ -static sqInt NoDbgRegParms -concretizePushCw(AbstractInstruction * self_in_concretizePushCw) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt value; - - value = ((self_in_concretizePushCw->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizePushCw, AT, high16BitsOf(self_in_concretizePushCw, value)); - ((self_in_concretizePushCw->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizePushCw, AT, AT, low16BitsOf(self_in_concretizePushCw, value)); - ((self_in_concretizePushCw->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = addiuRRC(self_in_concretizePushCw, SP, SP, -4); - ((self_in_concretizePushCw->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = swRbaseoffset(self_in_concretizePushCw, AT, SP, 0); - ((self_in_concretizePushCw->machineCode))[12 / 4] = aWord3; - return 16; -} - - /* CogMIPSELCompiler>>#concretizePushR */ -static sqInt NoDbgRegParms -concretizePushR(AbstractInstruction * self_in_concretizePushR) -{ - sqInt aWord; - sqInt aWord1; - usqInt srcReg; - - srcReg = ((self_in_concretizePushR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizePushR, SP, SP, -4); - ((self_in_concretizePushR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = swRbaseoffset(self_in_concretizePushR, srcReg, SP, 0); - ((self_in_concretizePushR->machineCode))[4 / 4] = aWord1; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeRetN */ -static sqInt NoDbgRegParms -concretizeRetN(AbstractInstruction * self_in_concretizeRetN) -{ - sqInt aWord; - sqInt aWord1; - sqInt offset; - - offset = ((self_in_concretizeRetN->operands))[0]; - /* begin machineCodeAt:put: */ - aWord1 = jR(self_in_concretizeRetN, RA); - ((self_in_concretizeRetN->machineCode))[0 / 4] = aWord1; - if (offset == 0) { - /* begin machineCodeAt:put: */ - ((self_in_concretizeRetN->machineCode))[4 / 4] = 0 /* nop */; - } - else { - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizeRetN, SP, SP, offset); - ((self_in_concretizeRetN->machineCode))[4 / 4] = aWord; - } - return 8; -} - - /* CogMIPSELCompiler>>#concretizeStop */ -static sqInt NoDbgRegParms -concretizeStop(AbstractInstruction * self_in_concretizeStop) -{ - sqInt aWord; - - /* begin machineCodeAt:put: */ - aWord = stop(self_in_concretizeStop); - ((self_in_concretizeStop->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeSubCheckOverflowCqR */ -static sqInt NoDbgRegParms -concretizeSubCheckOverflowCqR(AbstractInstruction * self_in_concretizeSubCheckOverflowCqR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - sqInt aWord4; - sqInt aWord5; - sqInt aWord6; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeSubCheckOverflowCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeSubCheckOverflowCqR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeSubCheckOverflowCqR, AT, high16BitsOf(self_in_concretizeSubCheckOverflowCqR, rightImm)); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeSubCheckOverflowCqR, AT, AT, low16BitsOf(self_in_concretizeSubCheckOverflowCqR, rightImm)); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = adduRRR(self_in_concretizeSubCheckOverflowCqR, OverflowTemp1, leftReg, ZR); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = subuRRR(self_in_concretizeSubCheckOverflowCqR, destReg, leftReg, AT); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[12 / 4] = aWord3; - /* begin machineCodeAt:put: */ - aWord4 = xorRRR(self_in_concretizeSubCheckOverflowCqR, OverflowTemp2, destReg, AT); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[16 / 4] = aWord4; - /* begin machineCodeAt:put: */ - aWord5 = xorRRR(self_in_concretizeSubCheckOverflowCqR, OverflowTemp1, destReg, OverflowTemp1); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[20 / 4] = aWord5; - /* begin machineCodeAt:put: */ - aWord6 = andRRR(self_in_concretizeSubCheckOverflowCqR, Overflow, OverflowTemp1, OverflowTemp2); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[24 / 4] = aWord6; - return 28; -} - - /* CogMIPSELCompiler>>#concretizeSubCheckOverflowRR */ -static sqInt NoDbgRegParms -concretizeSubCheckOverflowRR(AbstractInstruction * self_in_concretizeSubCheckOverflowRR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - sqInt aWord4; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeSubCheckOverflowRR->operands))[0]; - - /* Save original LHS */ - destReg = (leftReg = ((self_in_concretizeSubCheckOverflowRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeSubCheckOverflowRR, OverflowTemp1, leftReg, ZR); - ((self_in_concretizeSubCheckOverflowRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = subuRRR(self_in_concretizeSubCheckOverflowRR, destReg, leftReg, rightReg); - ((self_in_concretizeSubCheckOverflowRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = xorRRR(self_in_concretizeSubCheckOverflowRR, OverflowTemp2, destReg, rightReg); - ((self_in_concretizeSubCheckOverflowRR->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = xorRRR(self_in_concretizeSubCheckOverflowRR, OverflowTemp1, destReg, OverflowTemp1); - ((self_in_concretizeSubCheckOverflowRR->machineCode))[12 / 4] = aWord3; - /* begin machineCodeAt:put: */ - aWord4 = andRRR(self_in_concretizeSubCheckOverflowRR, Overflow, OverflowTemp1, OverflowTemp2); - ((self_in_concretizeSubCheckOverflowRR->machineCode))[16 / 4] = aWord4; - return 20; -} - - /* CogMIPSELCompiler>>#concretizeSubCqR */ -static sqInt NoDbgRegParms -concretizeSubCqR(AbstractInstruction * self_in_concretizeSubCqR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeSubCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeSubCqR->operands))[1]); - if (!(isShortOffset(self_in_concretizeSubCqR, -rightImm))) { - return concretizeSubCwR(self_in_concretizeSubCqR); - } - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizeSubCqR, destReg, leftReg, -rightImm); - ((self_in_concretizeSubCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeSubCwR */ -static sqInt NoDbgRegParms -concretizeSubCwR(AbstractInstruction * self_in_concretizeSubCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeSubCwR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeSubCwR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeSubCwR, AT, high16BitsOf(self_in_concretizeSubCwR, rightImm)); - ((self_in_concretizeSubCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeSubCwR, AT, AT, low16BitsOf(self_in_concretizeSubCwR, rightImm)); - ((self_in_concretizeSubCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = subuRRR(self_in_concretizeSubCwR, destReg, leftReg, AT); - ((self_in_concretizeSubCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeSubRRDest: */ -static sqInt NoDbgRegParms -concretizeSubRRDest(AbstractInstruction * self_in_concretizeSubRRDest, sqInt destReg) -{ - sqInt aWord; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeSubRRDest->operands))[0]; - leftReg = ((self_in_concretizeSubRRDest->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = subuRRR(self_in_concretizeSubRRDest, destReg, leftReg, rightReg); - ((self_in_concretizeSubRRDest->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeTstCqR */ -static sqInt NoDbgRegParms -concretizeTstCqR(AbstractInstruction * self_in_concretizeTstCqR) -{ - sqInt aWord; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeTstCqR->operands))[0]; - leftReg = ((self_in_concretizeTstCqR->operands))[1]; - if (!(isShortOffset(self_in_concretizeTstCqR, rightImm))) { - return concretizeTstCwR(self_in_concretizeTstCqR); - } - /* begin machineCodeAt:put: */ - aWord = andiRRC(self_in_concretizeTstCqR, Cmp, leftReg, rightImm); - ((self_in_concretizeTstCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeTstCwR */ -static sqInt NoDbgRegParms -concretizeTstCwR(AbstractInstruction * self_in_concretizeTstCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeTstCwR->operands))[0]; - leftReg = ((self_in_concretizeTstCwR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeTstCwR, AT, high16BitsOf(self_in_concretizeTstCwR, rightImm)); - ((self_in_concretizeTstCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeTstCwR, AT, AT, low16BitsOf(self_in_concretizeTstCwR, rightImm)); - ((self_in_concretizeTstCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = andRRR(self_in_concretizeTstCwR, Cmp, leftReg, AT); - ((self_in_concretizeTstCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeUnimplemented */ -static sqInt NoDbgRegParms -concretizeUnimplemented(AbstractInstruction * self_in_concretizeUnimplemented) -{ - error("Unimplemented RTL instruction"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeXorCwR */ -static sqInt NoDbgRegParms -concretizeXorCwR(AbstractInstruction * self_in_concretizeXorCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeXorCwR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeXorCwR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeXorCwR, AT, high16BitsOf(self_in_concretizeXorCwR, rightImm)); - ((self_in_concretizeXorCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeXorCwR, AT, AT, low16BitsOf(self_in_concretizeXorCwR, rightImm)); - ((self_in_concretizeXorCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = xorRRR(self_in_concretizeXorCwR, destReg, leftReg, AT); - ((self_in_concretizeXorCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeXorRR */ -static sqInt NoDbgRegParms -concretizeXorRR(AbstractInstruction * self_in_concretizeXorRR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeXorRR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeXorRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = xorRRR(self_in_concretizeXorRR, destReg, leftReg, rightReg); - ((self_in_concretizeXorRR->machineCode))[0 / 4] = aWord; - return 4; -} - - -/* Attempt to generate concrete machine code for the instruction at address. - This is the inner dispatch of concretizeAt: actualAddress which exists - only to get around the branch size limits in the SqueakV3 (blue book - derived) bytecode set. */ - - /* CogMIPSELCompiler>>#dispatchConcretize */ -static sqInt NoDbgRegParms -dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) -{ - AbstractInstruction *dependentChain; - - switch ((self_in_dispatchConcretize->opcode)) { - case BrEqualRR: - return concretizeBrEqualRR(self_in_dispatchConcretize); - - case BrNotEqualRR: - return concretizeBrNotEqualRR(self_in_dispatchConcretize); - - case BrUnsignedLessRR: - return concretizeBrUnsignedLessRR(self_in_dispatchConcretize); - - case BrUnsignedLessEqualRR: - return concretizeBrUnsignedLessEqualRR(self_in_dispatchConcretize); - - case BrUnsignedGreaterRR: - return concretizeBrUnsignedGreaterRR(self_in_dispatchConcretize); - - case BrUnsignedGreaterEqualRR: - return concretizeBrUnsignedGreaterEqualRR(self_in_dispatchConcretize); - - case BrSignedLessRR: - return concretizeBrSignedLessRR(self_in_dispatchConcretize); - - case BrSignedLessEqualRR: - return concretizeBrSignedLessEqualRR(self_in_dispatchConcretize); - - case BrSignedGreaterRR: - return concretizeBrSignedGreaterRR(self_in_dispatchConcretize); - - case BrSignedGreaterEqualRR: - return concretizeBrSignedGreaterEqualRR(self_in_dispatchConcretize); - - case BrLongEqualRR: - return concretizeBrLongEqualRR(self_in_dispatchConcretize); - - case BrLongNotEqualRR: - return concretizeBrLongNotEqualRR(self_in_dispatchConcretize); - - case MulRR: - case JumpNegative: - case JumpNonNegative: - case JumpCarry: - case JumpNoCarry: - case JumpFPEqual: - case JumpFPNotEqual: - case JumpFPLess: - case JumpFPGreaterOrEqual: - case JumpFPGreater: - case JumpFPLessOrEqual: - case JumpFPOrdered: - case JumpFPUnordered: - case XorCqR: - case AddRdRd: - case CmpRdRd: - case DivRdRd: - case MulRdRd: - case SubRdRd: - case SqrtRd: - case MoveRMbr: - case MoveM64rRd: - case MoveRdM64r: - case ConvertRRd: - return concretizeUnimplemented(self_in_dispatchConcretize); - - case DivRR: - return concretizeDivRR(self_in_dispatchConcretize); - - case MoveLowR: - return concretizeMoveLowR(self_in_dispatchConcretize); - - case MoveHighR: - return concretizeMoveHighR(self_in_dispatchConcretize); - - case Label: - /* begin concretizeLabel */ - dependentChain = (self_in_dispatchConcretize->dependent); - while (!(dependentChain == null)) { - /* begin updateLabel: */ - assert((((dependentChain->opcode)) == MoveCwR) - || (((dependentChain->opcode)) == PushCw)); - ((dependentChain->operands))[0] = (((self_in_dispatchConcretize->address)) + (((self_in_dispatchConcretize->operands))[1])); - dependentChain = (dependentChain->dependent); - } - return 0; - - case AlignmentNops: - return concretizeAlignmentNops(self_in_dispatchConcretize); - - case Fill32: - return concretizeFill32(self_in_dispatchConcretize); - - case Nop: - return concretizeNop(self_in_dispatchConcretize); - - case Call: - return concretizeCall(self_in_dispatchConcretize); - - case CallFull: - return concretizeCallFull(self_in_dispatchConcretize); - - case JumpR: - return concretizeJumpR(self_in_dispatchConcretize); - - case JumpFull: - return concretizeJumpFull(self_in_dispatchConcretize); - - case JumpLong: - return concretizeJumpLong(self_in_dispatchConcretize); - - case JumpLongZero: - return concretizeJumpLongZero(self_in_dispatchConcretize); - - case JumpLongNonZero: - return concretizeJumpLongNonZero(self_in_dispatchConcretize); - - case Jump: - return concretizeJump(self_in_dispatchConcretize); - - case JumpZero: - return concretizeJumpZero(self_in_dispatchConcretize); - - case JumpNonZero: - return concretizeJumpNonZero(self_in_dispatchConcretize); - - case JumpOverflow: - return concretizeJumpOverflow(self_in_dispatchConcretize); - - case JumpNoOverflow: - return concretizeJumpNoOverflow(self_in_dispatchConcretize); - - case JumpLess: - return concretizeJumpSignedLessThan(self_in_dispatchConcretize); - - case JumpGreaterOrEqual: - return concretizeJumpSignedGreaterEqual(self_in_dispatchConcretize); - - case JumpGreater: - return concretizeJumpSignedGreaterThan(self_in_dispatchConcretize); - - case JumpLessOrEqual: - return concretizeJumpSignedLessEqual(self_in_dispatchConcretize); - - case JumpBelow: - return concretizeJumpUnsignedLessThan(self_in_dispatchConcretize); - - case JumpAboveOrEqual: - return concretizeJumpUnsignedGreaterEqual(self_in_dispatchConcretize); - - case JumpAbove: - return concretizeJumpUnsignedGreaterThan(self_in_dispatchConcretize); - - case JumpBelowOrEqual: - return concretizeJumpUnsignedLessEqual(self_in_dispatchConcretize); - - case RetN: - return concretizeRetN(self_in_dispatchConcretize); - - case Stop: - return concretizeStop(self_in_dispatchConcretize); - - case AddCqR: - return concretizeAddCqR(self_in_dispatchConcretize); - - case AndCqR: - return concretizeAndCqRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]); - - case AndCqRR: - return concretizeAndCqRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[2]); - - case OrCqRR: - return concretizeOrCqRR(self_in_dispatchConcretize); - - case CmpCqR: - return concretizeCmpCqR(self_in_dispatchConcretize); - - case OrCqR: - return concretizeOrCqR(self_in_dispatchConcretize); - - case SubCqR: - return concretizeSubCqR(self_in_dispatchConcretize); - - case TstCqR: - return concretizeTstCqR(self_in_dispatchConcretize); - - case AddCwR: - return concretizeAddCwR(self_in_dispatchConcretize); - - case AndCwR: - return concretizeAndCwR(self_in_dispatchConcretize); - - case CmpCwR: - return concretizeCmpCwR(self_in_dispatchConcretize); - - case OrCwR: - return concretizeOrCwR(self_in_dispatchConcretize); - - case SubCwR: - return concretizeSubCwR(self_in_dispatchConcretize); - - case XorCwR: - return concretizeXorCwR(self_in_dispatchConcretize); - - case AddRR: - return concretizeAddRRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]); - - case AndRR: - return concretizeAndRR(self_in_dispatchConcretize); - - case CmpRR: - return concretizeCmpRR(self_in_dispatchConcretize); - - case OrRR: - return concretizeOrRR(self_in_dispatchConcretize); - - case SubRR: - return concretizeSubRRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]); - - case XorRR: - return concretizeXorRR(self_in_dispatchConcretize); - - case AddRRR: - return concretizeAddRRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[2]); - - case SubRRR: - return concretizeSubRRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[2]); - - case NegateR: - return concretizeNegateR(self_in_dispatchConcretize); - - case LoadEffectiveAddressMwrR: - return concretizeLoadEffectiveAddressMwrR(self_in_dispatchConcretize); - - case ArithmeticShiftRightCqR: - return concretizeArithmeticShiftRightCqR(self_in_dispatchConcretize); - - case LogicalShiftRightCqR: - return concretizeLogicalShiftRightCqR(self_in_dispatchConcretize); - - case LogicalShiftLeftCqR: - return concretizeLogicalShiftLeftCqR(self_in_dispatchConcretize); - - case ArithmeticShiftRightRR: - return concretizeArithmeticShiftRightRR(self_in_dispatchConcretize); - - case LogicalShiftLeftRR: - return concretizeLogicalShiftLeftRR(self_in_dispatchConcretize); - - case LogicalShiftRightRR: - return concretizeLogicalShiftRightRR(self_in_dispatchConcretize); - - case ClzRR: - return concretizeClzRR(self_in_dispatchConcretize); - - case MoveCqR: - return concretizeMoveCqR(self_in_dispatchConcretize); - - case MoveCwR: - return concretizeMoveCwR(self_in_dispatchConcretize); - - case MoveRR: - return concretizeMoveRR(self_in_dispatchConcretize); - - case MoveAwR: - return concretizeMoveAwR(self_in_dispatchConcretize); - - case MoveRAw: - return concretizeMoveRAw(self_in_dispatchConcretize); - - case MoveAbR: - return concretizeMoveAbR(self_in_dispatchConcretize); - - case MoveRAb: - return concretizeMoveRAb(self_in_dispatchConcretize); - - case MoveMbrR: - return concretizeMoveMbrR(self_in_dispatchConcretize); - - case MoveM16rR: - return concretizeMoveM16rR(self_in_dispatchConcretize); - - case MoveRM16r: - return concretizeMoveRM16r(self_in_dispatchConcretize); - - case MoveMwrR: - return concretizeMoveMwrR(self_in_dispatchConcretize); - - case MoveXbrRR: - return concretizeMoveXbrRR(self_in_dispatchConcretize); - - case MoveRXbrR: - return concretizeMoveRXbrR(self_in_dispatchConcretize); - - case MoveXwrRR: - return concretizeMoveXwrRR(self_in_dispatchConcretize); - - case MoveRXwrR: - return concretizeMoveRXwrR(self_in_dispatchConcretize); - - case MoveRMwr: - return concretizeMoveRMwr(self_in_dispatchConcretize); - - case PopR: - return concretizePopR(self_in_dispatchConcretize); - - case PushR: - return concretizePushR(self_in_dispatchConcretize); - - case PushCq: - return concretizePushCq(self_in_dispatchConcretize); - - case PushCw: - return concretizePushCw(self_in_dispatchConcretize); - - case PrefetchAw: - return concretizePrefetchAw(self_in_dispatchConcretize); - - case AddCheckOverflowCqR: - return concretizeAddCheckOverflowCqR(self_in_dispatchConcretize); - - case AddCheckOverflowRR: - return concretizeAddCheckOverflowRR(self_in_dispatchConcretize); - - case SubCheckOverflowCqR: - return concretizeSubCheckOverflowCqR(self_in_dispatchConcretize); - - case SubCheckOverflowRR: - return concretizeSubCheckOverflowRR(self_in_dispatchConcretize); - - case MulCheckOverflowRR: - return concretizeMulCheckOverflowRR(self_in_dispatchConcretize); - - default: - error("Case not found and no otherwise clause"); - } - return 0; -} - - /* CogMIPSELCompiler>>#divR:R: */ -static sqInt NoDbgRegParms -divRR(AbstractInstruction * self_in_divRR, sqInt dividendReg, sqInt divisorReg) -{ - flag("todo"); - return rtypersrtrdsafunct(self_in_divRR, SPECIAL, dividendReg, divisorReg, 0, 0, DIV); -} - - -/* Answer if CallFull and/or JumpFull are relative and hence need relocating - on method - compation. If so, they are annotated with IsRelativeCall in methods and - relocated in - relocateIfCallOrMethodReference:mcpc:delta: */ - - /* CogMIPSELCompiler>>#fullCallsAreRelative */ -static sqInt NoDbgRegParms -fullCallsAreRelative(AbstractInstruction * self_in_fullCallsAreRelative) -{ - return 0; -} - - /* CogMIPSELCompiler>>#functionAtAddress: */ -static sqInt NoDbgRegParms -functionAtAddress(AbstractInstruction * self_in_functionAtAddress, sqInt mcpc) -{ - return (longAt(mcpc)) & 0x3F; -} - - /* CogMIPSELCompiler>>#genDivR:R:Quo:Rem: */ -static sqInt NoDbgRegParms -genDivRRQuoRem(AbstractInstruction * self_in_genDivRRQuoRem, sqInt abstractRegDivisor, sqInt abstractRegDividend, sqInt abstractRegQuotient, sqInt abstractRegRemainder) -{ - genoperandoperand(DivRR, abstractRegDividend, abstractRegDivisor); - genoperand(MoveLowR, abstractRegQuotient); - genoperand(MoveHighR, abstractRegRemainder); - return 0; -} - - /* CogMIPSELCompiler>>#genMulR:R: */ -static AbstractInstruction * NoDbgRegParms -genMulRR(AbstractInstruction * self_in_genMulRR, sqInt regSource, sqInt regDest) -{ - return genoperandoperand(MulRR, regSource, regDest); -} - - -/* Ensure that the register args are pushed before the outer and - inner retpcs at an entry miss for arity <= self numRegArgs. The - outer retpc is that of a call at a send site. The inner is the call - from a method or PIC abort/miss to the trampoline. */ -/* Putting the receiver and args above the return address means the - CoInterpreter has a single machine-code frame format which saves - us a lot of work. */ -/* Iff there are register args convert - sp -> outerRetpc (send site retpc) - linkReg = innerRetpc (PIC abort/miss retpc) - to - base -> receiver - (arg0) - (arg1) - sp -> outerRetpc (send site retpc) - sp -> linkReg/innerRetpc (PIC abort/miss retpc) */ - - /* CogMIPSELCompiler>>#genPushRegisterArgsForAbortMissNumArgs: */ -static void NoDbgRegParms -genPushRegisterArgsForAbortMissNumArgs(AbstractInstruction * self_in_genPushRegisterArgsForAbortMissNumArgs, sqInt numArgs) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - flag("inefficient"); - if (numArgs <= 2 /* numRegArgs */) { - assert((numRegArgs()) <= 2); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, SPReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveRMwr, ReceiverResultReg, 0, SPReg); - if (numArgs > 0) { - /* begin PushR: */ - genoperand(PushR, Arg0Reg); - if (numArgs > 1) { - /* begin PushR: */ - genoperand(PushR, Arg1Reg); - } - } - /* begin PushR: */ - genoperand(PushR, TempReg); - } - /* begin PushR: */ - genoperand(PushR, LinkReg); -} - - -/* Ensure that the register args are pushed before the retpc for arity <= - self numRegArgs. - */ -/* This is easy on a RISC like ARM because the return address is in the link - register. Putting - the receiver and args above the return address means the CoInterpreter has - a single - machine-code frame format which saves us a lot of work - NOTA BENE: we do NOT push the return address here, which means it must be - dealt with later. */ - - /* CogMIPSELCompiler>>#genPushRegisterArgsForNumArgs:scratchReg: */ -static void NoDbgRegParms -genPushRegisterArgsForNumArgsscratchReg(AbstractInstruction * self_in_genPushRegisterArgsForNumArgsscratchReg, sqInt numArgs, sqInt ignored) -{ - flag("inefficient"); - if (numArgs <= 2 /* numRegArgs */) { - assert((numRegArgs()) <= 2); - /* begin PushR: */ - genoperand(PushR, ReceiverResultReg); - if (numArgs > 0) { - /* begin PushR: */ - genoperand(PushR, Arg0Reg); - if (numArgs > 1) { - /* begin PushR: */ - genoperand(PushR, Arg1Reg); - } - } - } -} - - -/* This is a no-op on MIPS since the ABI passes up to 4 args in registers and - trampolines currently observe that limit. - */ - - /* CogMIPSELCompiler>>#genRemoveNArgsFromStack: */ -static sqInt NoDbgRegParms -genRemoveNArgsFromStack(AbstractInstruction * self_in_genRemoveNArgsFromStack, sqInt n) -{ - assert(n <= 4); - return 0; -} - - -/* Restore the registers in regMask as saved by genSaveRegs:. - We don't need to do anything because all of the abstract registers are - allocated to C preserved registers. But for the future... */ - - /* CogMIPSELCompiler>>#genRestoreRegs: */ -static sqInt NoDbgRegParms -genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask) -{ - sqInt reg; - - assert(regMask == 0); - assert(!((((regMask & (registerMaskForandand(SP, FP, RA))) != 0)))); - for (reg = R0; reg <= R28; reg += 1) { - if (((regMask & (1U << reg)) != 0)) { - /* begin PopR: */ - genoperand(PopR, reg); - } - } - return 0; -} - - -/* Save the registers in regMask for a call into the C run-time from a - trampoline. We don't need to do anything because all of the abstract - registers are - allocated to C preserved registers. But for the future... */ - - /* CogMIPSELCompiler>>#genSaveRegs: */ -static sqInt NoDbgRegParms -genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask) -{ - sqInt reg; - - assert(regMask == 0); - assert(!((((regMask & (registerMaskForandand(SP, FP, RA))) != 0)))); - for (reg = R28; reg >= R0; reg += -1) { - if (((regMask & (1U << reg)) != 0)) { - /* begin PushR: */ - genoperand(PushR, reg); - } - } - return 0; -} - - /* CogMIPSELCompiler>>#genSubstituteReturnAddress: */ -static AbstractInstruction * NoDbgRegParms -genSubstituteReturnAddress(AbstractInstruction * self_in_genSubstituteReturnAddress, sqInt retpc) -{ - AbstractInstruction *anInstruction; - - /* begin checkLiteral:forInstruction: */ - anInstruction = genoperandoperand(MoveCwR, retpc, RA); - return anInstruction; -} - - -/* Answer if the processor has a dedicated callee-saved register to point to - the base of commonly-accessed variables. */ - - /* CogMIPSELCompiler>>#hasVarBaseRegister */ -static sqInt NoDbgRegParms -hasVarBaseRegister(AbstractInstruction * self_in_hasVarBaseRegister) -{ - return 1; -} - - /* CogMIPSELCompiler>>#high16BitsOf: */ -static usqInt NoDbgRegParms -high16BitsOf(AbstractInstruction * self_in_high16BitsOf, usqInt word) -{ - return (word) >> 16; -} - - -/* Answer the inline cache tag for the return address of a send. */ -/* MoveCwR ClassReg selectorIndex/expectedClass - Call: unlinked send stub/expectedTarget - Push ReceiverResult <-- callSiteReturnAddress */ -/* lui s3, selector/tagHigh - ori s3, s3, selector/tagLow - lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jalr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#inlineCacheTagAt: */ -static usqInt NoDbgRegParms -inlineCacheTagAt(AbstractInstruction * self_in_inlineCacheTagAt, usqInt callSiteReturnAddress) -{ - assert((opcodeAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 24)) == LUI); - assert((opcodeAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 20)) == ORI); - assert((opcodeAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_inlineCacheTagAt))); - return literalAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 20); -} - - -/* Answer the instruction size at pc. */ - - /* CogMIPSELCompiler>>#instructionSizeAt: */ -static sqInt NoDbgRegParms -instructionSizeAt(AbstractInstruction * self_in_instructionSizeAt, sqInt pc) -{ - return 4; -} - - -/* Assuming mcpc is a send return pc answer if the instruction before it is a - call (not a CallFull). - */ -/* cogit disassembleFrom: mcpc - 8 to: mcpc. */ - - /* CogMIPSELCompiler>>#isCallPrecedingReturnPC: */ -static sqInt NoDbgRegParms -isCallPrecedingReturnPC(AbstractInstruction * self_in_isCallPrecedingReturnPC, sqInt mcpc) -{ - if ((opcodeAtAddress(self_in_isCallPrecedingReturnPC, mcpc - 8)) == JAL) { - return 1; - } - if (((opcodeAtAddress(self_in_isCallPrecedingReturnPC, mcpc - 8)) == SPECIAL) - && ((functionAtAddress(self_in_isCallPrecedingReturnPC, mcpc - 8)) == JALR)) { - return 1; - } - return 0; -} - - /* CogMIPSELCompiler>>#isJump */ -static sqInt NoDbgRegParms -isJump(AbstractInstruction * self_in_isJump) -{ - return (((((self_in_isJump->opcode)) >= FirstJump) && (((self_in_isJump->opcode)) <= LastJump))) - || (((((self_in_isJump->opcode)) >= BrEqualRR) && (((self_in_isJump->opcode)) <= BrLongNotEqualRR))); -} - - -/* cogit disassembleFrom: pc to: pc + 4. */ - - /* CogMIPSELCompiler>>#isJumpAt: */ -static sqInt NoDbgRegParms -isJumpAt(AbstractInstruction * self_in_isJumpAt, sqInt pc) -{ - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == J) { - return 1; - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == SPECIAL) { - if ((functionAtAddress(self_in_isJumpAt, pc)) == JR) { - return 1; - } - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == BEQ) { - return 1; - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == BNE) { - return 1; - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == BLEZ) { - return 1; - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == BGTZ) { - return 1; - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == REGIMM) { - if ((rtAtAddress(self_in_isJumpAt, pc)) == BLTZ) { - return 1; - } - if ((rtAtAddress(self_in_isJumpAt, pc)) == BGEZ) { - return 1; - } - } - return 0; -} - - -/* Answer if the receiver is a pc-dependent instruction. */ - - /* CogMIPSELCompiler>>#isPCDependent */ -static sqInt NoDbgRegParms -isPCDependent(AbstractInstruction * self_in_isPCDependent) -{ - return (isJump(self_in_isPCDependent)) - || (((self_in_isPCDependent->opcode)) == AlignmentNops); -} - - /* CogMIPSELCompiler>>#isShortOffset: */ -static sqInt NoDbgRegParms -isShortOffset(AbstractInstruction * self_in_isShortOffset, sqInt offset) -{ - return ((offset >= -32768) && (offset <= 0x7FFF)); -} - - /* CogMIPSELCompiler>>#itype:rs:rt:eitherImmediate: */ -static sqInt NoDbgRegParms -itypersrteitherImmediate(AbstractInstruction * self_in_itypersrteitherImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate) -{ - assert(((op >= 0) && (op <= 0x3F))); - assert(((rs >= 0) && (rs <= 0x1F))); - assert(((rt >= 0) && (rt <= 0x1F))); - return (((((sqInt)((usqInt)(op) << 26))) | (((sqInt)((usqInt)(rs) << 21)))) | (((sqInt)((usqInt)(rt) << 16)))) | (immediate & 0xFFFF); -} - - /* CogMIPSELCompiler>>#itype:rs:rt:signedImmediate: */ -static sqInt NoDbgRegParms -itypersrtsignedImmediate(AbstractInstruction * self_in_itypersrtsignedImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate) -{ - assert(((op >= 0) && (op <= 0x3F))); - assert(((rs >= 0) && (rs <= 0x1F))); - assert(((rt >= 0) && (rt <= 0x1F))); - assert(isShortOffset(self_in_itypersrtsignedImmediate, immediate)); - return (((((sqInt)((usqInt)(op) << 26))) | (((sqInt)((usqInt)(rs) << 21)))) | (((sqInt)((usqInt)(rt) << 16)))) | (immediate & 0xFFFF); -} - - /* CogMIPSELCompiler>>#itype:rs:rt:unsignedImmediate: */ -static sqInt NoDbgRegParms -itypersrtunsignedImmediate(AbstractInstruction * self_in_itypersrtunsignedImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate) -{ - assert(((op >= 0) && (op <= 0x3F))); - assert(((rs >= 0) && (rs <= 0x1F))); - assert(((rt >= 0) && (rt <= 0x1F))); - assert(((immediate >= 0) && (immediate <= 0xFFFF))); - return (((((sqInt)((usqInt)(op) << 26))) | (((sqInt)((usqInt)(rs) << 21)))) | (((sqInt)((usqInt)(rt) << 16)))) | immediate; -} - - /* CogMIPSELCompiler>>#jA: */ -static sqInt NoDbgRegParms -jA(AbstractInstruction * self_in_jA, sqInt target) -{ - assert((target & 3) == 0); - return jtypetarget(self_in_jA, J, ((usqInt)((target & 0xFFFFFFF))) >> 2); -} - - /* CogMIPSELCompiler>>#jalA: */ -static sqInt NoDbgRegParms -jalA(AbstractInstruction * self_in_jalA, sqInt target) -{ - assert((target & 3) == 0); - return jtypetarget(self_in_jalA, JAL, ((usqInt)((target & 0xFFFFFFF))) >> 2); -} - - /* CogMIPSELCompiler>>#jalR: */ -static sqInt NoDbgRegParms -jalR(AbstractInstruction * self_in_jalR, sqInt targetReg) -{ - return rtypersrtrdsafunct(self_in_jalR, SPECIAL, targetReg, 0, RA, 0, JALR); -} - - /* CogMIPSELCompiler>>#jR: */ -static sqInt NoDbgRegParms -jR(AbstractInstruction * self_in_jR, sqInt targetReg) -{ - return rtypersrtrdsafunct(self_in_jR, SPECIAL, targetReg, 0, 0, 0, JR); -} - - /* CogMIPSELCompiler>>#jtype:target: */ -static sqInt NoDbgRegParms -jtypetarget(AbstractInstruction * self_in_jtypetarget, sqInt op, sqInt target) -{ - assert(((op >= 0) && (op <= 0x3F))); - assert(((target >= 0) && (target <= 0x7FFFFFF))); - return (((sqInt)((usqInt)(op) << 26))) | target; -} - - /* CogMIPSELCompiler>>#jumpLongByteSize */ -static sqInt NoDbgRegParms -jumpLongByteSize(AbstractInstruction * self_in_jumpLongByteSize) -{ - flag("bogus"); - return 16; -} - - /* CogMIPSELCompiler>>#jumpLongConditionalByteSize */ -static sqInt NoDbgRegParms -jumpLongConditionalByteSize(AbstractInstruction * self_in_jumpLongConditionalByteSize) -{ - return 16; -} - - -/* mcpc - 16: beq/ne Cmp, ZR, +12 - mcpc - 12: nop (delay slot) - mcpc - 8: j psuedo-address - mcpc - 4: nop (delay slot) */ - - /* CogMIPSELCompiler>>#jumpLongConditionalTargetBeforeFollowingAddress: */ -static usqInt NoDbgRegParms -jumpLongConditionalTargetBeforeFollowingAddress(AbstractInstruction * self_in_jumpLongConditionalTargetBeforeFollowingAddress, sqInt mcpc) -{ - assert(((opcodeAtAddress(self_in_jumpLongConditionalTargetBeforeFollowingAddress, mcpc - 16)) == BEQ) - || ((opcodeAtAddress(self_in_jumpLongConditionalTargetBeforeFollowingAddress, mcpc - 16)) == BNE)); - assert((longAt(mcpc - 12)) == (nop(self_in_jumpLongConditionalTargetBeforeFollowingAddress))); - assert((opcodeAtAddress(self_in_jumpLongConditionalTargetBeforeFollowingAddress, mcpc - 8)) == J); - assert((longAt(mcpc - 4)) == (nop(self_in_jumpLongConditionalTargetBeforeFollowingAddress))); - return targetFromJTypeAtAddress(self_in_jumpLongConditionalTargetBeforeFollowingAddress, mcpc - 8); -} - - -/* Answer the target address for the long jump immediately preceding mcpc */ - - /* CogMIPSELCompiler>>#jumpLongTargetBeforeFollowingAddress: */ -static usqInt NoDbgRegParms -jumpLongTargetBeforeFollowingAddress(AbstractInstruction * self_in_jumpLongTargetBeforeFollowingAddress, sqInt mcpc) -{ - assert((longAt(mcpc - 4)) == (nop(self_in_jumpLongTargetBeforeFollowingAddress))); - assert((opcodeAtAddress(self_in_jumpLongTargetBeforeFollowingAddress, mcpc - 8)) == SPECIAL); - assert((functionAtAddress(self_in_jumpLongTargetBeforeFollowingAddress, mcpc - 8)) == JR); - return literalAtAddress(self_in_jumpLongTargetBeforeFollowingAddress, mcpc - 12); -} - - /* CogMIPSELCompiler>>#jumpShortByteSize */ -static sqInt NoDbgRegParms -jumpShortByteSize(AbstractInstruction * self_in_jumpShortByteSize) -{ - return 8; -} - - -/* cogit disassembleFrom: pc to: pc + 4. */ - - /* CogMIPSELCompiler>>#jumpTargetPCAt: */ -static usqInt NoDbgRegParms -jumpTargetPCAt(AbstractInstruction * self_in_jumpTargetPCAt, sqInt pc) -{ - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == J) { - return targetFromJTypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == BEQ) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == BNE) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == BLEZ) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == BGTZ) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == REGIMM) { - if ((rtAtAddress(self_in_jumpTargetPCAt, pc)) == BLTZ) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((rtAtAddress(self_in_jumpTargetPCAt, pc)) == BGEZ) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - } - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#lbR:base:offset: */ -static sqInt NoDbgRegParms -lbRbaseoffset(AbstractInstruction * self_in_lbRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_lbRbaseoffset, LB, baseReg, destReg, offset); -} - - /* CogMIPSELCompiler>>#lbuR:base:offset: */ -static sqInt NoDbgRegParms -lbuRbaseoffset(AbstractInstruction * self_in_lbuRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_lbuRbaseoffset, LBU, baseReg, destReg, offset); -} - - /* CogMIPSELCompiler>>#lhR:base:offset: */ -static sqInt NoDbgRegParms -lhRbaseoffset(AbstractInstruction * self_in_lhRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_lhRbaseoffset, LH, baseReg, destReg, offset); -} - - /* CogMIPSELCompiler>>#lhuR:base:offset: */ -static sqInt NoDbgRegParms -lhuRbaseoffset(AbstractInstruction * self_in_lhuRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_lhuRbaseoffset, LHU, baseReg, destReg, offset); -} - - /* CogMIPSELCompiler>>#literalAtAddress: */ -static usqInt NoDbgRegParms -literalAtAddress(AbstractInstruction * self_in_literalAtAddress, sqInt mcpc) -{ - usqInt high; - usqInt low; - - assert((opcodeAtAddress(self_in_literalAtAddress, mcpc)) == ORI); - assert((opcodeAtAddress(self_in_literalAtAddress, mcpc - 4)) == LUI); - low = (longAt(mcpc)) & 0xFFFF; - high = (longAt(mcpc - 4)) & 0xFFFF; - return (high << 16) | low; -} - - /* CogMIPSELCompiler>>#literalAtAddress:put: */ -static sqInt NoDbgRegParms -literalAtAddressput(AbstractInstruction * self_in_literalAtAddressput, sqInt mcpc, sqInt newLiteral) -{ - usqInt newLower; - usqInt newUpper; - usqInt oldLower; - usqInt oldUpper; - - assert((opcodeAtAddress(self_in_literalAtAddressput, mcpc - 4)) == LUI); - assert((opcodeAtAddress(self_in_literalAtAddressput, mcpc)) == ORI); - oldUpper = longAt(mcpc - 4); - newUpper = (oldUpper & 0xFFFF0000U) | (high16BitsOf(self_in_literalAtAddressput, newLiteral)); - longAtput(mcpc - 4, newUpper); - oldLower = longAt(mcpc); - newLower = (oldLower & 0xFFFF0000U) | (low16BitsOf(self_in_literalAtAddressput, newLiteral)); - longAtput(mcpc, newLower); - assert((opcodeAtAddress(self_in_literalAtAddressput, mcpc - 4)) == LUI); - assert((opcodeAtAddress(self_in_literalAtAddressput, mcpc)) == ORI); - assert((literalAtAddress(self_in_literalAtAddressput, mcpc)) == newLiteral); - return newLiteral; -} - - -/* Answer the literal embedded in the instruction immediately preceding - followingAddress. This is used in the MoveCwR, PushCw and CmpCwR cases. */ -/* Cmp/MoveCwR - pc-8 lui rx, uper - pc-4 ori rx, rx, lower */ - - /* CogMIPSELCompiler>>#literalBeforeFollowingAddress: */ -static usqInt NoDbgRegParms -literalBeforeFollowingAddress(AbstractInstruction * self_in_literalBeforeFollowingAddress, sqInt followingAddress) -{ - if ((opcodeAtAddress(self_in_literalBeforeFollowingAddress, followingAddress - 4)) == ORI) { - return literalAtAddress(self_in_literalBeforeFollowingAddress, followingAddress - 4); - } - if (((opcodeAtAddress(self_in_literalBeforeFollowingAddress, followingAddress - 4)) == SW) - && ((opcodeAtAddress(self_in_literalBeforeFollowingAddress, followingAddress - 8)) == ADDIU)) { - return literalAtAddress(self_in_literalBeforeFollowingAddress, followingAddress - 12); - } - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#loadLiteralByteSize */ -static sqInt NoDbgRegParms -loadLiteralByteSize(AbstractInstruction * self_in_loadLiteralByteSize) -{ - return 8; -} - - -/* Answer the byte size of a MoveCwR opcode's corresponding machine code - when the argument is a PIC. This is for the self-reference at the end of a - closed PIC. */ - - /* CogMIPSELCompiler>>#loadPICLiteralByteSize */ -static sqInt NoDbgRegParms -loadPICLiteralByteSize(AbstractInstruction * self_in_loadPICLiteralByteSize) -{ - /* begin loadLiteralByteSize */ - return 8; -} - - /* CogMIPSELCompiler>>#low16BitsOf: */ -static usqInt NoDbgRegParms -low16BitsOf(AbstractInstruction * self_in_low16BitsOf, usqInt word) -{ - return word & 0xFFFF; -} - - /* CogMIPSELCompiler>>#luiR:C: */ -static sqInt NoDbgRegParms -luiRC(AbstractInstruction * self_in_luiRC, sqInt destReg, sqInt imm) -{ - return itypersrteitherImmediate(self_in_luiRC, LUI, 0, destReg, imm); -} - - /* CogMIPSELCompiler>>#lwR:base:offset: */ -static sqInt NoDbgRegParms -lwRbaseoffset(AbstractInstruction * self_in_lwRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_lwRbaseoffset, LW, baseReg, destReg, offset); -} - - /* CogMIPSELCompiler>>#machineCodeBytes */ -static sqInt NoDbgRegParms -machineCodeBytes(AbstractInstruction * self_in_machineCodeBytes) -{ - return 28; -} - - -/* Answer the maximum number of words of machine code generated for any - abstract instruction. - e.g. AddCheckOverflowCqR */ - - /* CogMIPSELCompiler>>#machineCodeWords */ -static sqInt NoDbgRegParms -machineCodeWords(AbstractInstruction * self_in_machineCodeWords) -{ - return 7; -} - - /* CogMIPSELCompiler>>#mfhiR: */ -static sqInt NoDbgRegParms -mfhiR(AbstractInstruction * self_in_mfhiR, sqInt destReg) -{ - flag("todo"); - return rtypersrtrdsafunct(self_in_mfhiR, SPECIAL, 0, 0, destReg, 0, MFHI); -} - - /* CogMIPSELCompiler>>#mfloR: */ -static sqInt NoDbgRegParms -mfloR(AbstractInstruction * self_in_mfloR, sqInt destReg) -{ - flag("todo"); - return rtypersrtrdsafunct(self_in_mfloR, SPECIAL, 0, 0, destReg, 0, MFLO); -} - - /* CogMIPSELCompiler>>#mipsbreak: */ -static sqInt NoDbgRegParms -mipsbreak(AbstractInstruction * self_in_mipsbreak, sqInt code) -{ - assert(((code >= 0) && (code <= 0xFFFFF))); - return (((sqInt)((usqInt)(code) << 6))) | BREAK; -} - - /* CogMIPSELCompiler>>#multR:R: */ -static sqInt NoDbgRegParms -multRR(AbstractInstruction * self_in_multRR, sqInt leftReg, sqInt rightReg) -{ - flag("todo"); - return rtypersrtrdsafunct(self_in_multRR, SPECIAL, leftReg, rightReg, 0, 0, MULT); -} - - /* CogMIPSELCompiler>>#nop */ -static sqInt NoDbgRegParms -nop(AbstractInstruction * self_in_nop) -{ - return 0; -} - - -/* Support for processors without condition codes, such as the MIPS. - Answer the branch opcode. Modify the receiver and the branch to - implement a suitable conditional branch that doesn't depend on - condition codes being set by the receiver. */ - - /* CogMIPSELCompiler>>#noteFollowingConditionalBranch: */ -static AbstractInstruction * NoDbgRegParms -noteFollowingConditionalBranch(AbstractInstruction * self_in_noteFollowingConditionalBranch, AbstractInstruction *branch) -{ - usqInt newBranchLeft; - sqInt newBranchOpcode; - usqInt newBranchRight; - - if ((((branch->opcode)) == JumpOverflow) - || (((branch->opcode)) == JumpNoOverflow)) { - return noteFollowingOverflowBranch(self_in_noteFollowingConditionalBranch, branch); - } - switch ((branch->opcode)) { - case JumpZero: - newBranchOpcode = BrEqualRR; - break; - - case JumpNonZero: - newBranchOpcode = BrNotEqualRR; - break; - - case JumpBelow: - newBranchOpcode = BrUnsignedLessRR; - break; - - case JumpBelowOrEqual: - newBranchOpcode = BrUnsignedLessEqualRR; - break; - - case JumpAbove: - newBranchOpcode = BrUnsignedGreaterRR; - break; - - case JumpAboveOrEqual: - newBranchOpcode = BrUnsignedGreaterEqualRR; - break; - - case JumpLess: - case JumpNegative: - newBranchOpcode = BrSignedLessRR; - break; - - case JumpLessOrEqual: - newBranchOpcode = BrSignedLessEqualRR; - break; - - case JumpGreater: - newBranchOpcode = BrSignedGreaterRR; - break; - - case JumpGreaterOrEqual: - newBranchOpcode = BrSignedGreaterEqualRR; - break; - - case JumpLongZero: - newBranchOpcode = BrLongEqualRR; - break; - - case JumpLongNonZero: - newBranchOpcode = BrLongNotEqualRR; - break; - - default: - /* begin unreachable */ - error("UNREACHABLE"); - newBranchOpcode = 0;; - } - switch ((self_in_noteFollowingConditionalBranch->opcode)) { - case BrEqualRR: - case BrUnsignedLessRR: - - /* I.e., two jumps after a compare. */ - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[1]; - newBranchRight = ((self_in_noteFollowingConditionalBranch->operands))[2]; - break; - case CmpRR: - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[1]; - newBranchRight = ((self_in_noteFollowingConditionalBranch->operands))[0]; - (self_in_noteFollowingConditionalBranch->opcode) = Label; - break; - case CmpCqR: - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[1]; - newBranchRight = AT; - (self_in_noteFollowingConditionalBranch->opcode) = MoveCqR; - ((self_in_noteFollowingConditionalBranch->operands))[1] = AT; - break; - case CmpCwR: - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[1]; - newBranchRight = AT; - (self_in_noteFollowingConditionalBranch->opcode) = MoveCwR; - ((self_in_noteFollowingConditionalBranch->operands))[1] = AT; - break; - case TstCqR: - newBranchLeft = Cmp; - newBranchRight = ZR; - break; - case AndCqR: - case OrRR: - case XorRR: - case SubCwR: - case SubCqR: - case ArithmeticShiftRightCqR: - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[1]; - newBranchRight = ZR; - break; - case AndCqRR: - case OrCqRR: - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[2]; - newBranchRight = ZR; - break; - case ClzRR: - - /* we test if the destination register is zero */ - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[0]; - newBranchRight = ZR; - break; - default: - /* begin unreachable */ - error("UNREACHABLE"); - - } - /* begin rewriteOpcode:with:with: */ - (branch->opcode) = newBranchOpcode; - ((branch->operands))[1] = newBranchLeft; - ((branch->operands))[2] = newBranchRight; - return branch; -} - - -/* Support for processors without condition codes, such as the MIPS. - Answer the branch opcode. Modify the receiver and the branch to - implement a suitable conditional branch that doesn't depend on - condition codes being set by the receiver. */ - - /* CogMIPSELCompiler>>#noteFollowingOverflowBranch: */ -static AbstractInstruction * NoDbgRegParms -noteFollowingOverflowBranch(AbstractInstruction * self_in_noteFollowingOverflowBranch, AbstractInstruction *branch) -{ - sqInt newBranchOpcode; - - if (((self_in_noteFollowingOverflowBranch->opcode)) == MulRR) { - (self_in_noteFollowingOverflowBranch->opcode) = MulCheckOverflowRR; - switch ((branch->opcode)) { - case JumpOverflow: - newBranchOpcode = BrNotEqualRR; - break; - - case JumpNoOverflow: - newBranchOpcode = BrEqualRR; - break; - - default: - /* begin unreachable */ - error("UNREACHABLE"); - newBranchOpcode = 0;; - } - /* begin rewriteOpcode:with:with: */ - (branch->opcode) = newBranchOpcode; - ((branch->operands))[1] = OverflowTemp1; - ((branch->operands))[2] = OverflowTemp2; - return branch; - } - switch ((self_in_noteFollowingOverflowBranch->opcode)) { - case AddCqR: - (self_in_noteFollowingOverflowBranch->opcode) = AddCheckOverflowCqR; - break; - - case AddRR: - (self_in_noteFollowingOverflowBranch->opcode) = AddCheckOverflowRR; - break; - - case SubCqR: - (self_in_noteFollowingOverflowBranch->opcode) = SubCheckOverflowCqR; - break; - - case SubRR: - (self_in_noteFollowingOverflowBranch->opcode) = SubCheckOverflowRR; - break; - - default: - /* begin unreachable */ - error("UNREACHABLE"); - (self_in_noteFollowingOverflowBranch->opcode) = 0;; - } - switch ((branch->opcode)) { - case JumpOverflow: - newBranchOpcode = BrSignedLessRR; - break; - - case JumpNoOverflow: - newBranchOpcode = BrSignedGreaterEqualRR; - break; - - default: - /* begin unreachable */ - error("UNREACHABLE"); - newBranchOpcode = 0;; - } - /* begin rewriteOpcode:with:with: */ - (branch->opcode) = newBranchOpcode; - ((branch->operands))[1] = Overflow; - ((branch->operands))[2] = ZR; - return branch; -} - - /* CogMIPSELCompiler>>#numIntRegArgs */ -static sqInt NoDbgRegParms -numIntRegArgs(AbstractInstruction * self_in_numIntRegArgs) -{ - flag("OABI"); - return 4; -} - - /* CogMIPSELCompiler>>#opcodeAtAddress: */ -static sqInt NoDbgRegParms -opcodeAtAddress(AbstractInstruction * self_in_opcodeAtAddress, sqInt mcpc) -{ - return ((usqInt)((longAt(mcpc)))) >> 26; -} - - /* CogMIPSELCompiler>>#oriR:R:C: */ -static sqInt NoDbgRegParms -oriRRC(AbstractInstruction * self_in_oriRRC, sqInt destReg, sqInt srcReg, sqInt imm) -{ - return itypersrteitherImmediate(self_in_oriRRC, ORI, srcReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#orR:R:R: */ -static sqInt NoDbgRegParms -orRRR(AbstractInstruction * self_in_orRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_orRRR, SPECIAL, leftReg, rightReg, destReg, 0, OR); -} - - /* CogMIPSELCompiler>>#padIfPossibleWithStopsFrom:to: */ -static void NoDbgRegParms -padIfPossibleWithStopsFromto(AbstractInstruction * self_in_padIfPossibleWithStopsFromto, sqInt startAddr, sqInt endAddr) -{ - sqInt addr; - - for (addr = startAddr; addr < endAddr; addr += 4) { - longAtput(addr, stop(self_in_padIfPossibleWithStopsFromto)); - } -} - - /* CogMIPSELCompiler>>#prefR:offset:hint: */ -static sqInt NoDbgRegParms -prefRoffsethint(AbstractInstruction * self_in_prefRoffsethint, sqInt baseReg, sqInt offset, sqInt hint) -{ - flag("todo"); - assert((hint == HintLoad) - || (hint == HintStore)); - return itypersrtsignedImmediate(self_in_prefRoffsethint, PREF, baseReg, hint, offset); -} - - /* CogMIPSELCompiler>>#pushLinkRegisterByteSize */ -static sqInt NoDbgRegParms -pushLinkRegisterByteSize(AbstractInstruction * self_in_pushLinkRegisterByteSize) -{ - return 8; -} - - /* CogMIPSELCompiler>>#relocateCallBeforeReturnPC:by: */ -static AbstractInstruction * NoDbgRegParms -relocateCallBeforeReturnPCby(AbstractInstruction * self_in_relocateCallBeforeReturnPCby, sqInt retpc, sqInt delta) -{ - usqInt target; - - assert((delta % 4) == 0); - if (delta == 0) { - return self_in_relocateCallBeforeReturnPCby; - } - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 16)) == LUI); - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 12)) == ORI); - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 8)) == SPECIAL); - assert((functionAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 8)) == JALR); - assert((longAt(retpc - 4)) == (nop(self_in_relocateCallBeforeReturnPCby))); - target = literalAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 12); - target += delta; - literalAtAddressput(self_in_relocateCallBeforeReturnPCby, retpc - 12, target); - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 16)) == LUI); - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 12)) == ORI); - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 8)) == SPECIAL); - assert((functionAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 8)) == JALR); - assert((longAt(retpc - 4)) == (nop(self_in_relocateCallBeforeReturnPCby))); - return 0; -} - - -/* lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jr t9 - nop (delay slot) - ... <-- pc */ - - /* CogMIPSELCompiler>>#relocateJumpLongBeforeFollowingAddress:by: */ -static AbstractInstruction * NoDbgRegParms -relocateJumpLongBeforeFollowingAddressby(AbstractInstruction * self_in_relocateJumpLongBeforeFollowingAddressby, sqInt pc, sqInt delta) -{ - usqInt newTarget; - usqInt oldTarget; - - assert((delta % 4) == 0); - if (delta == 0) { - return self_in_relocateJumpLongBeforeFollowingAddressby; - } - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 16)) == LUI); - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 12)) == ORI); - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 8)) == SPECIAL); - assert((functionAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 8)) == JR); - assert((longAt(pc - 4)) == (nop(self_in_relocateJumpLongBeforeFollowingAddressby))); - oldTarget = literalAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 12); - newTarget = oldTarget + delta; - literalAtAddressput(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 12, newTarget); - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 16)) == LUI); - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 12)) == ORI); - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 8)) == SPECIAL); - assert((functionAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 8)) == JR); - assert((longAt(pc - 4)) == (nop(self_in_relocateJumpLongBeforeFollowingAddressby))); - return 0; -} - - -/* lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jalr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#relocateJumpLongConditionalBeforeFollowingAddress:by: */ -static void NoDbgRegParms -relocateJumpLongConditionalBeforeFollowingAddressby(AbstractInstruction * self_in_relocateJumpLongConditionalBeforeFollowingAddressby, sqInt pc, sqInt delta) -{ - assert((opcodeAtAddress(self_in_relocateJumpLongConditionalBeforeFollowingAddressby, pc - 16)) == BNE); - assert((longAt(pc - 12)) == (nop(self_in_relocateJumpLongConditionalBeforeFollowingAddressby))); - assert((opcodeAtAddress(self_in_relocateJumpLongConditionalBeforeFollowingAddressby, pc - 8)) == J); - assert((longAt(pc - 4)) == (nop(self_in_relocateJumpLongConditionalBeforeFollowingAddressby))); - rewriteJTypeAtAddressdelta(self_in_relocateJumpLongConditionalBeforeFollowingAddressby, pc - 8, delta); - assert((opcodeAtAddress(self_in_relocateJumpLongConditionalBeforeFollowingAddressby, pc - 16)) == BNE); - assert((longAt(pc - 12)) == (nop(self_in_relocateJumpLongConditionalBeforeFollowingAddressby))); - assert((opcodeAtAddress(self_in_relocateJumpLongConditionalBeforeFollowingAddressby, pc - 8)) == J); - assert((longAt(pc - 4)) == (nop(self_in_relocateJumpLongConditionalBeforeFollowingAddressby))); -} - - -/* cogit disassembleFrom: pc - 16 to: pc + 16 a StackToRegisterMappingCogit. */ - - /* CogMIPSELCompiler>>#relocateMethodReferenceBeforeAddress:by: */ -static AbstractInstruction * NoDbgRegParms -relocateMethodReferenceBeforeAddressby(AbstractInstruction * self_in_relocateMethodReferenceBeforeAddressby, sqInt pc, sqInt delta) -{ - usqInt newValue; - usqInt oldValue; - - if (((opcodeAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 8)) == ADDIU) - && ((opcodeAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 4)) == SW)) { - - /* PushCw */ - oldValue = literalAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 12); - newValue = oldValue + delta; - literalAtAddressput(self_in_relocateMethodReferenceBeforeAddressby, pc - 12, newValue); - assert((literalAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 12)) == newValue); - return self_in_relocateMethodReferenceBeforeAddressby; - } - oldValue = literalAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 4); - newValue = oldValue + delta; - literalAtAddressput(self_in_relocateMethodReferenceBeforeAddressby, pc - 4, newValue); - assert((literalAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 4)) == newValue); - return 0; -} - - -/* Rewrite a call instruction to call a different target. This variant is - used to link PICs - in ceSendMiss et al,. - Answer the extent of the code change which is used to compute the range of - the icache to flush. */ -/* lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jalr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#rewriteCallAt:target: */ -static sqInt NoDbgRegParms -rewriteCallAttarget(AbstractInstruction * self_in_rewriteCallAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress) -{ - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteCallAttarget))); - literalAtAddressput(self_in_rewriteCallAttarget, callSiteReturnAddress - 12, callTargetAddress); - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteCallAttarget))); - return 20; -} - - -/* Rewrite a jump instruction to call a different target. This variant is - used to reset the - jumps in the prototype CPIC to suit each use,. - Answer the extent of the code change which is used to compute the range of - the icache to flush. */ - - /* CogMIPSELCompiler>>#rewriteConditionalJumpLongAt:target: */ -static void NoDbgRegParms -rewriteConditionalJumpLongAttarget(AbstractInstruction * self_in_rewriteConditionalJumpLongAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress) -{ - assert((opcodeAtAddress(self_in_rewriteConditionalJumpLongAttarget, callSiteReturnAddress - 8)) == J); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteConditionalJumpLongAttarget))); - rewriteJTypeAtAddresstarget(self_in_rewriteConditionalJumpLongAttarget, callSiteReturnAddress - 8, callTargetAddress); - assert((opcodeAtAddress(self_in_rewriteConditionalJumpLongAttarget, callSiteReturnAddress - 8)) == J); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteConditionalJumpLongAttarget))); -} - - -/* Rewrite a jump instruction to call a different target. This variant is - used to reset the - jumps in the prototype CPIC to suit each use,. - Answer the extent of the code change which is used to compute the range of - the icache to flush. */ -/* self CmpR: ClassReg R: TempReg. - ^self JumpNonZero: 0 */ -/* bne s5, s3, +156 ; =BE7C - nop (delay slot) - .... <-- addressFollowingJump */ - - /* CogMIPSELCompiler>>#rewriteCPICJumpAt:target: */ -static void NoDbgRegParms -rewriteCPICJumpAttarget(AbstractInstruction * self_in_rewriteCPICJumpAttarget, usqInt addressFollowingJump, usqInt jumpTargetAddr) -{ - assert((opcodeAtAddress(self_in_rewriteCPICJumpAttarget, addressFollowingJump - 8)) == BNE); - assert((longAt(addressFollowingJump - 4)) == (nop(self_in_rewriteCPICJumpAttarget))); - rewriteITypeBranchAtAddresstarget(self_in_rewriteCPICJumpAttarget, addressFollowingJump - 8, jumpTargetAddr); - assert((opcodeAtAddress(self_in_rewriteCPICJumpAttarget, addressFollowingJump - 8)) == BNE); - assert((longAt(addressFollowingJump - 4)) == (nop(self_in_rewriteCPICJumpAttarget))); -} - - -/* Rewrite an inline cache to call a different target for a new tag. This - variant is used - to link unlinked sends in ceSend:to:numArgs: et al. Answer the extent of - the code - change which is used to compute the range of the icache to flush. */ -/* MoveCwR ClassReg selectorIndex/expectedClass - Call: unlinked send stub/expectedTarget - Push ReceiverResult <-- callSiteReturnAddress */ -/* lui s3, selector/tagHigh - ori s3, s3, selector/tagLow - lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jalr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#rewriteInlineCacheAt:tag:target: */ -static sqInt NoDbgRegParms -rewriteInlineCacheAttagtarget(AbstractInstruction * self_in_rewriteInlineCacheAttagtarget, usqInt callSiteReturnAddress, sqInt cacheTag, usqInt callTargetAddress) -{ - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 24)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 20)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteInlineCacheAttagtarget))); - literalAtAddressput(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 20, cacheTag); - literalAtAddressput(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 12, callTargetAddress); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 24)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 20)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteInlineCacheAttagtarget))); - return 24; -} - - -/* Rewrite an inline cache with a new tag. This variant is used - by the garbage collector. */ -/* MoveCwR ClassReg selectorIndex/expectedClass - Call: unlinked send stub/expectedTarget - Push ReceiverResult <-- callSiteReturnAddress */ -/* lui s3, selector/tagHigh - ori s3, s3, selector/tagLow - lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jalr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#rewriteInlineCacheTag:at: */ -static void NoDbgRegParms -rewriteInlineCacheTagat(AbstractInstruction * self_in_rewriteInlineCacheTagat, sqInt cacheTag, usqInt callSiteReturnAddress) -{ - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 24)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 20)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteInlineCacheTagat))); - literalAtAddressput(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 20, cacheTag); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 24)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 20)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteInlineCacheTagat))); -} - - /* CogMIPSELCompiler>>#rewriteITypeBranchAtAddress:target: */ -static void NoDbgRegParms -rewriteITypeBranchAtAddresstarget(AbstractInstruction * self_in_rewriteITypeBranchAtAddresstarget, sqInt mcpc, sqInt newTarget) -{ - sqInt newDisplacement; - unsigned int newInstruction; - sqInt oldInstruction; - - - /* Displacement is relative to delay slot. */ - newDisplacement = newTarget - (mcpc + 4); - - /* Displacement is in words. */ - newDisplacement = (newDisplacement) >> 2; - newDisplacement = newDisplacement & 0xFFFF; - oldInstruction = longAt(mcpc); - newInstruction = (oldInstruction & 0xFFFF0000U) | newDisplacement; - longAtput(mcpc, newInstruction); -} - - /* CogMIPSELCompiler>>#rewriteJTypeAtAddress:delta: */ -static void NoDbgRegParms -rewriteJTypeAtAddressdelta(AbstractInstruction * self_in_rewriteJTypeAtAddressdelta, sqInt mcpc, sqInt delta) -{ - usqInt newTarget; - usqInt oldTarget; - - oldTarget = targetFromJTypeAtAddress(self_in_rewriteJTypeAtAddressdelta, mcpc); - newTarget = oldTarget + delta; - rewriteJTypeAtAddresstarget(self_in_rewriteJTypeAtAddressdelta, mcpc, newTarget); -} - - /* CogMIPSELCompiler>>#rewriteJTypeAtAddress:target: */ -static void NoDbgRegParms -rewriteJTypeAtAddresstarget(AbstractInstruction * self_in_rewriteJTypeAtAddresstarget, sqInt mcpc, sqInt newTarget) -{ - sqInt regionMask; - - assert((opcodeAtAddress(self_in_rewriteJTypeAtAddresstarget, mcpc)) == J); - - /* mcpc + 4: relative to delay slot not j */ - regionMask = 0xF0000000U; - assert(((mcpc + 4) & regionMask) == (newTarget & regionMask)); - longAtput(mcpc, jA(self_in_rewriteJTypeAtAddresstarget, newTarget)); -} - - -/* Rewrite a jump instruction to call a different target. This variant is - used to reset the - jumps in the prototype CPIC to suit each use,. - Answer the extent of the code change which is used to compute the range of - the icache to flush. */ -/* lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#rewriteJumpLongAt:target: */ -static sqInt NoDbgRegParms -rewriteJumpLongAttarget(AbstractInstruction * self_in_rewriteJumpLongAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress) -{ - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 8)) == JR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteJumpLongAttarget))); - literalAtAddressput(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 12, callTargetAddress); - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 8)) == JR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteJumpLongAttarget))); - return 20; -} - - /* CogMIPSELCompiler>>#rtAtAddress: */ -static sqInt NoDbgRegParms -rtAtAddress(AbstractInstruction * self_in_rtAtAddress, sqInt mcpc) -{ - return (((usqInt)((longAt(mcpc)))) >> 16) & 0x1F; -} - - /* CogMIPSELCompiler>>#rtype:rs:rt:rd:sa:funct: */ -static sqInt NoDbgRegParms -rtypersrtrdsafunct(AbstractInstruction * self_in_rtypersrtrdsafunct, sqInt op, sqInt rs, sqInt rt, sqInt rd, sqInt sa, sqInt funct) -{ - assert(((op >= 0) && (op <= 0x3F))); - assert(((rs >= 0) && (rs <= 0x1F))); - assert(((rt >= 0) && (rt <= 0x1F))); - assert(((rd >= 0) && (rd <= 0x1F))); - assert(((sa >= 0) && (sa <= 0x1F))); - assert(((funct >= 0) && (funct <= 0x3F))); - return (((((((sqInt)((usqInt)(op) << 26))) | (((sqInt)((usqInt)(rs) << 21)))) | (((sqInt)((usqInt)(rt) << 16)))) | (((sqInt)((usqInt)(rd) << 11)))) | (((sqInt)((usqInt)(sa) << 6)))) | funct; -} - - /* CogMIPSELCompiler>>#sbR:base:offset: */ -static sqInt NoDbgRegParms -sbRbaseoffset(AbstractInstruction * self_in_sbRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_sbRbaseoffset, SB, baseReg, srcReg, offset); -} - - -/* Not really, but we can merge this in noteFollowingConditionalBranch:. */ - - /* CogMIPSELCompiler>>#setsConditionCodesFor: */ -static sqInt NoDbgRegParms -setsConditionCodesFor(AbstractInstruction * self_in_setsConditionCodesFor, sqInt aConditionalJumpOpcode) -{ - if (((self_in_setsConditionCodesFor->opcode)) == XorRR) { - return 1; - } - if (((self_in_setsConditionCodesFor->opcode)) == ArithmeticShiftRightCqR) { - return 1; - } - if ((((self_in_setsConditionCodesFor->opcode)) == ClzRR) - && (aConditionalJumpOpcode == JumpZero)) { - return 1; - } - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#shR:base:offset: */ -static sqInt NoDbgRegParms -shRbaseoffset(AbstractInstruction * self_in_shRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_shRbaseoffset, SH, baseReg, srcReg, offset); -} - - -/* Size a jump and set its address. The target may be another instruction - or an absolute address. On entry the address inst var holds our virtual - address. On exit address is set to eventualAbsoluteAddress, which is - where this instruction will be output. The span of a jump to a following - instruction is therefore between that instruction's address and this - instruction's address ((which are both still their virtual addresses), but - the span of a jump to a preceding instruction or to an absolute address is - between that instruction's address (which by now is its eventual absolute - address) or absolute address and eventualAbsoluteAddress. - - ARM is simple; the 26-bit call/jump range means no short jumps. This - routine only has to determine the targets of jumps, not determine sizes. */ - - /* CogMIPSELCompiler>>#sizePCDependentInstructionAt: */ -static usqInt NoDbgRegParms -sizePCDependentInstructionAt(AbstractInstruction * self_in_sizePCDependentInstructionAt, sqInt eventualAbsoluteAddress) -{ - usqInt alignment; - - if (((self_in_sizePCDependentInstructionAt->opcode)) == AlignmentNops) { - (self_in_sizePCDependentInstructionAt->address) = eventualAbsoluteAddress; - alignment = ((self_in_sizePCDependentInstructionAt->operands))[0]; - return ((self_in_sizePCDependentInstructionAt->machineCodeSize) = ((eventualAbsoluteAddress + (alignment - 1)) & (-alignment)) - eventualAbsoluteAddress); - } - assert((isJump(self_in_sizePCDependentInstructionAt)) - || ((((self_in_sizePCDependentInstructionAt->opcode)) == Call) - || (((self_in_sizePCDependentInstructionAt->opcode)) == CallFull))); - if (isJump(self_in_sizePCDependentInstructionAt)) { - resolveJumpTarget(self_in_sizePCDependentInstructionAt); - } - (self_in_sizePCDependentInstructionAt->address) = eventualAbsoluteAddress; - return ((self_in_sizePCDependentInstructionAt->machineCodeSize) = (self_in_sizePCDependentInstructionAt->maxSize)); -} - - /* CogMIPSELCompiler>>#sllR:R:C: */ -static sqInt NoDbgRegParms -sllRRC(AbstractInstruction * self_in_sllRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount) -{ - return rtypersrtrdsafunct(self_in_sllRRC, SPECIAL, 0, sourceReg, destReg, shiftAmount, SLL); -} - - /* CogMIPSELCompiler>>#sllvR:R:R: */ -static sqInt NoDbgRegParms -sllvRRR(AbstractInstruction * self_in_sllvRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_sllvRRR, SPECIAL, rightReg, leftReg, destReg, 0, SLLV); -} - - /* CogMIPSELCompiler>>#sltiR:R:C: */ -static sqInt NoDbgRegParms -sltiRRC(AbstractInstruction * self_in_sltiRRC, sqInt destReg, sqInt leftReg, sqInt imm) -{ - return itypersrtsignedImmediate(self_in_sltiRRC, SLTI, leftReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#sltiuR:R:C: */ -static sqInt NoDbgRegParms -sltiuRRC(AbstractInstruction * self_in_sltiuRRC, sqInt destReg, sqInt leftReg, sqInt imm) -{ - return itypersrtsignedImmediate(self_in_sltiuRRC, SLTIU, leftReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#sltR:R:R: */ -static sqInt NoDbgRegParms -sltRRR(AbstractInstruction * self_in_sltRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_sltRRR, SPECIAL, leftReg, rightReg, destReg, 0, SLT); -} - - /* CogMIPSELCompiler>>#sltuR:R:R: */ -static sqInt NoDbgRegParms -sltuRRR(AbstractInstruction * self_in_sltuRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_sltuRRR, SPECIAL, leftReg, rightReg, destReg, 0, SLTU); -} - - /* CogMIPSELCompiler>>#sraR:R:C: */ -static sqInt NoDbgRegParms -sraRRC(AbstractInstruction * self_in_sraRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount) -{ - return rtypersrtrdsafunct(self_in_sraRRC, SPECIAL, 0, sourceReg, destReg, shiftAmount, SRA); -} - - /* CogMIPSELCompiler>>#sravR:R:R: */ -static sqInt NoDbgRegParms -sravRRR(AbstractInstruction * self_in_sravRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_sravRRR, SPECIAL, rightReg, leftReg, destReg, 0, SRAV); -} - - /* CogMIPSELCompiler>>#srlR:R:C: */ -static sqInt NoDbgRegParms -srlRRC(AbstractInstruction * self_in_srlRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount) -{ - return rtypersrtrdsafunct(self_in_srlRRC, SPECIAL, 0, sourceReg, destReg, shiftAmount, SRL); -} - - /* CogMIPSELCompiler>>#srlvR:R:R: */ -static sqInt NoDbgRegParms -srlvRRR(AbstractInstruction * self_in_srlvRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_srlvRRR, SPECIAL, rightReg, leftReg, destReg, 0, SRLV); -} - - /* CogMIPSELCompiler>>#stop */ -static sqInt NoDbgRegParms -stop(AbstractInstruction * self_in_stop) -{ - return mipsbreak(self_in_stop, 0); -} - - /* CogMIPSELCompiler>>#stopsFrom:to: */ -static void NoDbgRegParms -stopsFromto(AbstractInstruction * self_in_stopsFromto, sqInt startAddr, sqInt endAddr) -{ - sqInt addr; - - assert((((endAddr - startAddr) + 1) % 4) == 0); - for (addr = startAddr; addr <= endAddr; addr += 4) { - codeLongAtput(addr, stop(self_in_stopsFromto)); - } -} - - -/* Rewrite the long constant loaded by a MoveCwR or PushCw before the given - address - */ - - /* CogMIPSELCompiler>>#storeLiteral:beforeFollowingAddress: */ -static sqInt NoDbgRegParms -storeLiteralbeforeFollowingAddress(AbstractInstruction * self_in_storeLiteralbeforeFollowingAddress, sqInt literal, sqInt followingAddress) -{ - flag("bogus"); - if ((opcodeAtAddress(self_in_storeLiteralbeforeFollowingAddress, followingAddress - 4)) == ORI) { - return literalAtAddressput(self_in_storeLiteralbeforeFollowingAddress, followingAddress - 4, literal); - } - if (((opcodeAtAddress(self_in_storeLiteralbeforeFollowingAddress, followingAddress - 4)) == SW) - && ((opcodeAtAddress(self_in_storeLiteralbeforeFollowingAddress, followingAddress - 8)) == ADDIU)) { - return literalAtAddressput(self_in_storeLiteralbeforeFollowingAddress, followingAddress - 12, literal); - } - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#subuR:R:R: */ -static sqInt NoDbgRegParms -subuRRR(AbstractInstruction * self_in_subuRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_subuRRR, SPECIAL, leftReg, rightReg, destReg, 0, SUBU); -} - - /* CogMIPSELCompiler>>#swR:base:offset: */ -static sqInt NoDbgRegParms -swRbaseoffset(AbstractInstruction * self_in_swRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_swRbaseoffset, SW, baseReg, srcReg, offset); -} - - /* CogMIPSELCompiler>>#targetFromITypeAtAddress: */ -static usqInt NoDbgRegParms -targetFromITypeAtAddress(AbstractInstruction * self_in_targetFromITypeAtAddress, usqInt mcpc) -{ - usqInt offset; - - offset = (longAt(mcpc)) & 0xFFFF; - offset = offset << 2; - return (mcpc + offset) + OneInstruction; -} - - /* CogMIPSELCompiler>>#targetFromJTypeAtAddress: */ -static usqInt NoDbgRegParms -targetFromJTypeAtAddress(AbstractInstruction * self_in_targetFromJTypeAtAddress, usqInt mcpc) -{ - sqInt targetLow; - - - /* mcpc + 4: relative to delay slot not j */ - targetLow = (longAt(mcpc)) & 0x3FFFFFF; - return ((mcpc + 4) & 0xF0000000U) + (((sqInt)((usqInt)(targetLow) << 2))); -} - - /* CogMIPSELCompiler>>#xoriR:R:C: */ -static sqInt NoDbgRegParms -xoriRRC(AbstractInstruction * self_in_xoriRRC, sqInt destReg, sqInt srcReg, sqInt imm) -{ - return itypersrteitherImmediate(self_in_xoriRRC, XORI, srcReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#xorR:R:R: */ -static sqInt NoDbgRegParms -xorRRR(AbstractInstruction * self_in_xorRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_xorRRR, SPECIAL, leftReg, rightReg, destReg, 0, XOR); -} - - -/* Answer if Call and JumpLong are relative and hence need to take the - caller's relocation delta into account during code compaction, rather than - just the - callee's delta. */ - - /* CogMIPSELCompiler>>#zoneCallsAreRelative */ -static sqInt NoDbgRegParms -zoneCallsAreRelative(AbstractInstruction * self_in_zoneCallsAreRelative) -{ - return 0; -} - - /* CogObjectRepresentation>>#checkValidObjectReference: */ -static sqInt NoDbgRegParms -checkValidObjectReference(sqInt anOop) -{ - return (!(isImmediate(anOop))) - && ((heapMapAtWord(pointerForOop(anOop))) != 0); -} - - /* CogObjectRepresentation>>#genCmpClassFloatCompactIndexR: */ -static AbstractInstruction * NoDbgRegParms -genCmpClassFloatCompactIndexR(sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, ClassFloatCompactIndex, reg); - return anInstruction; -} - - /* CogObjectRepresentation>>#genCmpClassMethodContextCompactIndexR: */ -static AbstractInstruction * NoDbgRegParms -genCmpClassMethodContextCompactIndexR(sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, reg); - return anInstruction; -} - - -/* Get the method header (first word) of a CompiledMethod into headerReg. - Deal with the method possibly being cogged. */ - - /* CogObjectRepresentation>>#genGetMethodHeaderOf:into:scratch: */ -static sqInt NoDbgRegParms -genGetMethodHeaderOfintoscratch(sqInt methodReg, sqInt headerReg, sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *jumpNotCogged; - sqInt offset; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, BaseHeaderSize, methodReg, headerReg); - jumpNotCogged = genJumpSmallInteger(headerReg); - /* begin MoveMw:r:R: */ - offset = offsetof(CogMethod, methodHeader); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, offset, headerReg, headerReg); - jmpTarget(jumpNotCogged, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - /* CogObjectRepresentation>>#genLoadSlot:sourceReg:destReg: */ -static sqInt NoDbgRegParms -genLoadSlotsourceRegdestReg(sqInt index, sqInt sourceReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, (index * BytesPerWord) + BaseHeaderSize, sourceReg, destReg); - return 0; -} - - /* CogObjectRepresentation>>#genPrimitiveAdd */ -static sqInt -genPrimitiveAdd(void) -{ - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpOvfl; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genRemoveSmallIntegerTagsInScratchReg(ClassReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, ReceiverResultReg, ClassReg); - /* begin JumpOverflow: */ - jumpOvfl = genConditionalBranchoperand(JumpOverflow, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpOvfl, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveBitAnd */ -static sqInt -genPrimitiveBitAnd(void) -{ - AbstractInstruction *jumpNotSI; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - /* begin AndR:R: */ - genoperandoperand(AndRR, Arg0Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveBitOr */ -static sqInt -genPrimitiveBitOr(void) -{ - AbstractInstruction *jumpNotSI; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - /* begin OrR:R: */ - genoperandoperand(OrRR, Arg0Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - -/* rTemp := rArg0 - rClass := tTemp - rTemp := rTemp & 1 - jz nonInt - rClass >>= 1 - cmp 0,rClass - jge neg - cmp 31,rClass // numSmallIntegerBits, jge for sign - jge tooBig - rTemp := rReceiver - rTemp <<= rClass - rTemp >>= rClass (arithmetic) - cmp rTemp,rReceiver - jnz ovfl - rReceiver := rReceiver - 1 - rReceiver := rReceiver <<= rClass - rReceiver := rReceiver + 1 - ret - neg: - rClass := 0 - rClass - cmp 31,rClass // numSmallIntegerBits - jge inRange - rClass := 31 - inRange - rReceiver := rReceiver >>= rClass. - rReceiver := rReceiver | smallIntegerTags. - ret - ovfl - tooBig - nonInt: - fail - */ - - /* CogObjectRepresentation>>#genPrimitiveBitShift */ -static sqInt -genPrimitiveBitShift(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *jumpInRange; - AbstractInstruction *jumpNegative; - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpOvfl; - AbstractInstruction *jumpTooBig; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genConvertSmallIntegerToIntegerInReg(ClassReg); - if (!(setsConditionCodesFor(lastOpcode(), JumpNegative))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, ClassReg); - } - /* begin JumpNegative: */ - jumpNegative = genConditionalBranchoperand(JumpNegative, ((sqInt)0)); - /* begin CmpCq:R: */ - anInstruction1 = genoperandoperand(CmpCqR, 0x1F /* numSmallIntegerBits */, ClassReg); - /* begin JumpGreaterOrEqual: */ - jumpTooBig = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - /* begin LogicalShiftLeftR:R: */ - genoperandoperand(LogicalShiftLeftRR, ClassReg, TempReg); - /* begin ArithmeticShiftRightR:R: */ - genoperandoperand(ArithmeticShiftRightRR, ClassReg, TempReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, ReceiverResultReg); - /* begin JumpNonZero: */ - jumpOvfl = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genRemoveSmallIntegerTagsInScratchReg(ReceiverResultReg); - /* begin LogicalShiftLeftR:R: */ - genoperandoperand(LogicalShiftLeftRR, ClassReg, ReceiverResultReg); - genAddSmallIntegerTagsTo(ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNegative, genoperand(NegateR, ClassReg)); - /* begin CmpCq:R: */ - anInstruction2 = genoperandoperand(CmpCqR, 0x1F /* numSmallIntegerBits */, ClassReg); - /* begin JumpLessOrEqual: */ - jumpInRange = genConditionalBranchoperand(JumpLessOrEqual, ((sqInt)0)); - /* begin MoveCq:R: */ - anInstruction3 = genoperandoperand(MoveCqR, 0x1F /* numSmallIntegerBits */, ClassReg); - jmpTarget(jumpInRange, genoperandoperand(ArithmeticShiftRightRR, ClassReg, ReceiverResultReg)); - genClearAndSetSmallIntegerTagsIn(ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotSI, jmpTarget(jumpTooBig, jmpTarget(jumpOvfl, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveBitXor */ -static sqInt -genPrimitiveBitXor(void) -{ - AbstractInstruction *jumpNotSI; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genRemoveSmallIntegerTagsInScratchReg(Arg0Reg); - /* begin XorR:R: */ - genoperandoperand(XorRR, Arg0Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveClass */ -static sqInt -genPrimitiveClass(void) -{ - sqInt reg; - - reg = ReceiverResultReg; - if (methodOrBlockNumArgs > 0) { - if (methodOrBlockNumArgs > 1) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - reg = Arg0Reg; - assert(0 < (numRegArgs())); - } - if ((genGetClassObjectOfintoscratchRegmayBeAForwarder(reg, ReceiverResultReg, TempReg, reg != ReceiverResultReg)) == BadRegisterSet) { - genGetClassObjectOfintoscratchRegmayBeAForwarder(reg, ClassReg, TempReg, reg != ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, ReceiverResultReg); - } - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - return UnfailingPrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveDiv */ -static sqInt -genPrimitiveDiv(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *convert; - AbstractInstruction *jumpExact; - AbstractInstruction *jumpIsSI; - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpSameSign; - AbstractInstruction *jumpZero; - - if (!(processorHasDivQuoRemAndMClassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, Arg1Reg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genShiftAwaySmallIntegerTagsInScratchReg(ClassReg); - if (!(setsConditionCodesFor(lastOpcode(), JumpZero))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, ClassReg); - } - /* begin JumpZero: */ - jumpZero = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - genShiftAwaySmallIntegerTagsInScratchReg(TempReg); - gDivRRQuoRem(ClassReg, TempReg, TempReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(CmpCqR, 0, ClassReg); - /* begin JumpZero: */ - jumpExact = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin XorR:R: */ - genoperandoperand(XorRR, ClassReg, Arg1Reg); - if (!(setsConditionCodesFor(lastOpcode(), JumpZero))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, Arg1Reg); - } - /* begin JumpGreaterOrEqual: */ - jumpSameSign = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(SubCqR, 1, TempReg); - jmpTarget(jumpSameSign, (convert = genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - genConvertIntegerInRegtoSmallIntegerInReg(TempReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpExact, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - jumpIsSI = genJumpIsSmallIntegerValuescratch(TempReg, Arg1Reg); - jmpTarget(jumpIsSI, convert); - jmpTarget(jumpZero, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveDivide */ -static sqInt -genPrimitiveDivide(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *jumpInexact; - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpOverflow; - AbstractInstruction *jumpZero; - - if (!(processorHasDivQuoRemAndMClassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genShiftAwaySmallIntegerTagsInScratchReg(ClassReg); - /* begin JumpZero: */ - jumpZero = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - genShiftAwaySmallIntegerTagsInScratchReg(TempReg); - gDivRRQuoRem(ClassReg, TempReg, TempReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, ClassReg); - /* begin JumpNonZero: */ - jumpInexact = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - jumpOverflow = genJumpNotSmallIntegerValuescratch(TempReg, Arg1Reg); - genConvertIntegerInRegtoSmallIntegerInReg(TempReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpOverflow, jmpTarget(jumpInexact, jmpTarget(jumpZero, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveEqual */ -static sqInt -genPrimitiveEqual(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpZero, gJumpFPEqual, 0) - : genSmallIntegerComparison(JumpZero)); -} - - /* CogObjectRepresentation>>#genPrimitiveGreaterOrEqual */ -static sqInt -genPrimitiveGreaterOrEqual(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpGreaterOrEqual, gJumpFPGreaterOrEqual, 0) - : genSmallIntegerComparison(JumpGreaterOrEqual)); -} - - /* CogObjectRepresentation>>#genPrimitiveGreaterThan */ -static sqInt -genPrimitiveGreaterThan(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpGreater, gJumpFPGreater, 0) - : genSmallIntegerComparison(JumpGreater)); -} - - -/* Implementation notes: there are two reasons to use TempReg - -1) if primitive fails, ReceiverResultReg must remain unchanged (we - CompletePrimitive) -2) CLZ/BSR only work on 64bits for registers R0-R7 on - Intel X64. But Win64 uses R9 - Normally, this should be backEnd dependent, but for now we have a single - 64bits target... - */ - - /* CogObjectRepresentation>>#genPrimitiveHighBit */ -static sqInt -genPrimitiveHighBit(void) -{ - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *jumpNegativeReceiver; - AbstractInstruction *jumpNegativeReceiver2; - - - /* remove excess tag bits from the receiver oop */ - - /* and use the abstract cogit facility for case of single tag-bit */ - /* begin genHighBitIn:ofSmallIntegerOopWithSingleTagBit: */ - /* begin genHighBitClzIn:ofSmallIntegerOopWithSingleTagBit: */ - genoperandoperand(ClzRR, ReceiverResultReg, TempReg); - if (!(setsConditionCodesFor(lastOpcode(), JumpZero))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(CmpCqR, 0, TempReg); - } - - /* Note the nice bit trick below: - highBit_1based_of_small_int_value = (BytesPerWord * 8) - leadingZeroCout_of_oop - 1 toAccountForTagBit. - This is like 2 complements (- reg - 1) on (BytesPerWord * 8) log2 bits, or exactly a bit invert operation... */ - jumpNegativeReceiver2 = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkLiteral:forInstruction: */ - anInstruction3 = genoperandoperand(XorCwR, (BytesPerWord * 8) - 1, TempReg); - jumpNegativeReceiver = jumpNegativeReceiver2; - goto l4; - l4: /* end genHighBitIn:ofSmallIntegerOopWithSingleTagBit: */; - if (jumpNegativeReceiver == 0) { - return UnimplementedPrimitive; - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - genConvertIntegerToSmallIntegerInReg(ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNegativeReceiver, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveIdentical */ -static sqInt -genPrimitiveIdentical(void) -{ - return genPrimitiveIdenticalOrNotIf(0); -} - - /* CogObjectRepresentation>>#genPrimitiveLessOrEqual */ -static sqInt -genPrimitiveLessOrEqual(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpLessOrEqual, gJumpFPGreaterOrEqual, 1) - : genSmallIntegerComparison(JumpLessOrEqual)); -} - - /* CogObjectRepresentation>>#genPrimitiveLessThan */ -static sqInt -genPrimitiveLessThan(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpLess, gJumpFPGreater, 1) - : genSmallIntegerComparison(JumpLess)); -} - - /* CogObjectRepresentation>>#genPrimitiveMod */ -static sqInt -genPrimitiveMod(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *jumpExact; - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpSameSign; - AbstractInstruction *jumpZero; - - if (!(processorHasDivQuoRemAndMClassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genRemoveSmallIntegerTagsInScratchReg(ClassReg); - /* begin JumpZero: */ - jumpZero = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, Arg1Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - genRemoveSmallIntegerTagsInScratchReg(TempReg); - gDivRRQuoRem(ClassReg, TempReg, TempReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, ClassReg); - /* begin JumpZero: */ - jumpExact = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin XorR:R: */ - genoperandoperand(XorRR, ClassReg, Arg1Reg); - if (!(setsConditionCodesFor(lastOpcode(), JumpZero))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, Arg1Reg); - } - /* begin JumpGreaterOrEqual: */ - jumpSameSign = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin XorR:R: */ - genoperandoperand(XorRR, ClassReg, Arg1Reg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg1Reg, ClassReg); - jmpTarget(jumpSameSign, jmpTarget(jumpExact, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - genSetSmallIntegerTagsIn(ClassReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpZero, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveMultiply */ -static sqInt -genPrimitiveMultiply(void) -{ - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpOvfl; - - if (!(processorHasMultiplyAndMClassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, Arg1Reg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genShiftAwaySmallIntegerTagsInScratchReg(ClassReg); - genRemoveSmallIntegerTagsInScratchReg(Arg1Reg); - /* begin MulOverflowR:R: */ - genMulRR(backEnd, Arg1Reg, ClassReg); - /* begin JumpOverflow: */ - jumpOvfl = genConditionalBranchoperand(JumpOverflow, ((sqInt)0)); - genSetSmallIntegerTagsIn(ClassReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpOvfl, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - -/* subclasses override if they can */ - - /* CogObjectRepresentation>>#genPrimitiveNewMethod */ -static sqInt -genPrimitiveNewMethod(void) -{ - return UnimplementedPrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveNotEqual */ -static sqInt -genPrimitiveNotEqual(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpNonZero, gJumpFPNotEqual, 0) - : genSmallIntegerComparison(JumpNonZero)); -} - - /* CogObjectRepresentation>>#genPrimitiveNotIdentical */ -static sqInt -genPrimitiveNotIdentical(void) -{ - return genPrimitiveIdenticalOrNotIf(1); -} - - /* CogObjectRepresentation>>#genPrimitiveQuo */ -static sqInt -genPrimitiveQuo(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *convert; - AbstractInstruction *jumpExact; - AbstractInstruction *jumpIsSI; - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpZero; - - if (!(processorHasDivQuoRemAndMClassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genShiftAwaySmallIntegerTagsInScratchReg(ClassReg); - if (!(setsConditionCodesFor(lastOpcode(), JumpZero))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, ClassReg); - } - /* begin JumpZero: */ - jumpZero = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - genShiftAwaySmallIntegerTagsInScratchReg(TempReg); - gDivRRQuoRem(ClassReg, TempReg, TempReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, ClassReg); - /* begin JumpZero: */ - jumpExact = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin Label */ - convert = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - genConvertIntegerInRegtoSmallIntegerInReg(TempReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpExact, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - jumpIsSI = genJumpIsSmallIntegerValuescratch(TempReg, Arg1Reg); - jmpTarget(jumpIsSI, convert); - jmpTarget(jumpZero, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveSubtract */ -static sqInt -genPrimitiveSubtract(void) -{ - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpOvfl; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, Arg0Reg, TempReg); - /* begin JumpOverflow: */ - jumpOvfl = genConditionalBranchoperand(JumpOverflow, ((sqInt)0)); - genAddSmallIntegerTagsTo(TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpOvfl, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genSmallIntegerComparison: */ -static sqInt NoDbgRegParms -genSmallIntegerComparison(sqInt jumpOpcode) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt constant; - AbstractInstruction *jumpFail; - AbstractInstruction *jumpTrue; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpFail = genJumpNotSmallInteger(Arg0Reg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, ReceiverResultReg); - jumpTrue = genConditionalBranchoperand(jumpOpcode, 0); - /* begin genMoveConstant:R: */ - constant = falseObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpTrue, (shouldAnnotateObjectReference(trueObject()) - ? annotateobjRef(checkLiteralforInstruction(trueObject(), genoperandoperand(MoveCwR, trueObject(), ReceiverResultReg)), trueObject()) - : (/* begin checkQuickConstant:forInstruction: */ - trueObject(), - (anInstruction1 = genoperandoperand(MoveCqR, trueObject(), ReceiverResultReg)), - anInstruction1))); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpFail, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - -/* Stack looks like - return address */ - - /* CogObjectRepresentation>>#genSmallIntegerComparison:orDoubleComparison:invert: */ -static sqInt NoDbgRegParms -genSmallIntegerComparisonorDoubleComparisoninvert(sqInt jumpOpcode, AbstractInstruction * NoDbgRegParms (*jumpFPOpcodeGenerator)(void *), sqInt invertComparison) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt constant; - AbstractInstruction *jumpCond; - AbstractInstruction * jumpFail; - AbstractInstruction * jumpNonInt; - sqInt r; - - jumpNonInt = ((AbstractInstruction *) 0); - r = genSmallIntegerComparison(jumpOpcode); - if (r < 0) { - return r; - } -# if defined(DPFPReg0) - - /* Fall through on non-SmallInteger argument. Argument may be a Float : let us check or fail */ - jumpNonInt = genJumpImmediate(Arg0Reg); - genGetCompactClassIndexNonImmOfinto(Arg0Reg, SendNumArgsReg); - genCmpClassFloatCompactIndexR(SendNumArgsReg); - /* begin JumpNonZero: */ - jumpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genConvertSmallIntegerToIntegerInReg(ReceiverResultReg); - /* begin ConvertR:Rd: */ - genoperandoperand(ConvertRRd, ReceiverResultReg, DPFPReg0); - genGetDoubleValueOfinto(Arg0Reg, DPFPReg1); - if (invertComparison) { - - /* May need to invert for NaNs */ - /* begin CmpRd:Rd: */ - genoperandoperand(CmpRdRd, DPFPReg0, DPFPReg1); - } - else { - /* begin CmpRd:Rd: */ - genoperandoperand(CmpRdRd, DPFPReg1, DPFPReg0); - } - - /* FP jumps are a little weird */ - jumpCond = jumpFPOpcodeGenerator(0); - /* begin genMoveConstant:R: */ - constant = falseObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpCond, (shouldAnnotateObjectReference(trueObject()) - ? annotateobjRef(checkLiteralforInstruction(trueObject(), genoperandoperand(MoveCwR, trueObject(), ReceiverResultReg)), trueObject()) - : (/* begin checkQuickConstant:forInstruction: */ - trueObject(), - (anInstruction1 = genoperandoperand(MoveCqR, trueObject(), ReceiverResultReg)), - anInstruction1))); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNonInt, jmpTarget(jumpFail, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); -# endif // defined(DPFPReg0) - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#isUnannotatableConstant: */ -static sqInt NoDbgRegParms -isUnannotatableConstant(CogSimStackEntry *simStackEntry) -{ - return (((simStackEntry->type)) == SSConstant) - && ((isImmediate((simStackEntry->constant))) - || (!(shouldAnnotateObjectReference((simStackEntry->constant))))); -} - - -/* Character gets mapped to zero. See inlineCacheTagForInstance:. */ - - /* CogObjectRepresentationFor32BitSpur>>#classForInlineCacheTag: */ -static sqInt NoDbgRegParms -classForInlineCacheTag(sqInt inlineCacheTag) -{ - return classOrNilAtIndex((inlineCacheTag == 0 - ? characterTag() - : inlineCacheTag)); -} - - /* CogObjectRepresentationFor32BitSpur>>#genAddSmallIntegerTagsTo: */ -static sqInt NoDbgRegParms -genAddSmallIntegerTagsTo(sqInt aRegister) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, 1, aRegister); - return 0; -} - - -/* Set the SmallInteger tag bits when the tag bits may be filled with - garbage. - */ - - /* CogObjectRepresentationFor32BitSpur>>#genClearAndSetSmallIntegerTagsIn: */ -static sqInt NoDbgRegParms -genClearAndSetSmallIntegerTagsIn(sqInt scratchReg) -{ - return genSetSmallIntegerTagsIn(scratchReg); -} - - -/* Convert the Character in reg to a SmallInteger, assuming - the Character's value is a valid character. */ -/* self assume: objectMemory smallIntegerTag = 1 */ - - /* CogObjectRepresentationFor32BitSpur>>#genConvertCharacterToSmallIntegerInReg: */ -static void NoDbgRegParms -genConvertCharacterToSmallIntegerInReg(sqInt reg) -{ - assert(((numCharacterBits()) + 1) == (numSmallIntegerBits())); - /* begin LogicalShiftRightCq:R: */ - genoperandoperand(LogicalShiftRightCqR, 1, reg); -} - - /* CogObjectRepresentationFor32BitSpur>>#genConvertIntegerInReg:toSmallIntegerInReg: */ -static sqInt NoDbgRegParms -genConvertIntegerInRegtoSmallIntegerInReg(sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - - gLogicalShiftLeftCqRR(1, srcReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, 1, destReg); - return 0; -} - - /* CogObjectRepresentationFor32BitSpur>>#genConvertIntegerToSmallIntegerInReg: */ -static sqInt NoDbgRegParms -genConvertIntegerToSmallIntegerInReg(sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, 1, reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, 1, reg); - return 0; -} - - -/* Convert the SmallInteger in reg to a Character, assuming - the SmallInteger's value is a valid character. */ -/* self assume: objectMemory smallIntegerTag = 1 */ - - /* CogObjectRepresentationFor32BitSpur>>#genConvertSmallIntegerToCharacterInReg: */ -static void NoDbgRegParms -genConvertSmallIntegerToCharacterInReg(sqInt reg) -{ - assert(((numCharacterBits()) + 1) == (numSmallIntegerBits())); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, 1, reg); -} - - /* CogObjectRepresentationFor32BitSpur>>#genConvertSmallIntegerToIntegerInReg: */ -static sqInt NoDbgRegParms -genConvertSmallIntegerToIntegerInReg(sqInt reg) -{ - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, 1, reg); - return 0; -} - - -/* Fetch the instance's identity hash into destReg, encoded as a - SmallInteger. - */ -/* Get header word in scratchReg */ - - /* CogObjectRepresentationFor32BitSpur>>#genGetHashFieldNonImmOf:asSmallIntegerInto: */ -static sqInt NoDbgRegParms -genGetHashFieldNonImmOfasSmallIntegerInto(sqInt instReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 4, instReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - identityHashHalfWordMask(); - anInstruction1 = genoperandoperand(AndCqR, identityHashHalfWordMask(), destReg); - genConvertIntegerToSmallIntegerInReg(destReg); - return 0; -} - - -/* Fetch the instance's identity hash into destReg, unencoded. */ - - /* CogObjectRepresentationFor32BitSpur>>#genGetHashFieldNonImmOf:into: */ -static sqInt NoDbgRegParms -genGetHashFieldNonImmOfinto(sqInt instReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 4, instReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - identityHashHalfWordMask(); - anInstruction1 = genoperandoperand(AndCqR, identityHashHalfWordMask(), destReg); - return 0; -} - - -/* Extract the inline cache tag for the object in sourceReg into destReg. The - inline cache tag for a given object is the value loaded in inline caches - to distinguish - objects of different classes. In Spur this is either the tags for - immediates, (with - 1 & 3 collapsed to 1 for SmallIntegers, and 2 collapsed to 0 for - Characters), or - the receiver's classIndex. - If forEntry is true answer the entry label at which control is to enter - (cmEntryOffset). If forEntry is false, control enters at the start. - If forEntry is true, generate something like this: - Limm: - andl $0x1, rDest - j Lcmp - Lentry: - movl rSource, rDest - andl $0x3, rDest - jnz Limm - movl 0(%edx), rDest - andl $0x3fffff, rDest - Lcmp: - If forEntry is false, generate something like the following. - At least on a 2.2GHz Intel Core i7 the following is slightly faster than - the above, - 136m sends/sec vs 130m sends/sec for nfib in tinyBenchmarks - Lentry: - movl rSource, rDest - andl $0x3, rDest - jz LnotImm - andl $1, rDest - j Lcmp - LnotImm: - movl 0(%edx), rDest - andl $0x3fffff, rDest - Lcmp: - But we expect most SmallInteger arithmetic to be performed in-line and so - prefer the - version that is faster for non-immediates (because it branches for - immediates only). */ - - /* CogObjectRepresentationFor32BitSpur>>#genGetInlineCacheClassTagFrom:into:forEntry: */ -static AbstractInstruction * NoDbgRegParms -genGetInlineCacheClassTagFromintoforEntry(sqInt sourceReg, sqInt destReg, sqInt forEntry) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *entryLabel; - AbstractInstruction *immLabel; - AbstractInstruction *jumpCompare; - AbstractInstruction *jumpNotImm; - - if (forEntry) { - /* begin AlignmentNops: */ - genoperand(AlignmentNops, BytesPerWord); - /* begin Label */ - immLabel = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, 1, destReg); - /* begin Jump: */ - jumpCompare = genoperand(Jump, ((sqInt)0)); - /* begin AlignmentNops: */ - genoperand(AlignmentNops, BytesPerWord); - /* begin Label */ - entryLabel = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - gAndCqRR(tagMask(), sourceReg, destReg); - /* begin JumpNonZero: */ - genConditionalBranchoperand(JumpNonZero, ((sqInt)immLabel)); - flag("endianness"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, 0, sourceReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - classIndexMask(); - anInstruction2 = genoperandoperand(AndCqR, classIndexMask(), destReg); - jmpTarget(jumpCompare, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - else { - /* begin Label */ - entryLabel = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - gAndCqRR(tagMask(), sourceReg, destReg); - /* begin JumpZero: */ - jumpNotImm = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(AndCqR, 1, destReg); - /* begin Jump: */ - jumpCompare = genoperand(Jump, ((sqInt)0)); - flag("endianness"); - jmpTarget(jumpNotImm, checkQuickConstantforInstruction(0, genoperandoperandoperand(MoveMwrR, 0, sourceReg, destReg))); - jmpTarget(jumpCompare, checkQuickConstantforInstruction(classIndexMask(), genoperandoperand(AndCqR, classIndexMask(), destReg))); - } - return entryLabel; -} - - -/* Get the size in byte-sized slots of the object in srcReg into destReg. - srcReg may equal destReg. - destReg <- numSlots << self shiftForWord - (fmt bitAnd: 3). - Assumes the object in srcReg has a byte format, i.e. 16 to 23 or 24 to 31 */ - - /* CogObjectRepresentationFor32BitSpur>>#genGetNumBytesOf:into: */ -static sqInt NoDbgRegParms -genGetNumBytesOfinto(sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *jmp; - - genGetRawSlotSizeOfNonImminto(srcReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - numSlotsMask(); - anInstruction = genoperandoperand(CmpCqR, numSlotsMask(), destReg); - /* begin JumpLess: */ - jmp = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - genGetOverflowSlotsOfinto(srcReg, destReg); - jmpTarget(jmp, genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), destReg)); - genGetBitsofFormatByteOfinto(3, srcReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, destReg); - return 0; -} - - /* CogObjectRepresentationFor32BitSpur>>#genGetOverflowSlotsOf:into: */ -static sqInt NoDbgRegParms -genGetOverflowSlotsOfinto(sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - -BaseHeaderSize; - anInstruction = genoperandoperandoperand(MoveMwrR, -BaseHeaderSize, srcReg, destReg); - return 0; -} - - -/* Generate a test for aRegister containing an integer value in the - SmallInteger range, and a jump if so, answering the jump. - c.f. Spur32BitMemoryManager>>isIntegerValue: */ - - /* CogObjectRepresentationFor32BitSpur>>#genJumpIsSmallIntegerValue:scratch: */ -static AbstractInstruction * NoDbgRegParms -genJumpIsSmallIntegerValuescratch(sqInt aRegister, sqInt scratchReg) -{ - return (gLogicalShiftLeftCqRR(1, aRegister, scratchReg), - /* begin XorR:R: */ - genoperandoperand(XorRR, aRegister, scratchReg), - /* begin JumpGreaterOrEqual: */ - genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0))); -} - - /* CogObjectRepresentationFor32BitSpur>>#genJumpNotSmallIntegerInScratchReg: */ -static AbstractInstruction * NoDbgRegParms -genJumpNotSmallIntegerInScratchReg(sqInt aRegister) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, 1, aRegister); - /* begin JumpZero: */ - return genConditionalBranchoperand(JumpZero, ((sqInt)0)); -} - - -/* Generate a test for aRegister containing an integer value outside the - SmallInteger range, and a jump if so, answering the jump. - c.f. Spur32BitMemoryManager>>isIntegerValue: */ - - /* CogObjectRepresentationFor32BitSpur>>#genJumpNotSmallIntegerValue:scratch: */ -static AbstractInstruction * NoDbgRegParms -genJumpNotSmallIntegerValuescratch(sqInt aRegister, sqInt scratchReg) -{ - return (gArithmeticShiftRightCqRR(1, aRegister, scratchReg), - /* begin XorR:R: */ - genoperandoperand(XorRR, aRegister, scratchReg), - /* begin JumpLess: */ - genConditionalBranchoperand(JumpLess, ((sqInt)0))); -} - - /* CogObjectRepresentationFor32BitSpur>>#genJumpNotSmallInteger: */ -static AbstractInstruction * NoDbgRegParms -genJumpNotSmallInteger(sqInt aRegister) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(TstCqR, 1, aRegister); - /* begin JumpZero: */ - return genConditionalBranchoperand(JumpZero, ((sqInt)0)); -} - - /* CogObjectRepresentationFor32BitSpur>>#genJumpSmallInteger: */ -static AbstractInstruction * NoDbgRegParms -genJumpSmallInteger(sqInt aRegister) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(TstCqR, 1, aRegister); - /* begin JumpNonZero: */ - return genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -} - - -/* c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: - fixedFieldsOf:format:length: - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveAtPut */ -static sqInt -genPrimitiveAtPut(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt formatReg; - AbstractInstruction *jumpArrayOutOfBounds; - AbstractInstruction *jumpBadIndex; - AbstractInstruction *jumpBytesOutOfBounds; - AbstractInstruction *jumpBytesOutOfRange; - AbstractInstruction * jumpFixedFieldsOutOfBounds; - AbstractInstruction *jumpHasFixedFields; - AbstractInstruction *jumpImmediate; - AbstractInstruction * jumpImmutable; - AbstractInstruction *jumpIsBytes; - AbstractInstruction * jumpIsCompiledMethod; - AbstractInstruction *jumpIsContext; - AbstractInstruction *jumpIsShorts; - AbstractInstruction * jumpNonSmallIntegerValue; - AbstractInstruction *jumpNotIndexableBits; - AbstractInstruction *jumpNotIndexablePointers; - AbstractInstruction * jumpNotPointers; - AbstractInstruction *jumpShortsOutOfBounds; - AbstractInstruction *jumpShortsOutOfRange; - AbstractInstruction *jumpWordsOutOfBounds; - AbstractInstruction *jumpWordsOutOfRange; - AbstractInstruction *methodInBounds; - sqInt nSlotsOrBytesReg; - - jumpImmutable = ((AbstractInstruction *) 0); - nSlotsOrBytesReg = ClassReg; - /* begin genLoadArgAtDepth:into: */ - assert(1 < (numRegArgs())); - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - jumpImmediate = genJumpImmediate(ReceiverResultReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpBadIndex = genJumpNotSmallInteger(Arg0Reg); - genConvertSmallIntegerToIntegerInReg(Arg0Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(SubCqR, 1, Arg0Reg); -# if IMMUTABILITY - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), TempReg); - /* begin genJumpBaseHeaderImmutable: */ - immutableBitMask(); - anInstruction17 = genoperandoperand(TstCqR, immutableBitMask(), TempReg); - /* begin JumpNonZero: */ - jumpImmutable = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -# else // IMMUTABILITY - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), NoReg); -# endif // IMMUTABILITY - genGetNumSlotsOfinto(ReceiverResultReg, nSlotsOrBytesReg); - /* begin checkQuickConstant:forInstruction: */ - weakArrayFormat(); - anInstruction2 = genoperandoperand(CmpCqR, weakArrayFormat(), formatReg); - /* begin JumpAbove: */ - jumpNotPointers = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - genStoreCheckReceiverRegvalueRegscratchReginFrame(ReceiverResultReg, Arg1Reg, TempReg, 0); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction3 = genoperandoperand(CmpCqR, arrayFormat(), formatReg); - /* begin JumpBelow: */ - jumpNotIndexablePointers = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin JumpNonZero: */ - jumpHasFixedFields = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpArrayOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddCq:R: */ - anInstruction4 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg0Reg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, Arg1Reg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpHasFixedFields, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genGetClassIndexOfNonImminto(ReceiverResultReg, formatReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, formatReg); - /* begin JumpZero: */ - jumpIsContext = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin PushR: */ - genoperand(PushR, nSlotsOrBytesReg); - genGetClassObjectOfClassIndexintoscratchReg(formatReg, nSlotsOrBytesReg, TempReg); - genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, nSlotsOrBytesReg, formatReg); - /* begin PopR: */ - genoperand(PopR, nSlotsOrBytesReg); - genConvertSmallIntegerToIntegerInReg(formatReg); - /* begin checkQuickConstant:forInstruction: */ - fixedFieldsOfClassFormatMask(); - anInstruction6 = genoperandoperand(AndCqR, fixedFieldsOfClassFormatMask(), formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, nSlotsOrBytesReg); - /* begin AddCq:R: */ - anInstruction7 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), formatReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpFixedFieldsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddR:R: */ - genoperandoperand(AddRR, formatReg, Arg0Reg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, Arg1Reg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotPointers, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNonSmallIntegerValue = genJumpNotSmallInteger(Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction8 = genoperandoperand(CmpCqR, firstByteFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsBytes = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstShortFormat(); - anInstruction9 = genoperandoperand(CmpCqR, firstShortFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsShorts = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction10 = genoperandoperand(CmpCqR, firstLongFormat(), formatReg); - /* begin JumpBelow: */ - jumpNotIndexableBits = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpWordsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - if (!(setsConditionCodesFor(lastOpcode(), JumpLess))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, TempReg); - } - /* begin JumpLess: */ - jumpWordsOutOfRange = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin AddCq:R: */ - anInstruction11 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg0Reg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, TempReg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsBytes, checkQuickConstantforInstruction((((usqInt)0xFF << 1) | 1), genoperandoperand(CmpCqR, (((usqInt)0xFF << 1) | 1), Arg1Reg))); - /* begin JumpAbove: */ - jumpBytesOutOfRange = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), nSlotsOrBytesReg); - gAndCqRR(BytesPerWord - 1, formatReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, nSlotsOrBytesReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpBytesOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction12 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsCompiledMethod = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - methodInBounds = genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperand(AddCqR, BaseHeaderSize, Arg0Reg); - /* begin MoveR:Xbr:R: */ - genoperandoperandoperand(MoveRXbrR, TempReg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsShorts, checkQuickConstantforInstruction((((usqInt)0xFFFF << 1) | 1), genoperandoperand(CmpCqR, (((usqInt)0xFFFF << 1) | 1), Arg1Reg))); - /* begin JumpAbove: */ - jumpShortsOutOfRange = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (shiftForWord()) - 1, nSlotsOrBytesReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(AndCqR, (BytesPerWord / 2) - 1, formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, nSlotsOrBytesReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpShortsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperandoperand(MoveRM16r, TempReg, BaseHeaderSize, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsCompiledMethod, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - getLiteralCountOfplusOneinBytesintoscratch(ReceiverResultReg, 1, 1, nSlotsOrBytesReg, TempReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelow: */ - genConditionalBranchoperand(JumpBelow, ((sqInt)methodInBounds)); - jmpTarget(jumpIsContext, jmpTarget(jumpNotIndexableBits, jmpTarget(jumpBytesOutOfRange, jmpTarget(jumpWordsOutOfRange, jmpTarget(jumpShortsOutOfRange, jmpTarget(jumpIsCompiledMethod, jmpTarget(jumpArrayOutOfBounds, jmpTarget(jumpBytesOutOfBounds, jmpTarget(jumpShortsOutOfBounds, jmpTarget(jumpWordsOutOfBounds, jmpTarget(jumpNotIndexablePointers, jmpTarget(jumpNonSmallIntegerValue, jmpTarget(jumpFixedFieldsOutOfBounds, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))))))))))))); -# if IMMUTABILITY - jmpTarget(jumpImmutable, ((AbstractInstruction *) (((jumpIsContext->operands))[0]))); -# endif - /* begin checkQuickConstant:forInstruction: */ - anInstruction16 = genoperandoperand(AddCqR, 1, Arg0Reg); - genConvertIntegerToSmallIntegerInReg(Arg0Reg); - jmpTarget(jumpBadIndex, jmpTarget(jumpImmediate, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return 0; -} - - -/* Generate the code for primitives 61 & 165, at:put:/basicAt:put: & - integerAt:put:. If signedVersion is true - then generate signed accesses to the bits classes (a la 164 & 165). If - signedVersion is false, - generate unsigned accesses (a la 60, 61, 63 & 64). */ -/* c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: - fixedFieldsOf:format:length: - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveAtPutSigned: */ -static sqInt NoDbgRegParms -genPrimitiveAtPutSigned(sqInt signedVersion) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt formatReg; - AbstractInstruction * jumpArrayOutOfBounds; - AbstractInstruction * jumpBadIndex; - AbstractInstruction * jumpBytesOutOfBounds; - AbstractInstruction * jumpBytesOutOfRange; - AbstractInstruction * jumpFixedFieldsOutOfBounds; - AbstractInstruction * jumpHasFixedFields; - AbstractInstruction * jumpImmediate; - AbstractInstruction * jumpImmutable; - AbstractInstruction * jumpIsBytes; - AbstractInstruction * jumpIsCompiledMethod; - AbstractInstruction * jumpIsContext; - AbstractInstruction * jumpIsShorts; - AbstractInstruction * jumpNonSmallIntegerValue; - AbstractInstruction * jumpNotIndexableBits; - AbstractInstruction * jumpNotIndexablePointers; - AbstractInstruction * jumpNotPointers; - AbstractInstruction * jumpShortsOutOfBounds; - AbstractInstruction * jumpShortsOutOfRange; - AbstractInstruction * jumpWordsOutOfBounds; - AbstractInstruction * jumpWordsOutOfRange; - AbstractInstruction * methodInBounds; - sqInt nSlotsOrBytesReg; - - jumpImmutable = ((AbstractInstruction *) 0); - jumpWordsOutOfRange = ((AbstractInstruction *) 0); - nSlotsOrBytesReg = ClassReg; - /* begin genLoadArgAtDepth:into: */ - assert(1 < (numRegArgs())); - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - jumpImmediate = genJumpImmediate(ReceiverResultReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpBadIndex = genJumpNotSmallInteger(Arg0Reg); - genConvertSmallIntegerToIntegerInReg(Arg0Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(SubCqR, 1, Arg0Reg); -# if IMMUTABILITY - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), TempReg); - /* begin genJumpBaseHeaderImmutable: */ - immutableBitMask(); - anInstruction21 = genoperandoperand(TstCqR, immutableBitMask(), TempReg); - /* begin JumpNonZero: */ - jumpImmutable = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -# else // IMMUTABILITY - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), NoReg); -# endif // IMMUTABILITY - genGetNumSlotsOfinto(ReceiverResultReg, nSlotsOrBytesReg); - /* begin checkQuickConstant:forInstruction: */ - weakArrayFormat(); - anInstruction6 = genoperandoperand(CmpCqR, weakArrayFormat(), formatReg); - /* begin JumpAbove: */ - jumpNotPointers = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - genStoreCheckReceiverRegvalueRegscratchReginFrame(ReceiverResultReg, Arg1Reg, TempReg, 0); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction7 = genoperandoperand(CmpCqR, arrayFormat(), formatReg); - /* begin JumpBelow: */ - jumpNotIndexablePointers = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin JumpNonZero: */ - jumpHasFixedFields = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpArrayOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddCq:R: */ - anInstruction8 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg0Reg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, Arg1Reg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpHasFixedFields, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genGetClassIndexOfNonImminto(ReceiverResultReg, formatReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, formatReg); - /* begin JumpZero: */ - jumpIsContext = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin PushR: */ - genoperand(PushR, nSlotsOrBytesReg); - genGetClassObjectOfClassIndexintoscratchReg(formatReg, nSlotsOrBytesReg, TempReg); - genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, nSlotsOrBytesReg, formatReg); - /* begin PopR: */ - genoperand(PopR, nSlotsOrBytesReg); - genConvertSmallIntegerToIntegerInReg(formatReg); - /* begin checkQuickConstant:forInstruction: */ - fixedFieldsOfClassFormatMask(); - anInstruction10 = genoperandoperand(AndCqR, fixedFieldsOfClassFormatMask(), formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, nSlotsOrBytesReg); - /* begin AddCq:R: */ - anInstruction11 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), formatReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpFixedFieldsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddR:R: */ - genoperandoperand(AddRR, formatReg, Arg0Reg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, Arg1Reg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotPointers, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNonSmallIntegerValue = genJumpNotSmallInteger(Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction12 = genoperandoperand(CmpCqR, firstByteFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsBytes = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstShortFormat(); - anInstruction13 = genoperandoperand(CmpCqR, firstShortFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsShorts = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction14 = genoperandoperand(CmpCqR, firstLongFormat(), formatReg); - /* begin JumpBelow: */ - jumpNotIndexableBits = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpWordsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - if (!signedVersion) { - if (!(setsConditionCodesFor(lastOpcode(), JumpLess))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, TempReg); - } - /* begin JumpLess: */ - jumpWordsOutOfRange = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - } - /* begin AddCq:R: */ - anInstruction15 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg0Reg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, TempReg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - if (signedVersion) { - jmpTarget(jumpIsBytes, gArithmeticShiftRightCqRR(8, Arg1Reg, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AddCqR, 1, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(CmpCqR, 1, TempReg); - } - else { - jmpTarget(jumpIsBytes, checkQuickConstantforInstruction((((usqInt)0xFF << 1) | 1), genoperandoperand(CmpCqR, (((usqInt)0xFF << 1) | 1), Arg1Reg))); - } - /* begin JumpAbove: */ - jumpBytesOutOfRange = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), nSlotsOrBytesReg); - gAndCqRR(BytesPerWord - 1, formatReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, nSlotsOrBytesReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpBytesOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction16 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsCompiledMethod = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - methodInBounds = genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperand(AddCqR, BaseHeaderSize, Arg0Reg); - /* begin MoveR:Xbr:R: */ - genoperandoperandoperand(MoveRXbrR, TempReg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - if (signedVersion) { - jmpTarget(jumpIsShorts, gArithmeticShiftRightCqRR(16, Arg1Reg, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(AddCqR, 1, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, 1, TempReg); - } - else { - jmpTarget(jumpIsShorts, checkQuickConstantforInstruction((((usqInt)0xFFFF << 1) | 1), genoperandoperand(CmpCqR, (((usqInt)0xFFFF << 1) | 1), Arg1Reg))); - } - /* begin JumpAbove: */ - jumpShortsOutOfRange = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (shiftForWord()) - 1, nSlotsOrBytesReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction18 = genoperandoperand(AndCqR, (BytesPerWord / 2) - 1, formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, nSlotsOrBytesReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpShortsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperandoperand(MoveRM16r, TempReg, BaseHeaderSize, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsCompiledMethod, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - getLiteralCountOfplusOneinBytesintoscratch(ReceiverResultReg, 1, 1, nSlotsOrBytesReg, TempReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, nSlotsOrBytesReg); - /* begin JumpBelow: */ - genConditionalBranchoperand(JumpBelow, ((sqInt)methodInBounds)); - jmpTarget(jumpIsContext, jmpTarget(jumpNotIndexableBits, jmpTarget(jumpBytesOutOfRange, jmpTarget(jumpShortsOutOfRange, jmpTarget(jumpIsCompiledMethod, jmpTarget(jumpArrayOutOfBounds, jmpTarget(jumpBytesOutOfBounds, jmpTarget(jumpShortsOutOfBounds, jmpTarget(jumpWordsOutOfBounds, jmpTarget(jumpNotIndexablePointers, jmpTarget(jumpNonSmallIntegerValue, jmpTarget(jumpFixedFieldsOutOfBounds, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))))))))))); - if (!signedVersion) { - jmpTarget(jumpWordsOutOfRange, ((AbstractInstruction *) (((jumpIsContext->operands))[0]))); - } -# if IMMUTABILITY - jmpTarget(jumpImmutable, ((AbstractInstruction *) (((jumpIsContext->operands))[0]))); -# endif - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperand(AddCqR, 1, Arg0Reg); - genConvertIntegerToSmallIntegerInReg(Arg0Reg); - jmpTarget(jumpBadIndex, jmpTarget(jumpImmediate, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return 0; -} - - -/* Generate the code for primitives 60 & 164, at:/basicAt: & integerAt:. If - signedVersion is true - then generate signed accesses to the bits classes (a la 164 & 165). If - signedVersion is false, - generate unsigned accesses (a la 60, 61, 63 & 64). */ -/* c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: - fixedFieldsOf:format:length: - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveAtSigned: */ -static sqInt NoDbgRegParms -genPrimitiveAtSigned(sqInt signedVersion) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - AbstractInstruction * convertToIntAndReturn; - AbstractInstruction * first; - AbstractInstruction * first1; - sqInt formatReg; - AbstractInstruction * jumpArrayOutOfBounds; - AbstractInstruction * jumpBadIndex; - AbstractInstruction * jumpBytesOutOfBounds; - AbstractInstruction * jumpFixedFieldsOutOfBounds; - AbstractInstruction * jumpHasFixedFields; - AbstractInstruction * jumpImmediate; - AbstractInstruction * jumpIsArray; - AbstractInstruction * jumpIsBytes; - AbstractInstruction * jumpIsContext; - AbstractInstruction * jumpIsMethod; - AbstractInstruction * jumpIsShorts; - AbstractInstruction * jumpIsWords; - AbstractInstruction * jumpNotIndexable; - AbstractInstruction * jumpShortsOutOfBounds; - AbstractInstruction * jumpWordsOutOfBounds; - AbstractInstruction * jumpWordTooBig; - AbstractInstruction * methodInBounds; - sqInt nSlotsOrBytesReg; - - nSlotsOrBytesReg = ClassReg; - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - jumpImmediate = genJumpImmediate(ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, Arg1Reg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpBadIndex = genJumpNotSmallInteger(Arg0Reg); - genConvertSmallIntegerToIntegerInReg(Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, 1, Arg1Reg); - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), TempReg); - genGetNumSlotsOfinto(ReceiverResultReg, nSlotsOrBytesReg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction1 = genoperandoperand(CmpCqR, firstByteFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsBytes = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction2 = genoperandoperand(CmpCqR, arrayFormat(), formatReg); - /* begin JumpZero: */ - jumpIsArray = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin JumpBelow: */ - jumpNotIndexable = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - weakArrayFormat(); - anInstruction3 = genoperandoperand(CmpCqR, weakArrayFormat(), formatReg); - /* begin JumpBelowOrEqual: */ - jumpHasFixedFields = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstShortFormat(); - anInstruction4 = genoperandoperand(CmpCqR, firstShortFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsShorts = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction5 = genoperandoperand(CmpCqR, firstLongFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsWords = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - jmpTarget(jumpNotIndexable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin Jump: */ - jumpNotIndexable = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpIsArray, (assert(!((Arg1Reg == SPReg))), - genoperandoperand(CmpRR, Arg1Reg, nSlotsOrBytesReg))); - /* begin JumpBelowOrEqual: */ - jumpArrayOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddCq:R: */ - anInstruction6 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg1Reg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, Arg1Reg, ReceiverResultReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsBytes, genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), nSlotsOrBytesReg)); - gAndCqRR(BytesPerWord - 1, formatReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, nSlotsOrBytesReg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpBytesOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction7 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsMethod = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(AddCqR, BaseHeaderSize, Arg1Reg); - methodInBounds = anInstruction8; - if (signedVersion) { - /* begin MoveXbr:R:R: */ - genoperandoperandoperand(MoveXbrRR, Arg1Reg, ReceiverResultReg, ReceiverResultReg); - } - else { - - /* formatReg already contains a value <= 16r1f, so no need to zero it */ - /* begin MoveXbr:R:R: */ - genoperandoperandoperand(MoveXbrRR, Arg1Reg, ReceiverResultReg, formatReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, formatReg, ReceiverResultReg); - } - if (signedVersion) { - /* begin SignExtend8R:R: */ - /* begin LogicalShiftLeftCq:R: */ - first = genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 8, ReceiverResultReg); - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, (BytesPerWord * 8) - 8, ReceiverResultReg); - goto l8; - l8: /* end SignExtend8R:R: */; - } - /* begin Label */ - convertToIntAndReturn = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - genConvertIntegerToSmallIntegerInReg(ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsShorts, gLogicalShiftLeftCqR((shiftForWord()) - 1, nSlotsOrBytesReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(AndCqR, 1, formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, nSlotsOrBytesReg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpShortsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg1Reg, ReceiverResultReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg1Reg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveM16rR, BaseHeaderSize, ReceiverResultReg, ReceiverResultReg); - if (signedVersion) { - /* begin SignExtend16R:R: */ - /* begin LogicalShiftLeftCq:R: */ - first1 = genoperandoperand(LogicalShiftLeftCqR, (BytesPerWord * 8) - 16, ReceiverResultReg); - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, (BytesPerWord * 8) - 16, ReceiverResultReg); - goto l13; - l13: /* end SignExtend16R:R: */; - } - /* begin Jump: */ - genoperand(Jump, ((sqInt)convertToIntAndReturn)); - jmpTarget(jumpIsWords, (assert(!((Arg1Reg == SPReg))), - genoperandoperand(CmpRR, Arg1Reg, nSlotsOrBytesReg))); - /* begin JumpBelowOrEqual: */ - jumpWordsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddCq:R: */ - anInstruction11 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg1Reg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, Arg1Reg, ReceiverResultReg, TempReg); - jumpWordTooBig = jumpNotSmallIntegerUnsignedValueInRegister(TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)convertToIntAndReturn)); - jmpTarget(jumpHasFixedFields, checkQuickConstantforInstruction(classIndexMask(), genoperandoperand(AndCqR, classIndexMask(), TempReg))); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, formatReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, TempReg); - /* begin JumpZero: */ - jumpIsContext = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin PushR: */ - genoperand(PushR, nSlotsOrBytesReg); - genGetClassObjectOfClassIndexintoscratchReg(formatReg, nSlotsOrBytesReg, TempReg); - genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, nSlotsOrBytesReg, formatReg); - /* begin PopR: */ - genoperand(PopR, nSlotsOrBytesReg); - genConvertSmallIntegerToIntegerInReg(formatReg); - /* begin checkQuickConstant:forInstruction: */ - fixedFieldsOfClassFormatMask(); - anInstruction13 = genoperandoperand(AndCqR, fixedFieldsOfClassFormatMask(), formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, nSlotsOrBytesReg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, nSlotsOrBytesReg); - /* begin JumpBelowOrEqual: */ - jumpFixedFieldsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddR:R: */ - genoperandoperand(AddRR, formatReg, Arg1Reg); - /* begin AddCq:R: */ - anInstruction14 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg1Reg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, Arg1Reg, ReceiverResultReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsMethod, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - getLiteralCountOfplusOneinBytesintoscratch(ReceiverResultReg, 1, 1, nSlotsOrBytesReg, TempReg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, nSlotsOrBytesReg); - /* begin JumpBelow: */ - genConditionalBranchoperand(JumpBelow, ((sqInt)methodInBounds)); - jmpTarget(jumpWordTooBig, jmpTarget(jumpFixedFieldsOutOfBounds, jmpTarget(jumpArrayOutOfBounds, jmpTarget(jumpBytesOutOfBounds, jmpTarget(jumpShortsOutOfBounds, jmpTarget(jumpWordsOutOfBounds, jmpTarget(jumpNotIndexable, jmpTarget(jumpIsContext, jmpTarget(jumpBadIndex, jmpTarget(jumpImmediate, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))))))))); - return 0; -} - - -/* Arguably we should fail for immediates, but so far no one has complained, - so... - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveIdentityHash */ -static sqInt -genPrimitiveIdentityHash(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction * inst; - AbstractInstruction *jumpImm; - AbstractInstruction *jumpNotSet; - AbstractInstruction *jumpSI; - AbstractInstruction * ret; - - jumpImm = genJumpImmediate(ReceiverResultReg); - genGetHashFieldNonImmOfasSmallIntegerInto(ReceiverResultReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, ConstZero, TempReg); - /* begin JumpZero: */ - jumpNotSet = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - ret = genoperand(RetN, 0); - } - else { - /* begin RetN: */ - ret = genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpImm, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - jumpSI = genJumpSmallInteger(ReceiverResultReg); - jmpTarget(jumpSI, ret); - genConvertCharacterToSmallIntegerInReg(ReceiverResultReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)ret)); - jmpTarget(jumpNotSet, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (!(primitiveIndex == 75)) { - return 0; - } - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceNewHashTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin PopR: */ - genoperand(PopR, LinkReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - return UnfailingPrimitive; -} - - -/* :Assume the receiuver is never a SmallInteger. One would use ^self for - that. - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveImmediateAsInteger */ -static sqInt -genPrimitiveImmediateAsInteger(void) -{ - genConvertCharacterToSmallIntegerInReg(ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - return UnfailingPrimitive; -} - - -/* Implement primitiveNew for convenient cases: - - the receiver has a hash - - the receiver is fixed size (excluding ephemerons to save instructions & - miniscule time) - - single word header/num slots < numSlotsMask - - the result fits in eden (actually below scavengeThreshold) - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveNew */ -static sqInt -genPrimitiveNew(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt byteSizeReg; - AbstractInstruction *fillLoop; - sqInt fillReg; - sqInt halfHeaderReg; - sqInt instSpecReg; - AbstractInstruction *jumpHasSlots; - AbstractInstruction *jumpNoSpace; - AbstractInstruction *jumpTooBig; - AbstractInstruction *jumpUnhashed; - AbstractInstruction *jumpVariableOrEphemeron; - sqInt quickConstant; - sqInt quickConstant1; - AbstractInstruction *skip; - - if (methodOrBlockNumArgs != 0) { - return UnimplementedPrimitive; - } - - /* inst spec will hold class's instance specification, then byte size and finally end of new object. */ - halfHeaderReg = (fillReg = SendNumArgsReg); - - /* get freeStart as early as possible so as not to wait later... */ - instSpecReg = (byteSizeReg = ClassReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction = genoperandoperand(MoveAwR, freeStartAddress(), Arg1Reg); - genGetHashFieldNonImmOfinto(ReceiverResultReg, halfHeaderReg); - /* begin JumpZero: */ - jumpUnhashed = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, ReceiverResultReg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, instSpecReg); - /* begin LogicalShiftRightCq:R: */ - quickConstant = fixedFieldsFieldWidth(); - genoperandoperand(LogicalShiftRightCqR, quickConstant, TempReg); - /* begin checkQuickConstant:forInstruction: */ - formatMask(); - anInstruction1 = genoperandoperand(AndCqR, formatMask(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - fixedFieldsOfClassFormatMask(); - anInstruction2 = genoperandoperand(AndCqR, fixedFieldsOfClassFormatMask(), instSpecReg); - /* begin checkQuickConstant:forInstruction: */ - nonIndexablePointerFormat(); - anInstruction3 = genoperandoperand(CmpCqR, nonIndexablePointerFormat(), TempReg); - /* begin JumpAbove: */ - jumpVariableOrEphemeron = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - numSlotsMask(); - anInstruction4 = genoperandoperand(CmpCqR, numSlotsMask(), instSpecReg); - /* begin JumpAboveOrEqual: */ - jumpTooBig = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - quickConstant1 = formatShift(); - genoperandoperand(LogicalShiftLeftCqR, quickConstant1, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, halfHeaderReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(MoveRMwr, halfHeaderReg, 0, Arg1Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instSpecReg, halfHeaderReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(CmpCqR, 0, byteSizeReg); - /* begin JumpNonZero: */ - jumpHasSlots = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(MoveCqR, BaseHeaderSize * 2, byteSizeReg); - /* begin Jump: */ - skip = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpHasSlots, genoperandoperand(MoveRR, byteSizeReg, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(AndCqR, 1, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, byteSizeReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(AddCqR, BaseHeaderSize / BytesPerWord, byteSizeReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), byteSizeReg); - jmpTarget(skip, genoperandoperand(LogicalShiftLeftCqR, numSlotsHalfShift(), halfHeaderReg)); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg1Reg, byteSizeReg); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction10 = genoperandoperand(CmpCqR, getScavengeThreshold(), byteSizeReg); - /* begin JumpAboveOrEqual: */ - jumpNoSpace = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction11 = genoperandoperand(MoveRAw, byteSizeReg, freeStartAddress()); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveRMwr, halfHeaderReg, 4, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperandoperand(LoadEffectiveAddressMwrR, BaseHeaderSize, ReceiverResultReg, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - nilObject(); - anInstruction14 = genoperandoperand(MoveCqR, nilObject(), fillReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperandoperand(MoveRMwr, fillReg, 0, Arg1Reg); - fillLoop = anInstruction15; - /* begin checkQuickConstant:forInstruction: */ - anInstruction16 = genoperandoperandoperand(MoveRMwr, fillReg, 4, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperand(AddCqR, 8, Arg1Reg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, byteSizeReg); - /* begin JumpAbove: */ - genConditionalBranchoperand(JumpAbove, ((sqInt)fillLoop)); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpUnhashed, jmpTarget(jumpVariableOrEphemeron, jmpTarget(jumpTooBig, jmpTarget(jumpNoSpace, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))); - return 0; -} - - -/* Implement primitiveNewWithArg for convenient cases: - - the receiver has a hash - - the receiver is variable and not compiled method - - single word header/num slots < numSlotsMask - - the result fits in eden - See superclass method for dynamic frequencies of formats. - For the moment we implement only arrayFormat, firstByteFormat & - firstLongFormat - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveNewWithArg */ -static sqInt -genPrimitiveNewWithArg(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction22; - AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt byteSizeReg; - AbstractInstruction *fillLoop; - sqInt fillReg; - sqInt halfHeaderReg; - sqInt instSpecReg; - AbstractInstruction *jumpArrayFormat; - AbstractInstruction *jumpArrayTooBig; - AbstractInstruction *jumpByteFormat; - AbstractInstruction *jumpBytePrepDone; - AbstractInstruction *jumpByteTooBig; - AbstractInstruction *jumpFailCuzFixed; - AbstractInstruction *jumpHasSlots; - AbstractInstruction *jumpLongPrepDone; - AbstractInstruction *jumpLongTooBig; - AbstractInstruction *jumpNElementsNonInt; - AbstractInstruction *jumpNoSpace; - AbstractInstruction *jumpUnhashed; - sqInt maxSlots; - sqInt quickConstant; - sqInt quickConstant1; - sqInt quickConstant2; - AbstractInstruction *skip; - - if (methodOrBlockNumArgs != 1) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - - /* inst spec will hold class's instance specification and then byte size and finally numSlots half of header */ - halfHeaderReg = (fillReg = SendNumArgsReg); - - /* The max slots we'll allocate here are those for a single header */ - instSpecReg = (byteSizeReg = ClassReg); - - /* get freeStart as early as possible so as not to wait later... */ - maxSlots = (numSlotsMask()) - 1; - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction = genoperandoperand(MoveAwR, freeStartAddress(), Arg1Reg); - genGetHashFieldNonImmOfinto(ReceiverResultReg, halfHeaderReg); - /* begin JumpZero: */ - jumpUnhashed = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - - /* get class's format inst var for inst spec (format field) */ - jumpNElementsNonInt = genJumpNotSmallInteger(Arg0Reg); - genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, ReceiverResultReg, instSpecReg); - /* begin LogicalShiftRightCq:R: */ - quickConstant = (fixedFieldsFieldWidth()) + 1 /* numSmallIntegerTagBits */; - genoperandoperand(LogicalShiftRightCqR, quickConstant, instSpecReg); - /* begin checkQuickConstant:forInstruction: */ - formatMask(); - anInstruction1 = genoperandoperand(AndCqR, formatMask(), instSpecReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instSpecReg, TempReg); - /* begin LogicalShiftLeftCq:R: */ - quickConstant1 = formatShift(); - genoperandoperand(LogicalShiftLeftCqR, quickConstant1, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, halfHeaderReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction2 = genoperandoperand(CmpCqR, arrayFormat(), instSpecReg); - /* begin JumpZero: */ - jumpArrayFormat = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction3 = genoperandoperand(CmpCqR, firstByteFormat(), instSpecReg); - /* begin JumpZero: */ - jumpByteFormat = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction4 = genoperandoperand(CmpCqR, firstLongFormat(), instSpecReg); - /* begin JumpNonZero: */ - jumpFailCuzFixed = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)maxSlots << 1) | 1); - anInstruction5 = genoperandoperand(CmpCqR, (((usqInt)maxSlots << 1) | 1), Arg0Reg); - /* begin JumpAbove: */ - jumpLongTooBig = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, instSpecReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperand(PushCq, 0); - /* begin Jump: */ - jumpLongPrepDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpByteFormat, checkQuickConstantforInstruction((((usqInt)(maxSlots * BytesPerWord) << 1) | 1), genoperandoperand(CmpCqR, (((usqInt)(maxSlots * BytesPerWord) << 1) | 1), Arg0Reg))); - /* begin JumpAbove: */ - jumpByteTooBig = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, instSpecReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(MoveCqR, BytesPerWord, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, instSpecReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(AndCqR, BytesPerWord - 1, TempReg); - /* begin LogicalShiftLeftCq:R: */ - quickConstant2 = formatShift(); - genoperandoperand(LogicalShiftLeftCqR, quickConstant2, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, halfHeaderReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(AddCqR, BytesPerWord - 1, instSpecReg); - /* begin LogicalShiftRightCq:R: */ - genoperandoperand(LogicalShiftRightCqR, shiftForWord(), instSpecReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperand(PushCq, 0); - /* begin Jump: */ - jumpBytePrepDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpArrayFormat, checkQuickConstantforInstruction((((usqInt)maxSlots << 1) | 1), genoperandoperand(CmpCqR, (((usqInt)maxSlots << 1) | 1), Arg0Reg))); - /* begin JumpAbove: */ - jumpArrayTooBig = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, instSpecReg); - /* begin checkLiteral:forInstruction: */ - nilObject(); - anInstruction11 = genoperand(PushCw, nilObject()); - jmpTarget(jumpBytePrepDone, jmpTarget(jumpLongPrepDone, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveRMwr, halfHeaderReg, 0, Arg1Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instSpecReg, halfHeaderReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperand(CmpCqR, 0, byteSizeReg); - /* begin JumpNonZero: */ - jumpHasSlots = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(MoveCqR, BaseHeaderSize * 2, byteSizeReg); - /* begin Jump: */ - skip = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpHasSlots, genoperandoperand(MoveRR, byteSizeReg, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperand(AndCqR, 1, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, byteSizeReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction16 = genoperandoperand(AddCqR, BaseHeaderSize / BytesPerWord, byteSizeReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), byteSizeReg); - jmpTarget(skip, genoperandoperand(LogicalShiftLeftCqR, numSlotsHalfShift(), halfHeaderReg)); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg1Reg, byteSizeReg); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction17 = genoperandoperand(CmpCqR, getScavengeThreshold(), byteSizeReg); - /* begin JumpAboveOrEqual: */ - jumpNoSpace = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction18 = genoperandoperand(MoveRAw, byteSizeReg, freeStartAddress()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperandoperand(MoveRMwr, halfHeaderReg, 4, ReceiverResultReg); - /* begin PopR: */ - genoperand(PopR, fillReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperandoperand(LoadEffectiveAddressMwrR, BaseHeaderSize, ReceiverResultReg, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperandoperand(MoveRMwr, fillReg, 0, Arg1Reg); - fillLoop = anInstruction21; - /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperandoperand(MoveRMwr, fillReg, 4, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction23 = genoperandoperand(AddCqR, 8, Arg1Reg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, byteSizeReg); - /* begin JumpAbove: */ - genConditionalBranchoperand(JumpAbove, ((sqInt)fillLoop)); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNoSpace, genoperand(PopR, TempReg)); - jmpTarget(jumpUnhashed, jmpTarget(jumpFailCuzFixed, jmpTarget(jumpArrayTooBig, jmpTarget(jumpByteTooBig, jmpTarget(jumpLongTooBig, jmpTarget(jumpNElementsNonInt, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))))); - return 0; -} - - -/* Implement primitiveShallowCopy/primitiveClone for convenient cases: - - the receiver is not a context - - the receiver is not a compiled method - - the result fits in eden (actually below scavengeThreshold) */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveShallowCopy */ -static sqInt -genPrimitiveShallowCopy(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction22; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - AbstractInstruction *continuance; - AbstractInstruction *copyLoop; - sqInt formatReg; - AbstractInstruction * jumpEmpty; - AbstractInstruction *jumpImmediate; - AbstractInstruction *jumpIsMethod; - AbstractInstruction *jumpNoSpace; - AbstractInstruction *jumpTooBig; - AbstractInstruction *jumpVariable; - sqInt ptrReg; - sqInt quickConstant; - sqInt quickConstant1; - sqInt resultReg; - sqInt slotsReg; - - jumpImmediate = genJumpImmediate(ReceiverResultReg); - resultReg = Arg0Reg; - - /* get freeStart as early as possible so as not to wait later... */ - slotsReg = Arg1Reg; - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction = genoperandoperand(MoveAwR, freeStartAddress(), resultReg); - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (ptrReg = (formatReg = SendNumArgsReg)), NoReg); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction1 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsMethod = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - indexablePointersFormat(); - anInstruction2 = genoperandoperand(CmpCqR, indexablePointersFormat(), formatReg); - /* begin JumpZero: */ - jumpVariable = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin Label */ - continuance = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - genGetRawSlotSizeOfNonImminto(ReceiverResultReg, slotsReg); - /* begin checkQuickConstant:forInstruction: */ - numSlotsMask(); - anInstruction3 = genoperandoperand(CmpCqR, numSlotsMask(), slotsReg); - /* begin JumpZero: */ - jumpTooBig = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, 0, slotsReg); - /* begin JumpZero: */ - jumpEmpty = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, slotsReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(AndCqR, 1, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, TempReg, slotsReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(AddCqR, BaseHeaderSize / BytesPerWord, slotsReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), slotsReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, resultReg, slotsReg); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction7 = genoperandoperand(CmpCqR, getScavengeThreshold(), slotsReg); - /* begin JumpAboveOrEqual: */ - jumpNoSpace = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, resultReg, ptrReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction8 = genoperandoperand(MoveRAw, slotsReg, freeStartAddress()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(SubCqR, BytesPerWord * 2, slotsReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveMwrR, 0, ReceiverResultReg, TempReg); - /* begin AndCq:R: */ - quickConstant = (((sqInt)((usqInt)((formatMask())) << (formatShift())))) + (classIndexMask()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperand(AndCqR, quickConstant, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveRMwr, TempReg, 0, resultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperandoperand(MoveMwrR, BytesPerWord, ReceiverResultReg, TempReg); - /* begin AndCq:R: */ - quickConstant1 = ((sqInt)((usqInt)((numSlotsMask())) << (numSlotsHalfShift()))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(AndCqR, quickConstant1, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperandoperand(MoveRMwr, TempReg, BytesPerWord, resultReg); - /* begin Label */ - copyLoop = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - /* begin checkQuickConstant:forInstruction: */ - anInstruction16 = genoperandoperand(AddCqR, BytesPerWord * 2, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperand(AddCqR, BytesPerWord * 2, ptrReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction18 = genoperandoperandoperand(MoveMwrR, 0, ReceiverResultReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperandoperand(MoveRMwr, TempReg, 0, ptrReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperandoperand(MoveMwrR, BytesPerWord, ReceiverResultReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperandoperand(MoveRMwr, TempReg, BytesPerWord, ptrReg); - /* begin CmpR:R: */ - assert(!((ptrReg == SPReg))); - genoperandoperand(CmpRR, ptrReg, slotsReg); - /* begin JumpAbove: */ - genConditionalBranchoperand(JumpAbove, ((sqInt)copyLoop)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, resultReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpVariable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genGetClassIndexOfNonImminto(ReceiverResultReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, ClassReg); - /* begin JumpNonZero: */ - genConditionalBranchoperand(JumpNonZero, ((sqInt)continuance)); - jmpTarget(jumpImmediate, jmpTarget(jumpNoSpace, jmpTarget(jumpIsMethod, jmpTarget(jumpTooBig, jmpTarget(jumpEmpty, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))))); - return 0; -} - - -/* c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: - fixedFieldsOf:format:length: - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveStringAt */ -static sqInt -genPrimitiveStringAt(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - AbstractInstruction *done; - sqInt formatReg; - AbstractInstruction *jumpBadIndex; - AbstractInstruction *jumpBytesOutOfBounds; - AbstractInstruction *jumpIsBytes; - AbstractInstruction *jumpIsShorts; - AbstractInstruction *jumpNotIndexable; - AbstractInstruction *jumpShortsOutOfBounds; - AbstractInstruction *jumpWordsDone; - AbstractInstruction *jumpWordsOutOfBounds; - AbstractInstruction *jumpWordTooBig; - - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, Arg1Reg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpBadIndex = genJumpNotSmallInteger(Arg0Reg); - genConvertSmallIntegerToIntegerInReg(Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(SubCqR, 1, Arg1Reg); - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), NoReg); - genGetNumSlotsOfinto(ReceiverResultReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction2 = genoperandoperand(CmpCqR, firstByteFormat(), formatReg); - /* begin JumpGreaterOrEqual: */ - jumpIsBytes = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstShortFormat(); - anInstruction3 = genoperandoperand(CmpCqR, firstShortFormat(), formatReg); - /* begin JumpGreaterOrEqual: */ - jumpIsShorts = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction4 = genoperandoperand(CmpCqR, firstLongFormat(), formatReg); - /* begin JumpLess: */ - jumpNotIndexable = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, ClassReg); - /* begin JumpBelowOrEqual: */ - jumpWordsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddCq:R: */ - anInstruction5 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg1Reg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, Arg1Reg, ReceiverResultReg, TempReg); - jumpWordTooBig = jumpNotCharacterUnsignedValueInRegister(TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - /* begin Jump: */ - jumpWordsDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpIsBytes, genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), ClassReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(AndCqR, BytesPerWord - 1, formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, ClassReg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, ClassReg); - /* begin JumpBelowOrEqual: */ - jumpBytesOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(AddCqR, BaseHeaderSize, Arg1Reg); - /* begin MoveXbr:R:R: */ - genoperandoperandoperand(MoveXbrRR, Arg1Reg, ReceiverResultReg, ReceiverResultReg); - /* begin AndCq:R: */ - anInstruction = genoperandoperand(AndCqR, 0xFF, ReceiverResultReg); - jmpTarget(jumpWordsDone, (done = genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - genConvertIntegerToCharacterInReg(ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsShorts, gLogicalShiftLeftCqR((shiftForWord()) - 1, ClassReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(AndCqR, (BytesPerWord / 1) - 1, formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, ClassReg); - /* begin CmpR:R: */ - assert(!((Arg1Reg == SPReg))); - genoperandoperand(CmpRR, Arg1Reg, ClassReg); - /* begin JumpBelowOrEqual: */ - jumpShortsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg1Reg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperandoperand(MoveM16rR, BaseHeaderSize, ReceiverResultReg, ReceiverResultReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)done)); - jmpTarget(jumpWordTooBig, jmpTarget(jumpBytesOutOfBounds, jmpTarget(jumpShortsOutOfBounds, jmpTarget(jumpWordsOutOfBounds, jmpTarget(jumpNotIndexable, jmpTarget(jumpBadIndex, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))))); - return CompletePrimitive; -} - - -/* c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: - fixedFieldsOf:format:length: - */ - - /* CogObjectRepresentationFor32BitSpur>>#genPrimitiveStringAtPut */ -static sqInt -genPrimitiveStringAtPut(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt formatReg; - AbstractInstruction *jumpBadArg; - AbstractInstruction *jumpBadIndex; - AbstractInstruction *jumpBytesOutOfBounds; - AbstractInstruction *jumpBytesOutOfRange; - AbstractInstruction * jumpImmutable; - AbstractInstruction *jumpIsBytes; - AbstractInstruction * jumpIsCompiledMethod; - AbstractInstruction *jumpIsShorts; - AbstractInstruction * jumpNotString; - AbstractInstruction *jumpShortsOutOfBounds; - AbstractInstruction *jumpShortsOutOfRange; - AbstractInstruction *jumpWordsOutOfBounds; - AbstractInstruction *jumpWordsOutOfRange; - - jumpImmutable = ((AbstractInstruction *) 0); - /* begin genLoadArgAtDepth:into: */ - assert(1 < (numRegArgs())); - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - jumpBadIndex = genJumpNotSmallInteger(Arg0Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - jumpBadArg = genJumpNotCharacterInScratchReg(TempReg); - genConvertSmallIntegerToIntegerInReg(Arg0Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, 1, Arg0Reg); -# if IMMUTABILITY - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), TempReg); - /* begin genJumpBaseHeaderImmutable: */ - immutableBitMask(); - anInstruction12 = genoperandoperand(TstCqR, immutableBitMask(), TempReg); - /* begin JumpNonZero: */ - jumpImmutable = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -# else // IMMUTABILITY - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, (formatReg = SendNumArgsReg), NoReg); -# endif // IMMUTABILITY - genGetNumSlotsOfinto(ReceiverResultReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction1 = genoperandoperand(CmpCqR, firstLongFormat(), formatReg); - /* begin JumpBelow: */ - jumpNotString = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction2 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsCompiledMethod = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction3 = genoperandoperand(CmpCqR, firstByteFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsBytes = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstShortFormat(); - anInstruction4 = genoperandoperand(CmpCqR, firstShortFormat(), formatReg); - /* begin JumpAboveOrEqual: */ - jumpIsShorts = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(CmpCqR, 0, Arg1Reg); - /* begin JumpLess: */ - jumpWordsOutOfRange = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, ClassReg); - /* begin JumpBelowOrEqual: */ - jumpWordsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertCharacterToCodeInReg(TempReg); - /* begin AddCq:R: */ - anInstruction6 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg0Reg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, TempReg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsShorts, gCmpCqR(characterObjectOf(0xFFFF), Arg1Reg)); - /* begin JumpAbove: */ - jumpShortsOutOfRange = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (shiftForWord()) - 1, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(AndCqR, (BytesPerWord / 2) - 1, formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, ClassReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, ClassReg); - /* begin JumpBelowOrEqual: */ - jumpShortsOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertCharacterToCodeInReg(TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperandoperand(MoveRM16r, TempReg, BaseHeaderSize, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIsBytes, gCmpCqR(characterObjectOf(0xFF), Arg1Reg)); - /* begin JumpAbove: */ - jumpBytesOutOfRange = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(AndCqR, BytesPerWord - 1, formatReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, formatReg, ClassReg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, ClassReg); - /* begin JumpBelowOrEqual: */ - jumpBytesOutOfBounds = genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, TempReg); - genConvertCharacterToCodeInReg(TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperand(AddCqR, BaseHeaderSize, Arg0Reg); - /* begin MoveR:Xbr:R: */ - genoperandoperandoperand(MoveRXbrR, TempReg, Arg0Reg, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotString, jmpTarget(jumpBytesOutOfRange, jmpTarget(jumpShortsOutOfRange, jmpTarget(jumpWordsOutOfRange, jmpTarget(jumpIsCompiledMethod, jmpTarget(jumpBytesOutOfBounds, jmpTarget(jumpShortsOutOfBounds, jmpTarget(jumpWordsOutOfBounds, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))))))); -# if IMMUTABILITY - jmpTarget(jumpImmutable, ((AbstractInstruction *) (((jumpNotString->operands))[0]))); -# endif - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperand(AddCqR, 1, Arg0Reg); - genConvertIntegerToSmallIntegerInReg(Arg0Reg); - jmpTarget(jumpBadArg, jmpTarget(jumpBadIndex, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - /* CogObjectRepresentationFor32BitSpur>>#genRemoveSmallIntegerTagsInScratchReg: */ -static sqInt NoDbgRegParms -genRemoveSmallIntegerTagsInScratchReg(sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, 1, scratchReg); - return 0; -} - - /* CogObjectRepresentationFor32BitSpur>>#genShiftAwaySmallIntegerTagsInScratchReg: */ -static sqInt NoDbgRegParms -genShiftAwaySmallIntegerTagsInScratchReg(sqInt scratchReg) -{ - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, 1, scratchReg); - return 0; -} - - -/* Get the literal count of a CompiledMethod into headerReg, plus one if - requested. If inBytes is true, scale the count by the word size. Deal with - the possibility of - the method being cogged. */ - - /* CogObjectRepresentationFor32BitSpur>>#getLiteralCountOf:plusOne:inBytes:into:scratch: */ -static sqInt NoDbgRegParms -getLiteralCountOfplusOneinBytesintoscratch(sqInt methodReg, sqInt plusOne, sqInt inBytes, sqInt litCountReg, sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - sqInt quickConstant; - sqInt quickConstant1; - - genGetMethodHeaderOfintoscratch(methodReg, litCountReg, scratchReg); - if (inBytes) { - /* begin AndCq:R: */ - quickConstant = ((sqInt)((usqInt)((alternateHeaderNumLiteralsMask())) << 1)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, quickConstant, litCountReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, 1, litCountReg); - } - else { - /* begin LogicalShiftRightCq:R: */ - genoperandoperand(LogicalShiftRightCqR, 1, litCountReg); - /* begin checkQuickConstant:forInstruction: */ - alternateHeaderNumLiteralsMask(); - anInstruction1 = genoperandoperand(AndCqR, alternateHeaderNumLiteralsMask(), litCountReg); - } - if (plusOne) { - /* begin AddCq:R: */ - quickConstant1 = (inBytes - ? BytesPerWord - : 1); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AddCqR, quickConstant1, litCountReg); - } - return 0; -} - - -/* Answer the relevant inline cache tag for an instance. - c.f. getInlineCacheClassTagFrom:into: & inlineCacheTagForClass: */ - - /* CogObjectRepresentationFor32BitSpur>>#inlineCacheTagForInstance: */ -static sqInt NoDbgRegParms -inlineCacheTagForInstance(sqInt oop) -{ - return (isImmediate(oop) - ? oop & 1 - : classIndexOf(oop)); -} - - /* CogObjectRepresentationFor32BitSpur>>#jumpNotSmallIntegerUnsignedValueInRegister: */ -static AbstractInstruction * NoDbgRegParms -jumpNotSmallIntegerUnsignedValueInRegister(sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0x3FFFFFFF, reg); - /* begin JumpAbove: */ - return genConditionalBranchoperand(JumpAbove, ((sqInt)0)); -} - - -/* Mark and trace a literal in an inline cache preceding address in - cogMethodOrNil. Answer if code was modified. */ - - /* CogObjectRepresentationFor32BitSpur>>#markAndTraceCacheTagLiteral:in:atpc: */ -static sqInt NoDbgRegParms -markAndTraceCacheTagLiteralinatpc(sqInt literal, CogMethod *cogMethodOrNil, usqInt address) -{ - sqInt objOop; - - if (!(couldBeObject(literal))) { - return 0; - } - assert(addressCouldBeObj(literal)); - if (!(isForwarded(literal))) { - markAndTrace(literal); - return 0; - } - objOop = followForwarded(literal); - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheTagat(backEnd(), objOop, address); - markAndTraceUpdatedLiteralin(objOop, cogMethodOrNil); - return 1; -} - - /* CogObjectRepresentationFor32BitSpur>>#numSmallIntegerBits */ -static sqInt -numSmallIntegerBits(void) -{ - return 0x1F; -} - - -/* The two valid tag patterns are 0 (Character) and 1 (SmallInteger) */ - - /* CogObjectRepresentationFor32BitSpur>>#validInlineCacheTag: */ -static sqInt NoDbgRegParms -validInlineCacheTag(usqInt classIndexOrTagPattern) -{ - return (classIndexOrTagPattern <= 1) - || ((classAtIndex(classIndexOrTagPattern)) != null); -} - - /* CogObjectRepresentationForSpur>>#callStoreCheckTrampoline */ -static void -callStoreCheckTrampoline(void) -{ - AbstractInstruction *abstractInstruction; - - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceStoreCheckTrampoline); - (abstractInstruction->annotation = IsRelativeCall); -} - - /* CogObjectRepresentationForSpur>>#checkValidDerivedObjectReference: */ -static sqInt NoDbgRegParms -checkValidDerivedObjectReference(sqInt bodyAddress) -{ - return (heapMapAtWord(pointerForOop(bodyAddress - BaseHeaderSize))) != 0; -} - - /* CogObjectRepresentationForSpur>>#checkValidOopReference: */ -static sqInt NoDbgRegParms -checkValidOopReference(sqInt anOop) -{ - return (isImmediate(anOop)) - || ((heapMapAtWord(pointerForOop(anOop))) != 0); -} - - /* CogObjectRepresentationForSpur>>#couldBeDerivedObject: */ -static sqInt NoDbgRegParms -couldBeDerivedObject(sqInt bodyAddress) -{ - return oopisGreaterThanOrEqualTo(bodyAddress - BaseHeaderSize, startOfMemory()); -} - - /* CogObjectRepresentationForSpur>>#couldBeObject: */ -static sqInt NoDbgRegParms -couldBeObject(sqInt literal) -{ - return (isNonImmediate(literal)) - && (oopisGreaterThanOrEqualTo(literal, startOfMemory())); -} - - -/* Create a trampoline to answer the active context that will - answer it if a frame is already married, and create it otherwise. - Assume numArgs is in SendNumArgsReg and ClassReg is free. */ - - /* CogObjectRepresentationForSpur>>#genActiveContextTrampolineLarge:inBlock:called: */ -static usqInt NoDbgRegParms -genActiveContextTrampolineLargeinBlockcalled(sqInt isLarge, sqInt isInBlock, char *aString) -{ - usqInt startAddress; - - startAddress = methodZoneBase(); - zeroOpcodeIndex(); - genGetActiveContextLargeinBlock(isLarge, isInBlock); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress(aString, startAddress); - recordRunTimeObjectReferences(); - return startAddress; -} - - -/* Check the remembered bit of the object in objReg; answer the jump taken if - the bit is already set. - Only need to fetch the byte containing it, which reduces the size of the - mask constant. - */ - - /* CogObjectRepresentationForSpur>>#genCheckRememberedBitOf:scratch: */ -static AbstractInstruction * NoDbgRegParms -genCheckRememberedBitOfscratch(sqInt objReg, sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt mask; - sqInt rememberedBitByteOffset; - - rememberedBitByteOffset = (rememberedBitShift()) / 8; - mask = 1U << ((rememberedBitShift()) % 8); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMbrR, rememberedBitByteOffset, objReg, scratchReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(TstCqR, mask, scratchReg); - /* begin JumpNonZero: */ - return genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -} - - /* CogObjectRepresentationForSpur>>#genConvertCharacterToCodeInReg: */ -static sqInt NoDbgRegParms -genConvertCharacterToCodeInReg(sqInt reg) -{ - sqInt quickConstant; - - /* begin LogicalShiftRightCq:R: */ - quickConstant = numTagBits(); - genoperandoperand(LogicalShiftRightCqR, quickConstant, reg); - return 0; -} - - /* CogObjectRepresentationForSpur>>#genConvertIntegerToCharacterInReg: */ -static sqInt NoDbgRegParms -genConvertIntegerToCharacterInReg(sqInt reg) -{ - AbstractInstruction *anInstruction; - sqInt quickConstant; - - /* begin LogicalShiftLeftCq:R: */ - quickConstant = numTagBits(); - genoperandoperand(LogicalShiftLeftCqR, quickConstant, reg); - /* begin checkQuickConstant:forInstruction: */ - characterTag(); - anInstruction = genoperandoperand(AddCqR, characterTag(), reg); - return 0; -} - - -/* Create a closure with the given startpc, numArgs and numCopied - within a context with ctxtNumArgs, large if isLargeCtxt that is in a - block if isInBlock. If numCopied > 0 pop those values off the stack. */ - - /* CogObjectRepresentationForSpur>>#genCreateClosureAt:numArgs:numCopied:contextNumArgs:large:inBlock: */ -static sqInt NoDbgRegParms -genCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(sqInt bcpc, sqInt numArgs, sqInt numCopied, sqInt ctxtNumArgs, sqInt isLargeCtxt, sqInt isInBlock) -{ - AbstractInstruction *anInstruction; - sqInt i; - - genNoPopCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(bcpc, numArgs, numCopied, ctxtNumArgs, isLargeCtxt, isInBlock); - for (i = 1; i <= numCopied; i += 1) { - /* begin PopR: */ - genoperand(PopR, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveRMwr, TempReg, (((numCopied - i) + ClosureFirstCopiedValueIndex) * BytesPerOop) + BaseHeaderSize, ReceiverResultReg); - } - return 0; -} - - -/* Create a full closure with the given values. */ - - /* CogObjectRepresentationForSpur>>#genCreateFullClosure:numArgs:numCopied:ignoreContext:contextNumArgs:large:inBlock: */ -static sqInt NoDbgRegParms -genCreateFullClosurenumArgsnumCopiedignoreContextcontextNumArgslargeinBlock(sqInt compiledBlock, sqInt numArgs, sqInt numCopied, sqInt ignoreContext, sqInt contextNumArgs, sqInt contextIsLarge, sqInt contextIsBlock) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - usqInt byteSize; - sqInt constant; - usqLong header; - sqInt numSlots; - AbstractInstruction *skip; - - - /* First get thisContext into ReceiverResultReg and thence in ClassReg. */ - if (ignoreContext) { - /* begin genMoveConstant:R: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ClassReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperand(MoveCqR, constant, ClassReg); - } - } - else { - genGetActiveContextNumArgslargeinBlock(contextNumArgs, contextIsLarge, contextIsBlock); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, ClassReg); - } - numSlots = FullClosureFirstCopiedValueIndex + numCopied; - byteSize = smallObjectBytesForSlots(numSlots); - assert(ClassFullBlockClosureCompactIndex != 0); - header = headerForSlotsformatclassIndex(numSlots, indexablePointersFormat(), ClassFullBlockClosureCompactIndex); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction1 = genoperandoperand(MoveAwR, freeStartAddress(), ReceiverResultReg); - /* begin genStoreHeader:intoNewInstance:using: */ - anInstruction4 = genoperandoperand(MoveCqR, ((usqInt) header), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperandoperand(MoveRMwr, TempReg, 0, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, (header) >> 32, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperandoperand(MoveRMwr, TempReg, 4, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(LoadEffectiveAddressMwrR, byteSize, ReceiverResultReg, TempReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction6 = genoperandoperand(MoveRAw, TempReg, freeStartAddress()); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction7 = genoperandoperand(CmpCqR, getScavengeThreshold(), TempReg); - /* begin JumpBelow: */ - skip = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceScheduleScavengeTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperandoperand(MoveRMwr, ClassReg, (ClosureOuterContextIndex * BytesPerOop) + BaseHeaderSize, ReceiverResultReg); - if (shouldAnnotateObjectReference(compiledBlock)) { - annotateobjRef(gMoveCwR(compiledBlock, TempReg), compiledBlock); - } - else { - /* begin MoveCq:R: */ - anInstruction = genoperandoperand(MoveCqR, compiledBlock, TempReg); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperandoperand(MoveRMwr, TempReg, (ClosureStartPCIndex * BytesPerOop) + BaseHeaderSize, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)numArgs << 1) | 1); - anInstruction10 = genoperandoperand(MoveCqR, (((usqInt)numArgs << 1) | 1), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveRMwr, TempReg, (ClosureNumArgsIndex * BytesPerOop) + BaseHeaderSize, ReceiverResultReg); - return 0; -} - - -/* Make sure that the object in reg is not forwarded. This routine assumes - the object will - never be forwarded to an immediate, as it is used to unforward literal - variables (associations). - Use the fact that isForwardedObjectClassIndexPun is a power of two to save - an instruction. */ - - /* CogObjectRepresentationForSpur>>#genEnsureObjInRegNotForwarded:scratchReg: */ -static sqInt NoDbgRegParms -genEnsureObjInRegNotForwardedscratchReg(sqInt reg, sqInt scratch) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *loop; - AbstractInstruction *ok; - sqInt quickConstant; - - assert(reg != scratch); - /* begin Label */ - loop = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, reg, scratch); - /* begin AndCq:R: */ - quickConstant = (classIndexMask()) - (isForwardedObjectClassIndexPun()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, quickConstant, scratch); - /* begin JumpNonZero: */ - ok = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(0, reg, reg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)loop)); - jmpTarget(ok, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - /* CogObjectRepresentationForSpur>>#genEnsureOopInRegNotForwarded:scratchReg: */ -static sqInt NoDbgRegParms -genEnsureOopInRegNotForwardedscratchReg(sqInt reg, sqInt scratch) -{ - AbstractInstruction *instruction; - - /* begin genEnsureOopInRegNotForwarded:scratchReg:jumpBackTo: */ - instruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - return genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(reg, scratch, instruction, 0); -} - - -/* Make sure that the oop in reg is not forwarded. - Use the fact that isForwardedObjectClassIndexPun is a power of two to save - an instruction. */ -/* maybe a fixup or an instruction */ -/* maybe a fixup or an instruction */ - - /* CogObjectRepresentationForSpur>>#genEnsureOopInRegNotForwarded:scratchReg:ifForwarder:ifNotForwarder: */ -static sqInt NoDbgRegParms -genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(sqInt reg, sqInt scratch, void *fwdJumpTarget, void *nonFwdJumpTargetOrZero) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction * finished; - AbstractInstruction * imm; - AbstractInstruction * ok; - sqInt quickConstant; - - assert(reg != scratch); - - /* notionally - self genGetClassIndexOfNonImm: reg into: scratch. - cogit CmpCq: objectMemory isForwardedObjectClassIndexPun R: TempReg. - but the following is an instruction shorter: */ - imm = genJumpImmediate(reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, reg, scratch); - /* begin AndCq:R: */ - quickConstant = (classIndexMask()) - (isForwardedObjectClassIndexPun()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, quickConstant, scratch); - /* begin JumpNonZero: */ - ok = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(0, reg, reg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)fwdJumpTarget)); - if ((((usqInt)nonFwdJumpTargetOrZero)) == 0) { - /* begin Label */ - finished = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - else { - finished = nonFwdJumpTargetOrZero; - } - jmpTarget(imm, jmpTarget(ok, finished)); - return 0; -} - - -/* Make sure that the oop in reg is not forwarded, updating the slot in - objReg with the value. - */ - - /* CogObjectRepresentationForSpur>>#genEnsureOopInRegNotForwarded:scratchReg:updatingSlot:in: */ -static sqInt NoDbgRegParms -genEnsureOopInRegNotForwardedscratchRegupdatingSlotin(sqInt reg, sqInt scratch, sqInt index, sqInt objReg) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *imm; - AbstractInstruction *loop; - AbstractInstruction *ok; - sqInt quickConstant; - - - /* Open-code - self genEnsureOopInRegNotForwarded: reg - scratchReg: scratch - updatingMw: index * objectMemory wordSize + objectMemory baseHeaderSize - r: objReg. - to avoid calling the store check unless the receiver is forwarded. */ - assert((reg != scratch) - && (objReg != scratch)); - /* begin Label */ - loop = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - - /* notionally - self genGetClassIndexOfNonImm: reg into: scratch. - cogit CmpCq: objectMemory isForwardedObjectClassIndexPun R: TempReg. - but the following is an instruction shorter: */ - imm = genJumpImmediate(reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, reg, scratch); - /* begin AndCq:R: */ - quickConstant = (classIndexMask()) - (isForwardedObjectClassIndexPun()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, quickConstant, scratch); - /* begin JumpNonZero: */ - ok = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(0, reg, reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveRMwr, reg, (index * BytesPerWord) + BaseHeaderSize, objReg); - assert((reg == Arg0Reg) - && ((scratch == TempReg) - && (objReg == ReceiverResultReg))); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceStoreCheckContextReceiverTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin Jump: */ - genoperand(Jump, ((sqInt)loop)); - jmpTarget(ok, jmpTarget(imm, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return 0; -} - - -/* Do the store check. Answer the argument for the benefit of the code - generator; ReceiverResultReg may be caller-saved and hence smashed by this - call. Answering - it allows the code generator to reload ReceiverResultReg cheaply. - In Spur the only thing we leave to the run-time is adding the receiver to - the remembered set and setting its isRemembered bit. */ - - /* CogObjectRepresentationForSpur>>#generateObjectRepresentationTrampolines */ -static void -generateObjectRepresentationTrampolines(void) -{ - sqInt instVarIndex; - AbstractInstruction *jumpSC; - - -# if IMMUTABILITY - for (instVarIndex = 0; instVarIndex < NumStoreTrampolines; instVarIndex += 1) { - ceStoreTrampolines[instVarIndex] = (genStoreTrampolineCalledinstVarIndex(trampolineNamenumArgslimit("ceStoreTrampoline", instVarIndex, NumStoreTrampolines - 2), instVarIndex)); - } -# endif // IMMUTABILITY - ceNewHashTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewHashOf, "ceNewHash", 1, ReceiverResultReg, null, null, null, /* begin emptyRegisterMask */ 0, 1, ReceiverResultReg, 0); - /* begin genStoreCheckTrampoline */ - if (CheckRememberedInTrampoline) { - zeroOpcodeIndex(); - jumpSC = genCheckRememberedBitOfscratch(ReceiverResultReg, ABIResultReg); - assert(((jumpSC->opcode)) == JumpNonZero); - (jumpSC->opcode = JumpZero); - /* begin RetN: */ - genoperand(RetN, 0); - jmpTarget(jumpSC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) - ? ReceiverResultReg - : ABIResultReg), CheckRememberedInTrampoline); - ceStoreCheckContextReceiverTrampoline = genStoreCheckContextReceiverTrampoline(); - /* begin genTrampolineFor:called:regsToSave: */ - ceScheduleScavengeTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceScheduleScavenge, "ceScheduleScavengeTrampoline", 0, null, null, null, null, CallerSavedRegisterMask, 1, NoReg, 0); - ceSmallActiveContextInMethodTrampoline = genActiveContextTrampolineLargeinBlockcalled(0, 0, "ceSmallMethodContext"); - ceSmallActiveContextInBlockTrampoline = genActiveContextTrampolineLargeinBlockcalled(0, InVanillaBlock, "ceSmallBlockContext"); - ceSmallActiveContextInFullBlockTrampoline = genActiveContextTrampolineLargeinBlockcalled(0, InFullBlock, "ceSmallFullBlockContext"); - ceLargeActiveContextInMethodTrampoline = genActiveContextTrampolineLargeinBlockcalled(1, 0, "ceLargeMethodContext"); - ceLargeActiveContextInBlockTrampoline = genActiveContextTrampolineLargeinBlockcalled(1, InVanillaBlock, "ceLargeBlockContext"); - ceLargeActiveContextInFullBlockTrampoline = genActiveContextTrampolineLargeinBlockcalled(1, InFullBlock, "ceLargeFullBlockContext"); - } - - -/* Create a trampoline to answer the active context that will - answer it if a frame is already married, and create it otherwise. - Assume numArgs is in SendNumArgsReg and ClassReg is free. */ - - /* CogObjectRepresentationForSpur>>#genGetActiveContextLarge:inBlock: */ -static sqInt NoDbgRegParms -genGetActiveContextLargeinBlock(sqInt isLarge, sqInt isInBlock) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction22; - AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction24; - AbstractInstruction *anInstruction25; - AbstractInstruction *anInstruction26; - AbstractInstruction *anInstruction27; - AbstractInstruction *anInstruction28; - AbstractInstruction *anInstruction29; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction30; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction32; - AbstractInstruction *anInstruction33; - AbstractInstruction *anInstruction34; - AbstractInstruction *anInstruction35; - AbstractInstruction *anInstruction36; - AbstractInstruction *anInstruction37; - AbstractInstruction *anInstruction38; - AbstractInstruction *anInstruction39; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction40; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt constant; - AbstractInstruction * continuation; - AbstractInstruction * exit; - usqLong header; - AbstractInstruction * inst; - AbstractInstruction * jumpNeedScavenge; - AbstractInstruction * jumpSingle; - AbstractInstruction * loopHead; - sqInt offset; - sqInt offset1; - sqInt quickConstant; - sqInt quickConstant1; - sqInt slotSize; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, FoxMethod, FPReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(TstCqR, MFMethodFlagHasContextFlag, ClassReg); - /* begin JumpZero: */ - jumpSingle = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperandoperand(MoveMwrR, FoxThisContext, FPReg, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, 0); - jmpTarget(jumpSingle, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperand(OrCqR, MFMethodFlagHasContextFlag, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperandoperand(MoveRMwr, ClassReg, FoxMethod, FPReg); - switch (isInBlock) { - case InFullBlock: - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, 3, ClassReg); - break; - case InVanillaBlock: - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(SubCqR, 3, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveM16rR, 0, ClassReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, ClassReg); - break; - case 0: - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(SubCqR, 1, ClassReg); - break; - default: - error("Case not found and no otherwise clause"); - } - slotSize = (isLarge - ? LargeContextSlots - : SmallContextSlots); - header = headerForSlotsformatclassIndex(slotSize, indexablePointersFormat(), ClassMethodContextCompactIndex); - flag("endianness"); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction12 = genoperandoperand(MoveAwR, freeStartAddress(), ReceiverResultReg); - /* begin genStoreHeader:intoNewInstance:using: */ - anInstruction13 = genoperandoperand(MoveCqR, ((usqInt) header), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperandoperand(MoveRMwr, TempReg, 0, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperand(MoveCqR, (header) >> 32, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction31 = genoperandoperandoperand(MoveRMwr, TempReg, 4, ReceiverResultReg); - /* begin LoadEffectiveAddressMw:r:R: */ - offset = smallObjectBytesForSlots(slotSize); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperandoperand(LoadEffectiveAddressMwrR, offset, ReceiverResultReg, TempReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction16 = genoperandoperand(MoveRAw, TempReg, freeStartAddress()); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction17 = genoperandoperand(CmpCqR, getScavengeThreshold(), TempReg); - /* begin JumpAboveOrEqual: */ - jumpNeedScavenge = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin LoadEffectiveAddressMw:r:R: */ - anInstruction18 = genoperandoperandoperand(LoadEffectiveAddressMwrR, 1, FPReg, TempReg); - continuation = anInstruction18; - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperandoperand(MoveRMwr, TempReg, BaseHeaderSize + (SenderIndex * BytesPerOop), ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperandoperand(MoveMwrR, FoxSavedFP, FPReg, TempReg); - genSetSmallIntegerTagsIn(TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperandoperand(MoveRMwr, TempReg, BaseHeaderSize + (InstructionPointerIndex * BytesPerOop), ReceiverResultReg); - /* begin MoveMw:r:R: */ - offset1 = offsetof(CogMethod, methodObject); - /* begin checkQuickConstant:forInstruction: */ - anInstruction23 = genoperandoperandoperand(MoveMwrR, offset1, ClassReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction24 = genoperandoperandoperand(MoveRMwr, TempReg, BaseHeaderSize + (MethodIndex * BytesPerWord), ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction25 = genoperandoperandoperand(MoveRMwr, ReceiverResultReg, FoxThisContext, FPReg); - gSubRRR(SPReg, FPReg, TempReg); - /* begin LogicalShiftRightCq:R: */ - quickConstant = 2 /* log2BytesPerWord */; - genoperandoperand(LogicalShiftRightCqR, quickConstant, TempReg); - /* begin SubCq:R: */ - quickConstant1 = 3; - /* begin checkQuickConstant:forInstruction: */ - anInstruction26 = genoperandoperand(SubCqR, quickConstant1, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, SendNumArgsReg, TempReg); - genConvertIntegerToSmallIntegerInReg(TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction27 = genoperandoperandoperand(MoveRMwr, TempReg, BaseHeaderSize + (StackPointerIndex * BytesPerOop), ReceiverResultReg); - if (isInBlock > 0) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperandoperand(LoadEffectiveAddressMwrR, 2, SendNumArgsReg, TempReg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, TempReg, FPReg, TempReg); - } - else { - /* begin genMoveConstant:R: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, TempReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction40 = genoperandoperand(MoveCqR, constant, TempReg); - } - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction28 = genoperandoperandoperand(MoveRMwr, TempReg, BaseHeaderSize + (ClosureIndex * BytesPerOop), ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction29 = genoperandoperandoperand(MoveMwrR, FoxMFReceiver, FPReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction30 = genoperandoperandoperand(MoveRMwr, TempReg, BaseHeaderSize + (ReceiverIndex * BytesPerOop), ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction32 = genoperandoperand(MoveCqR, 1, ClassReg); - /* begin CmpR:R: */ - assert(!((SendNumArgsReg == SPReg))); - loopHead = genoperandoperand(CmpRR, SendNumArgsReg, ClassReg); - /* begin JumpGreater: */ - exit = genConditionalBranchoperand(JumpGreater, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SendNumArgsReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, ClassReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction33 = genoperandoperand(AddCqR, 2, TempReg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, TempReg, FPReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction34 = genoperandoperand(AddCqR, ReceiverIndex + (BaseHeaderSize / BytesPerWord), ClassReg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, TempReg, ClassReg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction35 = genoperandoperand(SubCqR, (ReceiverIndex + (BaseHeaderSize / BytesPerWord)) - 1, ClassReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)loopHead)); - jmpTarget(exit, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - nilObject(); - anInstruction5 = genoperandoperand(MoveCqR, nilObject(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction36 = genoperandoperandoperand(LoadEffectiveAddressMwrR, FoxMFReceiver, FPReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction37 = genoperandoperand(AddCqR, (ReceiverIndex + 1) + (BaseHeaderSize / BytesPerWord), SendNumArgsReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction38 = genoperandoperand(SubCqR, BytesPerWord, ClassReg); - loopHead = anInstruction38; - /* begin CmpR:R: */ - assert(!((ClassReg == SPReg))); - genoperandoperand(CmpRR, ClassReg, SPReg); - /* begin JumpAbove: */ - exit = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, TempReg, SendNumArgsReg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction39 = genoperandoperand(AddCqR, 1, SendNumArgsReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)loopHead)); - jmpTarget(exit, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin RetN: */ - genoperand(RetN, 0); - jmpTarget(jumpNeedScavenge, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - CallRTregistersToBeSavedMask(ceScheduleScavengeTrampoline, ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)) | (1U << ClassReg)); - /* begin PopR: */ - genoperand(PopR, LinkReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuation)); - return 0; -} - - -/* Get the active context into ReceiverResultReg, creating it if necessary. */ - - /* CogObjectRepresentationForSpur>>#genGetActiveContextNumArgs:large:inBlock: */ -static sqInt NoDbgRegParms -genGetActiveContextNumArgslargeinBlock(sqInt numArgs, sqInt isLargeContext, sqInt isInBlock) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - sqInt routine; - - if (isLargeContext) { - switch (isInBlock) { - case 0: - routine = ceLargeActiveContextInMethodTrampoline; - break; - - case InVanillaBlock: - routine = ceLargeActiveContextInBlockTrampoline; - break; - - case InFullBlock: - routine = ceLargeActiveContextInFullBlockTrampoline; - break; - - default: - error("Case not found and no otherwise clause"); - routine = -1; - } - } - else { - switch (isInBlock) { - case 0: - routine = ceSmallActiveContextInMethodTrampoline; - break; - - case InVanillaBlock: - routine = ceSmallActiveContextInBlockTrampoline; - break; - - case InFullBlock: - routine = ceSmallActiveContextInFullBlockTrampoline; - break; - - default: - error("Case not found and no otherwise clause"); - routine = -1; - } - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, numArgs, SendNumArgsReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, routine); - (abstractInstruction->annotation = IsRelativeCall); - return 0; -} - - /* CogObjectRepresentationForSpur>>#genGetBits:ofFormatByteOf:into: */ -static sqInt NoDbgRegParms -genGetBitsofFormatByteOfinto(sqInt mask, sqInt sourceReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - flag("endianness"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMbrR, 3, sourceReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, mask, destReg); - return 0; -} - - -/* Fetch the instance's class index into destReg. */ - - /* CogObjectRepresentationForSpur>>#genGetClassIndexOfNonImm:into: */ -static sqInt NoDbgRegParms -genGetClassIndexOfNonImminto(sqInt sourceReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, sourceReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - classIndexMask(); - anInstruction1 = genoperandoperand(AndCqR, classIndexMask(), destReg); - return 0; -} - - -/* Fetch the class object whose index is in instReg into destReg. - It is non-obvious, but the Cogit assumes loading a class does not involve - a runtime call, so do not call classAtIndex: */ - - /* CogObjectRepresentationForSpur>>#genGetClassObjectOfClassIndex:into:scratchReg: */ -static sqInt NoDbgRegParms -genGetClassObjectOfClassIndexintoscratchReg(sqInt instReg, sqInt destReg, sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - sqInt offset; - sqInt quickConstant; - - assert(instReg != destReg); - assert(instReg != scratchReg); - assert(destReg != scratchReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instReg, scratchReg); - /* begin LogicalShiftRightCq:R: */ - quickConstant = classTableMajorIndexShift(); - genoperandoperand(LogicalShiftRightCqR, quickConstant, scratchReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), scratchReg); - assert(!(shouldAnnotateObjectReference(classTableRootObj()))); - /* begin MoveMw:r:R: */ - offset = (classTableRootObj()) + BaseHeaderSize; - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, scratchReg, destReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instReg, scratchReg); - /* begin checkQuickConstant:forInstruction: */ - classTableMinorIndexMask(); - anInstruction3 = genoperandoperand(AndCqR, classTableMinorIndexMask(), scratchReg); - /* begin AddCq:R: */ - anInstruction4 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), scratchReg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, scratchReg, destReg, destReg); - return 0; -} - - -/* Fetch the instance's class into destReg. If the instance is not the - receiver and is forwarded, follow forwarding. */ - - /* CogObjectRepresentationForSpur>>#genGetClassObjectOf:into:scratchReg:mayBeAForwarder: */ -static sqInt NoDbgRegParms -genGetClassObjectOfintoscratchRegmayBeAForwarder(sqInt instReg, sqInt destReg, sqInt scratchReg, sqInt mayBeForwarder) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *jumpIsImm; - AbstractInstruction *jumpNotForwarded; - AbstractInstruction *loop; - - if ((instReg == destReg) - || ((instReg == scratchReg) - || (destReg == scratchReg))) { - return BadRegisterSet; - } - /* begin MoveR:R: */ - loop = genoperandoperand(MoveRR, instReg, scratchReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AndCqR, tagMask(), scratchReg); - /* begin JumpNonZero: */ - jumpIsImm = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - flag("endianness"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperandoperand(MoveMwrR, 0, instReg, scratchReg); - /* begin checkQuickConstant:forInstruction: */ - classIndexMask(); - anInstruction4 = genoperandoperand(AndCqR, classIndexMask(), scratchReg); - if (mayBeForwarder) { - - /* if it is forwarded... */ - /* begin checkQuickConstant:forInstruction: */ - isForwardedObjectClassIndexPun(); - anInstruction = genoperandoperand(CmpCqR, isForwardedObjectClassIndexPun(), scratchReg); - /* begin JumpNonZero: */ - jumpNotForwarded = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, BaseHeaderSize, instReg, instReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)loop)); - jmpTarget(jumpNotForwarded, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - jmpTarget(jumpIsImm, genoperandoperand(MoveRR, scratchReg, destReg)); - if (scratchReg == TempReg) { - /* begin PushR: */ - genoperand(PushR, instReg); - genGetClassObjectOfClassIndexintoscratchReg(destReg, instReg, TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instReg, destReg); - /* begin PopR: */ - genoperand(PopR, instReg); - } - else { - genGetClassObjectOfClassIndexintoscratchReg(destReg, scratchReg, TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, scratchReg, destReg); - } - return 0; -} - - /* CogObjectRepresentationForSpur>>#genGetClassTagOf:into:scratchReg: */ -static AbstractInstruction * NoDbgRegParms -genGetClassTagOfintoscratchReg(sqInt instReg, sqInt destReg, sqInt scratchReg) -{ - return genGetInlineCacheClassTagFromintoforEntry(instReg, destReg, 1); -} - - -/* Fetch the instance's class index into destReg. */ - - /* CogObjectRepresentationForSpur>>#genGetCompactClassIndexNonImmOf:into: */ -static sqInt NoDbgRegParms -genGetCompactClassIndexNonImmOfinto(sqInt instReg, sqInt destReg) -{ - return genGetClassIndexOfNonImminto(instReg, destReg); -} - - /* CogObjectRepresentationForSpur>>#genGetDoubleValueOf:into: */ -static sqInt NoDbgRegParms -genGetDoubleValueOfinto(sqInt srcReg, sqInt destFPReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveM64rRd, BaseHeaderSize, srcReg, destFPReg); - return 0; -} - - -/* Get the format field of the object in srcReg into destReg. - srcReg may equal destReg. */ - - /* CogObjectRepresentationForSpur>>#genGetFormatOf:into: */ -static sqInt NoDbgRegParms -genGetFormatOfinto(sqInt srcReg, sqInt destReg) -{ - return genGetBitsofFormatByteOfinto(formatMask(), srcReg, destReg); -} - - -/* Get the format of the object in sourceReg into destReg. If - scratchRegOrNone is not NoReg, load at least the least significant 32-bits - (64-bits in 64-bits) of the - header word, which contains the format, into scratchRegOrNone. */ - - /* CogObjectRepresentationForSpur>>#genGetFormatOf:into:leastSignificantHalfOfBaseHeaderIntoScratch: */ -static sqInt NoDbgRegParms -genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(sqInt sourceReg, sqInt destReg, sqInt scratchRegOrNone) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - - if (scratchRegOrNone == NoReg) { - flag("endianness"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMbrR, 3, sourceReg, destReg); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, 0, sourceReg, scratchRegOrNone); - gLogicalShiftRightCqRR(formatShift(), scratchRegOrNone, destReg); - } - /* begin checkQuickConstant:forInstruction: */ - formatMask(); - anInstruction2 = genoperandoperand(AndCqR, formatMask(), destReg); - return 0; -} - - -/* Get the size in word-sized slots of the object in srcReg into destReg. - srcReg may equal destReg. */ - - /* CogObjectRepresentationForSpur>>#genGetNumSlotsOf:into: */ -static sqInt NoDbgRegParms -genGetNumSlotsOfinto(sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *jmp; - - assert(srcReg != destReg); - genGetRawSlotSizeOfNonImminto(srcReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - numSlotsMask(); - anInstruction = genoperandoperand(CmpCqR, numSlotsMask(), destReg); - /* begin JumpLess: */ - jmp = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - genGetOverflowSlotsOfinto(srcReg, destReg); - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - -/* The raw numSlots field is the most significant byte of the 64-bit header - word. MoveMbrR zero-extends. */ - - /* CogObjectRepresentationForSpur>>#genGetRawSlotSizeOfNonImm:into: */ -static sqInt NoDbgRegParms -genGetRawSlotSizeOfNonImminto(sqInt sourceReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin MoveCq:R: */ - anInstruction = genoperandoperand(MoveCqR, 0, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMbrR, 7, sourceReg, destReg); - return 0; -} - - /* CogObjectRepresentationForSpur>>#genJumpImmediate: */ -static AbstractInstruction * NoDbgRegParms -genJumpImmediate(sqInt aRegister) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(TstCqR, tagMask(), aRegister); - /* begin JumpNonZero: */ - return genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -} - - /* CogObjectRepresentationForSpur>>#genJumpImmutable:scratchReg: */ -#if IMMUTABILITY -static AbstractInstruction * NoDbgRegParms -genJumpImmutablescratchReg(sqInt sourceReg, sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, sourceReg, scratchReg); - /* begin genJumpBaseHeaderImmutable: */ - immutableBitMask(); - anInstruction1 = genoperandoperand(TstCqR, immutableBitMask(), scratchReg); - /* begin JumpNonZero: */ - return genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -} -#endif /* IMMUTABILITY */ - - /* CogObjectRepresentationForSpur>>#genJumpMutable:scratchReg: */ -#if IMMUTABILITY -static AbstractInstruction * NoDbgRegParms -genJumpMutablescratchReg(sqInt sourceReg, sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, sourceReg, scratchReg); - /* begin genJumpBaseHeaderMutable: */ - immutableBitMask(); - anInstruction1 = genoperandoperand(TstCqR, immutableBitMask(), scratchReg); - /* begin JumpZero: */ - return genConditionalBranchoperand(JumpZero, ((sqInt)0)); -} -#endif /* IMMUTABILITY */ - - /* CogObjectRepresentationForSpur>>#genJumpNotCharacterInScratchReg: */ -static AbstractInstruction * NoDbgRegParms -genJumpNotCharacterInScratchReg(sqInt reg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, tagMask(), reg); - /* begin checkQuickConstant:forInstruction: */ - characterTag(); - anInstruction1 = genoperandoperand(CmpCqR, characterTag(), reg); - /* begin JumpNonZero: */ - return genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -} - - -/* Generate a call to code that allocates a new Array of size. - The Array should be initialized with nils iff initialize is true. - The size arg is passed in SendNumArgsReg, the result - must come back in ReceiverResultReg. */ - - /* CogObjectRepresentationForSpur>>#genNewArrayOfSize:initialized: */ -static sqInt NoDbgRegParms -genNewArrayOfSizeinitialized(sqInt size, sqInt initialize) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - usqLong header; - sqInt i; - sqInt offset; - sqInt quickConstant; - AbstractInstruction *skip; - - assert(size < (numSlotsMask())); - header = headerForSlotsformatclassIndex(size, arrayFormat(), ClassArrayCompactIndex); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction2 = genoperandoperand(MoveAwR, freeStartAddress(), ReceiverResultReg); - /* begin genStoreHeader:intoNewInstance:using: */ - anInstruction4 = genoperandoperand(MoveCqR, ((usqInt) header), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperandoperand(MoveRMwr, TempReg, 0, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperand(MoveCqR, (header) >> 32, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperandoperand(MoveRMwr, TempReg, 4, ReceiverResultReg); - if (initialize - && (size > 0)) { - if (shouldAnnotateObjectReference(nilObject())) { - annotateobjRef(gMoveCwR(nilObject(), TempReg), nilObject()); - } - else { - /* begin MoveCq:R: */ - quickConstant = nilObject(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, TempReg); - } - for (i = 0; i < size; i += 1) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveRMwr, TempReg, (i * BytesPerWord) + BaseHeaderSize, ReceiverResultReg); - } - } - /* begin LoadEffectiveAddressMw:r:R: */ - offset = smallObjectBytesForSlots(size); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(LoadEffectiveAddressMwrR, offset, ReceiverResultReg, TempReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction6 = genoperandoperand(MoveRAw, TempReg, freeStartAddress()); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction7 = genoperandoperand(CmpCqR, getScavengeThreshold(), TempReg); - /* begin JumpBelow: */ - skip = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceScheduleScavengeTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - -/* Create a closure with the given startpc, numArgs and numCopied - within a context with ctxtNumArgs, large if isLargeCtxt that is in a - block if isInBlock. Do /not/ initialize the copied values. */ - - /* CogObjectRepresentationForSpur>>#genNoPopCreateClosureAt:numArgs:numCopied:contextNumArgs:large:inBlock: */ -static sqInt NoDbgRegParms -genNoPopCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(sqInt bcpc, sqInt numArgs, sqInt numCopied, sqInt ctxtNumArgs, sqInt isLargeCtxt, sqInt isInBlock) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - usqInt byteSize; - usqLong header; - sqInt numSlots; - AbstractInstruction *skip; - - - /* First get thisContext into ReceiverResultRega and thence in ClassReg. */ - genGetActiveContextNumArgslargeinBlock(ctxtNumArgs, isLargeCtxt, isInBlock); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, ClassReg); - numSlots = ClosureFirstCopiedValueIndex + numCopied; - byteSize = smallObjectBytesForSlots(numSlots); - header = headerForSlotsformatclassIndex(numSlots, indexablePointersFormat(), ClassBlockClosureCompactIndex); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction = genoperandoperand(MoveAwR, freeStartAddress(), ReceiverResultReg); - /* begin genStoreHeader:intoNewInstance:using: */ - anInstruction4 = genoperandoperand(MoveCqR, ((usqInt) header), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveRMwr, TempReg, 0, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, (header) >> 32, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperandoperand(MoveRMwr, TempReg, 4, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(LoadEffectiveAddressMwrR, byteSize, ReceiverResultReg, TempReg); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction6 = genoperandoperand(MoveRAw, TempReg, freeStartAddress()); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction7 = genoperandoperand(CmpCqR, getScavengeThreshold(), TempReg); - /* begin JumpBelow: */ - skip = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceScheduleScavengeTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperandoperand(MoveRMwr, ClassReg, (ClosureOuterContextIndex * BytesPerOop) + BaseHeaderSize, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)bcpc << 1) | 1); - anInstruction9 = genoperandoperand(MoveCqR, (((usqInt)bcpc << 1) | 1), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveRMwr, TempReg, (ClosureStartPCIndex * BytesPerOop) + BaseHeaderSize, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)numArgs << 1) | 1); - anInstruction11 = genoperandoperand(MoveCqR, (((usqInt)numArgs << 1) | 1), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveRMwr, TempReg, (ClosureNumArgsIndex * BytesPerOop) + BaseHeaderSize, ReceiverResultReg); - return 0; -} - - /* CogObjectRepresentationForSpur>>#genPrimitiveAsCharacter */ -static sqInt -genPrimitiveAsCharacter(void) -{ - AbstractInstruction *jumpNotInt; - AbstractInstruction *jumpOutOfRange; - sqInt reg; - - jumpNotInt = ((AbstractInstruction *) 0); - if (methodOrBlockNumArgs == 0) { - reg = ReceiverResultReg; - } - else { - if (methodOrBlockNumArgs > 1) { - return UnimplementedPrimitive; - } - reg = Arg0Reg; - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotInt = genJumpNotSmallInteger(reg); - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, reg, TempReg); - genConvertSmallIntegerToIntegerInReg(TempReg); - jumpOutOfRange = jumpNotCharacterUnsignedValueInRegister(TempReg); - genConvertSmallIntegerToCharacterInReg(reg); - if (reg != ReceiverResultReg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, reg, ReceiverResultReg); - } - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpOutOfRange, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (reg != ReceiverResultReg) { - jmpTarget(jumpNotInt, ((AbstractInstruction *) (((jumpOutOfRange->operands))[0]))); - } - return CompletePrimitive; -} - - -/* Generate primitive 60, at: with unsigned access for pure bits classes. */ - - /* CogObjectRepresentationForSpur>>#genPrimitiveAt */ -static sqInt -genPrimitiveAt(void) -{ - return genPrimitiveAtSigned(0); -} - - /* CogObjectRepresentationForSpur>>#genPrimitiveIdenticalOrNotIf: */ -static sqInt NoDbgRegParms -genPrimitiveIdenticalOrNotIf(sqInt orNot) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *comp; - sqInt constant; - sqInt constant1; - AbstractInstruction *jumpCmp; - - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - comp = genoperandoperand(CmpRR, Arg0Reg, ReceiverResultReg); - if (orNot) { - /* begin JumpZero: */ - jumpCmp = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin genEnsureOopInRegNotForwarded:scratchReg:jumpBackTo: */ - genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(Arg0Reg, TempReg, comp, 0); - } - else { - /* begin JumpNonZero: */ - jumpCmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - } - /* begin genMoveConstant:R: */ - constant = trueObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpCmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (!orNot) { - /* begin genEnsureOopInRegNotForwarded:scratchReg:jumpBackTo: */ - genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(Arg0Reg, TempReg, comp, 0); - } - /* begin genMoveConstant:R: */ - constant1 = falseObject(); - if (shouldAnnotateObjectReference(constant1)) { - annotateobjRef(checkLiteralforInstruction(constant1, genoperandoperand(MoveCwR, constant1, ReceiverResultReg)), constant1); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, constant1, ReceiverResultReg); - } - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - return UnfailingPrimitive; -} - - -/* Generate primitive 164, at: with signed access for pure bits classes. */ - - /* CogObjectRepresentationForSpur>>#genPrimitiveIntegerAt */ -static sqInt -genPrimitiveIntegerAt(void) -{ - return genPrimitiveAtSigned(1); -} - - -/* Generate primitive 165, at:put: with signed access for pure bits classes. */ - - /* CogObjectRepresentationForSpur>>#genPrimitiveIntegerAtPut */ -static sqInt -genPrimitiveIntegerAtPut(void) -{ - return genPrimitiveAtPutSigned(1); -} - - -/* */ - - /* CogObjectRepresentationForSpur>>#genPrimitiveMakePoint */ -static sqInt -genPrimitiveMakePoint(void) -{ - sqInt allocSize; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction * jumpFail; - usqLong newPointHeader; - sqInt resultReg; - sqInt scratchReg; - - resultReg = ClassReg; - - /* */ - scratchReg = SendNumArgsReg; - allocSize = BaseHeaderSize + (BytesPerWord * 2); - newPointHeader = headerForSlotsformatclassIndex(2, nonIndexablePointerFormat(), ClassPointCompactIndex); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction = genoperandoperand(MoveAwR, freeStartAddress(), resultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(LoadEffectiveAddressMwrR, allocSize, resultReg, scratchReg); - /* begin checkQuickConstant:forInstruction: */ - getScavengeThreshold(); - anInstruction2 = genoperandoperand(CmpCqR, getScavengeThreshold(), scratchReg); - /* begin JumpAboveOrEqual: */ - jumpFail = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkLiteral:forInstruction: */ - freeStartAddress(); - anInstruction3 = genoperandoperand(MoveRAw, scratchReg, freeStartAddress()); - /* begin genStoreHeader:intoNewInstance:using: */ - anInstruction4 = genoperandoperand(MoveCqR, ((usqInt) newPointHeader), scratchReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperandoperand(MoveRMwr, scratchReg, 0, resultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperand(MoveCqR, (newPointHeader) >> 32, scratchReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction31 = genoperandoperandoperand(MoveRMwr, scratchReg, 4, resultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(MoveRMwr, ReceiverResultReg, BaseHeaderSize, resultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperandoperand(MoveRMwr, Arg0Reg, BaseHeaderSize + BytesPerWord, resultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, resultReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpFail, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - /* CogObjectRepresentationForSpur>>#genPrimitiveObjectAt */ -static sqInt -genPrimitiveObjectAt(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - sqInt headerReg; - AbstractInstruction *jumpBadIndex; - AbstractInstruction *jumpBounds; - AbstractInstruction *jumpNotHeaderIndex; - sqInt quickConstant; - - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpBadIndex = genJumpNotSmallInteger(Arg0Reg); - genGetMethodHeaderOfintoscratch(ReceiverResultReg, (headerReg = Arg1Reg), TempReg); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)1 << 1) | 1); - anInstruction = genoperandoperand(CmpCqR, (((usqInt)1 << 1) | 1), Arg0Reg); - /* begin JumpNonZero: */ - jumpNotHeaderIndex = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, headerReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotHeaderIndex, gAndCqR((((usqInt)(alternateHeaderNumLiteralsMask()) << 1) | 1), headerReg)); - /* begin SubCq:R: */ - quickConstant = ((((usqInt)1 << 1) | 1)) - (smallIntegerTag()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(SubCqR, quickConstant, Arg0Reg); - /* begin CmpR:R: */ - assert(!((headerReg == SPReg))); - genoperandoperand(CmpRR, headerReg, Arg0Reg); - /* begin JumpAbove: */ - jumpBounds = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - genConvertSmallIntegerToIntegerInReg(Arg0Reg); - /* begin AddCq:R: */ - anInstruction2 = genoperandoperand(AddCqR, ((usqInt)(BaseHeaderSize)) >> (shiftForWord()), Arg0Reg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, Arg0Reg, ReceiverResultReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpBounds, gAddCqR(((((usqInt)1 << 1) | 1)) - (smallIntegerTag()), Arg0Reg)); - jmpTarget(jumpBadIndex, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - -/* c.f. StackInterpreter>>stSizeOf: lengthOf:baseHeader:format: - fixedFieldsOf:format:length: - */ - - /* CogObjectRepresentationForSpur>>#genPrimitiveSize */ -static sqInt -genPrimitiveSize(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - AbstractInstruction * jump32BitLongsDone; - AbstractInstruction * jump64BitLongsDone; - AbstractInstruction * jumpArrayDone; - AbstractInstruction * jumpBytesDone; - AbstractInstruction * jumpHasFixedFields; - AbstractInstruction *jumpImm; - AbstractInstruction * jumpIs64BitLongs; - AbstractInstruction * jumpIsBytes; - AbstractInstruction *jumpIsContext; - AbstractInstruction * jumpIsContext1; - AbstractInstruction * jumpIsShorts; - AbstractInstruction *jumpNotIndexable; - AbstractInstruction * jumpNotIndexable1; - AbstractInstruction * jumpShortsDone; - - jumpImm = genJumpImmediate(ReceiverResultReg); - /* begin genGetSizeOf:into:formatReg:scratchReg:abortJumpsInto: */ - genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, SendNumArgsReg, TempReg); - genGetNumSlotsOfinto(ReceiverResultReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction = genoperandoperand(CmpCqR, firstByteFormat(), SendNumArgsReg); - /* begin JumpGreaterOrEqual: */ - jumpIsBytes = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction1 = genoperandoperand(CmpCqR, arrayFormat(), SendNumArgsReg); - /* begin JumpZero: */ - jumpArrayDone = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin JumpLess: */ - jumpNotIndexable1 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - weakArrayFormat(); - anInstruction2 = genoperandoperand(CmpCqR, weakArrayFormat(), SendNumArgsReg); - /* begin JumpLessOrEqual: */ - jumpHasFixedFields = genConditionalBranchoperand(JumpLessOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstShortFormat(); - anInstruction3 = genoperandoperand(CmpCqR, firstShortFormat(), SendNumArgsReg); - /* begin JumpGreaterOrEqual: */ - jumpIsShorts = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstLongFormat(); - anInstruction4 = genoperandoperand(CmpCqR, firstLongFormat(), SendNumArgsReg); - /* begin JumpGreaterOrEqual: */ - jump32BitLongsDone = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - sixtyFourBitIndexableFormat(); - anInstruction5 = genoperandoperand(CmpCqR, sixtyFourBitIndexableFormat(), SendNumArgsReg); - /* begin JumpZero: */ - jumpIs64BitLongs = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - jmpTarget(jumpNotIndexable1, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin Jump: */ - jumpNotIndexable1 = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpIsBytes, genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), ClassReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(AndCqR, BytesPerWord - 1, SendNumArgsReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, SendNumArgsReg, ClassReg); - /* begin Jump: */ - jumpBytesDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpIsShorts, gLogicalShiftLeftCqR((shiftForWord()) - 1, ClassReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(AndCqR, 1, SendNumArgsReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, SendNumArgsReg, ClassReg); - /* begin Jump: */ - jumpShortsDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpIs64BitLongs, genoperandoperand(LogicalShiftRightCqR, 1, ClassReg)); - /* begin Jump: */ - jump64BitLongsDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpHasFixedFields, checkQuickConstantforInstruction(classIndexMask(), genoperandoperand(AndCqR, classIndexMask(), TempReg))); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, SendNumArgsReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, TempReg); - /* begin JumpZero: */ - jumpIsContext1 = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin PushR: */ - genoperand(PushR, ClassReg); - genGetClassObjectOfClassIndexintoscratchReg(SendNumArgsReg, ClassReg, TempReg); - genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, ClassReg, SendNumArgsReg); - genConvertSmallIntegerToIntegerInReg(SendNumArgsReg); - /* begin PopR: */ - genoperand(PopR, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - fixedFieldsOfClassFormatMask(); - anInstruction9 = genoperandoperand(AndCqR, fixedFieldsOfClassFormatMask(), SendNumArgsReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, SendNumArgsReg, ClassReg); - jmpTarget(jumpArrayDone, jmpTarget(jump64BitLongsDone, jmpTarget(jump32BitLongsDone, jmpTarget(jumpShortsDone, jmpTarget(jumpBytesDone, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))))); - jumpNotIndexable = jumpNotIndexable1; - jumpIsContext = jumpIsContext1; - genConvertIntegerInRegtoSmallIntegerInReg(ClassReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpImm, jmpTarget(jumpNotIndexable, jmpTarget(jumpIsContext, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))); - return CompletePrimitive; -} - - -/* primitiveCompareWith: */ - - /* CogObjectRepresentationForSpur>>#genPrimitiveStringCompareWith */ -static sqInt -genPrimitiveStringCompareWith(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction * instr; - AbstractInstruction *jump; - AbstractInstruction *jumpAbove; - AbstractInstruction *jumpIncorrectFormat1; - AbstractInstruction *jumpIncorrectFormat2; - AbstractInstruction *jumpIncorrectFormat3; - AbstractInstruction *jumpIncorrectFormat4; - AbstractInstruction *jumpMidFailure; - AbstractInstruction *jumpSuccess; - sqInt minSizeReg; - sqInt string1CharOrByteSizeReg; - sqInt string1Reg; - sqInt string2CharOrByteSizeReg; - sqInt string2Reg; - - - /* I redefine those name to ease program comprehension */ - string1Reg = ReceiverResultReg; - string2Reg = Arg0Reg; - string1CharOrByteSizeReg = Arg1Reg; - string2CharOrByteSizeReg = ClassReg; - - /* Load arguments in reg */ - minSizeReg = SendNumArgsReg; - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - genGetFormatOfinto(string1Reg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction = genoperandoperand(CmpCqR, firstByteFormat(), TempReg); - /* begin JumpLess: */ - jumpIncorrectFormat1 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction1 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), TempReg); - /* begin JumpAboveOrEqual: */ - jumpIncorrectFormat2 = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - genGetNumSlotsOfinto(string1Reg, string1CharOrByteSizeReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), string1CharOrByteSizeReg); - gAndCqRR(BytesPerWord - 1, TempReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, string1CharOrByteSizeReg); - genGetFormatOfinto(string2Reg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction2 = genoperandoperand(CmpCqR, firstByteFormat(), TempReg); - /* begin JumpLess: */ - jumpIncorrectFormat3 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction3 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), TempReg); - /* begin JumpAboveOrEqual: */ - jumpIncorrectFormat4 = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - genGetNumSlotsOfinto(string2Reg, string2CharOrByteSizeReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), string2CharOrByteSizeReg); - gAndCqRR(BytesPerWord - 1, TempReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, string2CharOrByteSizeReg); - /* begin CmpR:R: */ - assert(!((string1CharOrByteSizeReg == SPReg))); - genoperandoperand(CmpRR, string1CharOrByteSizeReg, string2CharOrByteSizeReg); - /* begin JumpBelow: */ - jumpAbove = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, string1CharOrByteSizeReg, minSizeReg); - /* begin Jump: */ - jump = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpAbove, genoperandoperand(MoveRR, string2CharOrByteSizeReg, minSizeReg)); - jmpTarget(jump, checkQuickConstantforInstruction(0, genoperandoperand(CmpCqR, 0, minSizeReg))); - /* begin JumpZero: */ - jumpSuccess = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(MoveCqR, BaseHeaderSize, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(AddCqR, BaseHeaderSize, minSizeReg); - /* begin MoveXbr:R:R: */ - instr = genoperandoperandoperand(MoveXbrRR, TempReg, string1Reg, string1CharOrByteSizeReg); - /* begin MoveXbr:R:R: */ - genoperandoperandoperand(MoveXbrRR, TempReg, string2Reg, string2CharOrByteSizeReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, string2CharOrByteSizeReg, string1CharOrByteSizeReg); - /* begin JumpNonZero: */ - jumpMidFailure = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(AddCqR, 1, TempReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, minSizeReg); - /* begin JumpNonZero: */ - genConditionalBranchoperand(JumpNonZero, ((sqInt)instr)); - genGetNumBytesOfinto(string1Reg, string1CharOrByteSizeReg); - genGetNumBytesOfinto(string2Reg, string2CharOrByteSizeReg); - jmpTarget(jumpSuccess, genoperandoperand(SubRR, string2CharOrByteSizeReg, string1CharOrByteSizeReg)); - jmpTarget(jumpMidFailure, genoperandoperand(MoveRR, string1CharOrByteSizeReg, ReceiverResultReg)); - genConvertIntegerToSmallIntegerInReg(ReceiverResultReg); - if (methodOrBlockNumArgs <= 2 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpIncorrectFormat4, jmpTarget(jumpIncorrectFormat3, jmpTarget(jumpIncorrectFormat2, jmpTarget(jumpIncorrectFormat1, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))); - return CompletePrimitive; -} - - -/* replaceFrom: start to: stop with: replacement startingAt: repStart. - - The primitive in the JIT tries to deal with two pathological cases, copy - of arrays and byteStrings, - which often copies only a dozen of fields and where switching to the C - runtime cost a lot. - - Based on heuristics on the method class, I generate a quick array path - (typically for Array), - a quick byteString path (typically for ByteString, ByteArray and - LargeInteger) or no quick - path at all (Typically for Bitmap). - - The many tests to ensure that the primitive won't fail are not super - optimised (multiple reloading - or stack arguments in registers) but this is still good enough and worth - it since we're avoiding - the Smalltalk to C stack switch. The tight copying loops are optimised. - - It is possible to build a bigger version with the 2 different paths but I - (Clement) believe this - is too big machine code wise to be worth it. - */ - - /* CogObjectRepresentationForSpur>>#genPrimitiveStringReplace */ -static sqInt -genPrimitiveStringReplace(void) -{ - sqInt adjust; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction22; - AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction24; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt arrayReg; - AbstractInstruction * inst; - AbstractInstruction * instr; - AbstractInstruction *jmpAlreadyRemembered; - AbstractInstruction *jmpDestYoung; - AbstractInstruction *jumpEmpty; - AbstractInstruction *jumpImm; - AbstractInstruction *jumpImmutable; - AbstractInstruction *jumpIncorrectFormat1; - AbstractInstruction *jumpIncorrectFormat2; - AbstractInstruction *jumpIncorrectFormat3; - AbstractInstruction *jumpIncorrectFormat4; - AbstractInstruction *jumpNotSmi1; - AbstractInstruction *jumpNotSmi2; - AbstractInstruction *jumpNotSmi3; - AbstractInstruction *jumpOutOfBounds1; - AbstractInstruction *jumpOutOfBounds2; - AbstractInstruction *jumpOutOfBounds3; - AbstractInstruction *jumpOutOfBounds4; - sqInt offset; - sqInt offset1; - sqInt offset2; - sqInt offset3; - sqInt offset4; - sqInt offset5; - sqInt offset6; - sqInt offset7; - sqInt offset8; - sqInt offset9; - sqInt replReg; - sqInt repStartReg; - sqInt result; - sqInt startReg; - sqInt stopReg; - - - /* Can I generate a quick path for this method ? */ - jmpAlreadyRemembered = ((AbstractInstruction *) 0); - jumpImmutable = ((AbstractInstruction *) 0); - jumpOutOfBounds3 = ((AbstractInstruction *) 0); - jumpOutOfBounds4 = ((AbstractInstruction *) 0); - if (!((maybeMethodClassOfseemsToBeInstantiating(methodObj, arrayFormat())) - || (maybeMethodClassOfseemsToBeInstantiating(methodObj, firstByteFormat())))) { - return UnimplementedPrimitive; - } - arrayReg = ReceiverResultReg; - startReg = Arg0Reg; - stopReg = Arg1Reg; - replReg = ClassReg; - - /* Load arguments in reg */ - repStartReg = SendNumArgsReg; - /* begin genStackArgAt:into: */ - offset6 = (0) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperandoperand(MoveMwrR, offset6, SPReg, repStartReg); - /* begin genStackArgAt:into: */ - offset7 = (1) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperandoperand(MoveMwrR, offset7, SPReg, replReg); - /* begin genStackArgAt:into: */ - offset8 = (2) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction23 = genoperandoperandoperand(MoveMwrR, offset8, SPReg, stopReg); - /* begin genStackArgAt:into: */ - offset9 = (3) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction24 = genoperandoperandoperand(MoveMwrR, offset9, SPReg, startReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSmi1 = genJumpNotSmallInteger(repStartReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSmi2 = genJumpNotSmallInteger(stopReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSmi3 = genJumpNotSmallInteger(startReg); - - /* if start>stop primitive success */ - jumpImm = genJumpImmediate(replReg); - /* begin CmpR:R: */ - assert(!((startReg == SPReg))); - genoperandoperand(CmpRR, startReg, stopReg); - /* begin JumpLess: */ - jumpEmpty = genConditionalBranchoperand(JumpLess, ((sqInt)0)); -# if IMMUTABILITY - jumpImmutable = genJumpImmutablescratchReg(ReceiverResultReg, TempReg); -# endif - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)0 << 1) | 1); - anInstruction13 = genoperandoperand(CmpCqR, (((usqInt)0 << 1) | 1), startReg); - /* begin JumpLessOrEqual: */ - jumpOutOfBounds1 = genConditionalBranchoperand(JumpLessOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)0 << 1) | 1); - anInstruction14 = genoperandoperand(CmpCqR, (((usqInt)0 << 1) | 1), repStartReg); - /* begin JumpLessOrEqual: */ - jumpOutOfBounds2 = genConditionalBranchoperand(JumpLessOrEqual, ((sqInt)0)); - if (maybeMethodClassOfseemsToBeInstantiating(methodObj, arrayFormat())) { - - /* Are they both array format ? */ - genGetFormatOfinto(arrayReg, TempReg); - genGetFormatOfinto(replReg, startReg); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction2 = genoperandoperand(CmpCqR, arrayFormat(), startReg); - /* begin JumpNonZero: */ - jumpIncorrectFormat1 = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction3 = genoperandoperand(CmpCqR, arrayFormat(), TempReg); - /* begin JumpNonZero: */ - jumpIncorrectFormat2 = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genGetNumSlotsOfinto(arrayReg, TempReg); - genConvertSmallIntegerToIntegerInReg(stopReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, stopReg); - /* begin JumpGreater: */ - jumpOutOfBounds3 = genConditionalBranchoperand(JumpGreater, ((sqInt)0)); - genGetNumSlotsOfinto(replReg, TempReg); - /* begin genStackArgAt:into: */ - offset = (3) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperandoperand(MoveMwrR, offset, SPReg, startReg); - genConvertSmallIntegerToIntegerInReg(startReg); - genConvertSmallIntegerToIntegerInReg(repStartReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, startReg, stopReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, repStartReg, stopReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, stopReg); - /* begin JumpGreater: */ - jumpOutOfBounds4 = genConditionalBranchoperand(JumpGreater, ((sqInt)0)); - /* begin checkLiteral:forInstruction: */ - storeCheckBoundary(); - anInstruction4 = genoperandoperand(MoveCwR, storeCheckBoundary(), TempReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, arrayReg); - /* begin JumpBelow: */ - jmpDestYoung = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - if (!CheckRememberedInTrampoline) { - jmpAlreadyRemembered = genCheckRememberedBitOfscratch(arrayReg, TempReg); - } - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - callStoreCheckTrampoline(); - /* begin PopR: */ - genoperand(PopR, LinkReg); - jmpTarget(jmpDestYoung, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (!CheckRememberedInTrampoline) { - jmpTarget(jmpAlreadyRemembered, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - /* begin genStackArgAt:into: */ - offset1 = (2) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction16 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, stopReg); - genConvertSmallIntegerToIntegerInReg(stopReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, startReg, repStartReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), repStartReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, repStartReg, replReg); - adjust = (((usqInt)(BaseHeaderSize)) >> (shiftForWord())) - 1; - if (adjust != 0) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, adjust, startReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AddCqR, adjust, stopReg); - } - /* begin MoveXwr:R:R: */ - instr = genoperandoperandoperand(MoveXwrRR, startReg, replReg, TempReg); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, TempReg, startReg, arrayReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(AddCqR, 1, startReg); - /* begin CmpR:R: */ - assert(!((startReg == SPReg))); - genoperandoperand(CmpRR, startReg, stopReg); - /* begin JumpAboveOrEqual: */ - genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)instr)); - jmpTarget(jumpEmpty, (methodOrBlockNumArgs <= 2 /* numRegArgs */ - ? (/* begin RetN: */ - genoperand(RetN, 0)) - : (/* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord)))); - jmpTarget(jumpIncorrectFormat1, jmpTarget(jumpIncorrectFormat2, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - } - if (maybeMethodClassOfseemsToBeInstantiating(methodObj, firstByteFormat())) { - - /* Are they both byte array format ? CompiledMethod excluded */ - genGetFormatOfinto(arrayReg, TempReg); - genGetFormatOfinto(replReg, repStartReg); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction8 = genoperandoperand(CmpCqR, firstByteFormat(), repStartReg); - /* begin JumpLess: */ - jumpIncorrectFormat1 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction9 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), repStartReg); - /* begin JumpGreaterOrEqual: */ - jumpIncorrectFormat2 = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction10 = genoperandoperand(CmpCqR, firstByteFormat(), TempReg); - /* begin JumpLess: */ - jumpIncorrectFormat3 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction11 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), TempReg); - /* begin JumpGreaterOrEqual: */ - jumpIncorrectFormat4 = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - genGetNumSlotsOfinto(arrayReg, startReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), startReg); - gAndCqRR(BytesPerWord - 1, TempReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, startReg); - genConvertSmallIntegerToIntegerInReg(stopReg); - /* begin CmpR:R: */ - assert(!((startReg == SPReg))); - genoperandoperand(CmpRR, startReg, stopReg); - /* begin JumpGreater: */ - jumpOutOfBounds3 = genConditionalBranchoperand(JumpGreater, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, repStartReg, TempReg); - /* begin genStackArgAt:into: */ - offset2 = (0) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, repStartReg); - /* begin genStackArgAt:into: */ - offset3 = (3) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction18 = genoperandoperandoperand(MoveMwrR, offset3, SPReg, startReg); - genConvertSmallIntegerToIntegerInReg(startReg); - genConvertSmallIntegerToIntegerInReg(repStartReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, startReg, stopReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, repStartReg, stopReg); - genGetNumSlotsOfinto(replReg, startReg); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), startReg); - gAndCqRR(BytesPerWord - 1, TempReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, TempReg, startReg); - /* begin CmpR:R: */ - assert(!((startReg == SPReg))); - genoperandoperand(CmpRR, startReg, stopReg); - /* begin JumpGreater: */ - jumpOutOfBounds4 = genConditionalBranchoperand(JumpGreater, ((sqInt)0)); - /* begin genStackArgAt:into: */ - offset4 = (3) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperandoperand(MoveMwrR, offset4, SPReg, startReg); - genConvertSmallIntegerToIntegerInReg(startReg); - /* begin genStackArgAt:into: */ - offset5 = (2) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperandoperand(MoveMwrR, offset5, SPReg, stopReg); - genConvertSmallIntegerToIntegerInReg(stopReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, startReg, repStartReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, repStartReg, replReg); - adjust = BaseHeaderSize - 1; - if (adjust != 0) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(AddCqR, adjust, startReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(AddCqR, adjust, stopReg); - } - /* begin MoveXbr:R:R: */ - instr = genoperandoperandoperand(MoveXbrRR, startReg, replReg, TempReg); - /* begin MoveR:Xbr:R: */ - genoperandoperandoperand(MoveRXbrR, TempReg, startReg, arrayReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperand(AddCqR, 1, startReg); - /* begin CmpR:R: */ - assert(!((startReg == SPReg))); - genoperandoperand(CmpRR, startReg, stopReg); - /* begin JumpAboveOrEqual: */ - genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)instr)); - jmpTarget(jumpEmpty, (methodOrBlockNumArgs <= 2 /* numRegArgs */ - ? (/* begin RetN: */ - genoperand(RetN, 0)) - : (/* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord)))); - jmpTarget(jumpIncorrectFormat4, jmpTarget(jumpIncorrectFormat3, jmpTarget(jumpIncorrectFormat2, jmpTarget(jumpIncorrectFormat1, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))); - } - if (((result = compileInterpreterPrimitive())) < 0) { - return result; - } - jmpTarget(jumpImm, jmpTarget(jumpNotSmi1, jmpTarget(jumpNotSmi2, jmpTarget(jumpNotSmi3, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))); - jmpTarget(jumpOutOfBounds1, jmpTarget(jumpOutOfBounds2, jmpTarget(jumpOutOfBounds3, jmpTarget(jumpOutOfBounds4, ((AbstractInstruction *) (((jumpImm->operands))[0])))))); -# if IMMUTABILITY - jmpTarget(jumpImmutable, ((AbstractInstruction *) (((jumpImm->operands))[0]))); -# endif - return CompletePrimitive; -} - - /* CogObjectRepresentationForSpur>>#genSetSmallIntegerTagsIn: */ -static sqInt NoDbgRegParms -genSetSmallIntegerTagsIn(sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(OrCqR, 1, scratchReg); - return 0; -} - - -/* Create a trampoline to store-check the update of the receiver in a - closure's outerContext in compileBlockFrameBuild:. */ - - /* CogObjectRepresentationForSpur>>#genStoreCheckContextReceiverTrampoline */ -static usqInt -genStoreCheckContextReceiverTrampoline(void) -{ - usqInt startAddress; - - startAddress = methodZoneBase(); - zeroOpcodeIndex(); - genStoreCheckReceiverRegvalueRegscratchReginFrame(ReceiverResultReg, Arg0Reg, TempReg, 0); - /* begin RetN: */ - genoperand(RetN, 0); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress("ceStoreCheckContextReceiver", startAddress); - recordRunTimeObjectReferences(); - return startAddress; -} - - -/* Generate the code for a store check of valueReg into destReg. */ - - /* CogObjectRepresentationForSpur>>#genStoreCheckReceiverReg:valueReg:scratchReg:inFrame: */ -static sqInt NoDbgRegParms -genStoreCheckReceiverRegvalueRegscratchReginFrame(sqInt destReg, sqInt valueReg, sqInt scratchReg, sqInt inFrame) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction * inst; - AbstractInstruction *jmpAlreadyRemembered; - AbstractInstruction *jmpDestYoung; - AbstractInstruction *jmpImmediate; - AbstractInstruction *jmpSourceOld; - - - /* Is value stored an immediate? If so we're done */ - jmpAlreadyRemembered = ((AbstractInstruction *) 0); - - /* Get the old/new boundary in scratchReg */ - jmpImmediate = genJumpImmediate(valueReg); - /* begin checkLiteral:forInstruction: */ - storeCheckBoundary(); - anInstruction = genoperandoperand(MoveCwR, storeCheckBoundary(), scratchReg); - /* begin CmpR:R: */ - assert(!((scratchReg == SPReg))); - genoperandoperand(CmpRR, scratchReg, destReg); - /* begin JumpBelow: */ - jmpDestYoung = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((scratchReg == SPReg))); - genoperandoperand(CmpRR, scratchReg, valueReg); - /* begin JumpAboveOrEqual: */ - jmpSourceOld = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - if (!CheckRememberedInTrampoline) { - jmpAlreadyRemembered = genCheckRememberedBitOfscratch(destReg, scratchReg); - } - assert(destReg == ReceiverResultReg); - /* begin evaluateTrampolineCallBlock:protectLinkRegIfNot: */ - if (inFrame) { - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceStoreCheckTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - } - else { - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceStoreCheckTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin PopR: */ - genoperand(PopR, LinkReg); - } - jmpTarget(jmpImmediate, jmpTarget(jmpDestYoung, jmpTarget(jmpSourceOld, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))); - if (!CheckRememberedInTrampoline) { - jmpTarget(jmpAlreadyRemembered, ((AbstractInstruction *) (((jmpSourceOld->operands))[0]))); - } - return 0; -} - - /* CogObjectRepresentationForSpur>>#genStoreSourceReg:slotIndex:destReg:scratchReg:inFrame:needsStoreCheck: */ -static sqInt NoDbgRegParms -genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt inFrame, sqInt needsStoreCheck) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - - /* begin genTraceStores */ - if (traceStores > 0) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, TempReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceTraceStoreTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveRMwr, sourceReg, (index * BytesPerWord) + BaseHeaderSize, destReg); - if (needsStoreCheck) { - return genStoreCheckReceiverRegvalueRegscratchReginFrame(destReg, sourceReg, scratchReg, inFrame); - } - return 0; -} - - -/* This method is used for unchecked stores in objects after their creation - (typically, inlined creation of Array, closures and some temp vectors). - Currently there is no need to do the immutability check here - */ - - /* CogObjectRepresentationForSpur>>#genStoreSourceReg:slotIndex:intoNewObjectInDestReg: */ -static sqInt NoDbgRegParms -genStoreSourceRegslotIndexintoNewObjectInDestReg(sqInt sourceReg, sqInt index, sqInt destReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveRMwr, sourceReg, (index * BytesPerWord) + BaseHeaderSize, destReg); - return 0; -} - - -/* Convention: - - RcvrResultReg holds the object mutated. - If immutability failure: - - TempReg holds the instance variable index mutated - if instVarIndex > numDedicatedStoreTrampoline - - ClassReg holds the value to store - Registers are not lived across this trampoline as the - immutability failure may need new stack frames. */ - - /* CogObjectRepresentationForSpur>>#genStoreTrampolineCalled:instVarIndex: */ -#if IMMUTABILITY -static usqInt NoDbgRegParms -genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) -{ - AbstractInstruction * jumpImmutable; - AbstractInstruction * jumpImmutable1; - AbstractInstruction * jumpRC; - sqInt pushLinkReg; - usqInt startAddress; - - startAddress = methodZoneBase(); - zeroOpcodeIndex(); - if (CheckRememberedInTrampoline) { - /* begin genStoreTrampolineCheckingRememberedCalled:instVarIndex: */ - - /* Store check */ - /* If on 64-bits and doing the remembered bit test here, we can combine the tests to fetch the header once. */ - jumpImmutable = genJumpImmutablescratchReg(ReceiverResultReg, SendNumArgsReg); - jumpRC = genCheckRememberedBitOfscratch(ReceiverResultReg, SendNumArgsReg); - assert(((jumpRC->opcode)) == JumpNonZero); - (jumpRC->opcode = JumpZero); - /* begin RetN: */ - genoperand(RetN, 0); - jmpTarget(jumpRC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) - ? ReceiverResultReg - : ABIResultReg)); - jmpTarget(jumpImmutable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(ceCannotAssignTowithIndexvalueToAssign, 3, ReceiverResultReg, (instVarIndex < (NumStoreTrampolines - 1) - ? (/* begin trampolineArgConstant: */ - assert(instVarIndex >= 0), - -2 - instVarIndex) - : TempReg), ClassReg, null, 0 /* emptyRegisterMask */, 1, NoReg); - } - else { - /* begin genStoreTrampolineNotCheckingRememberedCalled:instVarIndex: */ - genSmalltalkToCStackSwitch((pushLinkReg = 1)); - - /* Store check */ - jumpImmutable1 = genJumpImmutablescratchReg(ReceiverResultReg, SendNumArgsReg); - compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) - ? ReceiverResultReg - : ABIResultReg), 0 /* emptyRegisterMask */); - genLoadStackPointers(backEnd()); - genTrampolineReturn(pushLinkReg); - jmpTarget(jumpImmutable1, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileCallFornumArgsargargargargresultRegregsToSave(ceCannotAssignTowithIndexvalueToAssign, 3, ReceiverResultReg, (instVarIndex < (NumStoreTrampolines - 1) - ? (/* begin trampolineArgConstant: */ - assert(instVarIndex >= 0), - -2 - instVarIndex) - : TempReg), ClassReg, null, NoReg, 0 /* emptyRegisterMask */); - genLoadStackPointers(backEnd()); - genTrampolineReturn(pushLinkReg); - } - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress(trampolineName, startAddress); - recordRunTimeObjectReferences(); - return startAddress; -} -#endif /* IMMUTABILITY */ - - -/* Store check code is duplicated to use a single trampoline */ - - /* CogObjectRepresentationForSpur>>#genStoreWithImmutabilityAndStoreCheckSourceReg:slotIndex:destReg:scratchReg:needRestoreRcvr: */ -#if IMMUTABILITY -static sqInt NoDbgRegParms -genStoreWithImmutabilityAndStoreCheckSourceRegslotIndexdestRegscratchRegneedRestoreRcvr(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt needRestoreRcvr) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *abstractInstruction2; - AbstractInstruction *abstractInstruction3; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *immutableJump; - AbstractInstruction *jmpAlreadyRemembered; - AbstractInstruction *jmpDestYoung; - AbstractInstruction *jmpImmediate; - AbstractInstruction *jmpSourceOld; - - jmpAlreadyRemembered = ((AbstractInstruction *) 0); - immutableJump = genJumpImmutablescratchReg(destReg, scratchReg); - /* begin genTraceStores */ - if (traceStores > 0) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, TempReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceTraceStoreTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveRMwr, sourceReg, (index * BytesPerWord) + BaseHeaderSize, destReg); - - /* Get the old/new boundary in scratchReg */ - jmpImmediate = genJumpImmediate(sourceReg); - /* begin checkLiteral:forInstruction: */ - storeCheckBoundary(); - anInstruction1 = genoperandoperand(MoveCwR, storeCheckBoundary(), scratchReg); - /* begin CmpR:R: */ - assert(!((scratchReg == SPReg))); - genoperandoperand(CmpRR, scratchReg, destReg); - /* begin JumpBelow: */ - jmpDestYoung = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((scratchReg == SPReg))); - genoperandoperand(CmpRR, scratchReg, sourceReg); - /* begin JumpAboveOrEqual: */ - jmpSourceOld = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - if (!CheckRememberedInTrampoline) { - jmpAlreadyRemembered = genCheckRememberedBitOfscratch(destReg, scratchReg); - } - jmpTarget(immutableJump, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin genStoreTrampolineCall: */ - assert(IMMUTABILITY); - if (index >= (NumStoreTrampolines - 1)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, index, TempReg); - /* begin CallRT: */ - abstractInstruction3 = genoperand(Call, ceStoreTrampolines[NumStoreTrampolines - 1]); - (abstractInstruction3->annotation = IsRelativeCall); - } - else { - /* begin CallRT: */ - abstractInstruction1 = genoperand(Call, ceStoreTrampolines[index]); - (abstractInstruction1->annotation = IsRelativeCall); - } - /* begin annotateBytecode: */ - abstractInstruction2 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction2->annotation = HasBytecodePC); - /* begin voidReceiverOptStatus */ - ((simSelf())->liveRegister = NoReg); - if (needRestoreRcvr) { - /* begin putSelfInReceiverResultReg */ - storeToReg(simSelf(), ReceiverResultReg); - } - jmpTarget(jmpImmediate, jmpTarget(jmpDestYoung, jmpTarget(jmpSourceOld, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))); - if (!CheckRememberedInTrampoline) { - jmpTarget(jmpAlreadyRemembered, ((AbstractInstruction *) (((jmpSourceOld->operands))[0]))); - } - return 0; -} -#endif /* IMMUTABILITY */ - - -/* Gen an immutability check with no store check (e.g. assigning an immediate - literal) - */ -/* imm check has its own trampoline */ - - /* CogObjectRepresentationForSpur>>#genStoreWithImmutabilityButNoStoreCheckSourceReg:slotIndex:destReg:scratchReg:needRestoreRcvr: */ -#if IMMUTABILITY -static sqInt NoDbgRegParms -genStoreWithImmutabilityButNoStoreCheckSourceRegslotIndexdestRegscratchRegneedRestoreRcvr(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt needRestoreRcvr) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *abstractInstruction2; - AbstractInstruction *abstractInstruction3; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *immutabilityFailure; - AbstractInstruction *mutableJump; - - mutableJump = genJumpMutablescratchReg(destReg, scratchReg); - /* begin genStoreTrampolineCall: */ - assert(IMMUTABILITY); - if (index >= (NumStoreTrampolines - 1)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, index, TempReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceStoreTrampolines[NumStoreTrampolines - 1]); - (abstractInstruction->annotation = IsRelativeCall); - } - else { - /* begin CallRT: */ - abstractInstruction1 = genoperand(Call, ceStoreTrampolines[index]); - (abstractInstruction1->annotation = IsRelativeCall); - } - /* begin annotateBytecode: */ - abstractInstruction2 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction2->annotation = HasBytecodePC); - /* begin voidReceiverOptStatus */ - ((simSelf())->liveRegister = NoReg); - if (needRestoreRcvr) { - /* begin putSelfInReceiverResultReg */ - storeToReg(simSelf(), ReceiverResultReg); - } - /* begin Jump: */ - immutabilityFailure = genoperand(Jump, ((sqInt)0)); - jmpTarget(mutableJump, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin genTraceStores */ - if (traceStores > 0) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, TempReg); - /* begin CallRT: */ - abstractInstruction3 = genoperand(Call, ceTraceStoreTrampoline); - (abstractInstruction3->annotation = IsRelativeCall); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveRMwr, sourceReg, (index * BytesPerWord) + BaseHeaderSize, destReg); - jmpTarget(immutabilityFailure, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} -#endif /* IMMUTABILITY */ - - -/* We know there is a frame as immutability check requires a frame */ -/* needRestoreRcvr has to be true to keep RcvrResultReg live with the - receiver in it across the trampoline - */ -/* Trampoline convention... */ - - /* CogObjectRepresentationForSpur>>#genStoreWithImmutabilityCheckSourceReg:slotIndex:destReg:scratchReg:needsStoreCheck:needRestoreRcvr: */ -#if IMMUTABILITY -static sqInt NoDbgRegParms -genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt needsStoreCheck, sqInt needRestoreRcvr) -{ - assert(destReg == ReceiverResultReg); - assert(scratchReg == TempReg); - assert(sourceReg == ClassReg); - if (needsStoreCheck) { - genStoreWithImmutabilityAndStoreCheckSourceRegslotIndexdestRegscratchRegneedRestoreRcvr(sourceReg, index, destReg, scratchReg, needRestoreRcvr); - } - else { - genStoreWithImmutabilityButNoStoreCheckSourceRegslotIndexdestRegscratchRegneedRestoreRcvr(sourceReg, index, destReg, scratchReg, needRestoreRcvr); - } - return 0; -} -#endif /* IMMUTABILITY */ - - -/* Make sure SendNumArgsReg and ClassReg are available in addition to - ReceiverResultReg and TempReg in - genGetActiveContextNumArgs:large:inBlock:. - */ - - /* CogObjectRepresentationForSpur>>#getActiveContextAllocatesInMachineCode */ -static sqInt -getActiveContextAllocatesInMachineCode(void) -{ - return 1; -} - - -/* Since all cache tags in Spur are class indices none of - them are young or have to be updated in a scavenge. */ - - /* CogObjectRepresentationForSpur>>#inlineCacheTagIsYoung: */ -static sqInt NoDbgRegParms -inlineCacheTagIsYoung(sqInt cacheTag) -{ - return 0; -} - - /* CogObjectRepresentationForSpur>>#jumpNotCharacterUnsignedValueInRegister: */ -static AbstractInstruction * NoDbgRegParms -jumpNotCharacterUnsignedValueInRegister(sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin CmpCq:R: */ - anInstruction = genoperandoperand(CmpCqR, 0x3FFFFFFF, reg); - /* begin JumpAbove: */ - return genConditionalBranchoperand(JumpAbove, ((sqInt)0)); -} - - -/* Mark and trace a literal in a machine code instruction preceding address - in cogMethodOrNil. - Answer if code was modified. */ - - /* CogObjectRepresentationForSpur>>#markAndTraceLiteral:in:atpc: */ -static sqInt NoDbgRegParms -markAndTraceLiteralinatpc(sqInt literal, CogMethod *cogMethodOrNil, usqInt address) -{ - sqInt objOop; - - if (!(couldBeObject(literal))) { - return 0; - } - assert(addressCouldBeObj(literal)); - if (!(isForwarded(literal))) { - markAndTrace(literal); - return 0; - } - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - objOop = followForwarded(literal); - storeLiteralbeforeFollowingAddress(backEnd(), objOop, address); - markAndTraceUpdatedLiteralin(objOop, cogMethodOrNil); - return 1; -} - - -/* Mark and trace a literal in a sqInt variable of cogMethod. */ - - /* CogObjectRepresentationForSpur>>#markAndTraceLiteral:in:at: */ -static void NoDbgRegParms -markAndTraceLiteralinat(sqInt literal, CogMethod *cogMethod, sqInt *address) -{ - sqInt objOop; - - if (!(couldBeObject(literal))) { - return; - } - assert(addressCouldBeObj(literal)); - if (!(isForwarded(literal))) { - markAndTrace(literal); - return; - } - objOop = followForwarded(literal); - address[0] = objOop; - markAndTraceUpdatedLiteralin(objOop, cogMethod); -} - - -/* Common code to mark a literal in cogMethod and add - the cogMethod to youngReferrers if the literal is young. */ - - /* CogObjectRepresentationForSpur>>#markAndTraceUpdatedLiteral:in: */ -static void NoDbgRegParms -markAndTraceUpdatedLiteralin(sqInt objOop, CogMethod *cogMethodOrNil) -{ - if (isNonImmediate(objOop)) { - if ((cogMethodOrNil != null) - && (isYoungObject(objOop))) { - ensureInYoungReferrers(cogMethodOrNil); - } - markAndTrace(objOop); - } -} - - -/* If primIndex has an accessorDepth and fails, or it is external and fails - with PrimErrNoMemory, - call ceCheckAndMaybeRetryPrimitive if so If ceCheck.... answers true, - retry the primitive. */ - - /* CogObjectRepresentationForSpur>>#maybeCompileRetryOnPrimitiveFail: */ -static sqInt NoDbgRegParms -maybeCompileRetryOnPrimitiveFail(sqInt primIndex) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *jmp; - - if ((accessorDepthForPrimitiveIndex(primIndex)) >= 0) { - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpZero: */ - jmp = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - } - else { - if ((primNumberExternalCall()) != primIndex) { - return 0; - } - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction2 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(CmpCqR, PrimErrNoMemory, TempReg); - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - } - compileCallFornumArgsargargargargresultRegregsToSave(ceCheckAndMaybeRetryPrimitive, 1, trampolineArgConstant(primIndex), null, null, null, TempReg, 0 /* emptyRegisterMask */); - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - -/* Generate a shift of the register containing the class tag in a method - cache probe. - c.f. SpurMemoryManager>>methodCacheHashOf:with: */ - - /* CogObjectRepresentationForSpur>>#maybeShiftClassTagRegisterForMethodCacheProbe: */ -static sqInt NoDbgRegParms -maybeShiftClassTagRegisterForMethodCacheProbe(sqInt classTagReg) -{ - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, 2, classTagReg); - return 0; -} - - /* CogObjectRepresentationForSpur>>#numCharacterBits */ -static sqInt -numCharacterBits(void) -{ - return 30; -} - - -/* Define how many register arguments a StackToRegisterMappingCogit can - and should use with the receiver. The value must be 0, 1 or 2. Note that a - SimpleStackBasedCogit always has 0 register args (although the receiver is - passed in a register). The Spur object representation is simple enough - that implementing at:put: is straight-forward and hence 2 register args - are worth - while. The method must be inlined in CoInterpreter, and dead code - eliminated so that the register-popping enilopmarts such as - enterRegisterArgCogMethod:- at:receiver: do not have to be implemented in - SimpleStackBasedCogit. */ - - /* CogObjectRepresentationForSpur>>#numRegArgs */ -sqInt -numRegArgs(void) -{ - return 2; -} - - /* CogObjectRepresentationForSpur>>#remapObject: */ -static sqInt NoDbgRegParms -remapObject(sqInt objOop) -{ - assert(addressCouldBeObj(objOop)); - return (shouldRemapObj(objOop) - ? remapObj(objOop) - : objOop); -} - - /* CogObjectRepresentationForSpur>>#remapOop: */ -static sqInt NoDbgRegParms -remapOop(sqInt objOop) -{ - return (shouldRemapOop(objOop) - ? remapObj(objOop) - : objOop); -} - - -/* Objects in newSpace or oldSpace except nil, true, false & - classTableRootObj need to be annotated. - */ - - /* CogObjectRepresentationForSpur>>#shouldAnnotateObjectReference: */ -static sqInt NoDbgRegParms -shouldAnnotateObjectReference(sqInt anOop) -{ - return (isNonImmediate(anOop)) - && ((oopisGreaterThan(anOop, classTableRootObj())) - || (oopisLessThan(anOop, nilObject()))); -} - - /* CogObjectRepresentationForSpur>>#slotOffsetOfInstVarIndex: */ -static sqInt NoDbgRegParms -slotOffsetOfInstVarIndex(sqInt index) -{ - return (index * BytesPerWord) + BaseHeaderSize; -} - - /* CogSimStackEntry>>#ensureSpilledAt:from: */ -static SimStackEntry * NoDbgRegParms -ensureSpilledAtfrom(SimStackEntry * self_in_ensureSpilledAtfrom, sqInt baseOffset, sqInt baseRegister) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *inst; - sqInt reg; - sqInt wordConstant; - - if ((self_in_ensureSpilledAtfrom->spilled)) { - if (((self_in_ensureSpilledAtfrom->type)) == SSSpill) { - assert(((((self_in_ensureSpilledAtfrom->offset)) == baseOffset) - && (((self_in_ensureSpilledAtfrom->registerr)) == baseRegister)) - || (violatesEnsureSpilledSpillAssert())); - return self_in_ensureSpilledAtfrom; - } - } - assert(((self_in_ensureSpilledAtfrom->type)) != SSSpill); - traceSpill(self_in_ensureSpilledAtfrom); - if (((self_in_ensureSpilledAtfrom->type)) == SSConstant) { - if (shouldAnnotateObjectReference((self_in_ensureSpilledAtfrom->constant))) { - inst = annotateobjRef(gPushCw((self_in_ensureSpilledAtfrom->constant)), (self_in_ensureSpilledAtfrom->constant)); - } - else { - /* begin PushCq: */ - wordConstant = (self_in_ensureSpilledAtfrom->constant); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperand(PushCq, wordConstant); - inst = anInstruction; - } - } - else { - if (((self_in_ensureSpilledAtfrom->type)) == SSBaseOffset) { - /* begin checkQuickConstant:forInstruction: */ - (self_in_ensureSpilledAtfrom->offset); - anInstruction1 = genoperandoperandoperand(MoveMwrR, (self_in_ensureSpilledAtfrom->offset), (self_in_ensureSpilledAtfrom->registerr), TempReg); - /* begin PushR: */ - inst = genoperand(PushR, TempReg); - } - else { - assert(((self_in_ensureSpilledAtfrom->type)) == SSRegister); - /* begin PushR: */ - reg = (self_in_ensureSpilledAtfrom->registerr); - inst = genoperand(PushR, reg); - } - (self_in_ensureSpilledAtfrom->type) = SSSpill; - (self_in_ensureSpilledAtfrom->offset) = baseOffset; - (self_in_ensureSpilledAtfrom->registerr) = baseRegister; - } - (self_in_ensureSpilledAtfrom->spilled) = 1; - return 0; -} - - /* CogSimStackEntry>>#isSameEntryAs: */ -static sqInt NoDbgRegParms -isSameEntryAs(SimStackEntry * self_in_isSameEntryAs, CogSimStackEntry *ssEntry) -{ - return (((self_in_isSameEntryAs->type)) == ((ssEntry->type))) - && ((((((self_in_isSameEntryAs->type)) == SSBaseOffset) - || (((self_in_isSameEntryAs->type)) == SSSpill)) - && ((((self_in_isSameEntryAs->offset)) == ((ssEntry->offset))) - && (((self_in_isSameEntryAs->registerr)) == ((ssEntry->registerr))))) - || (((((self_in_isSameEntryAs->type)) == SSRegister) - && (((self_in_isSameEntryAs->registerr)) == ((ssEntry->registerr)))) - || ((((self_in_isSameEntryAs->type)) == SSConstant) - && (((self_in_isSameEntryAs->constant)) == ((ssEntry->constant)))))); -} - - -/* Receiver is not a forwarder, except in blocks with no inst var access. - For now we optimize only the case where receiver is accessed in a method. */ - - /* CogSimStackEntry>>#mayBeAForwarder */ -static sqInt NoDbgRegParms -mayBeAForwarder(SimStackEntry * self_in_mayBeAForwarder) -{ - if ((((self_in_mayBeAForwarder->type)) == SSRegister) - && (isNonForwarderReceiver((self_in_mayBeAForwarder->registerr)))) { - return 0; - } - return ((self_in_mayBeAForwarder->type)) != SSConstant; -} - - /* CogSimStackEntry>>#popToReg: */ -static void NoDbgRegParms -popToReg(SimStackEntry * self_in_popToReg, sqInt reg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt quickConstant; - sqInt reg1; - - if ((self_in_popToReg->spilled)) { - /* begin PopR: */ - genoperand(PopR, reg); - } - else { - switch ((self_in_popToReg->type)) { - case SSBaseOffset: - /* begin checkQuickConstant:forInstruction: */ - (self_in_popToReg->offset); - anInstruction = genoperandoperandoperand(MoveMwrR, (self_in_popToReg->offset), (self_in_popToReg->registerr), reg); - break; - case SSConstant: - if (shouldAnnotateObjectReference((self_in_popToReg->constant))) { - annotateobjRef(gMoveCwR((self_in_popToReg->constant), reg), (self_in_popToReg->constant)); - } - else { - /* begin MoveCq:R: */ - quickConstant = (self_in_popToReg->constant); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, quickConstant, reg); - } - break; - case SSRegister: - if (reg != ((self_in_popToReg->registerr))) { - /* begin MoveR:R: */ - reg1 = (self_in_popToReg->registerr); - genoperandoperand(MoveRR, reg1, reg); - } - else { - /* begin Label */ - genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - break; - default: - error("Case not found and no otherwise clause"); - } - } -} - - -/* Answer a bit mask for the receiver's register, if any. */ - - /* CogSimStackEntry>>#registerMask */ -static sqInt NoDbgRegParms -registerMask(SimStackEntry * self_in_registerMask) -{ - sqInt reg; - - return ((((self_in_registerMask->type)) == SSBaseOffset) - || (((self_in_registerMask->type)) == SSRegister) - ? (/* begin registerMaskFor: */ - (reg = (self_in_registerMask->registerr)), - 1U << reg) - : 0); -} - - /* CogSimStackEntry>>#registerMaskOrNone */ -static sqInt NoDbgRegParms -registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone) -{ - sqInt reg; - - return (((self_in_registerMaskOrNone->type)) == SSRegister - ? (/* begin registerMaskFor: */ - (reg = (self_in_registerMaskOrNone->registerr)), - 1U << reg) - : 0); -} - - /* CogSimStackEntry>>#registerOrNone */ -static sqInt NoDbgRegParms -registerOrNone(SimStackEntry * self_in_registerOrNone) -{ - return (((self_in_registerOrNone->type)) == SSRegister - ? (self_in_registerOrNone->registerr) - : NoReg); -} - - /* CogSimStackEntry>>#storeToReg: */ -static void NoDbgRegParms -storeToReg(SimStackEntry * self_in_storeToReg, sqInt reg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt quickConstant; - sqInt reg1; - - switch ((self_in_storeToReg->type)) { - case SSBaseOffset: - case SSSpill: - /* begin checkQuickConstant:forInstruction: */ - (self_in_storeToReg->offset); - anInstruction = genoperandoperandoperand(MoveMwrR, (self_in_storeToReg->offset), (self_in_storeToReg->registerr), reg); - break; - case SSConstant: - if (shouldAnnotateObjectReference((self_in_storeToReg->constant))) { - annotateobjRef(gMoveCwR((self_in_storeToReg->constant), reg), (self_in_storeToReg->constant)); - } - else { - /* begin MoveCq:R: */ - quickConstant = (self_in_storeToReg->constant); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, quickConstant, reg); - } - break; - case SSRegister: - if (reg != ((self_in_storeToReg->registerr))) { - /* begin MoveR:R: */ - reg1 = (self_in_storeToReg->registerr); - genoperandoperand(MoveRR, reg1, reg); - } - else { - /* begin Label */ - genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - break; - default: - error("Case not found and no otherwise clause"); - } -} - - /* CogSSBytecodeFixup>>#isMergeFixup */ -static sqInt NoDbgRegParms -isMergeFixup(BytecodeFixup * self_in_isMergeFixup) -{ - return (((usqInt)((self_in_isMergeFixup->targetInstruction)))) == NeedsMergeFixupFlag; -} - - /* InLineLiteralsManager>>#checkLiteral:forInstruction: */ -static AbstractInstruction * NoDbgRegParms -checkLiteralforInstruction(sqInt literal, AbstractInstruction *anInstruction) -{ - return anInstruction; -} - - /* InLineLiteralsManager>>#checkQuickConstant:forInstruction: */ -static AbstractInstruction * NoDbgRegParms -checkQuickConstantforInstruction(sqInt literal, AbstractInstruction *anInstruction) -{ - return anInstruction; -} - - /* SimpleStackBasedCogit>>#cogMethodHasExternalPrim: */ -sqInt -cogMethodHasExternalPrim(CogMethod *aCogMethod) -{ - sqInt primIndex; - - primIndex = primitiveIndexOfMethodheader((aCogMethod->methodObject), (aCogMethod->methodHeader)); - return (primIndex == PrimNumberExternalCall) - || (primIndex == PrimNumberFFICall); -} - - /* SimpleStackBasedCogit>>#cogMethodHasMachineCodePrim: */ -sqInt -cogMethodHasMachineCodePrim(CogMethod *aCogMethod) -{ - sqInt primIndex; - - primIndex = primitiveIndexOfMethodheader((aCogMethod->methodObject), (aCogMethod->objectHeader)); - return (((primIndex >= 1) && (primIndex <= MaxCompiledPrimitiveIndex))) - && ((((primitiveGeneratorTable[primIndex]).primitiveGenerator)) != null); -} - - -/* Compile the jump instruction(s) at the end of the method that dispatch to - each block body. - */ - - /* SimpleStackBasedCogit>>#compileBlockDispatch */ -static sqInt -compileBlockDispatch(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *jumpSkip; - - assert(blockCount > 0); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 0, SendNumArgsReg); - blockEntryNoContextSwitch = anInstruction; - /* begin Jump: */ - jumpSkip = genoperand(Jump, ((sqInt)0)); - /* begin MoveR:R: */ - blockEntryLabel = genoperandoperand(MoveRR, ReceiverResultReg, SendNumArgsReg); - jmpTarget(jumpSkip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (blockCount > 1) { - genLoadSlotsourceRegdestReg(ClosureStartPCIndex, ReceiverResultReg, TempReg); - } - compileBlockDispatchFromto(0, blockCount - 1); - return 0; -} - - -/* After pushing the temporaries but before the stack limit check a primitive - method needs to fetch the error code, if any. If the primitive has failed, - call the trampoline - that will assign it to the last temp. */ - - /* SimpleStackBasedCogit>>#compileGetErrorCode */ -static void -compileGetErrorCode(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *jmpNoError; - - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpZero: */ - jmpNoError = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceReapAndResetErrorCodeTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - jmpTarget(jmpNoError, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); -} - - /* SimpleStackBasedCogit>>#compileInterpreterPrimitive */ -static sqInt -compileInterpreterPrimitive(void) -{ - sqInt flags; - void (*primitiveRoutine)(void); - - flags = 0; - primitiveRoutine = functionPointerForCompiledMethodprimitiveIndexprimitivePropertyFlagsInto(methodObj, primitiveIndex, (&flags)); - assert(!((((flags & PrimCallOnSmalltalkStack) != 0)))); - return compileInterpreterPrimitiveflags(primitiveRoutine, flags); -} - - -/* Compile a call to an interpreter primitive. Call the C routine with the - usual stack-switching dance, test the primFailCode and then either - return on success or continue to the method body. */ - - /* SimpleStackBasedCogit>>#compileInterpreterPrimitive:flags: */ -static sqInt NoDbgRegParms -compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) -{ - sqInt address; - sqInt address1; - sqInt address2; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction24; - AbstractInstruction *anInstruction25; - AbstractInstruction *anInstruction26; - AbstractInstruction *anInstruction28; - AbstractInstruction *anInstruction30; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction33; - AbstractInstruction *anInstruction34; - AbstractInstruction *anInstruction35; - AbstractInstruction *anInstruction36; - AbstractInstruction *anInstruction37; - AbstractInstruction *anInstruction38; - AbstractInstruction *anInstruction39; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction * continuePostSampleNonPrim; - AbstractInstruction * continuePostSamplePrim; - AbstractInstruction * jmp; - AbstractInstruction * jmpSampleNonPrim; - AbstractInstruction * jmpSamplePrim; - sqInt offset; - sqInt offset1; - sqInt offset2; - sqInt operand1; - sqInt operand3; - sqInt reg; - sqInt retpc; - - continuePostSampleNonPrim = ((AbstractInstruction *) 0); - continuePostSamplePrim = ((AbstractInstruction *) 0); - jmpSampleNonPrim = ((AbstractInstruction *) 0); - jmpSamplePrim = ((AbstractInstruction *) 0); - assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); - genExternalizePointersForPrimitiveCall(); - /* begin genLoadCStackPointersForPrimCall */ - if (cFramePointerInUse) { - genLoadCStackPointers(backEnd); - } - else { - genLoadCStackPointer(backEnd); - } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick if so */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin MoveAw:R: */ - address = (nextProfileTickAddress()) + BytesPerWord; - /* begin checkLiteral:forInstruction: */ - anInstruction1 = genoperandoperand(MoveAwR, address, ClassReg); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSampleNonPrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSampleNonPrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - if (recordPrimTraceForMethod(methodObj)) { - genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction36 = genoperandoperand(MoveCqR, 0, TempReg); - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction37 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); - if (methodOrBlockNumArgs != 0) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); - } - /* begin checkLiteral:forInstruction: */ - argumentCountAddress(); - anInstruction38 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); - if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { - /* begin checkLiteral:forInstruction: */ - ((sqInt)primitiveRoutine); - anInstruction5 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); - /* begin checkLiteral:forInstruction: */ - primitiveFunctionPointerAddress(); - anInstruction6 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); - } - if (((flags & (PrimCallNeedsNewMethod + PrimCallMayEndureCodeCompaction)) != 0)) { - - /* The ceActivateFailingPrimitiveMethod: machinery can't handle framelessness. */ - if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - needsFrame = 1; - } - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); - /* begin MoveMw:r:R: */ - offset = offsetof(CogMethod, methodObject); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - /* begin checkLiteral:forInstruction: */ - newMethodAddress(); - anInstruction8 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); - } - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction39 = genoperand(PrefetchAw, primFailCodeAddress()); - if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - - /* Sideways call the C primitive routine so that we return through cePrimReturnEnterCogCode. */ - /* On Spur ceActivateFailingPrimitiveMethod: would like to retry if forwarders - are found. So insist on PrimCallNeedsPrimitiveFunction being set too. */ - assert(((flags & PrimCallNeedsPrimitiveFunction) != 0)); - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l32; - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction11 = genoperandoperand(MoveCqR, -2 - null, A0); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A0); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction12 = genoperandoperand(MoveCqR, -2 - null, A1); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A1); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction21 = genoperandoperand(MoveCqR, -2 - null, A2); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A2); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction31 = genoperandoperand(MoveCqR, -2 - null, A3); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A3); - } - l32: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin genSubstituteReturnAddress: */ - retpc = (((flags & PrimCallCollectsProfileSamples) != 0) - ? cePrimReturnEnterCogCodeProfiling - : cePrimReturnEnterCogCode); - /* begin checkLiteral:forInstruction: */ - anInstruction13 = genoperandoperand(MoveCwR, retpc, RA); - /* begin gen:literal: */ - anInstruction10 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); - jmp = (jmpSamplePrim = (continuePostSamplePrim = null)); - } - else { - - /* Call the C primitive routine. */ - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l48; - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, A0); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, A1); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, A2); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, A3); - l48: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin gen:literal: */ - anInstruction15 = genoperand(CallFull, ((sqInt)primitiveRoutine)); - /* begin genRemoveNArgsFromStack: */ - assert(0 <= 4); - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction16 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin MoveAw:R: */ - address1 = (nextProfileTickAddress()) + BytesPerWord; - /* begin checkLiteral:forInstruction: */ - anInstruction17 = genoperandoperand(MoveAwR, address1, ClassReg); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSamplePrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSamplePrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - maybeCompileRetryOnPrimitiveFail(primitiveIndex); - /* begin MoveAw:R: */ - address2 = instructionPointerAddress(); - reg = LinkReg; - /* begin checkLiteral:forInstruction: */ - anInstruction23 = genoperandoperand(MoveAwR, address2, reg); - genLoadStackPointers(backEnd); - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction24 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction25 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset1 = 0; - /* begin checkQuickConstant:forInstruction: */ - anInstruction26 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, BytesPerWord); - } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* The sample is collected by cePrimReturnEnterCogCode for external calls */ - if (!(jmpSamplePrim == null)) { - - /* Call ceCheckProfileTick: to record sample and then continue. */ - jmpTarget(jmpSamplePrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin gen:literal: */ - operand1 = ((usqIntptr_t)ceCheckProfileTick); - /* begin checkLiteral:forInstruction: */ - anInstruction28 = genoperand(CallFull, operand1); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSamplePrim)); - } - jmpTarget(jmpSampleNonPrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction33 = genoperandoperand(MoveCqR, 0, TempReg); - /* begin checkLiteral:forInstruction: */ - newMethodAddress(); - anInstruction34 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); - /* begin gen:literal: */ - operand3 = ((usqIntptr_t)ceCheckProfileTick); - /* begin checkLiteral:forInstruction: */ - anInstruction30 = genoperand(CallFull, operand3); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSampleNonPrim)); - } - if (!(jmp == null)) { - - /* Jump to restore of receiver reg and proceed to frame build for failure. */ - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin MoveMw:r:R: */ - offset2 = BytesPerWord * (methodOrBlockNumArgs + (0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction35 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); - } - return 0; -} - - -/* Compile a call to a machine-code convention interpreter primitive. Call - the C routine - on the Smalltalk stack, assuming it consumes little or no stack space. */ -/* for now handle functions with less than 4 arguments; our C call - marshalling machinery - extends up to 4 arguments only, and the first argument of an mcprim is the - receiver. - */ - - /* SimpleStackBasedCogit>>#compileMachineCodeInterpreterPrimitive: */ -static sqInt NoDbgRegParms -compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)) -{ - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction5; - AbstractInstruction * jmpFail; - sqInt liveRegsMask; - sqInt n; - sqInt offset; - - assert(methodOrBlockNumArgs <= 3); - if ((methodOrBlockNumArgs > 2 /* numRegArgs */) - || (methodOrBlockNumArgs == 0)) { - /* begin registerMaskFor: */ - liveRegsMask = 1U << ReceiverResultReg; - } - else { - if (methodOrBlockNumArgs > 1) { - /* begin registerMaskFor:and:and: */ - liveRegsMask = ((1U << ReceiverResultReg) | (1U << Arg0Reg)) | (1U << Arg1Reg); - } - else { - /* begin registerMaskFor:and: */ - liveRegsMask = (1U << ReceiverResultReg) | (1U << Arg0Reg); - } - } - genSaveRegs(backEnd, liveRegsMask & CallerSavedRegisterMask); - if (methodOrBlockNumArgs > 2 /* numRegArgs */) { - - /* Wrangle args into Arg0Reg, Arg1Reg, SendNumArgsReg & ClassReg */ - /* offset := self bitCountOf: (liveRegsMask bitAnd: CallerSavedRegisterMask). */ - error("shouldBeImplemented"); - } - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - if ((methodOrBlockNumArgs + 1) == 0) { - goto l18; - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, A0); - if ((methodOrBlockNumArgs + 1) == 1) { - goto l18; - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, A1); - if ((methodOrBlockNumArgs + 1) == 2) { - goto l18; - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, A2); - if ((methodOrBlockNumArgs + 1) == 3) { - goto l18; - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SendNumArgsReg, A3); - l18: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin saveAndRestoreLinkRegUsingCalleeSavedRegNotLiveAtPointOfSendAround: */ - /* begin gen:literal: */ - anInstruction1 = genoperand(CallFull, ((sqInt)primitiveRoutine)); - /* begin genRemoveNArgsFromStack: */ - n = methodOrBlockNumArgs + 1; - assert(n <= 4); - genRestoreRegs(backEnd, liveRegsMask & CallerSavedRegisterMask); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(CmpCqR, 0, ABIResultReg); - /* begin JumpZero: */ - jmpFail = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - genWriteCResultIntoReg(backEnd, ReceiverResultReg); - /* begin RetN: */ - offset = (methodOrBlockNumArgs > 2 /* numRegArgs */ - ? (methodOrBlockNumArgs + 1) * BytesPerWord - : 0); - genoperand(RetN, offset); - jmpTarget(jmpFail, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - -/* Compile a fast call of a C primitive using the current stack page, - avoiding the stack switch except on failure. - This convention still uses stackPointer and argumentCount to access - operands. Push all operands to the stack, - assign stackPointer, argumentCount, and zero primFailCode. Make the call - (saving a LinkReg if required). - Test for failure and return. On failure on Spur, if there is an accessor - depth, assign framePointer and newMethod, - do the stack switch, call checkForAndFollowForwardedPrimitiveState, and - loop back if forwarders are found. - Fall through to frame build. */ - - /* SimpleStackBasedCogit>>#compileOnStackExternalPrimitive:flags: */ -static sqInt NoDbgRegParms -compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction22; - AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - sqInt calleeSavedRegisterMask; - AbstractInstruction * jmp; - sqInt linkRegSaveRegister; - sqInt offset; - sqInt offset1; - sqInt operand1; - AbstractInstruction * retry; - AbstractInstruction * skip; - sqInt spRegSaveRegister; - - linkRegSaveRegister = 0; - assert(((flags & PrimCallOnSmalltalkStack) != 0)); - assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); - if (recordFastCCallPrimTraceForMethod(methodObj)) { - genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction18 = genoperandoperand(MoveCqR, 0, TempReg); - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction19 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); - if (methodOrBlockNumArgs != 0) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); - } - /* begin checkLiteral:forInstruction: */ - argumentCountAddress(); - anInstruction20 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); - genExternalizeStackPointerForFastPrimitiveCall(); - calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | (1U << ClassReg)) - (1U << ClassReg)); - linkRegSaveRegister = availableRegisterOrNoneIn(calleeSavedRegisterMask); - assert(!((linkRegSaveRegister == NoReg))); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, LinkReg, linkRegSaveRegister); - calleeSavedRegisterMask = ((calleeSavedRegisterMask | (1U << linkRegSaveRegister)) - (1U << linkRegSaveRegister)); - spRegSaveRegister = NoReg; - /* begin Label */ - retry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - if (((flags & PrimCallOnSmalltalkStackAlign2x) != 0)) { - gAndCqRR((-1 - (((BytesPerWord * 2) - 1))), SPReg, NativeSPReg); - } - else { - } - /* begin gen:literal: */ - anInstruction2 = genoperand(CallFull, primitiveRoutine); - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction21 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - if (spRegSaveRegister != NoReg) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, spRegSaveRegister, SPReg); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkLiteral:forInstruction: */ - stackPointerAddress(); - anInstruction23 = genoperandoperand(MoveAwR, stackPointerAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperandoperand(MoveMwrR, 0, TempReg, ReceiverResultReg); - gAddCqRR(BytesPerWord, TempReg, SPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, linkRegSaveRegister, LinkReg); - /* begin RetN: */ - genoperand(RetN, 0); - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if ((accessorDepthForExternalPrimitiveMethod(methodObj)) >= 0) { - - /* Given that following primitive state to the accessor depth is recursive, we're asking for - trouble if we run the fixup on the Smalltalk stack page. Run it on the full C stack instead. - This won't be a performance issue since primitive failure should be very rare. */ - /* begin checkLiteral:forInstruction: */ - framePointerAddress(); - anInstruction9 = genoperandoperand(MoveRAw, FPReg, framePointerAddress()); - /* begin checkLiteral:forInstruction: */ - ((sqInt)primitiveRoutine); - anInstruction10 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); - /* begin checkLiteral:forInstruction: */ - primitiveFunctionPointerAddress(); - anInstruction11 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); - /* begin MoveMw:r:R: */ - offset = offsetof(CogMethod, methodObject); - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - /* begin checkLiteral:forInstruction: */ - newMethodAddress(); - anInstruction13 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); - /* begin genLoadCStackPointersForPrimCall */ - if (cFramePointerInUse) { - genLoadCStackPointers(backEnd); - } - else { - genLoadCStackPointer(backEnd); - } - /* begin gen:literal: */ - operand1 = ((usqIntptr_t)checkForAndFollowForwardedPrimitiveState); - /* begin checkLiteral:forInstruction: */ - anInstruction8 = genoperand(CallFull, operand1); - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(CmpCqR, 0, ABIResultReg); - /* begin JumpZero: */ - skip = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperand(MoveCqR, 0, TempReg); - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction16 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); - /* begin Jump: */ - genoperand(Jump, ((sqInt)retry)); - jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - else { - - /* must reload SPReg to undo any alignment change, */ - if (((flags & PrimCallOnSmalltalkStackAlign2x) != 0)) { - genLoadStackPointersForFastPrimCall(backEnd, ClassReg); - } - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, linkRegSaveRegister, LinkReg); - if (((ABICallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { - /* begin MoveMw:r:R: */ - offset1 = (methodOrBlockNumArgs + (0)) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); - } - return 0; -} - - -/* Compile one method cache probe in an OpenPIC's lookup of selector. - Answer the jump taken if the selector probe fails. - The class tag of the receiver must be in SendNumArgsReg. ClassReg and - TempReg are used as scratch registers. - On a hit, the offset of the entry is in ClassReg. */ - - /* SimpleStackBasedCogit>>#compileOpenPICMethodCacheProbeFor:withShift:baseRegOrNone: */ -static AbstractInstruction * NoDbgRegParms -compileOpenPICMethodCacheProbeForwithShiftbaseRegOrNone(sqInt selector, sqInt shift, sqInt baseRegOrNone) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *jumpSelectorMiss; - sqInt offset; - sqInt offset1; - - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SendNumArgsReg, ClassReg); - maybeShiftClassTagRegisterForMethodCacheProbe(ClassReg); - annotateobjRef(checkLiteralforInstruction(selector, genoperandoperand(XorCwR, selector, ClassReg)), selector); - assert(shift <= (shiftForWord())); - if (shift < (shiftForWord())) { - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (shiftForWord()) - shift, ClassReg); - } - /* begin AndCq:R: */ - anInstruction4 = genoperandoperand(AndCqR, ((int)((usqInt)(MethodCacheMask) << (shiftForWord()))), ClassReg); - if (baseRegOrNone == NoReg) { - /* begin MoveMw:r:R: */ - offset = (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheSelector) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - } - else { - /* begin AddR:R: */ - genoperandoperand(AddRR, baseRegOrNone, ClassReg); - /* begin MoveMw:r:R: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, ((int)((usqInt)(MethodCacheSelector) << (shiftForWord()))), ClassReg, TempReg); - } - annotateobjRef(checkLiteralforInstruction(selector, genoperandoperand(CmpCwR, selector, TempReg)), selector); - /* begin JumpNonZero: */ - jumpSelectorMiss = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - if (baseRegOrNone == NoReg) { - /* begin MoveMw:r:R: */ - offset1 = (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheClass) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveMwrR, offset1, ClassReg, TempReg); - } - else { - /* begin MoveMw:r:R: */ - anInstruction3 = genoperandoperandoperand(MoveMwrR, ((int)((usqInt)(MethodCacheClass) << (shiftForWord()))), ClassReg, TempReg); - } - /* begin CmpR:R: */ - assert(!((SendNumArgsReg == SPReg))); - genoperandoperand(CmpRR, SendNumArgsReg, TempReg); - return jumpSelectorMiss; -} - - -/* Compile the code for an open PIC. Perform a probe of the first-level - method lookup cache followed by a call of ceSendFromInLineCacheMiss: if - the probe fails. */ - - /* SimpleStackBasedCogit>>#compileOpenPIC:numArgs: */ -static void NoDbgRegParms -compileOpenPICnumArgs(sqInt selector, sqInt numArgs) -{ - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - sqInt cacheBaseReg; - AbstractInstruction *itsAHit; - AbstractInstruction *jumpBCMethod; - AbstractInstruction *jumpClassMiss; - AbstractInstruction *jumpSelectorMiss; - sqInt offset; - - /* begin preenMethodLabel */ - (((((AbstractInstruction *) methodLabel))->operands))[1] = 0; - compilePICAbort(numArgs); - entry = genGetClassTagOfintoscratchReg(ReceiverResultReg, SendNumArgsReg, TempReg); - flag("lookupInMethodCacheSel:classTag:"); - cacheBaseReg = NoReg; - jumpSelectorMiss = compileOpenPICMethodCacheProbeForwithShiftbaseRegOrNone(selector, 0, cacheBaseReg); - /* begin JumpNonZero: */ - jumpClassMiss = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset = (cacheBaseReg == NoReg - ? (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheMethod) << (shiftForWord())))) - : ((int)((usqInt)(MethodCacheMethod) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, SendNumArgsReg); - itsAHit = anInstruction1; - genLoadSlotsourceRegdestReg(HeaderIndex, SendNumArgsReg, ClassReg); - jumpBCMethod = genJumpImmediate(ClassReg); - jmpTarget(jumpBCMethod, picInterpretAbort); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AddCqR, cmNoCheckEntryOffset, ClassReg); - /* begin JumpR: */ - genoperand(JumpR, ClassReg); - jmpTarget(jumpSelectorMiss, jmpTarget(jumpClassMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - jumpSelectorMiss = compileOpenPICMethodCacheProbeForwithShiftbaseRegOrNone(selector, 1, cacheBaseReg); - /* begin JumpZero: */ - genConditionalBranchoperand(JumpZero, ((sqInt)itsAHit)); - jmpTarget(jumpSelectorMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - jumpSelectorMiss = compileOpenPICMethodCacheProbeForwithShiftbaseRegOrNone(selector, 2, cacheBaseReg); - /* begin JumpZero: */ - genConditionalBranchoperand(JumpZero, ((sqInt)itsAHit)); - jmpTarget(jumpSelectorMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genPushRegisterArgsForNumArgsscratchReg(backEnd, numArgs, SendNumArgsReg); - genSmalltalkToCStackSwitch(1); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), SendNumArgsReg)))); - compileCallFornumArgsargargargargresultRegregsToSave(ceSendFromInLineCacheMiss, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); -} - - -/* Compile one method cache probe in a perform: primitive's lookup of - selector. Answer the jump taken if the selector probe fails. */ - - /* SimpleStackBasedCogit>>#compilePerformMethodCacheProbeFor:withShift:baseRegOrNone: */ -static AbstractInstruction * NoDbgRegParms -compilePerformMethodCacheProbeForwithShiftbaseRegOrNone(sqInt selectorReg, sqInt shift, sqInt baseRegOrNone) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *jumpSelectorMiss; - sqInt offset; - sqInt offset1; - - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SendNumArgsReg, ClassReg); - maybeShiftClassTagRegisterForMethodCacheProbe(ClassReg); - /* begin XorR:R: */ - genoperandoperand(XorRR, selectorReg, ClassReg); - assert(shift <= (shiftForWord())); - if (shift < (shiftForWord())) { - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (shiftForWord()) - shift, ClassReg); - } - /* begin AndCq:R: */ - anInstruction4 = genoperandoperand(AndCqR, ((int)((usqInt)(MethodCacheMask) << (shiftForWord()))), ClassReg); - if (baseRegOrNone == NoReg) { - /* begin MoveMw:r:R: */ - offset = (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheSelector) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - } - else { - /* begin AddR:R: */ - genoperandoperand(AddRR, baseRegOrNone, ClassReg); - /* begin MoveMw:r:R: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, ((int)((usqInt)(MethodCacheSelector) << (shiftForWord()))), ClassReg, TempReg); - } - /* begin CmpR:R: */ - assert(!((selectorReg == SPReg))); - genoperandoperand(CmpRR, selectorReg, TempReg); - /* begin JumpNonZero: */ - jumpSelectorMiss = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - if (baseRegOrNone == NoReg) { - /* begin MoveMw:r:R: */ - offset1 = (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheClass) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveMwrR, offset1, ClassReg, TempReg); - } - else { - /* begin MoveMw:r:R: */ - anInstruction3 = genoperandoperandoperand(MoveMwrR, ((int)((usqInt)(MethodCacheClass) << (shiftForWord()))), ClassReg, TempReg); - } - /* begin CmpR:R: */ - assert(!((SendNumArgsReg == SPReg))); - genoperandoperand(CmpRR, SendNumArgsReg, TempReg); - return jumpSelectorMiss; -} - - -/* Compile a primitive. If possible, performance-critical primitives will - be generated by their own routines (primitiveGenerator). Otherwise, - if there is a primitive at all, we call the C routine with the usual - stack-switching dance, test the primFailCode and then either return - on success or continue to the method body. */ - - /* SimpleStackBasedCogit>>#compilePrimitive */ -static sqInt -compilePrimitive(void) -{ - sqInt code; - sqInt flags; - sqInt opcodeIndexAtPrimitive; - PrimitiveDescriptor *primitiveDescriptor; - void (*primitiveRoutine)(void); - - flags = 0; - if (primitiveIndex == 0) { - return 0; - } - if ((((primitiveDescriptor = primitiveGeneratorOrNil())) != null) - && ((((primitiveDescriptor->primitiveGenerator)) != null) - && ((((primitiveDescriptor->primNumArgs)) < 0) - || (((primitiveDescriptor->primNumArgs)) == (argumentCountOf(methodObj)))))) { - - /* Note opcodeIndex so that any arg load instructions - for unimplemented primitives can be discarded. */ - opcodeIndexAtPrimitive = opcodeIndex; - code = ((primitiveDescriptor->primitiveGenerator))(); - if ((code < 0) - && (code != UnimplementedPrimitive)) { - - /* Generator failed, so no point continuing... */ - return code; - } - if (code == UnfailingPrimitive) { - return 0; - } - if ((code == CompletePrimitive) - && (!(((primitiveIndexOfMethodheader(methodObj, methodHeader)) > 0) - && ((longStoreBytecodeForHeader(methodHeader)) == (fetchByteofObject((startPCOfMethod(methodObj)) + (sizeOfCallPrimitiveBytecode(methodHeader)), methodObj)))))) { - return 0; - } - if (code == UnimplementedPrimitive) { - opcodeIndex = opcodeIndexAtPrimitive; - } - } - primitiveRoutine = functionPointerForCompiledMethodprimitiveIndexprimitivePropertyFlagsInto(methodObj, primitiveIndex, (&flags)); - if (((flags & PrimCallDoNotJIT) != 0)) { - return ShouldNotJIT; - } - if ((primitiveRoutine == 0) - || (primitiveRoutine == (((void (*)(void)) primitiveFail)))) { - return genFastPrimFail(); - } - if (((flags & PrimCallOnSmalltalkStack) != 0)) { - assert(!(((((flags & FastCPrimitiveUseCABIFlag) != 0)) - && (((flags & PrimCallOnSmalltalkStackAlign2x) != 0))))); - if (((flags & FastCPrimitiveUseCABIFlag) != 0)) { - return compileMachineCodeInterpreterPrimitive(((void (*)(void)) (mcprimFunctionForPrimitiveIndex(primitiveIndex)))); - } - return compileOnStackExternalPrimitiveflags(primitiveRoutine, flags); - } - minValidCallAddress = ((minValidCallAddress < (((usqInt)primitiveRoutine))) ? minValidCallAddress : (((usqInt)primitiveRoutine))); - return compileInterpreterPrimitiveflags(primitiveRoutine, flags); -} - - /* SimpleStackBasedCogit>>#extendedPushBytecode */ -static sqInt -extendedPushBytecode(void) -{ - sqInt variableIndex; - sqInt variableType; - - variableType = (((usqInt)(byte1)) >> 6) & 3; - variableIndex = byte1 & 0x3F; - if (variableType == 0) { - return genPushReceiverVariable(variableIndex); - } - if (variableType == 1) { - return genPushTemporaryVariable(variableIndex); - } - if (variableType == 2) { - return genPushLiteralIndex(variableIndex); - } - return genPushLiteralVariable(variableIndex); -} - - /* SimpleStackBasedCogit>>#extendedStoreAndPopBytecode */ -static sqInt -extendedStoreAndPopBytecode(void) -{ - AbstractInstruction *abstractInstruction; - sqInt variableIndex; - sqInt variableType; - - variableType = (((usqInt)(byte1)) >> 6) & 3; - variableIndex = byte1 & 0x3F; - if (variableType == 0) { - return genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(1, variableIndex, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } - if (variableType == 1) { - genStorePopTemporaryVariable(1, variableIndex); -# if IMMUTABILITY - /* begin annotateBytecode: */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction->annotation = HasBytecodePC); -# endif // IMMUTABILITY - return 0; - } - if (variableType == 3) { - return genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(1, variableIndex, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } - return EncounteredUnknownBytecode; -} - - /* SimpleStackBasedCogit>>#extendedStoreBytecode */ -static sqInt -extendedStoreBytecode(void) -{ - AbstractInstruction *abstractInstruction; - sqInt variableIndex; - sqInt variableType; - - variableType = (((usqInt)(byte1)) >> 6) & 3; - variableIndex = byte1 & 0x3F; - if (variableType == 0) { - return genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(0, variableIndex, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } - if (variableType == 1) { - genStorePopTemporaryVariable(0, variableIndex); -# if IMMUTABILITY - /* begin annotateBytecode: */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction->annotation = HasBytecodePC); -# endif // IMMUTABILITY - return 0; - } - if (variableType == 3) { - return genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(0, variableIndex, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } - return EncounteredUnknownBytecode; -} - - /* SimpleStackBasedCogit>>#frameOffsetOfTemporary: */ -static sqInt NoDbgRegParms -frameOffsetOfTemporary(sqInt index) -{ - return (index < methodOrBlockNumArgs - ? FoxCallerSavedIP + ((methodOrBlockNumArgs - index) * BytesPerWord) - : (FoxMFReceiver - BytesPerWord) + ((methodOrBlockNumArgs - index) * BytesPerWord)); -} - - -/* Implemented with SistaCogit only */ - - /* SimpleStackBasedCogit>>#genCallMappedInlinedPrimitive */ -static sqInt -genCallMappedInlinedPrimitive(void) -{ - return EncounteredUnknownBytecode; -} - - -/* Can use any of the first 32 literals for the selector and pass up to 7 - arguments. - */ - - /* SimpleStackBasedCogit>>#genExtendedSendBytecode */ -static sqInt -genExtendedSendBytecode(void) -{ - return genSendnumArgs(byte1 & 0x1F, ((usqInt)(byte1)) >> 5); -} - - /* SimpleStackBasedCogit>>#genExtendedSuperBytecode */ -static sqInt -genExtendedSuperBytecode(void) -{ - return genSendSupernumArgs(byte1 & 0x1F, ((usqInt)(byte1)) >> 5); -} - - -/* 244 11110100 i i i i i i i i Pop and Jump 0n False i i i i i i i i (+ - Extend B * 256, where Extend B >= 0) - */ - - /* SimpleStackBasedCogit>>#genExtJumpIfFalse */ -static sqInt -genExtJumpIfFalse(void) -{ - sqInt distance; - sqInt target; - - distance = byte1 + (((sqInt)((usqInt)(extB) << 8))); - assert(distance == (v4LongForwardBranchDistance(generatorAt(byte0), bytecodePC, ((extA != 0 - ? 1 - : 0)) + ((extB != 0 - ? 1 - : 0)), methodObj))); - extB = 0; - numExtB = 0; - target = (distance + 2) + bytecodePC; - return genJumpIfto(falseObject(), target); -} - - -/* 243 11110011 i i i i i i i i Pop and Jump 0n True i i i i i i i i (+ - Extend B * 256, where Extend B >= 0) - */ - - /* SimpleStackBasedCogit>>#genExtJumpIfTrue */ -static sqInt -genExtJumpIfTrue(void) -{ - sqInt distance; - sqInt target; - - distance = byte1 + (((sqInt)((usqInt)(extB) << 8))); - assert(distance == (v4LongForwardBranchDistance(generatorAt(byte0), bytecodePC, ((extA != 0 - ? 1 - : 0)) + ((extB != 0 - ? 1 - : 0)), methodObj))); - extB = 0; - numExtB = 0; - target = (distance + 2) + bytecodePC; - return genJumpIfto(trueObject(), target); -} - - -/* NewspeakV4: 221 11011101 Nop */ -/* SistaV1: 91 01011011' Nop */ - - /* SimpleStackBasedCogit>>#genExtNopBytecode */ -static sqInt -genExtNopBytecode(void) -{ - extA = (numExtB = (extB = 0)); - return 0; -} - - -/* SistaV1: 233 11101001 iiiiiiii Push Character #iiiiiiii (+ Extend B * - 256) - */ - - /* SimpleStackBasedCogit>>#genExtPushCharacterBytecode */ -static sqInt -genExtPushCharacterBytecode(void) -{ - sqInt value; - - value = byte1 + (((sqInt)((usqInt)(extB) << 8))); - extB = 0; - numExtB = 0; - return genPushLiteral(characterObjectOf(value)); -} - - -/* NewsqueakV4: 229 11100101 iiiiiiii Push Integer #iiiiiiii (+ Extend B * - 256, where bbbbbbbb = sddddddd, e.g. -32768 = i=0, a=0, s=1) - SistaV1: 232 11101000 iiiiiiii Push Integer #iiiiiiii (+ Extend B * 256, - where bbbbbbbb = sddddddd, e.g. -32768 = i=0, a=0, s=1) - */ - - /* SimpleStackBasedCogit>>#genExtPushIntegerBytecode */ -static sqInt -genExtPushIntegerBytecode(void) -{ - sqInt value; - - value = byte1 + (((sqInt)((usqInt)(extB) << 8))); - extB = 0; - numExtB = 0; - return genPushLiteral((((usqInt)value << 1) | 1)); -} - - -/* 228 11100100 i i i i i i i i Push Literal #iiiiiiii (+ Extend A * 256) */ - - /* SimpleStackBasedCogit>>#genExtPushLiteralBytecode */ -static sqInt -genExtPushLiteralBytecode(void) -{ - sqInt index; - - index = byte1 + (((sqInt)((usqInt)(extA) << 8))); - extA = 0; - return genPushLiteralIndex(index); -} - - -/* 227 11100011 i i i i i i i i Push Literal Variable #iiiiiiii (+ Extend A - * 256) - */ - - /* SimpleStackBasedCogit>>#genExtPushLiteralVariableBytecode */ -static sqInt -genExtPushLiteralVariableBytecode(void) -{ - sqInt index; - - index = byte1 + (((sqInt)((usqInt)(extA) << 8))); - extA = 0; - return genPushLiteralVariable(index); -} - - -/* SistaV1: * 82 01010010 Push thisContext, (then Extend B = 1 => push - thisProcess) - */ - - /* SimpleStackBasedCogit>>#genExtPushPseudoVariable */ -static sqInt -genExtPushPseudoVariable(void) -{ - sqInt ext; - - ext = extB; - extB = 0; - numExtB = 0; - switch (ext) { - case 0: - return genPushActiveContextBytecode(); - - default: - /* begin unknownBytecode */ - return EncounteredUnknownBytecode; - - } - return 0; -} - - -/* 226 11100010 i i i i i i i i Push Receiver Variable #iiiiiiii (+ Extend A - * 256) - */ - - /* SimpleStackBasedCogit>>#genExtPushReceiverVariableBytecode */ -static sqInt -genExtPushReceiverVariableBytecode(void) -{ - sqInt index; - - index = byte1 + (((sqInt)((usqInt)(extA) << 8))); - extA = 0; - return (isReadMediatedContextInstVarIndex(index) - ? genPushMaybeContextReceiverVariable(index) - : genPushReceiverVariable(index)); -} - - -/* 238 11101110 i i i i i j j j Send Literal Selector #iiiii (+ Extend A * - 32) with jjj (+ Extend B * 8) Arguments - */ - - /* SimpleStackBasedCogit>>#genExtSendBytecode */ -static sqInt -genExtSendBytecode(void) -{ - sqInt litIndex; - sqInt nArgs; - - litIndex = (((usqInt)(byte1)) >> 3) + (((sqInt)((usqInt)(extA) << 5))); - extA = 0; - nArgs = (byte1 & 7) + (((sqInt)((usqInt)(extB) << 3))); - extB = 0; - numExtB = 0; - return genSendnumArgs(litIndex, nArgs); -} - - -/* 239 11101111 i i i i i j j j Send To Superclass Literal Selector #iiiii - (+ Extend A * 32) with jjj (+ Extend B * 8) Arguments - */ - - /* SimpleStackBasedCogit>>#genExtSendSuperBytecode */ -static sqInt -genExtSendSuperBytecode(void) -{ - int isDirected; - sqInt litIndex; - sqInt nArgs; - - if ((isDirected = extB >= 64)) { - extB = extB & 0x3F; - } - litIndex = (((usqInt)(byte1)) >> 3) + (((sqInt)((usqInt)(extA) << 5))); - extA = 0; - nArgs = (byte1 & 7) + (((sqInt)((usqInt)(extB) << 3))); - extB = 0; - numExtB = 0; - return (isDirected - ? genSendDirectedSupernumArgs(litIndex, nArgs) - : genSendSupernumArgs(litIndex, nArgs)); -} - - -/* 236 11101100 i i i i i i i i Pop and Store Literal Variable #iiiiiiii (+ - Extend A * 256) - */ - - /* SimpleStackBasedCogit>>#genExtStoreAndPopLiteralVariableBytecode */ -static sqInt -genExtStoreAndPopLiteralVariableBytecode(void) -{ - sqInt index; - - index = byte1 + (((sqInt)((usqInt)(extA) << 8))); - extA = 0; - return genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(1, index, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); -} - - -/* 235 11101011 i i i i i i i i Pop and Store Receiver Variable #iiiiiii (+ - Extend A * 256) - */ - - /* SimpleStackBasedCogit>>#genExtStoreAndPopReceiverVariableBytecode */ -static sqInt -genExtStoreAndPopReceiverVariableBytecode(void) -{ - sqInt index; - - index = byte1 + (((sqInt)((usqInt)(extA) << 8))); - extA = 0; - return (isWriteMediatedContextInstVarIndex(index) - ? genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(1, index, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1) - : genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(1, index, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1)); -} - - -/* 233 11101001 i i i i i i i i Store Literal Variable #iiiiiiii (+ Extend A - * 256) - */ - - /* SimpleStackBasedCogit>>#genExtStoreLiteralVariableBytecode */ -static sqInt -genExtStoreLiteralVariableBytecode(void) -{ - sqInt index; - - index = byte1 + (((sqInt)((usqInt)(extA) << 8))); - extA = 0; - return genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(0, index, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); -} - - -/* 232 11101000 i i i i i i i i Store Receiver Variable #iiiiiii (+ Extend A - * 256) - */ - - /* SimpleStackBasedCogit>>#genExtStoreReceiverVariableBytecode */ -static sqInt -genExtStoreReceiverVariableBytecode(void) -{ - sqInt index; - - index = byte1 + (((sqInt)((usqInt)(extA) << 8))); - extA = 0; - return (isWriteMediatedContextInstVarIndex(index) - ? genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(0, index, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1) - : genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(0, index, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1)); -} - - -/* 242 11110010 i i i i i i i i Jump i i i i i i i i (+ Extend B * 256, - where bbbbbbbb = sddddddd, e.g. -32768 = i=0, a=0, s=1) - */ - - /* SimpleStackBasedCogit>>#genExtUnconditionalJump */ -static sqInt -genExtUnconditionalJump(void) -{ - AbstractInstruction *abstractInstruction; - sqInt distance; - sqInt target; - - distance = byte1 + (((sqInt)((usqInt)(extB) << 8))); - assert(distance == (v4LongBranchDistance(generatorAt(byte0), bytecodePC, ((extA != 0 - ? 1 - : 0)) + ((extB != 0 - ? 1 - : 0)), methodObj))); - extB = 0; - numExtB = 0; - target = (distance + 2) + bytecodePC; - if (distance < 0) { - return genJumpBackTo(target); - } - genJumpTo(target); - /* begin annotateBytecode: */ - abstractInstruction = lastOpcode(); - (abstractInstruction->annotation = HasBytecodePC); - return 0; -} - - /* SimpleStackBasedCogit>>#genFastPrimFail */ -static sqInt -genFastPrimFail(void) -{ - primitiveIndex = 0; - return UnfailingPrimitive; -} - - -/* Suport for compileInterpreterPrimitive. Generate inline code so as to - record the primitive - trace as fast as possible. */ - - /* SimpleStackBasedCogit>>#genFastPrimTraceUsing:and: */ -static void NoDbgRegParms -genFastPrimTraceUsingand(sqInt r1, sqInt r2) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - sqInt offset; - - /* begin MoveCq:R: */ - anInstruction = genoperandoperand(MoveCqR, 0, r2); - /* begin checkLiteral:forInstruction: */ - primTraceLogIndexAddress(); - anInstruction1 = genoperandoperand(MoveAbR, primTraceLogIndexAddress(), r2); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(LoadEffectiveAddressMwrR, 1, r2, r1); - /* begin checkLiteral:forInstruction: */ - primTraceLogIndexAddress(); - anInstruction3 = genoperandoperand(MoveRAb, r1, primTraceLogIndexAddress()); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), r1)))); - /* begin MoveMw:r:R: */ - offset = offsetof(CogMethod, selector); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperandoperand(MoveMwrR, offset, r1, TempReg); - /* begin checkLiteral:forInstruction: */ - ((sqInt)(primTraceLogAddress())); - anInstruction5 = genoperandoperand(MoveCwR, ((sqInt)(primTraceLogAddress())), r1); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, TempReg, r2, r1); -} - - /* SimpleStackBasedCogit>>#genLongJumpIfFalse */ -static sqInt -genLongJumpIfFalse(void) -{ - sqInt distance; - sqInt target; - - distance = v3LongForwardBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - target = (distance + 2) + bytecodePC; - return genJumpIfto(falseObject(), target); -} - - /* SimpleStackBasedCogit>>#genLongJumpIfTrue */ -static sqInt -genLongJumpIfTrue(void) -{ - sqInt distance; - sqInt target; - - distance = v3LongForwardBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - target = (distance + 2) + bytecodePC; - return genJumpIfto(trueObject(), target); -} - - -/* 230 11100110 i i i i i i i i Push Temporary Variable #iiiiiiii */ - - /* SimpleStackBasedCogit>>#genLongPushTemporaryVariableBytecode */ -static sqInt -genLongPushTemporaryVariableBytecode(void) -{ - return genPushTemporaryVariable(byte1); -} - - -/* 237 11101101 i i i i i i i i Pop and Store Temporary Variable #iiiiiiii */ - - /* SimpleStackBasedCogit>>#genLongStoreAndPopTemporaryVariableBytecode */ -static sqInt -genLongStoreAndPopTemporaryVariableBytecode(void) -{ - return genStorePopTemporaryVariable(1, byte1); -} - - -/* 234 11101010 i i i i i i i i Store Temporary Variable #iiiiiiii */ - - /* SimpleStackBasedCogit>>#genLongStoreTemporaryVariableBytecode */ -static sqInt -genLongStoreTemporaryVariableBytecode(void) -{ - return genStorePopTemporaryVariable(0, byte1); -} - - /* SimpleStackBasedCogit>>#genLongUnconditionalBackwardJump */ -static sqInt -genLongUnconditionalBackwardJump(void) -{ - sqInt distance; - - distance = v3LongBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - assert(distance < 0); - return genJumpBackTo((distance + 2) + bytecodePC); -} - - /* SimpleStackBasedCogit>>#genLongUnconditionalForwardJump */ -static sqInt -genLongUnconditionalForwardJump(void) -{ - sqInt distance; - sqInt targetpc; - - distance = v3LongBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - assert(distance >= 0); - targetpc = (distance + 2) + bytecodePC; - return genJumpTo(targetpc); -} - - -/* Compile the code for a probe of the first-level method cache for a perform - primitive. The selector is assumed to be in Arg0Reg. Defer to - adjustArgumentsForPerform: to - adjust the arguments before the jump to the method. */ - - /* SimpleStackBasedCogit>>#genLookupForPerformNumArgs: */ -static sqInt NoDbgRegParms -genLookupForPerformNumArgs(sqInt numArgs) -{ - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - sqInt cacheBaseReg; - AbstractInstruction *itsAHit; - AbstractInstruction *jumpClassMiss; - AbstractInstruction *jumpInterpret; - AbstractInstruction *jumpSelectorMiss; - sqInt offset; - - - /* N.B. Can't assume TempReg already contains the tag because a method can - of course be invoked via the unchecked entry-point, e.g. as does perform:. */ - genGetInlineCacheClassTagFromintoforEntry(ReceiverResultReg, SendNumArgsReg, 0); - flag("lookupInMethodCacheSel:classTag:"); - cacheBaseReg = NoReg; - jumpSelectorMiss = compilePerformMethodCacheProbeForwithShiftbaseRegOrNone(Arg0Reg, 0, cacheBaseReg); - /* begin JumpNonZero: */ - jumpClassMiss = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset = (cacheBaseReg == NoReg - ? (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheMethod) << (shiftForWord())))) - : ((int)((usqInt)(MethodCacheMethod) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, SendNumArgsReg); - itsAHit = anInstruction1; - genLoadSlotsourceRegdestReg(HeaderIndex, SendNumArgsReg, ClassReg); - - /* Adjust arguments and jump to the method's unchecked entry-point. */ - jumpInterpret = genJumpImmediate(ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AddCqR, cmNoCheckEntryOffset, ClassReg); - adjustArgumentsForPerform(numArgs); - /* begin JumpR: */ - genoperand(JumpR, ClassReg); - jmpTarget(jumpSelectorMiss, jmpTarget(jumpClassMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - jumpSelectorMiss = compilePerformMethodCacheProbeForwithShiftbaseRegOrNone(Arg0Reg, 1, cacheBaseReg); - /* begin JumpZero: */ - genConditionalBranchoperand(JumpZero, ((sqInt)itsAHit)); - jmpTarget(jumpSelectorMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - jumpSelectorMiss = compilePerformMethodCacheProbeForwithShiftbaseRegOrNone(Arg0Reg, 2, cacheBaseReg); - /* begin JumpZero: */ - genConditionalBranchoperand(JumpZero, ((sqInt)itsAHit)); - jmpTarget(jumpSelectorMiss, jmpTarget(jumpInterpret, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return 0; -} - - /* SimpleStackBasedCogit>>#genMustBeBooleanTrampolineFor:called: */ -static usqInt NoDbgRegParms -genMustBeBooleanTrampolineForcalled(sqInt boolean, char *trampolineName) -{ - AbstractInstruction *anInstruction; - - zeroOpcodeIndex(); - assert(!(shouldAnnotateObjectReference(boolean))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, boolean, TempReg); - return genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceSendMustBeBoolean, trampolineName, 1, TempReg, null, null, null, 0 /* emptyRegisterMask */, 1, NoReg, 1); -} - - -/* Implement 28-bit hashMultiply for SmallInteger and LargePositiveInteger - receivers. - */ - - /* SimpleStackBasedCogit>>#genPrimitiveHashMultiply */ -static sqInt -genPrimitiveHashMultiply(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction * jmpFailImm; - AbstractInstruction * jmpFailNotPositiveLargeInt; - - return UnimplementedPrimitive; - if (mclassIsSmallInteger()) { - genConvertSmallIntegerToIntegerInReg(ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, HashMultiplyConstant, TempReg); - /* begin MulR:R: */ - genMulRR(backEnd, TempReg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, HashMultiplyMask, ReceiverResultReg); - genConvertIntegerToSmallIntegerInReg(ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, 0); - return CompletePrimitive; - } - jmpFailImm = genJumpImmediate(ReceiverResultReg); - genGetCompactClassIndexNonImmOfinto(ReceiverResultReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(CmpCqR, ClassLargePositiveIntegerCompactIndex, ClassReg); - /* begin JumpNonZero: */ - jmpFailNotPositiveLargeInt = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(0, ReceiverResultReg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(MoveCqR, HashMultiplyConstant, TempReg); - /* begin MulR:R: */ - genMulRR(backEnd, TempReg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(AndCqR, HashMultiplyMask, ReceiverResultReg); - genConvertIntegerToSmallIntegerInReg(ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, 0); - jmpTarget(jmpFailImm, jmpTarget(jmpFailNotPositiveLargeInt, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - -/* Generate the substitute return code for an external or FFI primitive call. - On success simply return, extracting numArgs from newMethod. - On primitive failure call ceActivateFailingPrimitiveMethod: newMethod. */ - - /* SimpleStackBasedCogit>>#genPrimReturnEnterCogCodeEnilopmart: */ -static void NoDbgRegParms -genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) -{ - sqInt address; - sqInt address1; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - sqInt callTarget; - AbstractInstruction *continuePostSample; - AbstractInstruction * inst; - AbstractInstruction *jmpFail; - AbstractInstruction *jmpSample; - sqInt quickConstant; - sqInt reg; - - continuePostSample = ((AbstractInstruction *) 0); - jmpSample = ((AbstractInstruction *) 0); - zeroOpcodeIndex(); - /* begin MoveCq:R: */ - quickConstant = varBaseAddress(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - if (profiling) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick: if so. - N.B. nextProfileTick is 64-bits so 32-bit systems need to test both halves. */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction1 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin MoveAw:R: */ - address = (nextProfileTickAddress()) + BytesPerWord; - /* begin checkLiteral:forInstruction: */ - anInstruction2 = genoperandoperand(MoveAwR, address, ClassReg); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSample = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction13 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadStackPointers(backEnd); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); - /* begin checkLiteral:forInstruction: */ - instructionPointerAddress(); - anInstruction7 = genoperandoperand(MoveAwR, instructionPointerAddress(), LinkReg); - /* begin RetN: */ - genoperand(RetN, BytesPerWord); - jmpTarget(jmpFail, checkLiteralforInstruction(newMethodAddress(), genoperandoperand(MoveAwR, newMethodAddress(), SendNumArgsReg))); - /* begin checkLiteral:forInstruction: */ - cStackPointerAddress(); - anInstruction15 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); - compileCallFornumArgsargargargargresultRegregsToSave(ceActivateFailingPrimitiveMethod, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); - /* begin MoveAw:R: */ - address1 = instructionPointerAddress(); - reg = LinkReg; - /* begin checkLiteral:forInstruction: */ - anInstruction16 = genoperandoperand(MoveAwR, address1, reg); - genLoadStackPointers(backEnd); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, BytesPerWord); - if (profiling) { - - /* Call ceCheckProfileTick: to record sample and then continue. newMethod - should be up-to-date. Need to save and restore the link reg around this call. */ - jmpTarget(jmpSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - /* begin CallFullRT: */ - callTarget = (usqIntptr_t)ceCheckProfileTick; - /* begin checkLiteral:forInstruction: */ - anInstruction18 = genoperand(CallFull, callTarget); - /* begin PopR: */ - genoperand(PopR, LinkReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSample)); - } -} - - /* SimpleStackBasedCogit>>#genPushConstantFalseBytecode */ -static sqInt -genPushConstantFalseBytecode(void) -{ - return genPushLiteral(falseObject()); -} - - /* SimpleStackBasedCogit>>#genPushConstantNilBytecode */ -static sqInt -genPushConstantNilBytecode(void) -{ - return genPushLiteral(nilObject()); -} - - -/* 79 01001111 Push 1 */ - - /* SimpleStackBasedCogit>>#genPushConstantOneBytecode */ -static sqInt -genPushConstantOneBytecode(void) -{ - return genPushLiteral((((usqInt)1 << 1) | 1)); -} - - /* SimpleStackBasedCogit>>#genPushConstantTrueBytecode */ -static sqInt -genPushConstantTrueBytecode(void) -{ - return genPushLiteral(trueObject()); -} - - -/* 78 01001110 Push 0 */ - - /* SimpleStackBasedCogit>>#genPushConstantZeroBytecode */ -static sqInt -genPushConstantZeroBytecode(void) -{ - return genPushLiteral((((usqInt)0 << 1) | 1)); -} - - /* SimpleStackBasedCogit>>#genPushLiteralConstantBytecode */ -static sqInt -genPushLiteralConstantBytecode(void) -{ - return genPushLiteralIndex(byte0 & 0x1F); -} - - -/* 16-31 0001 i i i i Push Literal Variable #iiii */ - - /* SimpleStackBasedCogit>>#genPushLiteralVariable16CasesBytecode */ -static sqInt -genPushLiteralVariable16CasesBytecode(void) -{ - return genPushLiteralVariable(byte0 & 15); -} - - /* SimpleStackBasedCogit>>#genPushLiteralVariableBytecode */ -static sqInt -genPushLiteralVariableBytecode(void) -{ - return genPushLiteralVariable(byte0 & 0x1F); -} - - /* SimpleStackBasedCogit>>#genPushQuickIntegerConstantBytecode */ -static sqInt -genPushQuickIntegerConstantBytecode(void) -{ - return genPushLiteral((((usqInt)(byte0 - 117) << 1) | 1)); -} - - /* SimpleStackBasedCogit>>#genPushReceiverVariableBytecode */ -static sqInt -genPushReceiverVariableBytecode(void) -{ - return genPushReceiverVariable(byte0 & 15); -} - - /* SimpleStackBasedCogit>>#genPushTemporaryVariableBytecode */ -static sqInt -genPushTemporaryVariableBytecode(void) -{ - return genPushTemporaryVariable(byte0 & 15); -} - - -/* because selected by CoInterpreter>>quickPrimitiveGeneratorFor: */ - - /* SimpleStackBasedCogit>>#genQuickReturnConst */ -sqInt -genQuickReturnConst(void) -{ - AbstractInstruction *anInstruction; - sqInt constant; - - constant = quickPrimitiveConstantFor(primitiveIndex); - /* begin genMoveConstant:R: */ - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - genUpArrowReturn(); - return UnfailingPrimitive; -} - - -/* because selected by CoInterpreter>>quickPrimitiveGeneratorFor: */ - - /* SimpleStackBasedCogit>>#genQuickReturnInstVar */ -sqInt -genQuickReturnInstVar(void) -{ - sqInt index; - - index = quickPrimitiveInstVarIndexFor(primitiveIndex); - genLoadSlotsourceRegdestReg(index, ReceiverResultReg, ReceiverResultReg); - genUpArrowReturn(); - return UnfailingPrimitive; -} - - -/* because selected by CoInterpreter>>quickPrimitiveGeneratorFor: */ - - /* SimpleStackBasedCogit>>#genQuickReturnSelf */ -sqInt -genQuickReturnSelf(void) -{ - genUpArrowReturn(); - return UnfailingPrimitive; -} - - /* SimpleStackBasedCogit>>#genReturnFalse */ -static sqInt -genReturnFalse(void) -{ - AbstractInstruction *anInstruction; - sqInt constant; - - /* begin genMoveFalseR: */ - constant = falseObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - return genUpArrowReturn(); -} - - /* SimpleStackBasedCogit>>#genReturnNil */ -static sqInt -genReturnNil(void) -{ - AbstractInstruction *anInstruction; - sqInt constant; - - /* begin genMoveNilR: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - return genUpArrowReturn(); -} - - /* SimpleStackBasedCogit>>#genReturnNilFromBlock */ -static sqInt -genReturnNilFromBlock(void) -{ - AbstractInstruction *anInstruction; - sqInt constant; - - assert(inBlock > 0); - /* begin genMoveNilR: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - return genBlockReturn(); -} - - /* SimpleStackBasedCogit>>#genReturnTrue */ -static sqInt -genReturnTrue(void) -{ - AbstractInstruction *anInstruction; - sqInt constant; - - /* begin genMoveTrueR: */ - constant = trueObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - return genUpArrowReturn(); -} - - -/* Can use any of the first 64 literals for the selector and pass up to 3 - arguments. - */ - - /* SimpleStackBasedCogit>>#genSecondExtendedSendBytecode */ -static sqInt -genSecondExtendedSendBytecode(void) -{ - return genSendnumArgs(byte1 & 0x3F, ((usqInt)(byte1)) >> 6); -} - - /* SimpleStackBasedCogit>>#genSendLiteralSelector0ArgsBytecode */ -static sqInt -genSendLiteralSelector0ArgsBytecode(void) -{ - return genSendnumArgs(byte0 & 15, 0); -} - - /* SimpleStackBasedCogit>>#genSendLiteralSelector1ArgBytecode */ -static sqInt -genSendLiteralSelector1ArgBytecode(void) -{ - return genSendnumArgs(byte0 & 15, 1); -} - - /* SimpleStackBasedCogit>>#genSendLiteralSelector2ArgsBytecode */ -static sqInt -genSendLiteralSelector2ArgsBytecode(void) -{ - return genSendnumArgs(byte0 & 15, 2); -} - - /* SimpleStackBasedCogit>>#genShortJumpIfFalse */ -static sqInt -genShortJumpIfFalse(void) -{ - sqInt distance; - sqInt target; - - distance = v3ShortForwardBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - target = (distance + 1) + bytecodePC; - return genJumpIfto(falseObject(), target); -} - - /* SimpleStackBasedCogit>>#genShortJumpIfTrue */ -static sqInt -genShortJumpIfTrue(void) -{ - sqInt distance; - sqInt target; - - distance = v3ShortForwardBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - target = (distance + 1) + bytecodePC; - return genJumpIfto(trueObject(), target); -} - - /* SimpleStackBasedCogit>>#genShortUnconditionalJump */ -static sqInt -genShortUnconditionalJump(void) -{ - sqInt distance; - sqInt target; - - distance = v3ShortForwardBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - target = (distance + 1) + bytecodePC; - return genJumpTo(target); -} - - /* SimpleStackBasedCogit>>#genSpecialSelectorEqualsEquals */ -static sqInt -genSpecialSelectorEqualsEquals(void) -{ - return genInlinedIdenticalOrNotIf(0); -} - - /* SimpleStackBasedCogit>>#genSpecialSelectorNotEqualsEquals */ -static sqInt -genSpecialSelectorNotEqualsEquals(void) -{ - return genInlinedIdenticalOrNotIf(1); -} - - /* SimpleStackBasedCogit>>#genSpecialSelectorSend */ -static sqInt -genSpecialSelectorSend(void) -{ - sqInt index; - sqInt numArgs; - - index = byte0 - ( -#if MULTIPLEBYTECODESETS - (bytecodeSetOffset == 0x100 - ? AltFirstSpecialSelector + 0x100 - : FirstSpecialSelector) -#else - FirstSpecialSelector -#endif - ); - numArgs = specialSelectorNumArgs(index); - return genSendnumArgs((-index) - 1, numArgs); -} - - /* SimpleStackBasedCogit>>#genStoreAndPopReceiverVariableBytecode */ -static sqInt -genStoreAndPopReceiverVariableBytecode(void) -{ - return genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(1, byte0 & 7, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); -} - - /* SimpleStackBasedCogit>>#genStoreAndPopRemoteTempLongBytecode */ -static sqInt -genStoreAndPopRemoteTempLongBytecode(void) -{ - return genStorePopRemoteTempAtneedsStoreCheck(1, byte1, byte2, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant))))); -} - - /* SimpleStackBasedCogit>>#genStoreAndPopTemporaryVariableBytecode */ -static sqInt -genStoreAndPopTemporaryVariableBytecode(void) -{ - return genStorePopTemporaryVariable(1, byte0 & 7); -} - - /* SimpleStackBasedCogit>>#genStoreRemoteTempLongBytecode */ -static sqInt -genStoreRemoteTempLongBytecode(void) -{ - return genStorePopRemoteTempAtneedsStoreCheck(0, byte1, byte2, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant))))); -} - - -/* SistaV1: * 217 Trap */ - - /* SimpleStackBasedCogit>>#genUnconditionalTrapBytecode */ -static sqInt -genUnconditionalTrapBytecode(void) -{ - return EncounteredUnknownBytecode; -} - - -/* Collect the branch and send data for cogMethod, storing it into arrayObj. */ - - /* SimpleStackBasedCogit>>#mapPCDataFor:into: */ -sqInt -mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj) -{ - sqInt aMethodHeader; - sqInt aMethodHeader1; - sqInt aMethodObj; - sqInt annotation; - sqInt bcpc; - sqInt bsOffset; - sqInt byte; - BytecodeDescriptor *descriptor; - sqInt distance; - sqInt endbcpc; - sqInt errCode; - CogMethod *homeMethod; - sqInt isBackwardBranch; - sqInt isInBlock; - sqInt latestContinuation; - usqInt map; - sqInt mapByte; - usqInt mcpc; - sqInt nExts; - sqInt nextBcpc; - sqInt result; - sqInt startbcpc; - sqInt targetPC; - - latestContinuation = 0; - introspectionDataIndex = 0; - introspectionData = arrayObj; - if (((cogMethod->stackCheckOffset)) == 0) { - assert(introspectionDataIndex == 0); - if ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock)) { - storePointerUncheckedofObjectwithValue(0, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(1, introspectionData, (((usqInt)cbNoSwitchEntryOffset << 1) | 1)); - storePointerUncheckedofObjectwithValue(2, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(3, introspectionData, (((usqInt)cbEntryOffset << 1) | 1)); - } - else { - storePointerUncheckedofObjectwithValue(0, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(1, introspectionData, (((usqInt)cmEntryOffset << 1) | 1)); - storePointerUncheckedofObjectwithValue(2, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(3, introspectionData, (((usqInt)cmNoCheckEntryOffset << 1) | 1)); - } - return 4; - } - /* begin mapFor:bcpc:performUntil:arg: */ - startbcpc = startPCOfMethod((cogMethod->methodObject)); - assert((((((CogBlockMethod *) cogMethod))->stackCheckOffset)) > 0); - - /* The stack check maps to the start of the first bytecode, - the first bytecode being effectively after frame build. */ - mcpc = (((usqInt)(((CogBlockMethod *) cogMethod)))) + (((((CogBlockMethod *) cogMethod))->stackCheckOffset)); - result = pcDataForAnnotationMcpcBcpcMethod(null, (0 + (((int)((usqInt)(HasBytecodePC) << 1)))), (((char *) mcpc)), startbcpc, (((void *)cogMethod))); - if (result != 0) { - errCode = result; - goto l7; - } - - /* In both CMMethod and CMBlock cases find the start of the map and - skip forward to the bytecode pc map entry for the stack check. */ - bcpc = startbcpc; - if ((((((CogBlockMethod *) cogMethod))->cmType)) == CMMethod) { - /* begin cmIsFullBlock */ - isInBlock = ((((CogBlockMethod *) cogMethod))->cpicHasMNUCaseOrCMIsFullBlock); - homeMethod = ((CogMethod *) (((CogBlockMethod *) cogMethod))); - assert(startbcpc == (startPCOfMethodHeader((homeMethod->methodHeader)))); - map = ((((usqInt)homeMethod)) + ((homeMethod->blockSize))) - 1; - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert((annotation == IsAbsPCReference) - || ((annotation == IsObjectReference) - || ((annotation == IsRelativeCall) - || (annotation == IsDisplacementX2N)))); - latestContinuation = startbcpc; - aMethodObj = (homeMethod->methodObject); - endbcpc = (numBytesOf(aMethodObj)) - 1; - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader) - ? 0x100 - : 0) -# else - 0 -# endif - ; - bcpc += deltaToSkipPrimAndErrorStoreInheader(aMethodObj, (homeMethod->methodHeader)); - } - else { - isInBlock = 1; - assert(bcpc == (((((CogBlockMethod *) cogMethod))->startpc))); - homeMethod = cmHomeMethod(((CogBlockMethod *) cogMethod)); - map = findMapLocationForMcpcinMethod((((usqInt)(((CogBlockMethod *) cogMethod)))) + (sizeof(CogBlockMethod)), homeMethod); - assert(map != 0); - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert(((((usqInt)(annotation)) >> AnnotationShift) == HasBytecodePC) - || ((((usqInt)(annotation)) >> AnnotationShift) == IsDisplacementX2N)); - while (((annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift)) != HasBytecodePC) { - map -= 1; - } - - /* skip fiducial; i.e. the map entry for the pc immediately following the method header. */ - map -= 1; - aMethodObj = (homeMethod->methodObject); - bcpc = startbcpc - ( -#if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet((homeMethod->methodHeader)) - ? AltBlockCreationBytecodeSize - : BlockCreationBytecodeSize) -#else // MULTIPLEBYTECODESETS - BlockCreationBytecodeSize -#endif - ); - /* begin bytecodeSetOffsetForHeader: */ - aMethodHeader1 = (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader1) - ? 0x100 - : 0) -# else - 0 -# endif - ; - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - endbcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, -1, aMethodObj)) - : 0)); - bcpc = startbcpc; - } - nExts = 0; - while ((((usqInt)((byteAt(map)))) >> AnnotationShift) != HasBytecodePC) { - map -= 1; - } - map -= 1; - while (((mapByte = byteAt(map))) != MapEnd) { - - /* defensive; we exit on bcpc */ - if (mapByte >= FirstAnnotation) { - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if (annotation >= HasBytecodePC) { - if ((annotation == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - while (1) { - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - if (isInBlock) { - if (bcpc >= endbcpc) { - errCode = 0; - goto l7; - } - } - else { - if (((descriptor->isReturn)) - && (bcpc >= latestContinuation)) { - errCode = 0; - goto l7; - } - if ((isBranch(descriptor)) - || ((descriptor->isBlockCreation))) { - /* begin latestContinuationPCFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj); - targetPC = (bcpc + ((descriptor->numBytes))) + (((distance < 0) ? 0 : distance)); - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - /* latestContinuation = */ latestContinuation; - } - nextBcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) - : 0)); - if (((descriptor->isMapped)) - || (isInBlock - && ((descriptor->isMappedInBlock)))) break; - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - isBackwardBranch = (isBranch(descriptor)) - && ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) < 0)); - result = pcDataForAnnotationMcpcBcpcMethod(descriptor, ((isBackwardBranch - ? (((sqInt)((usqInt)(annotation) << 1))) + 1 - : ((sqInt)((usqInt)(annotation) << 1)))), (((char *) mcpc)), ((isBackwardBranch - ? bcpc - (2 * nExts) - : bcpc)), (((void *)cogMethod))); - if (result != 0) { - errCode = result; - goto l7; - } - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - } - else { - assert(((((usqInt)(mapByte)) >> AnnotationShift) == IsDisplacementX2N) - || ((((usqInt)(mapByte)) >> AnnotationShift) == IsAnnotationExtension)); - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - errCode = 0; - l7: /* end mapFor:bcpc:performUntil:arg: */; - if (errCode != 0) { - assert(errCode == PrimErrNoMemory); - return -1; - } - if (((cogMethod->blockEntryOffset)) != 0) { - errCode = blockDispatchTargetsForperformarg(cogMethod, pcDataForBlockEntryMethod, ((sqInt)cogMethod)); - if (errCode != 0) { - assert(errCode == PrimErrNoMemory); - return -1; - } - } - return introspectionDataIndex; -} - - /* SimpleStackBasedCogit>>#numSpecialSelectors */ -static sqInt -numSpecialSelectors(void) -{ - return -# if MULTIPLEBYTECODESETS - (bytecodeSetOffset == 0x100 - ? AltNumSpecialSelectors - : NumSpecialSelectors) -# else - NumSpecialSelectors -# endif - ; -} - - -/* Collect the branch and send data for the block method starting at - blockEntryMcpc, storing it into picData. - */ - - /* SimpleStackBasedCogit>>#pcDataForBlockEntry:Method: */ -static usqInt NoDbgRegParms -pcDataForBlockEntryMethod(sqInt blockEntryMcpc, sqInt cogMethod) -{ - storePointerUncheckedofObjectwithValue(introspectionDataIndex, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 1, introspectionData, (((usqInt)(blockEntryMcpc - blockNoContextSwitchOffset) << 1) | 1)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 2, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 3, introspectionData, (((usqInt)blockEntryMcpc << 1) | 1)); - introspectionDataIndex += 4; - return 0; -} - - /* SimpleStackBasedCogit>>#pcDataFor:Annotation:Mcpc:Bcpc:Method: */ -static sqInt NoDbgRegParms -pcDataForAnnotationMcpcBcpcMethod(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *cogMethodArg) -{ - sqInt actualBcpc; - sqInt actualMcpc; - - if (!descriptor) { - - /* this is the stackCheck offset */ - assert(introspectionDataIndex == 0); - if (((((CogMethod *) cogMethodArg))->cpicHasMNUCaseOrCMIsFullBlock)) { - storePointerUncheckedofObjectwithValue(introspectionDataIndex, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 1, introspectionData, (((usqInt)cbNoSwitchEntryOffset << 1) | 1)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 2, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 3, introspectionData, (((usqInt)cbEntryOffset << 1) | 1)); - } - else { - storePointerUncheckedofObjectwithValue(introspectionDataIndex, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 1, introspectionData, (((usqInt)cmEntryOffset << 1) | 1)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 2, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 3, introspectionData, (((usqInt)cmNoCheckEntryOffset << 1) | 1)); - } - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 4, introspectionData, (((usqInt)(bcpc + 1) << 1) | 1)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 5, introspectionData, (((((((CogMethod *) cogMethodArg))->stackCheckOffset)) << 1) | 1)); - introspectionDataIndex += 6; - return 0; - } - if ((((usqInt)(isBackwardBranchAndAnnotation)) >> 1) >= HasBytecodePC) { - actualBcpc = (((isBackwardBranchAndAnnotation & 1) != 0) - ? bcpc + 1 - : (bcpc + ((descriptor->numBytes))) + 1); - actualMcpc = (((usqInt)mcpc)) - (((usqInt)cogMethodArg)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex, introspectionData, (((usqInt)actualBcpc << 1) | 1)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 1, introspectionData, (((usqInt)actualMcpc << 1) | 1)); - introspectionDataIndex += 2; - } - return 0; -} - - -/* If there is a generator for the current primitive then answer it; - otherwise answer nil. */ - - /* SimpleStackBasedCogit>>#primitiveGeneratorOrNil */ -static PrimitiveDescriptor * -primitiveGeneratorOrNil(void) -{ - PrimitiveDescriptor *primitiveDescriptor; - - if (isQuickPrimitiveIndex(primitiveIndex)) { - - /* an unused one */ - primitiveDescriptor = (&(primitiveGeneratorTable[0])); - (primitiveDescriptor->primitiveGenerator = quickPrimitiveGeneratorFor(primitiveIndex)); - return primitiveDescriptor; - } - if (((primitiveIndex >= 1) && (primitiveIndex <= MaxCompiledPrimitiveIndex))) { - return (&(primitiveGeneratorTable[primitiveIndex])); - } - return null; -} - - /* SimpleStackBasedCogit>>#register:isInMask: */ -static sqInt NoDbgRegParms -registerisInMask(sqInt reg, sqInt mask) -{ - return ((mask & (1U << reg)) != 0); -} - - /* SimpleStackBasedCogit>>#v3:Block:Code:Size: */ -static sqInt NoDbgRegParms -v3BlockCodeSize(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - assert(nExts <= 0); - return (((sqInt)((usqInt)((fetchByteofObject(pc + 2, aMethodObj))) << 8))) + (fetchByteofObject(pc + 3, aMethodObj)); -} - - -/* Answer the distance of a two byte forward long jump. */ - - /* SimpleStackBasedCogit>>#v3:LongForward:Branch:Distance: */ -static sqInt NoDbgRegParms -v3LongForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - assert(nExts == 0); - return (((sqInt)((usqInt)(((fetchByteofObject(pc, aMethodObj)) & 3)) << 8))) + (fetchByteofObject(pc + 1, aMethodObj)); -} - - -/* Answer the distance of a two byte forward long jump. */ - - /* SimpleStackBasedCogit>>#v3:Long:Branch:Distance: */ -static sqInt NoDbgRegParms -v3LongBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - assert(nExts == 0); - return (((sqInt)((usqInt)((((fetchByteofObject(pc, aMethodObj)) & 7) - 4)) << 8))) + (fetchByteofObject(pc + 1, aMethodObj)); -} - - -/* N.B. This serves for both BlueBook/V3 and V4 short jumps. */ - - /* SimpleStackBasedCogit>>#v3:ShortForward:Branch:Distance: */ -static sqInt NoDbgRegParms -v3ShortForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - assert(nExts == 0); - return ((fetchByteofObject(pc, aMethodObj)) & 7) + 1; -} - - -/* 253 11111101 eei i i kkk jjjjjjjj Push Closure Num Copied iii (+ Ext A - // 16 * 8) Num Args kkk (+ Ext A \\ 16 * 8) BlockSize jjjjjjjj (+ Ext B * - 256). ee = num extensions - */ - - /* SimpleStackBasedCogit>>#v4:Block:Code:Size: */ -static sqInt NoDbgRegParms -v4BlockCodeSize(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - sqInt byte; - sqInt byteOne; - sqInt extAValue; - sqInt extBValue; - sqInt extBValue1; - sqInt extByte; - sqInt pc1; - - - /* If nExts < 0 it isn't known and we rely on the number of extensions encoded in the eeiiikkk byte. */ - byteOne = fetchByteofObject(pc + 1, aMethodObj); - assert((nExts < 0) - || (nExts == (((usqInt)(byteOne)) >> 6))); - /* begin parseV4Exts:priorTo:in:into: */ - extAValue = (extBValue1 = 0); - pc1 = (pc - (((usqInt)(byteOne)) >> 6)) - (((usqInt)(byteOne)) >> 6); - while (pc1 < pc) { - byte = fetchByteofObject(pc1, aMethodObj); - pc1 += 1; - extByte = fetchByteofObject(pc1, aMethodObj); - pc1 += 1; - assert((byte == 224) - || (byte == 225)); - if (byte == 224) { - extAValue = ((((sqInt)((usqInt)(extAValue) << 8)))) + extByte; - } - else { - extBValue1 = ((extBValue1 == 0) - && (extByte > 0x7F) - ? extByte - 0x100 - : ((((sqInt)((usqInt)(extBValue1) << 8)))) + extByte); - } - } - extBValue = extBValue1; - return (fetchByteofObject(pc + 2, aMethodObj)) + (((sqInt)((usqInt)(extBValue) << 8))); -} - - -/* 242 11110010 i i i i i i i i Jump i i i i i i i i (+ Extend B * 256, - where bbbbbbbb = sddddddd, e.g. -32768 = i=0, a=0, s=1) - */ -/* 243 11110011 i i i i i i i i Pop and Jump 0n True i i i i i i i i (+ - Extend A * 256) - */ -/* 244 11110100 i i i i i i i i Pop and Jump 0n False i i i i i i i i (+ - Extend A * 256) - */ - - /* SimpleStackBasedCogit>>#v4:LongForward:Branch:Distance: */ -static sqInt NoDbgRegParms -v4LongForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - sqInt byte; - sqInt extAValue; - sqInt extBValue; - sqInt extBValue1; - sqInt extByte; - sqInt pc1; - - assert(nExts >= 0); - /* begin parseV4Exts:priorTo:in:into: */ - extAValue = (extBValue1 = 0); - pc1 = (pc - nExts) - nExts; - while (pc1 < pc) { - byte = fetchByteofObject(pc1, aMethodObj); - pc1 += 1; - extByte = fetchByteofObject(pc1, aMethodObj); - pc1 += 1; - assert((byte == 224) - || (byte == 225)); - if (byte == 224) { - extAValue = ((((sqInt)((usqInt)(extAValue) << 8)))) + extByte; - } - else { - extBValue1 = ((extBValue1 == 0) - && (extByte > 0x7F) - ? extByte - 0x100 - : ((((sqInt)((usqInt)(extBValue1) << 8)))) + extByte); - } - } - extBValue = extBValue1; - return (fetchByteofObject(pc + 1, aMethodObj)) + (((sqInt)((usqInt)(extBValue) << 8))); -} - - -/* 242 11110010 i i i i i i i i Jump i i i i i i i i (+ Extend B * 256, - where bbbbbbbb = sddddddd, e.g. -32768 = i=0, a=0, s=1) - */ - - /* SimpleStackBasedCogit>>#v4:Long:Branch:Distance: */ -static sqInt NoDbgRegParms -v4LongBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - sqInt byte; - sqInt extAValue; - sqInt extBValue; - sqInt extBValue1; - sqInt extByte; - sqInt pc1; - - assert(nExts >= 0); - /* begin parseV4Exts:priorTo:in:into: */ - extAValue = (extBValue1 = 0); - pc1 = (pc - nExts) - nExts; - while (pc1 < pc) { - byte = fetchByteofObject(pc1, aMethodObj); - pc1 += 1; - extByte = fetchByteofObject(pc1, aMethodObj); - pc1 += 1; - assert((byte == 224) - || (byte == 225)); - if (byte == 224) { - extAValue = ((((sqInt)((usqInt)(extAValue) << 8)))) + extByte; - } - else { - extBValue1 = ((extBValue1 == 0) - && (extByte > 0x7F) - ? extByte - 0x100 - : ((((sqInt)((usqInt)(extBValue1) << 8)))) + extByte); - } - } - extBValue = extBValue1; - return (fetchByteofObject(pc + 1, aMethodObj)) + (((sqInt)((usqInt)(extBValue) << 8))); -} - - -/* Add a blockStart for an embedded block. For a binary tree walk block - dispatch blocks must be compiled in pc/depth-first order but are scanned - in breadth-first - order, so do an insertion sort (which of course is really a bubble sort - because we - have to move everything higher to make room). */ - - /* StackToRegisterMappingCogit>>#addBlockStartAt:numArgs:numCopied:span: */ -static BlockStart * NoDbgRegParms -addBlockStartAtnumArgsnumCopiedspan(sqInt bytecodepc, sqInt numArgs, sqInt numCopied, sqInt span) -{ - BlockStart *blockStart; - sqInt i; - sqInt j; - - - /* Transcript ensureCr; nextPutAll: 'addBlockStartAt: '; print: bytecodepc; cr; flush. */ - if (blockCount > 0) { - i = blockCount - 1; - while (1) { - - /* check for repeat addition during recompilation due to initialNil miscount. */ - blockStart = (&(blockStarts[i])); - if (((blockStart->startpc)) == bytecodepc) { - return blockStart; - } - if (!((((blockStart->startpc)) > bytecodepc) - && (i > 0))) break; - i -= 1; - } - for (j = blockCount; j >= (i + 1); j += -1) { - blockStarts[j] = (blockStarts[j - 1]); - } - blockStart = (&(blockStarts[i + 1])); - } - else { - blockStart = (&(blockStarts[blockCount])); - } - blockCount += 1; - (blockStart->startpc = bytecodepc); - (blockStart->numArgs = numArgs); - (blockStart->numCopied = numCopied); - (blockStart->numInitialNils = 0); - (blockStart->stackCheckLabel = null); - (blockStart->hasInstVarRef = 0); - (blockStart->span = span); - return blockStart; -} - - -/* e.g. Receiver Receiver or Receiver Receiver (RISC) - Selector/Arg0 => Arg1 Selector/Arg0 => Arg1 - Arg1 Arg2 Arg1 Arg2 - Arg2 Arg3 Arg2 sp-> Arg3 - Arg3 sp-> retpc sp-> Arg3 - sp-> retpc */ -/* Generate code to adjust the possibly stacked arguments immediately - before jumping to a method looked up by a perform primitive. */ - - /* StackToRegisterMappingCogit>>#adjustArgumentsForPerform: */ -static void NoDbgRegParms -adjustArgumentsForPerform(sqInt numArgs) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction3; - sqInt index; - - assert((numRegArgs()) <= 2); - assert(numArgs >= 1); - if (numArgs <= 2 /* numRegArgs */) { - if (numArgs == 2) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, Arg0Reg); - } - return; - } - if ((3) == numArgs) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, SPReg, Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, BytesPerWord, SPReg, Arg0Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(AddCqR, (numArgs + 1) * BytesPerWord, SPReg); - return; - } - for (index = (numArgs - 2); index >= 0; index += -1) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveMwrR, index * BytesPerWord, SPReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperandoperand(MoveRMwr, TempReg, (index + 1) * BytesPerWord, SPReg); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperand(AddCqR, BytesPerWord, SPReg); -} - - -/* If the stack entry is already in a register not conflicting with regMask, - answers it, - else allocate a new register not conflicting with reg mask - */ - - /* StackToRegisterMappingCogit>>#allocateRegForStackEntryAt:notConflictingWith: */ -static sqInt NoDbgRegParms -allocateRegForStackEntryAtnotConflictingWith(sqInt index, sqInt regMask) -{ - sqInt mask; - CogSimStackEntry *stackEntry; - - stackEntry = ssValue(index); - mask = registerMaskOrNone(stackEntry); - if ((mask != 0) - && ((!(mask & regMask)))) { - flag("TODO"); - return registerOrNone(stackEntry); - } - return allocateRegNotConflictingWith(regMask); -} - - -/* if there's a free register, use it */ - - /* StackToRegisterMappingCogit>>#allocateRegNotConflictingWith: */ -static sqInt NoDbgRegParms -allocateRegNotConflictingWith(sqInt regMask) -{ - sqInt reg; - - reg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); - if (reg == NoReg) { - - /* No free register, choose one that does not conflict with regMask */ - reg = freeAnyRegNotConflictingWith(regMask); - } - if (reg == ReceiverResultReg) { - - /* If we've allocated RcvrResultReg, it's not live anymore */ - voidReceiverResultRegContainsSelf(); - } - return reg; -} - - /* StackToRegisterMappingCogit>>#anyReferencesToRegister:inTopNItems: */ -static sqInt NoDbgRegParms -anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n) -{ - sqInt i; - sqInt regMask; - - /* begin registerMaskFor: */ - regMask = 1U << reg; - for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { - if ((((registerMask(simStackAt(i))) & regMask) != 0)) { - return 1; - } - } - return 0; -} - - -/* This is a static version of ceCallCogCodePopReceiverArg0Regs - for break-pointing when debugging in C. */ -/* This exists only for break-pointing. */ - - /* StackToRegisterMappingCogit>>#callCogCodePopReceiverArg0Regs */ -void -callCogCodePopReceiverArg0Regs(void) -{ - realCECallCogCodePopReceiverArg0Regs(); -} - - -/* This is a static version of ceCallCogCodePopReceiverArg1Arg0Regs - for break-pointing when debugging in C. */ -/* This exists only for break-pointing. */ - - /* StackToRegisterMappingCogit>>#callCogCodePopReceiverArg1Arg0Regs */ -void -callCogCodePopReceiverArg1Arg0Regs(void) -{ - realCECallCogCodePopReceiverArg1Arg0Regs(); -} - - -/* Loop over bytecodes, dispatching to the generator for each bytecode, - handling fixups in due course. - */ - - /* StackToRegisterMappingCogit>>#compileAbstractInstructionsFrom:through: */ -static sqInt NoDbgRegParms -compileAbstractInstructionsFromthrough(sqInt start, sqInt end) -{ - BytecodeDescriptor *descriptor; - BytecodeFixup *fixup; - sqInt nExts; - sqInt nextOpcodeIndex; - sqInt result; - - traceSimStack(); - bytecodePC = start; - nExts = (result = 0); - descriptor = null; - deadCode = 0; - while (1) { - maybeHaltIfDebugPC(); - mergeWithFixupIfRequired((fixup = fixupAt(bytecodePC))); - descriptor = loadBytesAndGetDescriptor(); - nextOpcodeIndex = opcodeIndex; - result = (deadCode - ? mapDeadDescriptorIfNeeded(descriptor) - : ((descriptor->generator))()); - if (result == 0) { - /* begin assertExtsAreConsumed: */ - if (!((descriptor->isExtension))) { - assert((extA == 0) - && ((extB == 0) - && (numExtB == 0))); - } - } - traceDescriptor(descriptor); - traceSimStack(); - /* begin patchFixupTargetIfNeeded:nextOpcodeIndex: */ - if ((((((usqInt)((fixup->targetInstruction)))) >= NeedsNonMergeFixupFlag) && ((((usqInt)((fixup->targetInstruction)))) <= NeedsMergeFixupFlag))) { - - /* There is a fixup for this bytecode. It must point to the first generated - instruction for this bytecode. If there isn't one we need to add a label. */ - if (opcodeIndex == nextOpcodeIndex) { - /* begin Label */ - genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (fixup->targetInstruction = abstractInstructionAt(nextOpcodeIndex)); - } - /* begin maybeDumpLiterals: */ - if (((isBranch(descriptor)) - && (!(((descriptor->isBranchTrue)) - || ((descriptor->isBranchFalse))))) - || ((descriptor->isReturn))) { - /* begin dumpLiterals: */ - !(((isBranch(descriptor)) - && (!(((descriptor->isBranchTrue)) - || ((descriptor->isBranchFalse))))) - || ((descriptor->isReturn))); - } - /* begin nextBytecodePCFor:exts: */ - bytecodePC = (bytecodePC + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? ((descriptor->spanFunction))(descriptor, bytecodePC, nExts, methodObj) - : 0)); - if (!((result == 0) - && (bytecodePC <= end))) break; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - /* begin checkEnoughOpcodes */ - if (opcodeIndex > numAbstractOpcodes) { - error("Cog JIT internal error. Too many abstract opcodes. Num opcodes heuristic is too optimistic."); - } - return result; -} - - /* StackToRegisterMappingCogit>>#compileBlockBodies */ -static sqInt -compileBlockBodies(void) -{ - BlockStart *blockStart; - sqInt compiledBlocksCount; - sqInt initialCounterIndex; - sqInt initialOpcodeIndex; - sqInt initialStackPtr; - sqInt (* const pushNilSizeFunction)(sqInt,sqInt) = squeakV3orSistaV1PushNilSizenumInitialNils; - sqInt result; - sqInt savedNeedsFrame; - sqInt savedNumArgs; - sqInt savedNumTemps; - - assert(blockCount > 0); - savedNeedsFrame = needsFrame; - savedNumArgs = methodOrBlockNumArgs; - savedNumTemps = methodOrBlockNumTemps; - inBlock = InVanillaBlock; - compiledBlocksCount = 0; - while (compiledBlocksCount < blockCount) { - compilationPass = 1; - blockStart = blockStartAt(compiledBlocksCount); - if (((result = scanBlock(blockStart))) < 0) { - return result; - } - initialOpcodeIndex = opcodeIndex; - - /* for SistaCogit */ - initialCounterIndex = 0 /* maybeCounterIndex */; - while (1) { - compileBlockEntry(blockStart); - initialStackPtr = simStackPtr; - if (((result = compileAbstractInstructionsFromthrough(((blockStart->startpc)) + (pushNilSizeFunction(methodObj, ((blockStart->numInitialNils)))), (((blockStart->startpc)) + ((blockStart->span))) - 1))) < 0) { - return result; - } - if (initialStackPtr == simStackPtr) break; - assert((initialStackPtr > simStackPtr) - || (deadCode)); - - /* for asserts */ - compilationPass += 1; - (blockStart->numInitialNils = (((blockStart->numInitialNils)) + simStackPtr) - initialStackPtr); - (((blockStart->fakeHeader))->dependent = null); - reinitializeFixupsFromthrough(((blockStart->startpc)) + ((blockStart->numInitialNils)), (((blockStart->startpc)) + ((blockStart->span))) - 1); - bzero(abstractOpcodes + initialOpcodeIndex, - (opcodeIndex - initialOpcodeIndex) * sizeof(AbstractInstruction)); - opcodeIndex = initialOpcodeIndex; - } - compiledBlocksCount += 1; - } - needsFrame = savedNeedsFrame; - methodOrBlockNumArgs = savedNumArgs; - methodOrBlockNumTemps = savedNumTemps; - return 0; -} - - -/* Build a frame for a block activation. See CoInterpreter - class>>initializeFrameIndices. closure (in ReceiverResultReg) - arg0 - ... - argN - caller's saved ip/this stackPage (for a base frame) - fp-> saved fp - method - context (uninitialized?) - receiver - first temp - ... - sp-> Nth temp - Avoid use of SendNumArgsReg which is the flag determining whether - context switch is allowed on stack-overflow. */ -/* Build a frame for a block activation. See CoInterpreter - class>>initializeFrameIndices. Override to push the register receiver and - register arguments, if any, and to correctly - initialize the explicitly nilled/pushed temp entries (they are /not/ of - type constant nil). */ - - /* StackToRegisterMappingCogit>>#compileBlockFrameBuild: */ -static void NoDbgRegParms -compileBlockFrameBuild(BlockStart *blockStart) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction * cascade0; - sqInt constant; - sqInt constant1; - sqInt i; - sqInt ign; - - /* begin annotateBytecode: */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction->annotation = HasBytecodePC); - /* begin PushR: */ - genoperand(PushR, LinkReg); - /* begin PushR: */ - genoperand(PushR, FPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SPReg, FPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, ClassReg); - cascade0 = (blockStart->fakeHeader); - addDependent(cascade0, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)((blockStart->fakeHeader))), genoperand(PushCw, ((sqInt)((blockStart->fakeHeader))))))); - /* begin setLabelOffset: */ - ((cascade0->operands))[1] = MFMethodFlagIsBlockFlag; - annotateobjRef(checkLiteralforInstruction(nilObject(), genoperand(PushCw, nilObject())), nilObject()); - if ((blockStart->hasInstVarRef)) { - - /* Use ReceiverResultReg for Context to agree with store check trampoline */ - genLoadSlotsourceRegdestReg(ClosureOuterContextIndex, ClassReg, ReceiverResultReg); - genLoadSlotsourceRegdestReg(ReceiverIndex, ReceiverResultReg, Arg0Reg); - genEnsureOopInRegNotForwardedscratchRegupdatingSlotin(Arg0Reg, TempReg, ReceiverIndex, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ReceiverResultReg); - } - else { - genLoadSlotsourceRegdestReg(ClosureOuterContextIndex, ClassReg, Arg0Reg); - genLoadSlotsourceRegdestReg(ReceiverIndex, Arg0Reg, ReceiverResultReg); - } - /* begin PushR: */ - genoperand(PushR, ReceiverResultReg); - for (i = 0; i < ((blockStart->numCopied)); i += 1) { - genLoadSlotsourceRegdestReg(i + ClosureFirstCopiedValueIndex, ClassReg, TempReg); - /* begin PushR: */ - genoperand(PushR, TempReg); - } - (blockStart->stackCheckLabel = compileStackOverflowCheck(1)); - methodOrBlockNumTemps = (((blockStart->numArgs)) + ((blockStart->numCopied))) + ((blockStart->numInitialNils)); - initSimStackForFramefulMethod((blockStart->startpc)); - if (((blockStart->numInitialNils)) > 0) { - if (((blockStart->numInitialNils)) > 1) { - /* begin genMoveNilR: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, TempReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, TempReg); - } - for (ign = 1; ign <= ((blockStart->numInitialNils)); ign += 1) { - /* begin PushR: */ - genoperand(PushR, TempReg); - } - } - else { - /* begin genPushConstant: */ - constant1 = nilObject(); - if (shouldAnnotateObjectReference(constant1)) { - annotateobjRef(checkLiteralforInstruction(constant1, genoperand(PushCw, constant1)), constant1); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperand(PushCq, constant1); - } - } - } -} - - -/* Make sure ReceiverResultReg holds the receiver, loaded from the closure, - which is what is initially in ReceiverResultReg. We must annotate the - first instruction in vanilla blocks so that - findMethodForStartBcpc:inHomeMethod: can function. We need two annotations - because the first is a fiducial. */ -/* Make sure ReceiverResultReg holds the receiver, loaded from - the closure, which is what is initially in ReceiverResultReg */ - - /* StackToRegisterMappingCogit>>#compileBlockFramelessEntry: */ -static void NoDbgRegParms -compileBlockFramelessEntry(BlockStart *blockStart) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - - methodOrBlockNumTemps = (((blockStart->numArgs)) + ((blockStart->numCopied))) + ((blockStart->numInitialNils)); - initSimStackForFramelessBlock((blockStart->startpc)); - if (!(((blockStart->entryLabel)) == null)) { - /* begin annotateBytecode: */ - abstractInstruction = (blockStart->entryLabel); - (abstractInstruction->annotation = HasBytecodePC); - /* begin annotateBytecode: */ - abstractInstruction1 = (blockStart->entryLabel); - (abstractInstruction1->annotation = HasBytecodePC); - } - if ((blockStart->hasInstVarRef)) { - - /* Use ReceiverResultReg for Context to agree with store check trampoline */ - genLoadSlotsourceRegdestReg(ClosureOuterContextIndex, ReceiverResultReg, ReceiverResultReg); - genLoadSlotsourceRegdestReg(ReceiverIndex, ReceiverResultReg, Arg0Reg); - genEnsureOopInRegNotForwardedscratchRegupdatingSlotin(Arg0Reg, TempReg, ReceiverIndex, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ReceiverResultReg); - } - else { - genLoadSlotsourceRegdestReg(ClosureOuterContextIndex, ReceiverResultReg, TempReg); - genLoadSlotsourceRegdestReg(ReceiverIndex, TempReg, ReceiverResultReg); - } -} - - /* StackToRegisterMappingCogit>>#compileCogFullBlockMethod: */ -static CogMethod * NoDbgRegParms -compileCogFullBlockMethod(sqInt numCopied) -{ - sqInt allocBytes; - sqInt fixupBytes; - sqInt numBlocks; - sqInt numBytecodes; - sqInt numberOfAbstractOpcodes; - sqInt numCleanBlocks; - sqInt opcodeBytes; - sqInt result; - - methodOrBlockNumTemps = tempCountOf(methodObj); - setHasMovableLiteral(0); - setHasYoungReferent(isYoungObject(methodObj)); - methodOrBlockNumArgs = argumentCountOf(methodObj); - inBlock = InFullBlock; - maxLitIndex = -1; - assert((primitiveIndexOf(methodObj)) == 0); - - /* initial estimate. Actual endPC is determined in scanMethod. */ - initialPC = startPCOfMethod(methodObj); - endPC = numBytesOf(methodObj); - numBytecodes = (endPC - initialPC) + 1; - primitiveIndex = 0; - /* begin allocateOpcodes:bytecodes:ifFail: */ - numberOfAbstractOpcodes = (numBytecodes + 10) * 10 /* estimateOfAbstractOpcodesPerBytecodes */; - numAbstractOpcodes = numberOfAbstractOpcodes; - opcodeBytes = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupBytes = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - - /* Document the fact that the MaxStackAllocSize ensures that the number of abstract - opcodes fits in a 16 bit integer (e.g. CogBytecodeFixup's instructionIndex). */ - allocBytes = opcodeBytes + fixupBytes; - assert((((sizeof(CogAbstractInstruction)) + (sizeof(CogBytecodeFixup))) * 0xC000) > MaxStackAllocSize); - if (allocBytes > MaxStackAllocSize) { - return ((CogMethod *) MethodTooBig); - goto l1; - } - abstractOpcodes = alloca(allocBytes); - bzero(abstractOpcodes, allocBytes); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeBytes)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - l1: /* end allocateOpcodes:bytecodes:ifFail: */; - flag("TODO"); - if (((numBlocks = scanMethod())) < 0) { - return ((CogMethod *) numBlocks); - } - assert(numBlocks == 0); - numCleanBlocks = scanForCleanBlocks(); - assert(numCleanBlocks == 0); - allocateBlockStarts(numBlocks + numCleanBlocks); - blockCount = 0; - if (numCleanBlocks > 0) { - addCleanBlockStarts(); - } - if (!(maybeAllocAndInitIRCs())) { - - /* Inaccurate error code, but it'll do. This will likely never fail. */ - return ((CogMethod *) InsufficientCodeSpace); - } - blockEntryLabel = null; - (methodLabel->dependent = null); - if (((result = compileEntireFullBlockMethod(numCopied))) < 0) { - return ((CogMethod *) result); - } - return generateCogFullBlock(); -} - - /* StackToRegisterMappingCogit>>#compileCogMethod: */ -static CogMethod * NoDbgRegParms -compileCogMethod(sqInt selector) -{ - sqInt allocBytes; - int extra; - sqInt fixupBytes; - sqInt numBlocks; - sqInt numBytecodes; - sqInt numberOfAbstractOpcodes; - sqInt numCleanBlocks; - sqInt opcodeBytes; - sqInt result; - - methodOrBlockNumTemps = tempCountOf(methodObj); - setHasMovableLiteral(0); - setHasYoungReferent((isYoungObject(methodObj)) - || (isYoung(selector))); - methodOrBlockNumArgs = argumentCountOf(methodObj); - inBlock = 0; - maxLitIndex = -1; - extra = ((((primitiveIndex = primitiveIndexOf(methodObj))) > 0) - && (!(isQuickPrimitiveIndex(primitiveIndex))) - ? 30 - : 10); - - /* initial estimate. Actual endPC is determined in scanMethod. */ - initialPC = startPCOfMethod(methodObj); - endPC = (isQuickPrimitiveIndex(primitiveIndex) - ? initialPC - 1 - : numBytesOf(methodObj)); - numBytecodes = (endPC - initialPC) + 1; - /* begin allocateOpcodes:bytecodes:ifFail: */ - numberOfAbstractOpcodes = (numBytecodes + extra) * 10 /* estimateOfAbstractOpcodesPerBytecodes */; - numAbstractOpcodes = numberOfAbstractOpcodes; - opcodeBytes = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupBytes = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - - /* Document the fact that the MaxStackAllocSize ensures that the number of abstract - opcodes fits in a 16 bit integer (e.g. CogBytecodeFixup's instructionIndex). */ - allocBytes = opcodeBytes + fixupBytes; - assert((((sizeof(CogAbstractInstruction)) + (sizeof(CogBytecodeFixup))) * 0xC000) > MaxStackAllocSize); - if (allocBytes > MaxStackAllocSize) { - return ((CogMethod *) MethodTooBig); - goto l1; - } - abstractOpcodes = alloca(allocBytes); - bzero(abstractOpcodes, allocBytes); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeBytes)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - l1: /* end allocateOpcodes:bytecodes:ifFail: */; - if (((numBlocks = scanMethod())) < 0) { - return ((CogMethod *) numBlocks); - } - numCleanBlocks = scanForCleanBlocks(); - if (methodFoundInvalidPostScan()) { - return ((CogMethod *) ShouldNotJIT); - } - allocateBlockStarts(numBlocks + numCleanBlocks); - blockCount = 0; - if (numCleanBlocks > 0) { - addCleanBlockStarts(); - } - if (!(maybeAllocAndInitIRCs())) { - - /* Inaccurate error code, but it'll do. This will likely never fail. */ - return ((CogMethod *) InsufficientCodeSpace); - } - blockEntryLabel = null; - (methodLabel->dependent = null); - if (((result = compileEntireMethod())) < 0) { - return ((CogMethod *) result); - } - return generateCogMethod(selector); -} - - -/* Compile the abstract instructions for the entire method, including blocks. */ -/* Compile the abstract instructions for the entire method, including blocks. */ - - /* StackToRegisterMappingCogit>>#compileEntireMethod */ -static sqInt -compileEntireMethod(void) -{ - sqInt result; - - regArgsHaveBeenPushed = 0; - /* begin preenMethodLabel */ - (((((AbstractInstruction *) methodLabel))->operands))[1] = 0; - compileAbort(); - compileEntry(); - if (((result = compilePrimitive())) < 0) { - return result; - } - compileFrameBuild(); - if (((result = compileMethodBody())) < 0) { - return result; - } - if (blockCount == 0) { - return 0; - } - if (((result = compileBlockBodies())) < 0) { - return result; - } - return compileBlockDispatch(); -} - - -/* Build a frame for a CogMethod activation. See CoInterpreter - class>>initializeFrameIndices. receiver (in ReceiverResultReg) - arg0 - ... - argN - caller's saved ip/this stackPage (for a base frame) - fp-> saved fp - method - context (uninitialized?) - receiver - first temp - ... - sp-> Nth temp - If there is a primitive and an error code the Nth temp is the error code. - Ensure SendNumArgsReg is set early on (incidentally to nilObj) because - it is the flag determining whether context switch is allowed on - stack-overflow. */ -/* Build a frame for a CogMethod activation. See CoInterpreter - class>>initializeFrameIndices. Override to push the register receiver and - register arguments, if any. */ - - /* StackToRegisterMappingCogit>>#compileFrameBuild */ -static void -compileFrameBuild(void) -{ - AbstractInstruction *anInstruction; - sqInt constant; - sqInt i; - sqInt iLimiT; - - -# if IMMUTABILITY - if (useTwoPaths) { - compileTwoPathFrameBuild(); - return; - } -# endif - if (!needsFrame) { - if (useTwoPaths) { - compileTwoPathFramelessInit(); - } - initSimStackForFramelessMethod(initialPC); - return; - } - assert(!(useTwoPaths)); - genPushRegisterArgs(); - if (!needsFrame) { - return; - } - /* begin PushR: */ - genoperand(PushR, LinkReg); - /* begin PushR: */ - genoperand(PushR, FPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SPReg, FPReg); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperand(PushCw, ((sqInt)methodLabel))))); - /* begin genMoveNilR: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, SendNumArgsReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, SendNumArgsReg); - } - /* begin PushR: */ - genoperand(PushR, SendNumArgsReg); - /* begin PushR: */ - genoperand(PushR, ReceiverResultReg); - for (i = (methodOrBlockNumArgs + 1), iLimiT = (temporaryCountOfMethodHeader(methodHeader)); i <= iLimiT; i += 1) { - /* begin PushR: */ - genoperand(PushR, SendNumArgsReg); - } - if (((primitiveIndexOfMethodheader(methodObj, methodHeader)) > 0) - && ((longStoreBytecodeForHeader(methodHeader)) == (fetchByteofObject((startPCOfMethod(methodObj)) + (sizeOfCallPrimitiveBytecode(methodHeader)), methodObj)))) { - compileGetErrorCode(); - } - stackCheckLabel = compileStackOverflowCheck(canContextSwitchIfActivatingheader(methodObj, methodHeader)); - initSimStackForFramefulMethod(initialPC); -} - - -/* Make sure ReceiverResultReg holds the receiver, loaded from the closure, - which is what is initially in ReceiverResultReg. */ -/* Make sure ReceiverResultReg holds the receiver, loaded from - the closure, which is what is initially in ReceiverResultReg */ - - /* StackToRegisterMappingCogit>>#compileFullBlockFramelessEntry: */ -static void NoDbgRegParms -compileFullBlockFramelessEntry(sqInt numCopied) -{ - initSimStackForFramelessBlock(initialPC); - flag("TODO"); - genLoadSlotsourceRegdestReg(FullClosureReceiverIndex, ReceiverResultReg, Arg0Reg); - genEnsureOopInRegNotForwardedscratchRegupdatingSlotin(Arg0Reg, TempReg, FullClosureReceiverIndex, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ReceiverResultReg); -} - - -/* Build a frame for a block activation. See CoInterpreter - class>>initializeFrameIndices. closure (in ReceiverResultReg) - arg0 - ... - argN - caller's saved ip/this stackPage (for a base frame) - fp-> saved fp - method - context (uninitialized?) - receiver - first temp - ... - sp-> Nth temp - Avoid use of SendNumArgsReg which is the flag determining whether - context switch is allowed on stack-overflow. */ - - /* StackToRegisterMappingCogit>>#compileFullBlockMethodFrameBuild: */ -static void NoDbgRegParms -compileFullBlockMethodFrameBuild(sqInt numCopied) -{ - AbstractInstruction *anInstruction; - sqInt constant; - sqInt i; - sqInt iLimiT; - - if (useTwoPaths) { - - /* method with only inst var store, we compile only slow path for now */ - useTwoPaths = 0; -# if IMMUTABILITY - needsFrame = 1; -# endif - } - if (!needsFrame) { - - /* it is OK for numCopied to be non-zero provided that the block does not actually use the copied values. - There are some blocks like this, e.g. that simply reference copied values to mark them as used for Slang. - See e.g. CroquetPlugin>>#primitiveGatherEntropy which contains the block [bufPtr. bufSize. false], - which the bytecode compiler optimizes to [false]. */ - compileFullBlockFramelessEntry(numCopied); - initSimStackForFramelessBlock(initialPC); - return; - } - if (!needsFrame) { - return; - } - /* begin PushR: */ - genoperand(PushR, LinkReg); - /* begin PushR: */ - genoperand(PushR, FPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SPReg, FPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, ClassReg); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperand(PushCw, ((sqInt)methodLabel))))); - /* begin setLabelOffset: */ - (((((AbstractInstruction *) methodLabel))->operands))[1] = MFMethodFlagIsBlockFlag; - /* begin genMoveNilR: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, SendNumArgsReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, SendNumArgsReg); - } - /* begin PushR: */ - genoperand(PushR, SendNumArgsReg); - flag("TODO"); - genLoadSlotsourceRegdestReg(FullClosureReceiverIndex, ClassReg, Arg0Reg); - genEnsureOopInRegNotForwardedscratchRegupdatingSlotin(Arg0Reg, TempReg, FullClosureReceiverIndex, ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ReceiverResultReg); - /* begin PushR: */ - genoperand(PushR, ReceiverResultReg); - for (i = 0; i < numCopied; i += 1) { - genLoadSlotsourceRegdestReg(i + FullClosureFirstCopiedValueIndex, ClassReg, TempReg); - /* begin PushR: */ - genoperand(PushR, TempReg); - } - for (i = ((methodOrBlockNumArgs + numCopied) + 1), iLimiT = (temporaryCountOfMethodHeader(methodHeader)); i <= iLimiT; i += 1) { - /* begin PushR: */ - genoperand(PushR, SendNumArgsReg); - } - stackCheckLabel = compileStackOverflowCheck(1); - initSimStackForFramefulMethod(initialPC); -} - - -/* Build a frame for a CogMethod activation. See CoInterpreter - class>>initializeFrameIndices. receiver (in ReceiverResultReg) - arg0 - ... - argN - caller's saved ip/this stackPage (for a base frame) - fp-> saved fp - method - context (uninitialized?) - receiver - first temp - ... - sp-> Nth temp - If there is a primitive and an error code the Nth temp is the error code. - Ensure SendNumArgsReg is set early on (incidentally to nilObj) because - it is the flag determining whether context switch is allowed on - stack-overflow. */ -/* We are in a method where the frame is needed *only* for instance variable - store, typically a setter method. - This case has 20% overhead with Immutability compared to setter without - immutability because of the stack - frame creation. We compile two path, one where the object is immutable, - one where it isn't. At the beginning - of the frame build, we take one path or the other depending on the - receiver mutability. - - Note: this specific case happens only where there are only instance - variabel stores. We could do something - similar for literal variable stores, but we don't as it's too uncommon. - */ - - /* StackToRegisterMappingCogit>>#compileTwoPathFrameBuild */ -#if IMMUTABILITY -static void -compileTwoPathFrameBuild(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt constant; - sqInt i; - sqInt iLimiT; - AbstractInstruction * jumpImmutable; - AbstractInstruction * jumpOld; - - assert(useTwoPaths); - assert(blockCount == 0); - jumpImmutable = genJumpImmutablescratchReg(ReceiverResultReg, TempReg); - - /* first path. The receiver is mutable */ - - /* N.B. FLAGS := destReg - scratchReg */ - /* begin checkQuickConstant:forInstruction: */ - storeCheckBoundary(); - anInstruction = genoperandoperand(CmpCqR, storeCheckBoundary(), ReceiverResultReg); - /* begin JumpAboveOrEqual: */ - jumpOld = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - assert(!needsFrame); - initSimStackForFramelessMethod(initialPC); - /* begin compileMethodBody */ - if (endPC < initialPC) { - goto l3; - } - compileAbstractInstructionsFromthrough(initialPC + (deltaToSkipPrimAndErrorStoreInheader(methodObj, methodHeader)), endPC); - l3: /* end compileMethodBody */; - - /* reset because it impacts inst var store compilation */ - useTwoPaths = 0; - needsFrame = 1; - jmpTarget(jumpOld, jmpTarget(jumpImmutable, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - genPushRegisterArgs(); - if (!needsFrame) { - return; - } - /* begin PushR: */ - genoperand(PushR, LinkReg); - /* begin PushR: */ - genoperand(PushR, FPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SPReg, FPReg); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperand(PushCw, ((sqInt)methodLabel))))); - /* begin genMoveNilR: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, SendNumArgsReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, constant, SendNumArgsReg); - } - /* begin PushR: */ - genoperand(PushR, SendNumArgsReg); - /* begin PushR: */ - genoperand(PushR, ReceiverResultReg); - for (i = (methodOrBlockNumArgs + 1), iLimiT = (temporaryCountOfMethodHeader(methodHeader)); i <= iLimiT; i += 1) { - /* begin PushR: */ - genoperand(PushR, SendNumArgsReg); - } - if (((primitiveIndexOfMethodheader(methodObj, methodHeader)) > 0) - && ((longStoreBytecodeForHeader(methodHeader)) == (fetchByteofObject((startPCOfMethod(methodObj)) + (sizeOfCallPrimitiveBytecode(methodHeader)), methodObj)))) { - compileGetErrorCode(); - } - stackCheckLabel = compileStackOverflowCheck(canContextSwitchIfActivatingheader(methodObj, methodHeader)); - initSimStackForFramefulMethod(initialPC); -} -#endif /* IMMUTABILITY */ - - -/* We are in a frameless method with at least two inst var stores. We compile - two paths, - one where the object is in new space, and one where it isn't. At the - beginning - of the method, we take one path or the other depending on the receiver - being in newSpace. - */ - - /* StackToRegisterMappingCogit>>#compileTwoPathFramelessInit */ -static void -compileTwoPathFramelessInit(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction * jumpOld; - - assert(!(IMMUTABILITY)); - assert(!(needsFrame)); - assert(useTwoPaths); - - /* first path. The receiver is young */ - - /* N.B. FLAGS := destReg - scratchReg */ - /* begin checkQuickConstant:forInstruction: */ - storeCheckBoundary(); - anInstruction = genoperandoperand(CmpCqR, storeCheckBoundary(), ReceiverResultReg); - /* begin JumpAboveOrEqual: */ - jumpOld = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - initSimStackForFramelessMethod(initialPC); - /* begin compileMethodBody */ - if (endPC < initialPC) { - goto l1; - } - compileAbstractInstructionsFromthrough(initialPC + (deltaToSkipPrimAndErrorStoreInheader(methodObj, methodHeader)), endPC); - l1: /* end compileMethodBody */; - - /* reset because it impacts inst var store compilation */ - useTwoPaths = 0; - jmpTarget(jumpOld, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); -} - - /* StackToRegisterMappingCogit>>#cPICMissTrampolineFor: */ -static sqInt NoDbgRegParms -cPICMissTrampolineFor(sqInt numArgs) -{ - return picMissTrampolines[((numArgs < (3)) ? numArgs : (3))]; -} - - -/* Replaces the Blue Book double-extended send [132], in which the first byte - was wasted on 8 bits of argument count. - Here we use 3 bits for the operation sub-type (opType), and the remaining - 5 bits for argument count where needed. - The last byte give access to 256 instVars or literals. - See also secondExtendedSendBytecode - */ - - /* StackToRegisterMappingCogit>>#doubleExtendedDoAnythingBytecode */ -static sqInt -doubleExtendedDoAnythingBytecode(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *abstractInstruction2; - sqInt opType; - - opType = ((usqInt)(byte1)) >> 5; - if (opType == 0) { - return genSendnumArgs(byte2, byte1 & 0x1F); - } - if (opType == 1) { - return genSendSupernumArgs(byte2, byte1 & 0x1F); - } - switch (opType) { - case 2: - if (isReadMediatedContextInstVarIndex(byte2)) { - genPushMaybeContextReceiverVariable(byte2); - } - else { - genPushReceiverVariable(byte2); - /* begin annotateInstructionForBytecode */ - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (abstractInstruction->annotation = HasBytecodePC); - return 0; - } - break; - case 3: - genPushLiteralIndex(byte2); - /* begin annotateInstructionForBytecode */ - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction1 = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction1 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (abstractInstruction1->annotation = HasBytecodePC); - return 0; - - case 4: - genPushLiteralVariable(byte2); - break; - case 7: - genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(0, byte2, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); -# if IMMUTABILITY - - /* genStorePop:LiteralVariable: annotates; don't annotate twice */ - return 0; -# endif - break; - default: - - /* 5 & 6 */ - if (isWriteMediatedContextInstVarIndex(byte2)) { - genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(opType == 6, byte2, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } - else { - genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(opType == 6, byte2, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } -# if IMMUTABILITY - - /* genStorePop:...ReceiverVariable: annotate; don't annotate twice */ - return 0; -# endif -; - } - assert(needsFrame); - assert(!(prevInstIsPCAnnotated())); - /* begin annotateBytecode: */ - abstractInstruction2 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction2->annotation = HasBytecodePC); - return 0; -} - - /* StackToRegisterMappingCogit>>#duplicateTopBytecode */ -static sqInt -duplicateTopBytecode(void) -{ - SimStackEntry desc; - - /* begin ssTopDescriptor */ - desc = simStack[simStackPtr]; - return ssPushDesc(desc); -} - - -/* Make sure there's a flagged fixup at the target pc in fixups. - Initially a fixup's target is just a flag. Later on it is replaced with a - proper instruction. */ - - /* StackToRegisterMappingCogit>>#ensureFixupAt: */ -static BytecodeFixup * NoDbgRegParms -ensureFixupAt(sqInt targetPC) -{ - BytecodeFixup *fixup; - - /* begin fixupAt: */ - fixup = fixupAtIndex(targetPC - initialPC); - traceFixupmerge(fixup, 1); - if ((((usqInt)((fixup->targetInstruction)))) <= NeedsNonMergeFixupFlag) { - - /* convert a non-merge into a merge */ - /* begin becomeMergeFixup */ - (fixup->targetInstruction) = ((AbstractInstruction *) NeedsMergeFixupFlag); - (fixup->simStackPtr = simStackPtr); - } - else { - if ((fixup->isTargetOfBackwardBranch)) { - - /* this is the target of a backward branch and - so doesn't have a simStackPtr assigned yet. */ - (fixup->simStackPtr = simStackPtr); - } - else { - assert(((fixup->simStackPtr)) == simStackPtr); - } - } - /* begin recordBcpc: */ - return fixup; -} - - -/* Make sure there's a flagged fixup at the target pc in fixups. - Initially a fixup's target is just a flag. Later on it is replaced with a - proper instruction. */ - - /* StackToRegisterMappingCogit>>#ensureNonMergeFixupAt: */ -static BytecodeFixup * NoDbgRegParms -ensureNonMergeFixupAt(sqInt targetPC) -{ - BytecodeFixup *fixup; - - /* begin fixupAt: */ - fixup = fixupAtIndex(targetPC - initialPC); - traceFixupmerge(fixup, 1); - if (((fixup->targetInstruction)) == 0) { - /* begin becomeNonMergeFixup */ - (fixup->targetInstruction) = ((AbstractInstruction *) NeedsNonMergeFixupFlag); - } - /* begin recordBcpc: */ - return fixup; -} - - /* StackToRegisterMappingCogit>>#ensureReceiverResultRegContainsSelf */ -static void -ensureReceiverResultRegContainsSelf(void) -{ - if (needsFrame) { - if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); - /* begin putSelfInReceiverResultReg */ - storeToReg(simSelf(), ReceiverResultReg); - ((simSelf())->liveRegister = ReceiverResultReg); - } - } - else { - assert(((((simSelf())->type)) == SSRegister) - && (((((simSelf())->registerr)) == ReceiverResultReg) - && (receiverIsInReceiverResultReg()))); - } -} - - /* StackToRegisterMappingCogit>>#evaluate:at: */ -static void NoDbgRegParms -evaluateat(BytecodeDescriptor *descriptor, sqInt pc) -{ - byte0 = fetchByteofObject(pc, methodObj); - assert(descriptor == (generatorAt(bytecodeSetOffset + byte0))); - loadSubsequentBytesForDescriptorat(descriptor, pc); - ((descriptor->generator))(); -} - - -/* Attempt to follow a branch to a pc. Handle branches to unconditional jumps - and branches to push: aBoolean; conditional branch pairs. If the branch - cannot be - followed answer targetBytecodePC. It is not possible to follow jumps to - conditional branches because the stack changes depth. That following is - left to the genJumpIf:to: - clients. */ - - /* StackToRegisterMappingCogit>>#eventualTargetOf: */ -static sqInt NoDbgRegParms -eventualTargetOf(sqInt targetBytecodePC) -{ - sqInt cond; - sqInt currentTarget; - BytecodeDescriptor *descriptor; - sqInt nExts; - sqInt nextPC; - sqInt span; - - cond = 0; - nextPC = (currentTarget = targetBytecodePC); - while (1) { - nExts = 0; - while (1) { - /* begin generatorForPC: */ - descriptor = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC, methodObj))); - if ((descriptor->isReturn)) { - return currentTarget; - } - if (!((descriptor->isExtension))) break; - nExts += 1; - nextPC += (descriptor->numBytes); - } - if ((isBranch(descriptor)) - && (!(((descriptor->isBranchTrue)) - || ((descriptor->isBranchFalse))))) { - /* begin spanFor:at:exts:in: */ - span = ((descriptor->spanFunction))(descriptor, nextPC, nExts, methodObj); - if (span < 0) { - - /* Do *not* follow backward branches; these are interrupt points and should not be elided. */ - return currentTarget; - } - nextPC = (nextPC + ((descriptor->numBytes))) + span; - } - else { - if (((descriptor->generator)) == genPushConstantTrueBytecode) { - cond = 1; - } - else { - if (((descriptor->generator)) == genPushConstantFalseBytecode) { - cond = 0; - } - else { - return currentTarget; - } - } - if (((fixupAt(nextPC))->isTargetOfBackwardBranch)) { - return currentTarget; - } - nextPC = eventualTargetOf(nextPC + ((descriptor->numBytes))); - nExts = 0; - while (1) { - /* begin generatorForPC: */ - descriptor = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC, methodObj))); - if ((descriptor->isReturn)) { - return currentTarget; - } - if (!((descriptor->isExtension))) break; - nExts += 1; - nextPC += (descriptor->numBytes); - } - if (!(isBranch(descriptor))) { - return currentTarget; - } - if ((isBranch(descriptor)) - && (!(((descriptor->isBranchTrue)) - || ((descriptor->isBranchFalse))))) { - return currentTarget; - } - nextPC = (cond == ((descriptor->isBranchTrue)) - ? (nextPC + ((descriptor->numBytes))) + (((descriptor->spanFunction))(descriptor, nextPC, nExts, methodObj)) - : nextPC + ((descriptor->numBytes))); - } - currentTarget = nextPC; - } - return 0; -} - - -/* Spill the closest register on stack not conflicting with regMask. - Assertion Failure if regMask has already all the registers */ - - /* StackToRegisterMappingCogit>>#freeAnyRegNotConflictingWith: */ -static sqInt NoDbgRegParms -freeAnyRegNotConflictingWith(sqInt regMask) -{ - CogSimStackEntry *desc; - sqInt index; - sqInt reg; - - assert(needsFrame); - reg = NoReg; - index = ((simSpillBase < 0) ? 0 : simSpillBase); - while ((reg == NoReg) - && (index < simStackPtr)) { - desc = simStackAt(index); - if (((desc->type)) == SSRegister) { - if (!(((regMask & (1U << ((desc->registerr)))) != 0))) { - reg = (desc->registerr); - } - } - index += 1; - } - assert(!((reg == NoReg))); - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << reg, simStackPtr, simNativeStackPtr); - return reg; -} - - -/* Return from block, assuming result already loaded into ReceiverResultReg. */ -/* Return from block, assuming result already loaded into ReceiverResultReg. */ - - /* StackToRegisterMappingCogit>>#genBlockReturn */ -static sqInt -genBlockReturn(void) -{ - if (needsFrame) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, FPReg, SPReg); - /* begin PopR: */ - genoperand(PopR, FPReg); - /* begin PopR: */ - genoperand(PopR, LinkReg); - } - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - - /* can't fall through */ - deadCode = 1; - return 0; -} - - -/* Generate special versions of the ceCallCogCodePopReceiverAndClassRegs - enilopmart that also pop register args from the stack to undo the pushing - of register args in the abort/miss trampolines. */ - - /* StackToRegisterMappingCogit>>#genCallPICEnilopmartNumArgs: */ -static void (*genCallPICEnilopmartNumArgs(sqInt numArgs))(void) - -{ - AbstractInstruction *anInstruction; - sqInt endAddress; - usqInt enilopmart; - sqInt quickConstant; - sqInt reg; - sqInt size; - - zeroOpcodeIndex(); - /* begin MoveCq:R: */ - quickConstant = varBaseAddress(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - genLoadStackPointers(backEnd); - /* begin PopR: */ - genoperand(PopR, ClassReg); - /* begin PopR: */ - genoperand(PopR, TempReg); - /* begin PopR: */ - reg = LinkReg; - genoperand(PopR, reg); - if (numArgs > 0) { - if (numArgs > 1) { - /* begin PopR: */ - genoperand(PopR, Arg1Reg); - assert((numRegArgs()) == 2); - } - /* begin PopR: */ - genoperand(PopR, Arg0Reg); - } - /* begin PopR: */ - genoperand(PopR, ReceiverResultReg); - /* begin JumpR: */ - genoperand(JumpR, TempReg); - computeMaximumSizes(); - size = generateInstructionsAt(methodZoneBase); - endAddress = outputInstructionsAt(methodZoneBase); - assert((methodZoneBase + size) == endAddress); - enilopmart = methodZoneBase; - methodZoneBase = alignUptoRoutineBoundary(endAddress); - stopsFromto(backEnd, endAddress, methodZoneBase - 1); - recordGeneratedRunTimeaddress(trampolineNamenumRegArgs("ceCallPIC", numArgs), enilopmart); - return ((void (*)(void)) enilopmart); -} - - -/* SistaV1: ** 248 (2) 11111000 iiiiiiii mssjjjjj Call Primitive #iiiiiiii - + (jjjjj * 256) - m=1 means inlined primitive, no hard return after execution. - ss defines the unsafe operation set used to encode the operations. - (ss = 0 means sista unsafe operations, ss = 01 means lowcode operations, - other numbers are as yet used). - See SistaCogit genCallPrimitiveBytecode, EncoderForSistaV1's class comment - and StackInterpreter>>#callPrimitiveBytecode for more information. */ - - /* StackToRegisterMappingCogit>>#genCallPrimitiveBytecode */ -static sqInt -genCallPrimitiveBytecode(void) -{ - sqInt prim; - sqInt primSet; - - if (byte2 < 128) { - return (bytecodePC == initialPC - ? 0 - : EncounteredUnknownBytecode); - } - prim = (((sqInt)((usqInt)((byte2 - 128)) << 8))) + byte1; - primSet = (((usqInt)(prim)) >> 13) & 3; - prim = prim & 0x1FFF; - return EncounteredUnknownBytecode; -} - - -/* Override to push the register receiver and register arguments, if any. */ - - /* StackToRegisterMappingCogit>>#genExternalizePointersForPrimitiveCall */ -static sqInt -genExternalizePointersForPrimitiveCall(void) -{ - AbstractInstruction *anInstruction; - - genPushRegisterArgs(); - /* begin checkLiteral:forInstruction: */ - instructionPointerAddress(); - anInstruction = genoperandoperand(MoveRAw, LinkReg, instructionPointerAddress()); - return genSaveStackPointers(backEnd); -} - - -/* Override to push the register receiver and register arguments, if any. */ - - /* StackToRegisterMappingCogit>>#genExternalizeStackPointerForFastPrimitiveCall */ -static AbstractInstruction * -genExternalizeStackPointerForFastPrimitiveCall(void) -{ - AbstractInstruction *anInstruction; - - genPushRegisterArgs(); - return (/* begin checkLiteral:forInstruction: */ - stackPointerAddress(), - (anInstruction = genoperandoperand(MoveRAw, SPReg, stackPointerAddress())), - anInstruction); -} - - -/* Block compilation. At this point in the method create the block. Note its - start and defer generating code for it until after the method and any - other preceding - blocks. The block's actual code will be compiled later. */ -/* 253 11111101 eei i i kkk jjjjjjjj Push Closure Num Copied iii (+ Ext A - // 16 * 8) Num Args kkk (+ Ext A \\ 16 * 8) BlockSize jjjjjjjj (+ Ext B * - 256). ee = num extensions - */ - - /* StackToRegisterMappingCogit>>#genExtPushClosureBytecode */ -static sqInt -genExtPushClosureBytecode(void) -{ - sqInt i; - sqInt numArgs; - sqInt numCopied; - sqInt reg; - sqInt startpc; - - assert(needsFrame); - startpc = bytecodePC + (((generatorAt(byte0))->numBytes)); - addBlockStartAtnumArgsnumCopiedspan(startpc, (numArgs = (byte1 & 7) + ((extA % 16) * 8)), (numCopied = ((((usqInt)(byte1)) >> 3) & 7) + ((extA / 16) * 8)), byte2 + (((sqInt)((usqInt)(extB) << 8)))); - extA = (numExtB = (extB = 0)); - /* begin genInlineClosure:numArgs:numCopied: */ - assert(getActiveContextAllocatesInMachineCode()); - voidReceiverResultRegContainsSelf(); - /* begin ssAllocateCallReg:and:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg) | (1U << SendNumArgsReg)) | (1U << ClassReg)), simStackPtr, simNativeStackPtr); - genNoPopCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(startpc + 1, numArgs, numCopied, methodOrBlockNumArgs, methodNeedsLargeContext(methodObj), inBlock); - for (i = 1; i <= numCopied; i += 1) { - reg = ssStorePoptoPreferredReg(1, TempReg); - genStoreSourceRegslotIndexintoNewObjectInDestReg(reg, (ClosureFirstCopiedValueIndex + numCopied) - i, ReceiverResultReg); - } - ssPushRegister(ReceiverResultReg); - return 0; -} - - -/* Full Block creation compilation. The block's actual code will be compiled - separatedly. - */ -/* * 255 11111111 xxxxxxxx siyyyyyy push Closure Compiled block literal - index xxxxxxxx (+ Extend A * 256) numCopied yyyyyy receiverOnStack: s = 1 - ignoreOuterContext: i = 1 - */ - - /* StackToRegisterMappingCogit>>#genExtPushFullClosureBytecode */ -static sqInt -genExtPushFullClosureBytecode(void) -{ - sqInt compiledBlock; - sqInt i; - int ignoreContext; - sqInt numCopied; - int receiverIsOnStack; - sqInt reg; - - assert(needsFrame); - compiledBlock = getLiteral(byte1 + (((sqInt)((usqInt)(extA) << 8)))); - extA = 0; - numCopied = byte2 & (0x3F); - receiverIsOnStack = ((byte2 & (128)) != 0); - ignoreContext = ((byte2 & (64)) != 0); - voidReceiverResultRegContainsSelf(); - /* begin ssAllocateCallReg:and:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg) | (1U << SendNumArgsReg)) | (1U << ClassReg)), simStackPtr, simNativeStackPtr); - genCreateFullClosurenumArgsnumCopiedignoreContextcontextNumArgslargeinBlock(compiledBlock, argumentCountOf(compiledBlock), numCopied, ignoreContext, methodOrBlockNumArgs, methodNeedsLargeContext(methodObj), inBlock); - for (i = 1; i <= numCopied; i += 1) { - reg = ssStorePoptoPreferredReg(1, TempReg); - genStoreSourceRegslotIndexintoNewObjectInDestReg(reg, (FullClosureFirstCopiedValueIndex + numCopied) - i, ReceiverResultReg); - } - if (receiverIsOnStack) { - reg = ssStorePoptoPreferredReg(1, TempReg); - } - else { - storeToReg(simSelf(), (reg = TempReg)); - } - genStoreSourceRegslotIndexintoNewObjectInDestReg(reg, FullClosureReceiverIndex, ReceiverResultReg); - ssPushRegister(ReceiverResultReg); - return 0; -} - - -/* Enilopmarts transfer control from C into machine code (backwards - trampolines). - */ -/* Enilopmarts transfer control from C into machine code (backwards - trampolines). Override to add version for generic and PIC-specific entry - with reg args. */ - - /* StackToRegisterMappingCogit>>#generateEnilopmarts */ -static void -generateEnilopmarts(void) -{ - -# if Debug - /* begin genEnilopmartFor:forCall:called: */ - realCEEnterCogCodePopReceiverReg = genEnilopmartForandandforCallcalled(ReceiverResultReg, NoReg, NoReg, 0, "realCEEnterCogCodePopReceiverReg"); - ceEnterCogCodePopReceiverReg = enterCogCodePopReceiver; - /* begin genEnilopmartFor:forCall:called: */ - realCECallCogCodePopReceiverReg = genEnilopmartForandandforCallcalled(ReceiverResultReg, NoReg, NoReg, 1, "realCECallCogCodePopReceiverReg"); - ceCallCogCodePopReceiverReg = callCogCodePopReceiver; - /* begin genEnilopmartFor:and:forCall:called: */ - realCECallCogCodePopReceiverAndClassRegs = genEnilopmartForandandforCallcalled(ReceiverResultReg, ClassReg, NoReg, 1, "realCECallCogCodePopReceiverAndClassRegs"); - ceCallCogCodePopReceiverAndClassRegs = callCogCodePopReceiverAndClassRegs; -# else // Debug - /* begin genEnilopmartFor:forCall:called: */ - ceEnterCogCodePopReceiverReg = genEnilopmartForandandforCallcalled(ReceiverResultReg, NoReg, NoReg, 0, "ceEnterCogCodePopReceiverReg"); - /* begin genEnilopmartFor:forCall:called: */ - ceCallCogCodePopReceiverReg = genEnilopmartForandandforCallcalled(ReceiverResultReg, NoReg, NoReg, 1, "ceCallCogCodePopReceiverReg"); - /* begin genEnilopmartFor:and:forCall:called: */ - ceCallCogCodePopReceiverAndClassRegs = genEnilopmartForandandforCallcalled(ReceiverResultReg, ClassReg, NoReg, 1, "ceCallCogCodePopReceiverAndClassRegs"); -# endif // Debug - genPrimReturnEnterCogCodeEnilopmart(0); - cePrimReturnEnterCogCode = methodZoneBase; - outputInstructionsForGeneratedRuntimeAt(cePrimReturnEnterCogCode); - recordGeneratedRunTimeaddress("cePrimReturnEnterCogCode", cePrimReturnEnterCogCode); - genPrimReturnEnterCogCodeEnilopmart(1); - cePrimReturnEnterCogCodeProfiling = methodZoneBase; - outputInstructionsForGeneratedRuntimeAt(cePrimReturnEnterCogCodeProfiling); - recordGeneratedRunTimeaddress("cePrimReturnEnterCogCodeProfiling", cePrimReturnEnterCogCodeProfiling); -# if Debug - /* begin genEnilopmartFor:and:forCall:called: */ - realCECallCogCodePopReceiverArg0Regs = genEnilopmartForandandforCallcalled(ReceiverResultReg, Arg0Reg, NoReg, 1, "realCECallCogCodePopReceiverArg0Regs"); - ceCallCogCodePopReceiverArg0Regs = callCogCodePopReceiverArg0Regs; - realCECallCogCodePopReceiverArg1Arg0Regs = genEnilopmartForandandforCallcalled(ReceiverResultReg, Arg0Reg, Arg1Reg, 1, "realCECallCogCodePopReceiverArg1Arg0Regs"); - ceCallCogCodePopReceiverArg1Arg0Regs = callCogCodePopReceiverArg1Arg0Regs; -# else // Debug - /* begin genEnilopmartFor:and:forCall:called: */ - ceCallCogCodePopReceiverArg0Regs = genEnilopmartForandandforCallcalled(ReceiverResultReg, Arg0Reg, NoReg, 1, "ceCallCogCodePopReceiverArg0Regs"); - ceCallCogCodePopReceiverArg1Arg0Regs = genEnilopmartForandandforCallcalled(ReceiverResultReg, Arg0Reg, Arg1Reg, 1, "ceCallCogCodePopReceiverArg1Arg0Regs"); -# endif // Debug - ceCall0ArgsPIC = genCallPICEnilopmartNumArgs(0); - ceCall1ArgsPIC = genCallPICEnilopmartNumArgs(1); - ceCall2ArgsPIC = genCallPICEnilopmartNumArgs(2); - assert((numRegArgs()) == 2); -} - - -/* Size pc-dependent instructions and assign eventual addresses to all - instructions. Answer the size of the code. - Compute forward branches based on virtual address (abstract code starts at - 0), assuming that any branches branched over are long. - Compute backward branches based on actual address. - Reuse the fixups array to record the pc-dependent instructions that need - to have - their code generation postponed until after the others. - - Override to add handling for null branches (branches to the immediately - following instruction) occasioned by StackToRegisterMapping's following of - jumps. */ - - /* StackToRegisterMappingCogit>>#generateInstructionsAt: */ -static sqInt NoDbgRegParms -generateInstructionsAt(sqInt eventualAbsoluteAddress) -{ - sqInt absoluteAddress; - AbstractInstruction *abstractInstruction; - BytecodeFixup *fixup; - sqInt i; - sqInt j; - sqInt pcDependentIndex; - - absoluteAddress = eventualAbsoluteAddress; - pcDependentIndex = 0; - for (i = 0; i < opcodeIndex; i += 1) { - - /* N.B. if you want to break in resizing, break here, note the instruction index, back up to the - sender, restart, and step into computeMaximumSizes, breaking at this instruction's index. */ - abstractInstruction = abstractInstructionAt(i); - maybeBreakGeneratingFromto(absoluteAddress, absoluteAddress + ((abstractInstruction->maxSize))); - if (isPCDependent(abstractInstruction)) { - sizePCDependentInstructionAt(abstractInstruction, absoluteAddress); - if ((isJump(abstractInstruction)) - && ((((i + 1) < opcodeIndex) - && ((((AbstractInstruction *) (((abstractInstruction->operands))[0]))) == (abstractInstructionAt(i + 1)))) - || (((i + 2) < opcodeIndex) - && (((((AbstractInstruction *) (((abstractInstruction->operands))[0]))) == (abstractInstructionAt(i + 2))) - && ((((abstractInstructionAt(i + 1))->opcode)) == Nop))))) { - (abstractInstruction->opcode = Nop); - concretizeAt(abstractInstruction, absoluteAddress); - } - else { - fixup = fixupAtIndex(pcDependentIndex); - pcDependentIndex += 1; - (fixup->instructionIndex = i); - } - absoluteAddress += (abstractInstruction->machineCodeSize); - } - else { - - /* N.B. if you want to break in resizing, break here, note the instruction index, back up to the - sender, restart, and step into computeMaximumSizes, breaking at this instruction's index. */ - absoluteAddress = concretizeAt(abstractInstruction, absoluteAddress); - assert(((abstractInstruction->machineCodeSize)) == ((abstractInstruction->maxSize))); - } - } - for (j = 0; j < pcDependentIndex; j += 1) { - fixup = fixupAtIndex(j); - abstractInstruction = abstractInstructionAt((fixup->instructionIndex)); - maybeBreakGeneratingFromto((abstractInstruction->address), (((abstractInstruction->address)) + ((abstractInstruction->maxSize))) - 1); - concretizeAt(abstractInstruction, (abstractInstruction->address)); - } - return absoluteAddress - eventualAbsoluteAddress; -} - - -/* Generate the run-time entries for the various method and PIC entry misses - and aborts. - Read the class-side method trampolines for documentation on the various - trampolines - */ - - /* StackToRegisterMappingCogit>>#generateMissAbortTrampolines */ -static void -generateMissAbortTrampolines(void) -{ - sqInt numArgs; - sqInt numArgsLimiT; - - for (numArgs = 0, numArgsLimiT = (3); numArgs <= numArgsLimiT; numArgs += 1) { - methodAbortTrampolines[numArgs] = (genMethodAbortTrampolineFor(numArgs)); - } - for (numArgs = 0, numArgsLimiT = (3); numArgs <= numArgsLimiT; numArgs += 1) { - picAbortTrampolines[numArgs] = (genPICAbortTrampolineFor(numArgs)); - } - for (numArgs = 0, numArgsLimiT = (3); numArgs <= numArgsLimiT; numArgs += 1) { - picMissTrampolines[numArgs] = (genPICMissTrampolineFor(numArgs)); - } - /* begin genTrampolineFor:called:arg: */ - ceReapAndResetErrorCodeTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceReapAndResetErrorCodeFor, "ceReapAndResetErrorCodeTrampoline", 1, ClassReg, null, null, null, 0 /* emptyRegisterMask */, 1, NoReg, 0); -} - - -/* Override to generate code to push the register arg(s) for <= numRegArg - arity sends. - */ - - /* StackToRegisterMappingCogit>>#generateSendTrampolines */ -static void -generateSendTrampolines(void) -{ - sqInt numArgs; - - for (numArgs = 0; numArgs < NumSendTrampolines; numArgs += 1) { - ordinarySendTrampolines[numArgs] = (genSendTrampolineFornumArgscalledargargargarg(ceSendsupertonumArgs, numArgs, trampolineNamenumArgs("ceSend", numArgs), ClassReg, trampolineArgConstant(0), ReceiverResultReg, (numArgs <= (NumSendTrampolines - 2) - ? (/* begin trampolineArgConstant: */ - assert(numArgs >= 0), - -2 - numArgs) - : SendNumArgsReg))); - } - for (numArgs = 0; numArgs < NumSendTrampolines; numArgs += 1) { - directedSuperSendTrampolines[numArgs] = (genSendTrampolineFornumArgscalledargargargarg(ceSendabovetonumArgs, numArgs, trampolineNamenumArgs("ceDirectedSuperSend", numArgs), ClassReg, TempReg, ReceiverResultReg, (numArgs <= (NumSendTrampolines - 2) - ? (/* begin trampolineArgConstant: */ - assert(numArgs >= 0), - -2 - numArgs) - : SendNumArgsReg))); - directedSuperBindingSendTrampolines[numArgs] = (genSendTrampolineFornumArgscalledargargargarg(ceSendaboveClassBindingtonumArgs, numArgs, trampolineNamenumArgs("ceDirectedSuperBindingSend", numArgs), ClassReg, TempReg, ReceiverResultReg, (numArgs <= (NumSendTrampolines - 2) - ? (/* begin trampolineArgConstant: */ - assert(numArgs >= 0), - -2 - numArgs) - : SendNumArgsReg))); - } - for (numArgs = 0; numArgs < NumSendTrampolines; numArgs += 1) { - superSendTrampolines[numArgs] = (genSendTrampolineFornumArgscalledargargargarg(ceSendsupertonumArgs, numArgs, trampolineNamenumArgs("ceSuperSend", numArgs), ClassReg, trampolineArgConstant(1), ReceiverResultReg, (numArgs <= (NumSendTrampolines - 2) - ? (/* begin trampolineArgConstant: */ - assert(numArgs >= 0), - -2 - numArgs) - : SendNumArgsReg))); - } - firstSend = ordinarySendTrampolines[0]; - lastSend = superSendTrampolines[NumSendTrampolines - 1]; -} - - -/* Generate trampolines for tracing. In the simulator we can save a lot of - time and avoid noise instructions in the lastNInstructions log by - short-cutting these - trampolines, but we need them in the real vm. */ - - /* StackToRegisterMappingCogit>>#generateTracingTrampolines */ -static void -generateTracingTrampolines(void) -{ - /* begin genTrampolineFor:called:arg:regsToSave: */ - ceTraceLinkedSendTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceTraceLinkedSend, "ceTraceLinkedSendTrampoline", 1, ReceiverResultReg, null, null, null, CallerSavedRegisterMask, 1, NoReg, 0); - /* begin genTrampolineFor:called:regsToSave: */ - ceTraceBlockActivationTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceTraceBlockActivation, "ceTraceBlockActivationTrampoline", 0, null, null, null, null, CallerSavedRegisterMask, 1, NoReg, 0); - /* begin genTrampolineFor:called:arg:arg:regsToSave: */ - ceTraceStoreTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceTraceStoreOfinto, "ceTraceStoreTrampoline", 2, TempReg, ReceiverResultReg, null, null, CallerSavedRegisterMask, 1, NoReg, 0); -} - - /* StackToRegisterMappingCogit>>#genForwardersInlinedIdenticalOrNotIf: */ -static sqInt NoDbgRegParms -genForwardersInlinedIdenticalOrNotIf(sqInt orNot) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - sqInt argConstant; - sqInt argNeedsReg; - sqInt argReg; - sqInt argReg1; - BytecodeDescriptor *branchDescriptor; - BytecodeDescriptor *branchDescriptor1; - sqInt constant; - sqInt constant1; - BytecodeFixup * fixup; - sqInt i; - void *jumpTarget; - void *jumpTarget1; - AbstractInstruction *label; - sqInt nExts; - sqInt nextPC; - sqInt nextPC1; - sqInt postBranchPC; - sqInt postBranchPC1; - BytecodeDescriptor *primDescriptor; - sqInt rcvrConstant; - sqInt rcvrNeedsReg; - sqInt rcvrReg; - sqInt rcvrReg1; - sqInt reg; - sqInt rNext1; - sqInt rTop1; - CogSimStackEntry *simStackEntry; - CogSimStackEntry *simStackEntry1; - sqInt targetBytecodePC; - sqInt targetBytecodePC1; - sqInt topRegistersMask; - sqInt unforwardArg; - sqInt unforwardRcvr; - - unforwardRcvr = mayBeAForwarder(ssValue(1)); - unforwardArg = mayBeAForwarder(ssTop()); - if ((!unforwardRcvr) - && (!unforwardArg)) { - return genVanillaInlinedIdenticalOrNotIf(orNot); - } - assert(unforwardArg - || (unforwardRcvr)); - /* begin isUnannotatableConstant: */ - simStackEntry = ssValue(1); - rcvrConstant = (((simStackEntry->type)) == SSConstant) - && ((isImmediate((simStackEntry->constant))) - || (!(shouldAnnotateObjectReference((simStackEntry->constant))))); - /* begin isUnannotatableConstant: */ - simStackEntry1 = ssTop(); - argConstant = (((simStackEntry1->type)) == SSConstant) - && ((isImmediate((simStackEntry1->constant))) - || (!(shouldAnnotateObjectReference((simStackEntry1->constant))))); - /* begin extractMaybeBranchDescriptorInto: */ - primDescriptor = generatorAt(byte0); - nextPC1 = bytecodePC + ((primDescriptor->numBytes)); - nExts = 0; - while (1) { - while (1) { - /* begin generatorForPC: */ - branchDescriptor1 = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC1, methodObj))); - if (!((branchDescriptor1->isExtension))) break; - nExts += 1; - nextPC1 += (branchDescriptor1->numBytes); - } - /* begin isUnconditionalBranch */ - if (!((isBranch(branchDescriptor1)) - && (!(((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse)))))) break; - nextPC1 = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - } - targetBytecodePC1 = (postBranchPC1 = 0); - if (((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse))) { - targetBytecodePC1 = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - postBranchPC1 = eventualTargetOf(nextPC1 + ((branchDescriptor1->numBytes))); - } - else { - nextPC1 = bytecodePC + ((primDescriptor->numBytes)); - } - branchDescriptor = branchDescriptor1; - nextPC = nextPC1; - postBranchPC = postBranchPC1; - targetBytecodePC = targetBytecodePC1; - /* begin allocateEqualsEqualsRegistersArgNeedsReg:rcvrNeedsReg:into: */ - argNeedsReg = !argConstant; - rcvrNeedsReg = !rcvrConstant; - assert(argNeedsReg - || (rcvrNeedsReg)); - argReg1 = (rcvrReg1 = NoReg); - if (argNeedsReg) { - if (rcvrNeedsReg) { - /* begin allocateRegForStackTopTwoEntriesInto: */ - topRegistersMask = 0; - rTop1 = (rNext1 = NoReg); - if ((registerOrNone(ssTop())) != NoReg) { - rTop1 = registerOrNone(ssTop()); - } - if ((registerOrNone(ssValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; - } - if (rTop1 == NoReg) { - rTop1 = allocateRegNotConflictingWith(topRegistersMask); - } - if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); - } - assert(!(((rTop1 == NoReg) - || (rNext1 == NoReg)))); - argReg1 = rTop1; - rcvrReg1 = rNext1; - popToReg(ssTop(), argReg1); - popToReg(ssValue(1), rcvrReg1); - } - else { - argReg1 = allocateRegForStackEntryAtnotConflictingWith(0, 0); - popToReg(ssTop(), argReg1); - if (((ssValue(1))->spilled)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AddCqR, BytesPerWord, SPReg); - } - } - } - else { - assert(rcvrNeedsReg); - assert(!((((ssTop())->spilled)))); - rcvrReg1 = allocateRegForStackEntryAtnotConflictingWith(1, 0); - popToReg(ssValue(1), rcvrReg1); - } - assert(!((argNeedsReg - && (argReg1 == NoReg)))); - assert(!((rcvrNeedsReg - && (rcvrReg1 == NoReg)))); - rcvrReg = rcvrReg1; - argReg = argReg1; - if (!(((branchDescriptor->isBranchTrue)) - || ((branchDescriptor->isBranchFalse)))) { - return genIdenticalNoBranchArgIsConstantrcvrIsConstantargRegrcvrRegorNotIf(argConstant, rcvrConstant, argReg, rcvrReg, orNot); - } - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 2)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 2)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 2))); i <= (simStackPtr - 2); i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 2) + 1; - } - /* begin Label */ - label = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - /* begin genCmpArgIsConstant:rcvrIsConstant:argReg:rcvrReg: */ - assert((argReg != NoReg) - || (rcvrReg != NoReg)); - if (argConstant) { - /* begin genCmpConstant:R: */ - constant = ((ssTop())->constant); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(CmpCwR, constant, rcvrReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, constant, rcvrReg); - } - } - else { - if (rcvrConstant) { - /* begin genCmpConstant:R: */ - constant1 = ((ssValue(1))->constant); - if (shouldAnnotateObjectReference(constant1)) { - annotateobjRef(checkLiteralforInstruction(constant1, genoperandoperand(CmpCwR, constant1, argReg)), constant1); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, constant1, argReg); - } - } - else { - /* begin CmpR:R: */ - assert(!((argReg == SPReg))); - genoperandoperand(CmpRR, argReg, rcvrReg); - } - } - ssPop(2); - if ((((fixupAt(nextPC))->targetInstruction)) == 0) { - - /* The next instruction is dead. we can skip it. */ - deadCode = 1; - ensureFixupAt(targetBytecodePC); - ensureFixupAt(postBranchPC); - } - else { - assert(!(deadCode)); - } - if (orNot == ((branchDescriptor->isBranchTrue))) { - - /* a == b ifFalse: ... or a ~~ b ifTrue: ... jump on equal to post-branch pc */ - fixup = ensureNonMergeFixupAt(targetBytecodePC); - /* begin JumpZero: */ - jumpTarget = ensureNonMergeFixupAt(postBranchPC); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget)); - } - else { - - /* orNot is true for ~~ */ - /* a == b ifTrue: ... or a ~~ b ifFalse: ... jump on equal to target pc */ - fixup = ensureNonMergeFixupAt(postBranchPC); - /* begin JumpZero: */ - jumpTarget1 = ensureNonMergeFixupAt(targetBytecodePC); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget1)); - } - if (unforwardArg - && (unforwardRcvr)) { - /* begin genEnsureOopInRegNotForwarded:scratchReg:jumpBackTo: */ - genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(argReg, TempReg, label, 0); - } - genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder((unforwardRcvr - ? rcvrReg - : argReg), TempReg, label, fixup); - if (!deadCode) { - ssPushConstant(trueObject()); - } - return 0; -} - - -/* Generates the machine code for #== in the case where the instruction is - not followed by a branch - */ - - /* StackToRegisterMappingCogit>>#genIdenticalNoBranchArgIsConstant:rcvrIsConstant:argReg:rcvrReg:orNotIf: */ -static sqInt NoDbgRegParms -genIdenticalNoBranchArgIsConstantrcvrIsConstantargRegrcvrRegorNotIf(sqInt argIsConstant, sqInt rcvrIsConstant, sqInt argReg, sqInt rcvrRegOrNone, sqInt orNot) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - sqInt constant; - sqInt constant1; - sqInt constant11; - sqInt constant2; - sqInt constant3; - sqInt constant4; - AbstractInstruction *jumpEqual; - AbstractInstruction *jumpNotEqual; - AbstractInstruction *label; - sqInt resultReg; - - /* begin Label */ - label = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - /* begin genCmpArgIsConstant:rcvrIsConstant:argReg:rcvrReg: */ - assert((argReg != NoReg) - || (rcvrRegOrNone != NoReg)); - if (argIsConstant) { - /* begin genCmpConstant:R: */ - constant4 = ((ssTop())->constant); - if (shouldAnnotateObjectReference(constant4)) { - annotateobjRef(checkLiteralforInstruction(constant4, genoperandoperand(CmpCwR, constant4, rcvrRegOrNone)), constant4); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, constant4, rcvrRegOrNone); - } - } - else { - if (rcvrIsConstant) { - /* begin genCmpConstant:R: */ - constant11 = ((ssValue(1))->constant); - if (shouldAnnotateObjectReference(constant11)) { - annotateobjRef(checkLiteralforInstruction(constant11, genoperandoperand(CmpCwR, constant11, argReg)), constant11); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, constant11, argReg); - } - } - else { - /* begin CmpR:R: */ - assert(!((argReg == SPReg))); - genoperandoperand(CmpRR, argReg, rcvrRegOrNone); - } - } - ssPop(2); - resultReg = (rcvrRegOrNone == NoReg - ? argReg - : rcvrRegOrNone); - /* begin JumpZero: */ - jumpEqual = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - if (!argIsConstant) { - /* begin genEnsureOopInRegNotForwarded:scratchReg:jumpBackTo: */ - genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(argReg, TempReg, label, 0); - } - if (!rcvrIsConstant) { - /* begin genEnsureOopInRegNotForwarded:scratchReg:jumpBackTo: */ - genEnsureOopInRegNotForwardedscratchRegifForwarderifNotForwarder(rcvrRegOrNone, TempReg, label, 0); - } - if (orNot) { - /* begin genMoveTrueR: */ - constant = trueObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, resultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, constant, resultReg); - } - } - else { - /* begin genMoveFalseR: */ - constant1 = falseObject(); - if (shouldAnnotateObjectReference(constant1)) { - annotateobjRef(checkLiteralforInstruction(constant1, genoperandoperand(MoveCwR, constant1, resultReg)), constant1); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(MoveCqR, constant1, resultReg); - } - } - /* begin Jump: */ - jumpNotEqual = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpEqual, (orNot - ? (/* begin genMoveFalseR: */ - (constant2 = falseObject()), - (shouldAnnotateObjectReference(constant2) - ? annotateobjRef(checkLiteralforInstruction(constant2, genoperandoperand(MoveCwR, constant2, resultReg)), constant2) - : (/* begin checkQuickConstant:forInstruction: */ - (anInstruction4 = genoperandoperand(MoveCqR, constant2, resultReg)), - anInstruction4))) - : (/* begin genMoveTrueR: */ - (constant3 = trueObject()), - (shouldAnnotateObjectReference(constant3) - ? annotateobjRef(checkLiteralforInstruction(constant3, genoperandoperand(MoveCwR, constant3, resultReg)), constant3) - : (/* begin checkQuickConstant:forInstruction: */ - (anInstruction5 = genoperandoperand(MoveCqR, constant3, resultReg)), - anInstruction5))))); - jmpTarget(jumpNotEqual, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushRegister(resultReg); - return 0; -} - - -/* Decompose code generation for #== into a common constant-folding version, - followed by a double dispatch through the objectRepresentation to a - version that doesn't deal with forwarders and a version that does. */ - - /* StackToRegisterMappingCogit>>#genInlinedIdenticalOrNotIf: */ -static sqInt NoDbgRegParms -genInlinedIdenticalOrNotIf(sqInt orNot) -{ - BytecodeDescriptor *primDescriptor; - sqInt result; - - primDescriptor = generatorAt(byte0); - if ((isUnannotatableConstant(ssTop())) - && (isUnannotatableConstant(ssValue(1)))) { - assert(!((primDescriptor->isMapped))); - result = ((orNot - ? (((ssTop())->constant)) != (((ssValue(1))->constant)) - : (((ssTop())->constant)) == (((ssValue(1))->constant))) - ? trueObject() - : falseObject()); - ssPop(2); - return ssPushConstant(result); - } - /* begin genInlinedIdenticalOrNotIfGuts: */ - return genForwardersInlinedIdenticalOrNotIf(orNot); -} - - /* StackToRegisterMappingCogit>>#genJumpBackTo: */ -static sqInt NoDbgRegParms -genJumpBackTo(sqInt targetBytecodePC) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *anInstruction; - sqInt i; - void *jumpTarget; - void *jumpTarget1; - - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - - /* can't fall through */ - deadCode = 1; - /* begin checkLiteral:forInstruction: */ - stackLimitAddress(); - anInstruction = genoperandoperand(MoveAwR, stackLimitAddress(), TempReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, SPReg); - /* begin JumpAboveOrEqual: */ - jumpTarget = fixupAtIndex(targetBytecodePC - initialPC); - genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)jumpTarget)); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceCheckForInterruptTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin annotateBytecode: */ - abstractInstruction1 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction1->annotation = HasBytecodePC); - /* begin Jump: */ - jumpTarget1 = fixupAtIndex(targetBytecodePC - initialPC); - genoperand(Jump, ((sqInt)jumpTarget1)); - return 0; -} - - /* StackToRegisterMappingCogit>>#genJumpIf:to: */ -static sqInt NoDbgRegParms -genJumpIfto(sqInt boolean, sqInt targetBytecodePC) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - CogSimStackEntry *desc; - sqInt eventualTarget; - BytecodeFixup *fixup; - sqInt i; - void *jumpTarget; - AbstractInstruction *ok; - sqInt quickConstant; - - eventualTarget = eventualTargetOf(targetBytecodePC); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 1)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 1)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 1))); i < simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 1) + 1; - } - desc = ssTop(); - ssPop(1); - if ((((desc->type)) == SSConstant) - && ((((desc->constant)) == (trueObject())) - || (((desc->constant)) == (falseObject())))) { - - /* Must arrange there's a fixup at the target whether it is jumped to or - not so that the simStackPtr can be kept correct. */ - - /* Must annotate the bytecode for correct pc mapping. */ - fixup = ensureFixupAt(eventualTarget); - /* begin annotateBytecode: */ - if (((desc->constant)) == boolean) { - /* begin Jump: */ - abstractInstruction = genoperand(Jump, ((sqInt)fixup)); - } - else { - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - } - (abstractInstruction->annotation = HasBytecodePC); - extA = 0; - return 0; - } - popToReg(desc, TempReg); - assert((objectAfter(falseObject())) == (trueObject())); - /* begin genSubConstant:R: */ - if (shouldAnnotateObjectReference(boolean)) { - annotateobjRef(checkLiteralforInstruction(boolean, genoperandoperand(SubCwR, boolean, TempReg)), TempReg); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, boolean, TempReg); - } - /* begin JumpZero: */ - jumpTarget = ensureFixupAt(eventualTarget); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget)); - if (((extA & 1) != 0)) { - extA = 0; - /* begin annotateBytecode: */ - abstractInstruction1 = lastOpcode(); - (abstractInstruction1->annotation = HasBytecodePC); - return 0; - } - extA = 0; - /* begin CmpCq:R: */ - quickConstant = (boolean == (falseObject()) - ? (trueObject()) - (falseObject()) - : (falseObject()) - (trueObject())); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, quickConstant, TempReg); - /* begin JumpZero: */ - ok = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - genCallMustBeBooleanFor(boolean); - jmpTarget(ok, annotateBytecode(genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return 0; -} - - /* StackToRegisterMappingCogit>>#genJumpTo: */ -static sqInt NoDbgRegParms -genJumpTo(sqInt targetBytecodePC) -{ - sqInt eventualTarget; - BytecodeFixup * fixup; - BytecodeDescriptor * generator; - sqInt i; - sqInt i1; - - eventualTarget = eventualTargetOf(targetBytecodePC); - if ((eventualTarget > bytecodePC) - && (((simStackPtr >= methodOrBlockNumArgs) - && (stackEntryIsBoolean(ssTop()))) - && ((((generator = generatorForPC(eventualTarget))->isBranchTrue)) - || (((generator = generatorForPC(eventualTarget))->isBranchFalse))))) { - eventualTarget = (eventualTarget + ((generator->numBytes))) + ((((generator->isBranchTrue)) == ((((ssTop())->constant)) == (trueObject())) - ? (/* begin spanFor:at:exts:in: */ - ((generator->spanFunction))(generator, eventualTarget, 0, methodObj)) - : 0)); - ssPop(1); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - fixup = ensureFixupAt(eventualTarget); - ssPop(-1); - } - else { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i1 <= simStackPtr; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - fixup = ensureFixupAt(eventualTarget); - } - - /* can't fall through */ - deadCode = 1; - /* begin Jump: */ - genoperand(Jump, ((sqInt)fixup)); - return 0; -} - - /* StackToRegisterMappingCogit>>#genMarshalledSend:numArgs:sendTable: */ -static sqInt NoDbgRegParms -genMarshalledSendnumArgssendTable(sqInt selectorIndex, sqInt numArgs, sqInt *sendTable) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt annotation; - - assert(needsFrame); - /* begin annotationForSendTable: */ - if (sendTable == ordinarySendTrampolines) { - annotation = IsSendCall; - goto l2; - } - if (sendTable == directedSuperSendTrampolines) { - annotation = IsDirectedSuperSend; - goto l2; - } - if (sendTable == directedSuperBindingSendTrampolines) { - annotation = IsDirectedSuperBindingSend; - goto l2; - } - assert(sendTable == superSendTrampolines); - annotation = IsSuperSend; - l2: /* end annotationForSendTable: */; - if ((annotation == IsSuperSend) - || (((annotation >= IsDirectedSuperSend) && (annotation <= IsDirectedSuperBindingSend)))) { - genEnsureOopInRegNotForwardedscratchReg(ReceiverResultReg, TempReg); - } - if (numArgs >= (NumSendTrampolines - 1)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, numArgs, SendNumArgsReg); - } - if (((annotation >= IsDirectedSuperSend) && (annotation <= IsDirectedSuperBindingSend))) { - /* begin genMoveConstant:R: */ - if (shouldAnnotateObjectReference(tempOop)) { - annotateobjRef(checkLiteralforInstruction(tempOop, genoperandoperand(MoveCwR, tempOop, TempReg)), tempOop); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, tempOop, TempReg); - } - } - genLoadInlineCacheWithSelector(selectorIndex); - ((genoperand(Call, sendTable[((numArgs < (NumSendTrampolines - 1)) ? numArgs : (NumSendTrampolines - 1))]))->annotation = annotation); - /* begin voidReceiverOptStatus */ - ((simSelf())->liveRegister = NoReg); - return ssPushRegister(ReceiverResultReg); -} - - -/* Generate the abort for a method. This abort performs either a call of - ceSICMiss: to handle a single-in-line cache miss or a call of - ceStackOverflow: to handle a - stack overflow. It distinguishes the two by testing ResultReceiverReg. If - the register is zero then this is a stack-overflow because a) the receiver - has already - been pushed and so can be set to zero before calling the abort, and b) the - receiver must always contain an object (and hence be non-zero) on SIC - miss. */ - - /* StackToRegisterMappingCogit>>#genMethodAbortTrampolineFor: */ -static usqInt NoDbgRegParms -genMethodAbortTrampolineFor(sqInt numArgs) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *jumpSICMiss; - - zeroOpcodeIndex(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, ReceiverResultReg); - /* begin JumpNonZero: */ - jumpSICMiss = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveR:Mw:r: */ - anInstruction = genoperandoperandoperand(MoveRMwr, LinkReg, 0, SPReg); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(ceStackOverflow, 1, SendNumArgsReg, null, null, null, 0 /* emptyRegisterMask */, 0, NoReg); - jmpTarget(jumpSICMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genPushRegisterArgsForAbortMissNumArgs(backEnd, numArgs); - return genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceSICMiss, trampolineNamenumRegArgs("ceMethodAbort", numArgs), 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 0, NoReg, 1); -} - - -/* Generate the abort for a PIC. This abort performs either a call of - ceInterpretMethodFromPIC:receiver: to handle invoking an uncogged - target or a call of ceMNUFromPICMNUMethod:receiver: to handle an - MNU dispatch in a closed PIC. It distinguishes the two by testing - ClassReg. If the register is zero then this is an MNU. */ - - /* StackToRegisterMappingCogit>>#genPICAbortTrampolineFor: */ -static usqInt NoDbgRegParms -genPICAbortTrampolineFor(sqInt numArgs) -{ - zeroOpcodeIndex(); - genPushRegisterArgsForAbortMissNumArgs(backEnd, numArgs); - return genInnerPICAbortTrampoline(trampolineNamenumRegArgs("cePICAbort", numArgs)); -} - - /* StackToRegisterMappingCogit>>#genPICMissTrampolineFor: */ -static usqInt NoDbgRegParms -genPICMissTrampolineFor(sqInt numArgs) -{ - usqInt startAddress; - - startAddress = methodZoneBase; - zeroOpcodeIndex(); - genPushRegisterArgsForNumArgsscratchReg(backEnd, numArgs, SendNumArgsReg); - genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceCPICMissreceiver, trampolineNamenumRegArgs("cePICMiss", numArgs), 2, ClassReg, ReceiverResultReg, null, null, 0 /* emptyRegisterMask */, 1, NoReg, 1); - return startAddress; -} - - /* StackToRegisterMappingCogit>>#genPopStackBytecode */ -static sqInt -genPopStackBytecode(void) -{ - AbstractInstruction *anInstruction; - - if (((ssTop())->spilled)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, BytesPerWord, SPReg); - } - ssPop(1); - return 0; -} - - -/* Check the argument count. Fail if wrong. - Get the method from the outerContext and see if it is cogged. If so, jump - to the - block entry or the no-context-switch entry, as appropriate, and we're - done. If not, - invoke the interpreter primitive. */ -/* Check the argument count. Fail if wrong. - Get the method from the outerContext and see if it is cogged. If so, jump - to the - block entry or the no-context-switch entry, as appropriate, and we're - done. If not, - invoke the interpreter primitive. - Override to push the register args first. */ - - /* StackToRegisterMappingCogit>>#genPrimitiveClosureValue */ -static sqInt -genPrimitiveClosureValue(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *jumpBCMethod; - AbstractInstruction *jumpFail1; - AbstractInstruction *jumpFail2; - AbstractInstruction *jumpFail3; - AbstractInstruction *jumpFail4; - AbstractInstruction *jumpFailNArgs; - sqInt offset; - void (*primitiveRoutine)(void); - sqInt result; - - genPushRegisterArgs(); - genLoadSlotsourceRegdestReg(ClosureNumArgsIndex, ReceiverResultReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)methodOrBlockNumArgs << 1) | 1); - anInstruction1 = genoperandoperand(CmpCqR, (((usqInt)methodOrBlockNumArgs << 1) | 1), TempReg); - /* begin JumpNonZero: */ - jumpFailNArgs = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(ClosureOuterContextIndex, ReceiverResultReg, ClassReg); - jumpFail1 = genJumpImmediate(ClassReg); - genGetCompactClassIndexNonImmOfinto(ClassReg, TempReg); - genCmpClassMethodContextCompactIndexR(TempReg); - /* begin JumpNonZero: */ - jumpFail2 = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(MethodIndex, ClassReg, SendNumArgsReg); - jumpFail3 = genJumpImmediate(SendNumArgsReg); - genGetFormatOfinto(SendNumArgsReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction2 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), TempReg); - /* begin JumpLess: */ - jumpFail4 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - genLoadSlotsourceRegdestReg(HeaderIndex, SendNumArgsReg, ClassReg); - jumpBCMethod = genJumpImmediate(ClassReg); - /* begin MoveM16:r:R: */ - offset = offsetof(CogMethod, blockEntryOffset); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperandoperand(MoveM16rR, offset, ClassReg, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, ClassReg, TempReg); - primitiveRoutine = functionPointerForCompiledMethodprimitiveIndexprimitivePropertyFlagsInto(methodObj, primitiveIndex, null); - if (primitiveRoutine == primitiveClosureValueNoContextSwitch) { - if (blockNoContextSwitchOffset == null) { - return NotFullyInitialized; - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, blockNoContextSwitchOffset, TempReg); - } - /* begin JumpR: */ - genoperand(JumpR, TempReg); - jmpTarget(jumpBCMethod, jmpTarget(jumpFail1, jmpTarget(jumpFail2, jmpTarget(jumpFail3, jmpTarget(jumpFail4, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))))); - if (((result = compileInterpreterPrimitiveflags(primitiveRoutine, primitivePropertyFlags(primitiveIndex)))) < 0) { - return result; - } - jmpTarget(jumpFailNArgs, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - -/* Check the argument count. Fail if wrong. - Get the method from the outerContext and see if it is cogged. If so, jump - to the - block entry or the no-context-switch entry, as appropriate, and we're - done. If not, - invoke the interpreter primitive. */ -/* Override to push the register args first. */ - - /* StackToRegisterMappingCogit>>#genPrimitiveFullClosureValue */ -static sqInt -genPrimitiveFullClosureValue(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *jumpBCMethod; - AbstractInstruction *jumpFail4; - AbstractInstruction *jumpFailImmediateMethod; - AbstractInstruction *jumpFailNArgs; - void (*primitiveRoutine)(void); - sqInt quickConstant; - sqInt result; - - genPushRegisterArgs(); - genLoadSlotsourceRegdestReg(ClosureNumArgsIndex, ReceiverResultReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)methodOrBlockNumArgs << 1) | 1); - anInstruction = genoperandoperand(CmpCqR, (((usqInt)methodOrBlockNumArgs << 1) | 1), TempReg); - /* begin JumpNonZero: */ - jumpFailNArgs = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(FullClosureCompiledBlockIndex, ReceiverResultReg, SendNumArgsReg); - jumpFailImmediateMethod = genJumpImmediate(SendNumArgsReg); - genGetFormatOfinto(SendNumArgsReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction1 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), TempReg); - /* begin JumpLess: */ - jumpFail4 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - genLoadSlotsourceRegdestReg(HeaderIndex, SendNumArgsReg, ClassReg); - jumpBCMethod = genJumpImmediate(ClassReg); - primitiveRoutine = functionPointerForCompiledMethodprimitiveIndexprimitivePropertyFlagsInto(methodObj, primitiveIndex, null); - /* begin AddCq:R: */ - quickConstant = (primitiveRoutine == primitiveFullClosureValueNoContextSwitch - ? fullBlockNoContextSwitchEntryOffset() - : fullBlockEntryOffset()); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AddCqR, quickConstant, ClassReg); - /* begin JumpR: */ - genoperand(JumpR, ClassReg); - jmpTarget(jumpBCMethod, jmpTarget(jumpFailImmediateMethod, jmpTarget(jumpFail4, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))); - if (((result = compileInterpreterPrimitiveflags(primitiveRoutine, primitivePropertyFlags(primitiveIndex)))) < 0) { - return result; - } - jmpTarget(jumpFailNArgs, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - -/* Generate an in-line perform primitive. The lookup code requires the - selector to be in Arg0Reg. - adjustArgumentsForPerform: adjusts the arguments once - genLookupForPerformNumArgs: has generated the code for the lookup. */ - - /* StackToRegisterMappingCogit>>#genPrimitivePerform */ -static sqInt -genPrimitivePerform(void) -{ - AbstractInstruction *anInstruction; - sqInt offset; - - if (methodOrBlockNumArgs > 2 /* numRegArgs */) { - /* begin MoveMw:r:R: */ - offset = (methodOrBlockNumArgs - 1) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, SPReg, Arg0Reg); - } - return genLookupForPerformNumArgs(methodOrBlockNumArgs); -} - - /* StackToRegisterMappingCogit>>#genPushActiveContextBytecode */ -static sqInt -genPushActiveContextBytecode(void) -{ - assert(needsFrame); - voidReceiverResultRegContainsSelf(); - /* begin ssAllocateCallReg:and:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg) | (1U << SendNumArgsReg)) | (1U << ClassReg)), simStackPtr, simNativeStackPtr); - genGetActiveContextNumArgslargeinBlock(methodOrBlockNumArgs, methodNeedsLargeContext(methodObj), inBlock); - return ssPushRegister(ReceiverResultReg); -} - - -/* Block compilation. At this point in the method create the block. Note its - start and defer generating code for it until after the method and any - other preceding - blocks. The block's actual code will be compiled later. */ -/* 143 10001111 llllkkkk jjjjjjjj iiiiiiii Push Closure Num Copied llll Num - Args kkkk BlockSize jjjjjjjjiiiiiiii */ - - /* StackToRegisterMappingCogit>>#genPushClosureCopyCopiedValuesBytecode */ -static sqInt -genPushClosureCopyCopiedValuesBytecode(void) -{ - sqInt i; - sqInt numArgs; - sqInt numCopied; - sqInt reg; - sqInt startpc; - - assert(needsFrame); - startpc = bytecodePC + (((generatorAt(byte0))->numBytes)); - addBlockStartAtnumArgsnumCopiedspan(startpc, (numArgs = byte1 & 15), (numCopied = ((usqInt)(byte1)) >> 4), (((sqInt)((usqInt)(byte2) << 8))) + byte3); - /* begin genInlineClosure:numArgs:numCopied: */ - assert(getActiveContextAllocatesInMachineCode()); - voidReceiverResultRegContainsSelf(); - /* begin ssAllocateCallReg:and:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg) | (1U << SendNumArgsReg)) | (1U << ClassReg)), simStackPtr, simNativeStackPtr); - genNoPopCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(startpc + 1, numArgs, numCopied, methodOrBlockNumArgs, methodNeedsLargeContext(methodObj), inBlock); - for (i = 1; i <= numCopied; i += 1) { - reg = ssStorePoptoPreferredReg(1, TempReg); - genStoreSourceRegslotIndexintoNewObjectInDestReg(reg, (ClosureFirstCopiedValueIndex + numCopied) - i, ReceiverResultReg); - } - ssPushRegister(ReceiverResultReg); - return 0; -} - - -/* */ -/* Override to avoid the BytecodeSetHasDirectedSuperSend check, which is - unnecessary here given the simulation stack. */ - - /* StackToRegisterMappingCogit>>#genPushLiteralIndex: */ -static sqInt NoDbgRegParms -genPushLiteralIndex(sqInt literalIndex) -{ - sqInt literal; - - literal = getLiteral(literalIndex); - return genPushLiteral(literal); -} - - /* StackToRegisterMappingCogit>>#genPushLiteralVariable: */ -static sqInt NoDbgRegParms -genPushLiteralVariable(sqInt literalIndex) -{ - AbstractInstruction *anInstruction; - sqInt association; - sqInt bcpc; - BytecodeDescriptor *descriptor1; - sqInt eA; - sqInt eB; - sqInt freeReg; - sqInt savedB0; - sqInt savedB1; - sqInt savedB2; - sqInt savedB3; - sqInt savedEA; - sqInt savedEB; - sqInt savedNEB; - - - /* If followed by a directed super send bytecode, avoid generating any code yet. - The association will be passed to the directed send trampoline in a register - and fully dereferenced only when first linked. It will be ignored in later sends. */ - association = getLiteral(literalIndex); - assert(!(directedSendUsesBinding)); - /* begin nextDescriptorExtensionsAndNextPCInto: */ - descriptor1 = generatorAt(byte0); - savedB0 = byte0; - savedB1 = byte1; - savedB2 = byte2; - savedB3 = byte3; - savedEA = extA; - savedEB = extB; - savedNEB = numExtB; - bcpc = bytecodePC + ((descriptor1->numBytes)); - do { - if (bcpc > endPC) { - goto l1; - } - byte0 = (fetchByteofObject(bcpc, methodObj)) + bytecodeSetOffset; - descriptor1 = generatorAt(byte0); - loadSubsequentBytesForDescriptorat(descriptor1, bcpc); - if (!((descriptor1->isExtension))) { - eA = extA; - eB = extB; - extA = savedEA; - extB = savedEB; - numExtB = savedNEB; - byte0 = savedB0; - byte1 = savedB1; - byte2 = savedB2; - byte3 = savedB3; - if ((descriptor1 != null) - && ((((descriptor1->generator)) == genExtSendSuperBytecode) - && (eB >= 64))) { - ssPushConstant(association); - directedSendUsesBinding = 1; - return 0; - } - goto l1; - } - ((descriptor1->generator))(); - bcpc += (descriptor1->numBytes); - } while(1); - l1: /* end nextDescriptorExtensionsAndNextPCInto: */; - - /* N.B. Do _not_ use ReceiverResultReg to avoid overwriting receiver in assignment in frameless methods. */ - /* So far descriptors are not rich enough to describe the entire dereference so generate the register - load but don't push the result. There is an order-of-evaluation issue if we defer the dereference. */ - freeReg = allocateRegNotConflictingWith(0); - /* begin genMoveConstant:R: */ - if (shouldAnnotateObjectReference(association)) { - annotateobjRef(checkLiteralforInstruction(association, genoperandoperand(MoveCwR, association, TempReg)), association); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, association, TempReg); - } - genLoadSlotsourceRegdestReg(ValueIndex, TempReg, freeReg); - ssPushRegister(freeReg); - return 0; -} - - /* StackToRegisterMappingCogit>>#genPushLiteral: */ -static sqInt NoDbgRegParms -genPushLiteral(sqInt literal) -{ - return ssPushConstant(literal); -} - - /* StackToRegisterMappingCogit>>#genPushMaybeContextReceiverVariable: */ -static sqInt NoDbgRegParms -genPushMaybeContextReceiverVariable(sqInt slotIndex) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *jmpDone; - AbstractInstruction *jmpSingle; - - /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); - ensureReceiverResultRegContainsSelf(); - /* begin genPushMaybeContextSlotIndex: */ - assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { - - /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ - voidReceiverResultRegContainsSelf(); - } - if (slotIndex == InstructionPointerIndex) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, slotIndex, SendNumArgsReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceFetchContextInstVarTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - return ssPushRegister(SendNumArgsReg); - } - genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); - jmpSingle = genJumpNotSmallIntegerInScratchReg(TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, slotIndex, SendNumArgsReg); - /* begin CallRT: */ - abstractInstruction1 = genoperand(Call, ceFetchContextInstVarTrampoline); - (abstractInstruction1->annotation = IsRelativeCall); - /* begin Jump: */ - jmpDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jmpSingle, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genLoadSlotsourceRegdestReg(slotIndex, ReceiverResultReg, SendNumArgsReg); - jmpTarget(jmpDone, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return ssPushRegister(SendNumArgsReg); -} - - /* StackToRegisterMappingCogit>>#genPushNewArrayBytecode */ -static sqInt -genPushNewArrayBytecode(void) -{ - sqInt i; - sqInt i1; - int popValues; - sqInt size; - - assert(needsFrame); - voidReceiverResultRegContainsSelf(); - if ((popValues = byte1 > 0x7F)) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i1 <= simStackPtr; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - } - else { - /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); - } - size = byte1 & 0x7F; - if (!popValues) { - if (tryCollapseTempVectorInitializationOfSize(size)) { - return 0; - } - } - genNewArrayOfSizeinitialized(size, !popValues); - if (popValues) { - for (i = (size - 1); i >= 0; i += -1) { - /* begin PopR: */ - genoperand(PopR, TempReg); - genStoreSourceRegslotIndexintoNewObjectInDestReg(TempReg, i, ReceiverResultReg); - } - ssPop(size); - } - return ssPushRegister(ReceiverResultReg); -} - - /* StackToRegisterMappingCogit>>#genPushReceiverBytecode */ -static sqInt -genPushReceiverBytecode(void) -{ - if ((((simSelf())->liveRegister)) == ReceiverResultReg) { - return ssPushRegister(ReceiverResultReg); - } - return ssPushDesc(ssSelfDescriptor()); -} - - /* StackToRegisterMappingCogit>>#genPushReceiverVariable: */ -static sqInt NoDbgRegParms -genPushReceiverVariable(sqInt index) -{ - ensureReceiverResultRegContainsSelf(); - return ssPushBaseoffset(ReceiverResultReg, slotOffsetOfInstVarIndex(index)); -} - - -/* Ensure that the register args are pushed before the retpc for methods with - arity <= self numRegArgs. - */ -/* This isn't as clumsy on a RISC. But putting the receiver and - args above the return address means the CoInterpreter has a - single machine-code frame format which saves us a lot of work. */ - - /* StackToRegisterMappingCogit>>#genPushRegisterArgs */ -static void -genPushRegisterArgs(void) -{ - if (!(regArgsHaveBeenPushed - || (methodOrBlockNumArgs > 2 /* numRegArgs */))) { - genPushRegisterArgsForNumArgsscratchReg(backEnd, methodOrBlockNumArgs, SendNumArgsReg); - regArgsHaveBeenPushed = 1; - } -} - - /* StackToRegisterMappingCogit>>#genPushRemoteTempLongBytecode */ -static sqInt -genPushRemoteTempLongBytecode(void) -{ - AbstractInstruction *anInstruction; - sqInt offset; - sqInt regMask; - sqInt remoteTempReg; - sqInt tempVectReg; - - tempVectReg = allocateRegNotConflictingWith(0); - /* begin MoveMw:r:R: */ - offset = frameOffsetOfTemporary(byte2); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, FPReg, tempVectReg); - /* begin availableRegOrNoneNotConflictingWith: */ - regMask = 1U << tempVectReg; - remoteTempReg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); - if (remoteTempReg == NoReg) { - remoteTempReg = tempVectReg; - } - genLoadSlotsourceRegdestReg(byte1, tempVectReg, remoteTempReg); - return ssPushRegister(remoteTempReg); -} - - -/* If a frameless method (not a block), only argument temps can be accessed. - This is assured by the use of needsFrameIfMod16GENumArgs: in pushTemp. */ - - /* StackToRegisterMappingCogit>>#genPushTemporaryVariable: */ -static sqInt NoDbgRegParms -genPushTemporaryVariable(sqInt index) -{ - assert((inBlock > 0) - || (needsFrame - || (index < methodOrBlockNumArgs))); - return ssPushDesc(simStack[index + 1]); -} - - -/* In a frameless method ReceiverResultReg already contains self. - In a frameful method, ReceiverResultReg /may/ contain self. */ - - /* StackToRegisterMappingCogit>>#genReturnReceiver */ -static sqInt -genReturnReceiver(void) -{ - if (needsFrame) { - if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { - /* begin putSelfInReceiverResultReg */ - storeToReg(simSelf(), ReceiverResultReg); - } - } - return genUpArrowReturn(); -} - - /* StackToRegisterMappingCogit>>#genReturnTopFromBlock */ -static sqInt -genReturnTopFromBlock(void) -{ - assert(inBlock > 0); - popToReg(ssTop(), ReceiverResultReg); - ssPop(1); - return genBlockReturn(); -} - - /* StackToRegisterMappingCogit>>#genReturnTopFromMethod */ -static sqInt -genReturnTopFromMethod(void) -{ - popToReg(ssTop(), ReceiverResultReg); - ssPop(1); - return genUpArrowReturn(); -} - - /* StackToRegisterMappingCogit>>#genSendDirectedSuper:numArgs: */ -static sqInt NoDbgRegParms -genSendDirectedSupernumArgs(sqInt selectorIndex, sqInt numArgs) -{ - sqInt result; - - assert((((ssTop())->type)) == SSConstant); - tempOop = ((ssTop())->constant); - ssPop(1); - marshallSendArguments(numArgs); - result = genMarshalledSendnumArgssendTable(selectorIndex, numArgs, (directedSendUsesBinding - ? directedSuperBindingSendTrampolines - : directedSuperSendTrampolines)); - directedSendUsesBinding = 0; - return result; -} - - /* StackToRegisterMappingCogit>>#genSendSuper:numArgs: */ -static sqInt NoDbgRegParms -genSendSupernumArgs(sqInt selectorIndex, sqInt numArgs) -{ - marshallSendArguments(numArgs); - return genMarshalledSendnumArgssendTable(selectorIndex, numArgs, superSendTrampolines); -} - - -/* Generate a trampoline with four arguments. - Hack: a negative value indicates an abstract register, a non-negative - value indicates a constant. */ - - /* StackToRegisterMappingCogit>>#genSendTrampolineFor:numArgs:called:arg:arg:arg:arg: */ -static usqInt NoDbgRegParms -genSendTrampolineFornumArgscalledargargargarg(void *aRoutine, sqInt numArgs, char *aString, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3) -{ - sqInt routine; - usqInt startAddress; - - startAddress = methodZoneBase; - zeroOpcodeIndex(); - genPushRegisterArgsForNumArgsscratchReg(backEnd, numArgs, SendNumArgsReg); - /* begin selectorIndexDereferenceRoutine */ - routine = null; - if (!(routine == null)) { - - /* Explicitly save LinkReg via ExtraReg2; it's presumably faster than pushing/popping */ - /* begin MoveR:R: */ - genoperandoperand(MoveRR, LinkReg, Extra2Reg); - /* begin Call: */ - genoperand(Call, routine); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Extra2Reg, LinkReg); - } - genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(aRoutine, aString, 4, regOrConst0, regOrConst1, regOrConst2, regOrConst3, 0 /* emptyRegisterMask */, 1, NoReg, 1); - return startAddress; -} - - /* StackToRegisterMappingCogit>>#genSend:numArgs: */ -static sqInt NoDbgRegParms -genSendnumArgs(sqInt selectorIndex, sqInt numArgs) -{ - marshallSendArguments(numArgs); - return genMarshalledSendnumArgssendTable(selectorIndex, numArgs, ordinarySendTrampolines); -} - - /* StackToRegisterMappingCogit>>#genSpecialSelectorArithmetic */ -static sqInt -genSpecialSelectorArithmetic(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - sqInt argInt; - int argIsConst; - sqInt argIsInt; - sqInt i; - sqInt index; - AbstractInstruction *jumpContinue; - AbstractInstruction *jumpNotSmallInts; - BytecodeDescriptor *primDescriptor; - sqInt rcvrInt; - int rcvrIsConst; - sqInt rcvrIsInt; - sqInt result; - - primDescriptor = generatorAt(byte0); - argIsInt = ((argIsConst = (((ssTop())->type)) == SSConstant)) - && ((((argInt = ((ssTop())->constant))) & 1)); - rcvrIsInt = (((rcvrIsConst = (((ssValue(1))->type)) == SSConstant)) - && ((((rcvrInt = ((ssValue(1))->constant))) & 1))) - || ((mclassIsSmallInteger()) - && (isSameEntryAs(ssValue(1), simSelf()))); - if (argIsInt - && (rcvrIsInt - && (rcvrIsConst))) { - rcvrInt = (rcvrInt >> 1); - argInt = (argInt >> 1); - switch ((primDescriptor->opcode)) { - case AddRR: - result = rcvrInt + argInt; - break; - case SubRR: - result = rcvrInt - argInt; - break; - case AndRR: - result = rcvrInt & argInt; - break; - case OrRR: - result = rcvrInt | argInt; - break; - default: - error("Case not found and no otherwise clause"); - } - if (isIntegerValue(result)) { - - /* Must annotate the bytecode for correct pc mapping. */ - return (ssPop(2), - ssPushAnnotatedConstant((((usqInt)result << 1) | 1))); - } - return genSpecialSelectorSend(); - } - if ((rcvrIsConst - && (!rcvrIsInt)) - || (argIsConst - && (!argIsInt))) { - return genSpecialSelectorSend(); - } - if (!(argIsInt - || (rcvrIsInt))) { - return genSpecialSelectorSend(); - } - if (argIsInt) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 2)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 2)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 2))); i <= (simStackPtr - 2); i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 2) + 1; - } - popToReg(ssValue(1), ReceiverResultReg); - ssPop(2); - } - else { - marshallSendArguments(1); - } - jumpNotSmallInts = (!(rcvrIsInt - && (argIsInt)) - ? (argIsInt - ? genJumpNotSmallInteger(ReceiverResultReg) - : (rcvrIsInt - ? genJumpNotSmallInteger(Arg0Reg) - : (/* begin genJumpNotSmallIntegersIn:and:scratch: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg), - /* begin AndR:R: */ - genoperandoperand(AndRR, Arg0Reg, TempReg), - genJumpNotSmallIntegerInScratchReg(TempReg)))) - : 0); - switch ((primDescriptor->opcode)) { - case AddRR: - if (argIsInt) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, argInt - ConstZero, ReceiverResultReg); - /* begin JumpNoOverflow: */ - jumpContinue = genConditionalBranchoperand(JumpNoOverflow, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(SubCqR, argInt - ConstZero, ReceiverResultReg); - } - else { - genRemoveSmallIntegerTagsInScratchReg(ReceiverResultReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - /* begin JumpNoOverflow: */ - jumpContinue = genConditionalBranchoperand(JumpNoOverflow, ((sqInt)0)); - if (rcvrIsInt - && (rcvrIsConst)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, rcvrInt, ReceiverResultReg); - } - else { - /* begin SubR:R: */ - genoperandoperand(SubRR, Arg0Reg, ReceiverResultReg); - genSetSmallIntegerTagsIn(ReceiverResultReg); - } - } - break; - case SubRR: - if (argIsInt) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(SubCqR, argInt - ConstZero, ReceiverResultReg); - /* begin JumpNoOverflow: */ - jumpContinue = genConditionalBranchoperand(JumpNoOverflow, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(AddCqR, argInt - ConstZero, ReceiverResultReg); - } - else { - genRemoveSmallIntegerTagsInScratchReg(Arg0Reg); - /* begin SubR:R: */ - genoperandoperand(SubRR, Arg0Reg, ReceiverResultReg); - /* begin JumpNoOverflow: */ - jumpContinue = genConditionalBranchoperand(JumpNoOverflow, ((sqInt)0)); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - genSetSmallIntegerTagsIn(Arg0Reg); - } - break; - case AndRR: - if (argIsInt) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(AndCqR, argInt, ReceiverResultReg); - } - else { - /* begin AndR:R: */ - genoperandoperand(AndRR, Arg0Reg, ReceiverResultReg); - } - jumpContinue = (!(jumpNotSmallInts == null) - ? (/* begin Jump: */ - genoperand(Jump, ((sqInt)0))) - : 0); - break; - case OrRR: - if (argIsInt) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(OrCqR, argInt, ReceiverResultReg); - } - else { - /* begin OrR:R: */ - genoperandoperand(OrRR, Arg0Reg, ReceiverResultReg); - } - jumpContinue = (!(jumpNotSmallInts == null) - ? (/* begin Jump: */ - genoperand(Jump, ((sqInt)0))) - : 0); - break; - default: - error("Case not found and no otherwise clause"); - } - if (jumpNotSmallInts == null) { - if (!jumpContinue) { - - /* overflow cannot happen */ - /* begin annotateInstructionForBytecode */ - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (abstractInstruction->annotation = HasBytecodePC); - ssPushRegister(ReceiverResultReg); - return 0; - } - } - else { - jmpTarget(jumpNotSmallInts, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - if (argIsInt) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(MoveCqR, argInt, Arg0Reg); - } - index = byte0 - ( -#if MULTIPLEBYTECODESETS - (bytecodeSetOffset == 0x100 - ? AltFirstSpecialSelector + 0x100 - : FirstSpecialSelector) -#else - FirstSpecialSelector -#endif - ); - genMarshalledSendnumArgssendTable((-index) - 1, 1, ordinarySendTrampolines); - jmpTarget(jumpContinue, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - /* StackToRegisterMappingCogit>>#genSpecialSelectorClass */ -static sqInt -genSpecialSelectorClass(void) -{ - sqInt requiredReg1; - sqInt topReg; - - topReg = registerOrNone(ssTop()); - ssPop(1); - if ((topReg == NoReg) - || (topReg == ClassReg)) { - /* begin ssAllocateRequiredReg:and: */ - requiredReg1 = (topReg = SendNumArgsReg); - ssAllocateRequiredRegMaskupThroughupThroughNative((1U << requiredReg1) | (1U << ClassReg), simStackPtr, simNativeStackPtr); - } - else { - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr, simNativeStackPtr); - } - ssPush(1); - popToReg(ssTop(), topReg); - genGetClassObjectOfintoscratchRegmayBeAForwarder(topReg, ClassReg, TempReg, mayBeAForwarder(ssTop())); - return (ssPop(1), - ssPushRegister(ClassReg)); -} - - /* StackToRegisterMappingCogit>>#genSpecialSelectorComparison */ -static sqInt -genSpecialSelectorComparison(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt argInt; - sqInt argIsIntConst; - BytecodeDescriptor *branchDescriptor; - BytecodeDescriptor *branchDescriptor1; - sqInt i; - sqInt index; - sqInt inlineCAB; - AbstractInstruction *jumpNotSmallInts; - void *jumpTarget; - sqInt nExts; - sqInt nextPC; - sqInt nextPC1; - sqInt postBranchPC; - sqInt postBranchPC1; - BytecodeDescriptor *primDescriptor; - BytecodeDescriptor *primDescriptor1; - int rcvrIsConst; - sqInt rcvrIsInt; - sqInt targetBytecodePC; - sqInt targetPC; - - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 2)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 2)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 2))); i <= (simStackPtr - 2); i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 2) + 1; - } - primDescriptor = generatorAt(byte0); - argIsIntConst = ((((ssTop())->type)) == SSConstant) - && ((((argInt = ((ssTop())->constant))) & 1)); - rcvrIsInt = (((rcvrIsConst = (((ssValue(1))->type)) == SSConstant)) - && (((((ssValue(1))->constant)) & 1))) - || ((mclassIsSmallInteger()) - && (isSameEntryAs(ssValue(1), simSelf()))); - if (argIsIntConst - && (rcvrIsInt - && (rcvrIsConst))) { - return genStaticallyResolvedSpecialSelectorComparison(); - } - /* begin extractMaybeBranchDescriptorInto: */ - primDescriptor1 = generatorAt(byte0); - nextPC1 = bytecodePC + ((primDescriptor1->numBytes)); - nExts = 0; - while (1) { - while (1) { - /* begin generatorForPC: */ - branchDescriptor1 = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC1, methodObj))); - if (!((branchDescriptor1->isExtension))) break; - nExts += 1; - nextPC1 += (branchDescriptor1->numBytes); - } - /* begin isUnconditionalBranch */ - if (!((isBranch(branchDescriptor1)) - && (!(((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse)))))) break; - nextPC1 = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - } - targetBytecodePC = (postBranchPC1 = 0); - if (((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse))) { - targetBytecodePC = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - postBranchPC1 = eventualTargetOf(nextPC1 + ((branchDescriptor1->numBytes))); - } - else { - nextPC1 = bytecodePC + ((primDescriptor1->numBytes)); - } - branchDescriptor = branchDescriptor1; - nextPC = nextPC1; - postBranchPC = postBranchPC1; - targetPC = targetBytecodePC; - - /* Further, only interested in inlining = and ~= if there's a SmallInteger constant involved. - The relational operators successfully statically predict SmallIntegers; the equality operators do not. */ - inlineCAB = ((branchDescriptor->isBranchTrue)) - || ((branchDescriptor->isBranchFalse)); - if (inlineCAB - && ((((primDescriptor->opcode)) == JumpZero) - || (((primDescriptor->opcode)) == JumpNonZero))) { - inlineCAB = argIsIntConst - || (rcvrIsInt); - } - if (!inlineCAB) { - return genSpecialSelectorSend(); - } - if (argIsIntConst) { - popToReg(ssValue(1), ReceiverResultReg); - ssPop(2); - } - else { - marshallSendArguments(1); - } - jumpNotSmallInts = (!(rcvrIsInt - && (argIsIntConst)) - ? (argIsIntConst - ? genJumpNotSmallInteger(ReceiverResultReg) - : (rcvrIsInt - ? genJumpNotSmallInteger(Arg0Reg) - : (/* begin genJumpNotSmallIntegersIn:and:scratch: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg), - /* begin AndR:R: */ - genoperandoperand(AndRR, Arg0Reg, TempReg), - genJumpNotSmallIntegerInScratchReg(TempReg)))) - : 0); - if (argIsIntConst) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, argInt, ReceiverResultReg); - } - else { - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, ReceiverResultReg); - } - genConditionalBranchoperand(((branchDescriptor->isBranchTrue) - ? (primDescriptor->opcode) - : inverseBranchFor((primDescriptor->opcode))), ((usqInt)(ensureNonMergeFixupAt(targetPC)))); - /* begin Jump: */ - jumpTarget = ensureNonMergeFixupAt(postBranchPC); - genoperand(Jump, ((sqInt)jumpTarget)); - if (!jumpNotSmallInts) { - /* begin annotateInstructionForBytecode */ - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (abstractInstruction->annotation = HasBytecodePC); - ensureFixupAt(postBranchPC); - ensureFixupAt(targetPC); - deadCode = 1; - return 0; - } - jmpTarget(jumpNotSmallInts, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (argIsIntConst) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, argInt, Arg0Reg); - } - index = byte0 - ( -#if MULTIPLEBYTECODESETS - (bytecodeSetOffset == 0x100 - ? AltFirstSpecialSelector + 0x100 - : FirstSpecialSelector) -#else - FirstSpecialSelector -#endif - ); - return genMarshalledSendnumArgssendTable((-index) - 1, 1, ordinarySendTrampolines); -} - - -/* Assumes both operands are ints */ - - /* StackToRegisterMappingCogit>>#genStaticallyResolvedSpecialSelectorComparison */ -static sqInt -genStaticallyResolvedSpecialSelectorComparison(void) -{ - sqInt argInt; - BytecodeDescriptor *primDescriptor; - sqInt rcvrInt; - int result; - - primDescriptor = generatorAt(byte0); - argInt = ((ssTop())->constant); - rcvrInt = ((ssValue(1))->constant); - switch ((primDescriptor->opcode)) { - case JumpLess: - result = rcvrInt < argInt; - break; - case JumpLessOrEqual: - result = rcvrInt <= argInt; - break; - case JumpGreater: - result = rcvrInt > argInt; - break; - case JumpGreaterOrEqual: - result = rcvrInt >= argInt; - break; - case JumpZero: - result = rcvrInt == argInt; - break; - case JumpNonZero: - result = rcvrInt != argInt; - break; - default: - error("Case not found and no otherwise clause"); - } - ssPop(2); - return ssPushAnnotatedConstant((result - ? trueObject() - : falseObject())); -} - - -/* We need a frame because the association has to be in ReceiverResultReg for - the various trampolines - and ReceiverResultReg holds only the receiver in frameless methods. - */ - - /* StackToRegisterMappingCogit>>#genStorePop:LiteralVariable:needsStoreCheck:needsImmutabilityCheck: */ -static sqInt NoDbgRegParms -genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt litVarIndex, sqInt needsStoreCheck, sqInt needsImmCheck) -{ - AbstractInstruction *anInstruction; - sqInt association; - sqInt i; - sqInt topReg; - - assert(needsFrame); - /* begin genLoadLiteralVariable:in: */ - association = getLiteral(litVarIndex); - voidReceiverResultRegContainsSelf(); - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); - /* begin genMoveConstant:R: */ - if (shouldAnnotateObjectReference(association)) { - annotateobjRef(checkLiteralforInstruction(association, genoperandoperand(MoveCwR, association, ReceiverResultReg)), association); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, association, ReceiverResultReg); - } - /* begin genGenericStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr:needsImmutabilityCheck: */ -# if IMMUTABILITY - if (needsImmCheck) { - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); - ssStoreAndReplacePoptoReg(popBoolean, ClassReg); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0); - } -# endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); - ssStorePoptoReg(popBoolean, topReg); - return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); -} - - -/* The reason we need a frame here is that assigning to an inst var of a - context may - involve wholesale reorganization of stack pages, and the only way to - preserve the - execution state of an activation in that case is if it has a frame. */ - - /* StackToRegisterMappingCogit>>#genStorePop:MaybeContextReceiverVariable:needsStoreCheck:needsImmutabilityCheck: */ -static sqInt NoDbgRegParms -genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt slotIndex, sqInt needsStoreCheck, sqInt needsImmCheck) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *abstractInstruction2; - AbstractInstruction *abstractInstruction3; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt i; - AbstractInstruction *immutabilityFailure; - AbstractInstruction *mutableJump; - - immutabilityFailure = ((AbstractInstruction *) 0); - assert(needsFrame); - ssFlushUpThroughReceiverVariable(slotIndex); - ensureReceiverResultRegContainsSelf(); - /* begin genGenericStorePop:MaybeContextSlotIndex:needsStoreCheck:needsRestoreRcvr:needsImmutabilityCheck: */ - assert(needsFrame); -# if IMMUTABILITY - if (needsImmCheck) { - mutableJump = genJumpMutablescratchReg(ReceiverResultReg, TempReg); - /* begin genStoreTrampolineCall: */ - assert(IMMUTABILITY); - if (slotIndex >= (NumStoreTrampolines - 1)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, slotIndex, TempReg); - /* begin CallRT: */ - abstractInstruction3 = genoperand(Call, ceStoreTrampolines[NumStoreTrampolines - 1]); - (abstractInstruction3->annotation = IsRelativeCall); - } - else { - /* begin CallRT: */ - abstractInstruction1 = genoperand(Call, ceStoreTrampolines[slotIndex]); - (abstractInstruction1->annotation = IsRelativeCall); - } - /* begin annotateBytecode: */ - abstractInstruction2 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction2->annotation = HasBytecodePC); - /* begin putSelfInReceiverResultReg */ - storeToReg(simSelf(), ReceiverResultReg); - /* begin Jump: */ - immutabilityFailure = genoperand(Jump, ((sqInt)0)); - jmpTarget(mutableJump, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } -# endif // IMMUTABILITY - ssPop(1); - /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); - ssPush(1); - genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); - ssStoreAndReplacePoptoReg(popBoolean, ClassReg); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, slotIndex, SendNumArgsReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceStoreContextInstVarTrampoline); - (abstractInstruction->annotation = IsRelativeCall); -# if IMMUTABILITY - if (needsImmCheck) { - jmpTarget(immutabilityFailure, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } -# endif - return 0; -} - - /* StackToRegisterMappingCogit>>#genStorePop:ReceiverVariable:needsStoreCheck:needsImmutabilityCheck: */ -static sqInt NoDbgRegParms -genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt slotIndex, sqInt needsStoreCheck, sqInt needsImmCheck) -{ - sqInt i; - sqInt needsImmCheck1; - sqInt needsStoreCheck1; - sqInt topReg; - - ssFlushUpThroughReceiverVariable(slotIndex); - ensureReceiverResultRegContainsSelf(); - /* begin genGenericStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr:needsImmutabilityCheck: */ - needsStoreCheck1 = (!useTwoPaths) - && (needsStoreCheck); - needsImmCheck1 = needsImmCheck - && (!useTwoPaths); -# if IMMUTABILITY - if (needsImmCheck1) { - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); - ssStoreAndReplacePoptoReg(popBoolean, ClassReg); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck1, 1); - } -# endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); - ssStorePoptoReg(popBoolean, topReg); - return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck1); -} - - -/* The only reason we assert needsFrame here is that in a frameless method - ReceiverResultReg must and does contain only self, but the ceStoreCheck - trampoline expects the target of the store to be in ReceiverResultReg. So - in a frameless method we would have a conflict between the receiver and - the temote temp store, unless we we smart enough to realise that - ReceiverResultReg was unused after the literal variable store, unlikely - given that methods return self by default. */ - - /* StackToRegisterMappingCogit>>#genStorePop:RemoteTemp:At:needsStoreCheck: */ -static sqInt NoDbgRegParms -genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt remoteTempIndex, sqInt needsStoreCheck) -{ - AbstractInstruction *anInstruction; - sqInt offset; - sqInt topReg; - - assert(needsFrame); - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); - voidReceiverResultRegContainsSelf(); - /* begin MoveMw:r:R: */ - offset = frameOffsetOfTemporary(remoteTempIndex); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, FPReg, ReceiverResultReg); - /* begin genGenericStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr:needsImmutabilityCheck: */ -# if IMMUTABILITY - -# endif - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); - ssStorePoptoReg(popBoolean, topReg); - return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); -} - - /* StackToRegisterMappingCogit>>#genStorePop:TemporaryVariable: */ -static sqInt NoDbgRegParms -genStorePopTemporaryVariable(sqInt popBoolean, sqInt tempIndex) -{ - AbstractInstruction *anInstruction; - sqInt offset; - sqInt reg; - - ssFlushUpThroughTemporaryVariable(tempIndex); - reg = ssStorePoptoPreferredReg(popBoolean, TempReg); - /* begin MoveR:Mw:r: */ - offset = frameOffsetOfTemporary(tempIndex); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveRMwr, reg, offset, FPReg); - ((simStackAt(tempIndex + 1))->bcptr = bytecodePC); - return 0; -} - - -/* Generate a method return from within a method or a block. - Frameless method activation looks like - CISCs (x86): - receiver - args - sp-> ret pc. - RISCs (ARM): - receiver - args - ret pc in LR. - A fully framed activation is described in CoInterpreter - class>initializeFrameIndices. Return pops receiver and arguments off the - stack. Callee pushes the result. */ - - /* StackToRegisterMappingCogit>>#genUpArrowReturn */ -static sqInt -genUpArrowReturn(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - sqInt i; - sqInt offset; - - - /* can't fall through */ - deadCode = 1; - if (inBlock > 0) { - assert(needsFrame); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceNonLocalReturnTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin annotateBytecode: */ - abstractInstruction1 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction1->annotation = HasBytecodePC); - return 0; - } - if ( -# if IMMUTABILITY - needsFrame - && (!useTwoPaths) -# else - needsFrame -# endif - ) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, FPReg, SPReg); - /* begin PopR: */ - genoperand(PopR, FPReg); - /* begin PopR: */ - genoperand(PopR, LinkReg); - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - else { - /* begin RetN: */ - offset = ((methodOrBlockNumArgs > 2 /* numRegArgs */) - || (regArgsHaveBeenPushed) - ? (methodOrBlockNumArgs + 1) * BytesPerWord - : 0); - genoperand(RetN, offset); - } - return 0; -} - - /* StackToRegisterMappingCogit>>#genVanillaInlinedIdenticalOrNotIf: */ -static sqInt NoDbgRegParms -genVanillaInlinedIdenticalOrNotIf(sqInt orNot) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - int argIsConstant; - sqInt argNeedsReg; - sqInt argReg; - sqInt argReg1; - BytecodeDescriptor *branchDescriptor; - BytecodeDescriptor *branchDescriptor1; - sqInt constant; - sqInt constant1; - sqInt i; - void *jumpTarget; - void *jumpTarget1; - void *jumpTarget2; - void *jumpTarget3; - sqInt nExts; - sqInt nextPC; - sqInt nextPC1; - sqInt postBranchPC; - sqInt postBranchPC1; - BytecodeDescriptor *primDescriptor; - sqInt rcvrIsConstant; - sqInt rcvrNeedsReg; - sqInt rcvrReg; - sqInt rcvrReg1; - sqInt reg; - sqInt rNext1; - sqInt rTop1; - sqInt targetBytecodePC; - sqInt targetPC; - sqInt topRegistersMask; - - /* begin extractMaybeBranchDescriptorInto: */ - primDescriptor = generatorAt(byte0); - nextPC1 = bytecodePC + ((primDescriptor->numBytes)); - nExts = 0; - while (1) { - while (1) { - /* begin generatorForPC: */ - branchDescriptor1 = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC1, methodObj))); - if (!((branchDescriptor1->isExtension))) break; - nExts += 1; - nextPC1 += (branchDescriptor1->numBytes); - } - /* begin isUnconditionalBranch */ - if (!((isBranch(branchDescriptor1)) - && (!(((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse)))))) break; - nextPC1 = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - } - targetBytecodePC = (postBranchPC1 = 0); - if (((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse))) { - targetBytecodePC = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - postBranchPC1 = eventualTargetOf(nextPC1 + ((branchDescriptor1->numBytes))); - } - else { - nextPC1 = bytecodePC + ((primDescriptor->numBytes)); - } - branchDescriptor = branchDescriptor1; - nextPC = nextPC1; - postBranchPC = postBranchPC1; - targetPC = targetBytecodePC; - - /* They can't be both constants to use correct machine opcodes. - However annotable constants can't be resolved statically, hence we need to careful. */ - argIsConstant = (((ssTop())->type)) == SSConstant; - rcvrIsConstant = (!argIsConstant) - && ((((ssValue(1))->type)) == SSConstant); - /* begin allocateEqualsEqualsRegistersArgNeedsReg:rcvrNeedsReg:into: */ - argNeedsReg = !argIsConstant; - rcvrNeedsReg = !rcvrIsConstant; - assert(argNeedsReg - || (rcvrNeedsReg)); - argReg1 = (rcvrReg1 = NoReg); - if (argNeedsReg) { - if (rcvrNeedsReg) { - /* begin allocateRegForStackTopTwoEntriesInto: */ - topRegistersMask = 0; - rTop1 = (rNext1 = NoReg); - if ((registerOrNone(ssTop())) != NoReg) { - rTop1 = registerOrNone(ssTop()); - } - if ((registerOrNone(ssValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; - } - if (rTop1 == NoReg) { - rTop1 = allocateRegNotConflictingWith(topRegistersMask); - } - if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); - } - assert(!(((rTop1 == NoReg) - || (rNext1 == NoReg)))); - argReg1 = rTop1; - rcvrReg1 = rNext1; - popToReg(ssTop(), argReg1); - popToReg(ssValue(1), rcvrReg1); - } - else { - argReg1 = allocateRegForStackEntryAtnotConflictingWith(0, 0); - popToReg(ssTop(), argReg1); - if (((ssValue(1))->spilled)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AddCqR, BytesPerWord, SPReg); - } - } - } - else { - assert(rcvrNeedsReg); - assert(!((((ssTop())->spilled)))); - rcvrReg1 = allocateRegForStackEntryAtnotConflictingWith(1, 0); - popToReg(ssValue(1), rcvrReg1); - } - assert(!((argNeedsReg - && (argReg1 == NoReg)))); - assert(!((rcvrNeedsReg - && (rcvrReg1 == NoReg)))); - rcvrReg = rcvrReg1; - argReg = argReg1; - if (!(((branchDescriptor->isBranchTrue)) - || ((branchDescriptor->isBranchFalse)))) { - return genIdenticalNoBranchArgIsConstantrcvrIsConstantargRegrcvrRegorNotIf(argIsConstant, rcvrIsConstant, argReg, rcvrReg, orNot); - } - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 2)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 2)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 2))); i <= (simStackPtr - 2); i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 2) + 1; - } - /* begin genCmpArgIsConstant:rcvrIsConstant:argReg:rcvrReg: */ - assert((argReg != NoReg) - || (rcvrReg != NoReg)); - if (argIsConstant) { - /* begin genCmpConstant:R: */ - constant = ((ssTop())->constant); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(CmpCwR, constant, rcvrReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, constant, rcvrReg); - } - } - else { - if (rcvrIsConstant) { - /* begin genCmpConstant:R: */ - constant1 = ((ssValue(1))->constant); - if (shouldAnnotateObjectReference(constant1)) { - annotateobjRef(checkLiteralforInstruction(constant1, genoperandoperand(CmpCwR, constant1, argReg)), constant1); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, constant1, argReg); - } - } - else { - /* begin CmpR:R: */ - assert(!((argReg == SPReg))); - genoperandoperand(CmpRR, argReg, rcvrReg); - } - } - ssPop(2); - if ((((fixupAt(nextPC))->targetInstruction)) == 0) { - - /* The next instruction is dead. we can skip it. */ - deadCode = 1; - ensureFixupAt(targetPC); - ensureFixupAt(postBranchPC); - } - else { - assert(!(deadCode)); - } - if (orNot == ((branchDescriptor->isBranchTrue))) { - - /* a == b ifFalse: ... or a ~~ b ifTrue: ... jump on equal to post-branch pc */ - ensureNonMergeFixupAt(targetPC); - /* begin JumpZero: */ - jumpTarget = ensureNonMergeFixupAt(postBranchPC); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget)); - /* begin Jump: */ - jumpTarget1 = ensureNonMergeFixupAt(targetPC); - genoperand(Jump, ((sqInt)jumpTarget1)); - } - else { - - /* orNot is true for ~~ */ - /* a == b ifTrue: ... or a ~~ b ifFalse: ... jump on equal to target pc */ - /* begin JumpZero: */ - jumpTarget2 = ensureNonMergeFixupAt(targetPC); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget2)); - /* begin Jump: */ - jumpTarget3 = ensureNonMergeFixupAt(postBranchPC); - genoperand(Jump, ((sqInt)jumpTarget3)); - } - if (!deadCode) { - ssPushConstant(trueObject()); - } - return 0; -} - - /* StackToRegisterMappingCogit>>#initSimStackForFramefulMethod: */ -static void NoDbgRegParms -initSimStackForFramefulMethod(sqInt startpc) -{ - CogSimStackEntry * cascade0; - CogSimStackEntry *desc; - sqInt i; - - - /* N.B. Includes num args */ - simStackPtr = methodOrBlockNumTemps; - simSpillBase = methodOrBlockNumTemps + 1; - cascade0 = simSelf(); - (cascade0->type = SSBaseOffset); - (cascade0->spilled = 1); - (cascade0->registerr = FPReg); - (cascade0->offset = FoxMFReceiver); - (cascade0->liveRegister = NoReg); - for (i = 1; i <= methodOrBlockNumArgs; i += 1) { - desc = simStackAt(i); - (desc->type = SSBaseOffset); - (desc->spilled = 1); - (desc->registerr = FPReg); - (desc->offset = FoxCallerSavedIP + (((methodOrBlockNumArgs - i) + 1) * BytesPerWord)); - (desc->bcptr = startpc); - } - for (i = (methodOrBlockNumArgs + 1); i <= simStackPtr; i += 1) { - desc = simStackAt(i); - (desc->type = SSBaseOffset); - (desc->spilled = 1); - (desc->registerr = FPReg); - (desc->offset = FoxMFReceiver - ((i - methodOrBlockNumArgs) * BytesPerWord)); - (desc->bcptr = startpc); - } -} - - -/* The register receiver (the closure itself) and args are pushed by the - closure value primitive(s) - and hence a frameless block has all arguments and copied values pushed to - the stack. However, - the method receiver (self) is put in the ReceiverResultReg by the block - entry. - */ - - /* StackToRegisterMappingCogit>>#initSimStackForFramelessBlock: */ -static void NoDbgRegParms -initSimStackForFramelessBlock(sqInt startpc) -{ - CogSimStackEntry * cascade0; - CogSimStackEntry *desc; - sqInt i; - - cascade0 = simSelf(); - (cascade0->type = SSRegister); - (cascade0->spilled = 0); - (cascade0->registerr = ReceiverResultReg); - (cascade0->liveRegister = ReceiverResultReg); - assert(methodOrBlockNumTemps >= methodOrBlockNumArgs); - for (i = 1; i <= methodOrBlockNumTemps; i += 1) { - desc = simStackAt(i); - (desc->type = SSBaseOffset); - (desc->spilled = 1); - (desc->registerr = SPReg); - (desc->offset = (methodOrBlockNumArgs - i) * BytesPerWord); - (desc->bcptr = startpc); - } - - /* N.B. Includes num args */ - simStackPtr = methodOrBlockNumTemps; - simSpillBase = methodOrBlockNumTemps + 1; - } - - /* StackToRegisterMappingCogit>>#initSimStackForFramelessMethod: */ -static void NoDbgRegParms -initSimStackForFramelessMethod(sqInt startpc) -{ - CogSimStackEntry * cascade0; - CogSimStackEntry *desc; - sqInt i; - - cascade0 = simSelf(); - (cascade0->type = SSRegister); - (cascade0->spilled = 0); - (cascade0->registerr = ReceiverResultReg); - (cascade0->liveRegister = ReceiverResultReg); - assert(methodOrBlockNumTemps == methodOrBlockNumArgs); - assert((numRegArgs()) <= 2); - if (((methodOrBlockNumArgs >= 1) && (methodOrBlockNumArgs <= 2 /* numRegArgs */))) { - desc = simStackAt(1); - (desc->type = SSRegister); - (desc->spilled = 0); - (desc->registerr = Arg0Reg); - (desc->bcptr = startpc); - if (methodOrBlockNumArgs > 1) { - desc = simStackAt(2); - (desc->type = SSRegister); - (desc->spilled = 0); - (desc->registerr = Arg1Reg); - (desc->bcptr = startpc); - } - } - else { - for (i = 1; i <= methodOrBlockNumArgs; i += 1) { - desc = simStackAt(i); - (desc->type = SSBaseOffset); - (desc->registerr = SPReg); - (desc->spilled = 1); - (desc->offset = (methodOrBlockNumArgs - i) * BytesPerWord); - (desc->bcptr = startpc); - } - } - simStackPtr = methodOrBlockNumArgs; - simSpillBase = methodOrBlockNumArgs + 1; - } - - -/* Do not inline (inBlock access) */ - - /* StackToRegisterMappingCogit>>#isNonForwarderReceiver: */ -static sqInt NoDbgRegParms -isNonForwarderReceiver(sqInt reg) -{ - return ((((simSelf())->liveRegister)) == ReceiverResultReg) - && ((inBlock == 0) - && (reg == ReceiverResultReg)); -} - - /* StackToRegisterMappingCogit>>#liveRegisters */ -static sqInt -liveRegisters(void) -{ - sqInt i; - sqInt regsSet; - - if (needsFrame) { - regsSet = 0; - } - else { - /* begin registerMaskFor: */ - regsSet = 1U << ReceiverResultReg; - if ((methodOrBlockNumArgs <= 2 /* numRegArgs */) - && (methodOrBlockNumArgs > 0)) { - regsSet = regsSet | (1U << Arg0Reg); - if (methodOrBlockNumArgs > 1) { - regsSet = regsSet | (1U << Arg1Reg); - } - } - } - for (i = (((simSpillBase < 0) ? 0 : simSpillBase)); i <= simStackPtr; i += 1) { - regsSet = regsSet | (registerMask(simStackAt(i))); - } - return regsSet; -} - - -/* insert nops for dead code that is mapped so that bc - to mc mapping is not many to one */ - - /* StackToRegisterMappingCogit>>#mapDeadDescriptorIfNeeded: */ -static sqInt NoDbgRegParms -mapDeadDescriptorIfNeeded(BytecodeDescriptor *descriptor) -{ - AbstractInstruction *abstractInstruction; - - flag("annotateInstruction"); - if (((descriptor->isMapped)) - || ((inBlock > 0) - && ((descriptor->isMappedInBlock)))) { - /* begin annotateBytecode: */ - abstractInstruction = gen(Nop); - (abstractInstruction->annotation = HasBytecodePC); - } - return 0; -} - - -/* Spill everything on the simulated stack that needs spilling (that below - receiver and arguments). - Marshall receiver and arguments to stack and/or registers depending on arg - count. If the args don't fit in registers push receiver and args (spill - everything), but still assign - the receiver to ReceiverResultReg. */ - - /* StackToRegisterMappingCogit>>#marshallSendArguments: */ -static void NoDbgRegParms -marshallSendArguments(sqInt numArgs) -{ - sqInt anyRefs; - CogSimStackEntry * cascade0; - sqInt i; - sqInt i1; - sqInt i2; - sqInt numSpilled; - - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= ((simStackPtr - numArgs) - 1)) { - for (i2 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < ((simStackPtr - numArgs) - 1)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : ((simStackPtr - numArgs) - 1))); i2 < (simStackPtr - numArgs); i2 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i2), frameOffsetOfTemporary(i2 - 1), FPReg); - } - simSpillBase = ((simStackPtr - numArgs) - 1) + 1; - } - if (numArgs > 2 /* numRegArgs */) { - - /* If there are no spills and no references to ReceiverResultReg - the fetch of ReceiverResultReg from the stack can be avoided - by assigning directly to ReceiverResultReg and pushing it. */ - numSpilled = numberOfSpillsInTopNItems(numArgs + 1); - anyRefs = anyReferencesToRegisterinTopNItems(ReceiverResultReg, numArgs + 1); - if ((numSpilled > 0) - || (anyRefs)) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - storeToReg(simStackAt(simStackPtr - numArgs), ReceiverResultReg); - } - else { - cascade0 = simStackAt(simStackPtr - numArgs); - storeToReg(cascade0, ReceiverResultReg); - (cascade0->type = SSRegister); - (cascade0->registerr = ReceiverResultReg); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i1 <= simStackPtr; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - } - } - else { - - /* Move the args to the register arguments, being careful to do - so last to first so e.g. previous contents don't get overwritten. - Also check for any arg registers in use by other args. */ - if (numArgs > 0) { - if (numArgs > 1) { - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 2, simNativeStackPtr); - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg1Reg, simStackPtr - 1, simNativeStackPtr); - } - else { - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); - } - } - if (numArgs > 1) { - popToReg(simStackAt(simStackPtr), Arg1Reg); - } - if (numArgs > 0) { - popToReg(simStackAt((simStackPtr - numArgs) + 1), Arg0Reg); - } - popToReg(simStackAt(simStackPtr - numArgs), ReceiverResultReg); - } - ssPop(numArgs + 1); -} - - -/* For assert checking; or rather for avoiding assert fails when dealing with - the hack for block temps in the SqueakV3PlusClosures bytecode set. - */ - - /* StackToRegisterMappingCogit>>#maybeCompilingFirstPassOfBlockWithInitialPushNil */ -static sqInt -maybeCompilingFirstPassOfBlockWithInitialPushNil(void) -{ - return (inBlock == InVanillaBlock) - && ((methodOrBlockNumTemps > methodOrBlockNumArgs) - && (compilationPass == 1)); -} - - -/* If this bytecode has a fixup, some kind of merge needs to be done. There - are 4 cases: - 1) the bytecode has no fixup (fixup isNotAFixup) - do nothing - 2) the bytecode has a non merge fixup - the fixup has needsNonMergeFixup. - The code generating non merge fixup (currently only special selector code) - is responsible - for the merge so no need to do it. - We set deadCode to false as the instruction can be reached from jumps. - 3) the bytecode has a merge fixup, but execution flow *cannot* fall - through to the merge point. - the fixup has needsMergeFixup and deadCode = true. - ignores the current simStack as it does not mean anything - restores the simStack to the state the jumps to the merge point expects it - to be. - 4) the bytecode has a merge fixup and execution flow *can* fall through to - the merge point. - the fixup has needsMergeFixup and deadCode = false. - flushes the stack to the stack pointer so the fall through execution path - simStack is - in the state the merge point expects it to be. - restores the simStack to the state the jumps to the merge point expects it - to be. - - In addition, if this is a backjump merge point, we patch the fixup to hold - the current simStackPtr - for later assertions. */ - - /* StackToRegisterMappingCogit>>#mergeWithFixupIfRequired: */ -static sqInt NoDbgRegParms -mergeWithFixupIfRequired(BytecodeFixup *fixup) -{ - CogSimStackEntry * cascade0; - sqInt i; - sqInt i1; - - /* begin assertCorrectSimStackPtr */ - assert((simSpillBase >= methodOrBlockNumTemps) - || ((maybeCompilingFirstPassOfBlockWithInitialPushNil()) - && (simSpillBase > methodOrBlockNumArgs))); - if (needsFrame - && (simSpillBase > 0)) { - assert((((simStackAt(simSpillBase - 1))->spilled)) == 1); - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); - } - if (((fixup->targetInstruction)) == 0) { - return 0; - } - if ((((usqInt)((fixup->targetInstruction)))) == NeedsNonMergeFixupFlag) { - deadCode = 0; - return 0; - } - assert(isMergeFixup(fixup)); - traceMerge(fixup); - if (deadCode) { - - /* case 3 */ - /* Would like to assert fixup simStackPtr >= methodOrBlockNumTemps - but can't because of the initialNils hack. */ - assert((((fixup->simStackPtr)) >= methodOrBlockNumTemps) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - simStackPtr = (fixup->simStackPtr); - } - else { - - /* case 4 */ - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - } - deadCode = 0; - if ((fixup->isTargetOfBackwardBranch)) { - (fixup->simStackPtr = simStackPtr); - } - (fixup->targetInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(simStackPtr == ((fixup->simStackPtr))); - /* begin restoreSimStackAtMergePoint: */ - ((simSelf())->liveRegister = NoReg); - for (i1 = (methodOrBlockNumTemps + 1); i1 <= simStackPtr; i1 += 1) { - cascade0 = simStackAt(i1); - (cascade0->type = SSSpill); - (cascade0->offset = FoxMFReceiver - ((i1 - methodOrBlockNumArgs) * BytesPerOop)); - (cascade0->registerr = FPReg); - (cascade0->spilled = 1); - } - simSpillBase = simStackPtr + 1; - return 0; -} - - /* StackToRegisterMappingCogit>>#methodAbortTrampolineFor: */ -static sqInt NoDbgRegParms -methodAbortTrampolineFor(sqInt numArgs) -{ - return methodAbortTrampolines[((numArgs < (3)) ? numArgs : (3))]; -} - - -/* This is a hook for subclasses to filter out methods they can't deal with. */ -/* Frameless methods with local temporaries cause problems, - mostly in asserts, and yet they matter not at all for performance. - Shun them. */ - - /* StackToRegisterMappingCogit>>#methodFoundInvalidPostScan */ -static sqInt -methodFoundInvalidPostScan(void) -{ - if (!needsFrame) { - return methodOrBlockNumTemps > methodOrBlockNumArgs; - } - return 0; -} - - /* StackToRegisterMappingCogit>>#needsFrameIfMod16GENumArgs: */ -static sqInt NoDbgRegParms -needsFrameIfMod16GENumArgs(sqInt stackDelta) -{ - return (byte0 % 16) >= methodOrBlockNumArgs; -} - - -/* As of August 2013, the code generator can't deal with spills in frameless - methods (the - issue is to do with the stack offset to get at an argument, which is - changed when there's a spill). - In e.g. TextColor>>#dominates: other ^other class == self class the second - send of class - needs also rto allocate a register that the first one used, but the first - one's register can't be - spilled. So avoid this by only allowing class to be sent if the stack - contains a single element. */ - - /* StackToRegisterMappingCogit>>#needsFrameIfStackGreaterThanOne: */ -static sqInt NoDbgRegParms -needsFrameIfStackGreaterThanOne(sqInt stackDelta) -{ - return stackDelta > 1; -} - - /* StackToRegisterMappingCogit>>#numberOfSpillsInTopNItems: */ -static sqInt NoDbgRegParms -numberOfSpillsInTopNItems(sqInt n) -{ - sqInt i; - - for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { - if ((((simStackAt(i))->type)) == SSSpill) { - return n - (simStackPtr - i); - } - } - return 0; -} - - /* StackToRegisterMappingCogit>>#picAbortTrampolineFor: */ -static sqInt NoDbgRegParms -picAbortTrampolineFor(sqInt numArgs) -{ - return picAbortTrampolines[((numArgs < (3)) ? numArgs : (3))]; -} - - /* StackToRegisterMappingCogit>>#prevInstIsPCAnnotated */ -static sqInt -prevInstIsPCAnnotated(void) -{ - sqInt prevIndex; - AbstractInstruction *prevInst; - - if (!(opcodeIndex > 0)) { - return 0; - } - prevIndex = opcodeIndex - 1; - while (1) { - if (prevIndex <= 0) { - return 0; - } - prevInst = abstractInstructionAt(prevIndex); - if (isPCMappedAnnotation((!((prevInst->annotation)) - ? 0 - : (prevInst->annotation)))) { - return 1; - } - if (!(((prevInst->opcode)) == Label)) break; - prevIndex -= 1; - } - return 0; -} - - -/* Used to mark ReceiverResultReg as dead or not containing simSelf. - Used when the simStack has already been flushed, e.g. for sends. */ - - /* StackToRegisterMappingCogit>>#receiverIsInReceiverResultReg */ -static sqInt -receiverIsInReceiverResultReg(void) -{ - return (((simSelf())->liveRegister)) == ReceiverResultReg; -} - - -/* When a block must be recompiled due to overestimating the - numInitialNils fixups must be restored, which means rescannning - since backward branches need their targets initialized. */ - - /* StackToRegisterMappingCogit>>#reinitializeFixupsFrom:through: */ -static void NoDbgRegParms -reinitializeFixupsFromthrough(sqInt start, sqInt end) -{ - BytecodeDescriptor *descriptor; - sqInt distance; - BytecodeFixup * fixup; - sqInt nExts; - sqInt pc; - BytecodeFixup * self_in_reinitialize; - sqInt targetPC; - - pc = start; - nExts = 0; - while (pc <= end) { - /* begin reinitialize */ - self_in_reinitialize = fixupAtIndex(pc - initialPC); - (self_in_reinitialize->targetInstruction) = 0; - (self_in_reinitialize->simStackPtr) = 0; - byte0 = (fetchByteofObject(pc, methodObj)) + bytecodeSetOffset; - descriptor = generatorAt(byte0); - if ((isBranch(descriptor)) - && ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, pc, nExts, methodObj)) < 0))) { - /* begin spanFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, pc, nExts, methodObj); - targetPC = (pc + ((descriptor->numBytes))) + distance; - /* begin initializeFixupAt: */ - fixup = fixupAtIndex(targetPC - initialPC); - /* begin initializeFixup: */ - (fixup->targetInstruction) = ((AbstractInstruction *) NeedsMergeFixupFlag); - /* begin setIsBackwardBranchFixup */ - (fixup->isTargetOfBackwardBranch) = 1; - } - if ((descriptor->isBlockCreation)) { - /* begin spanFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, pc, nExts, methodObj); - pc = (pc + ((descriptor->numBytes))) + distance; - } - else { - pc += (descriptor->numBytes); - } - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } -} - - -/* Scan the block to determine if the block needs a frame or not */ - - /* StackToRegisterMappingCogit>>#scanBlock: */ -static sqInt NoDbgRegParms -scanBlock(BlockStart *blockStart) -{ - BytecodeDescriptor *descriptor; - sqInt end; - sqInt framelessStackDelta; - sqInt nExts; - sqInt numPushNils; - sqInt (* const numPushNilsFunction)(struct _BytecodeDescriptor *,sqInt,sqInt,sqInt) = squeakV3orSistaV1NumPushNils; - sqInt pc; - sqInt pushingNils; - - needsFrame = 0; - prevBCDescriptor = null; - methodOrBlockNumArgs = (blockStart->numArgs); - inBlock = InVanillaBlock; - pc = (blockStart->startpc); - end = ((blockStart->startpc)) + ((blockStart->span)); - framelessStackDelta = (nExts = (extA = (numExtB = (extB = 0)))); - pushingNils = 1; - while (pc < end) { - byte0 = (fetchByteofObject(pc, methodObj)) + bytecodeSetOffset; - descriptor = generatorAt(byte0); - if ((descriptor->isExtension)) { - loadSubsequentBytesForDescriptorat(descriptor, pc); - ((descriptor->generator))(); - } - if (!needsFrame) { - if ((((descriptor->needsFrameFunction)) == null) - || (((descriptor->needsFrameFunction))(framelessStackDelta))) { - needsFrame = 1; - } - else { - framelessStackDelta += (descriptor->stackDelta); - } - } - /* begin maybeNoteDescriptor:blockStart: */ - if ((descriptor->isInstVarRef)) { - (blockStart->hasInstVarRef = 1); - } - if (pushingNils - && (!((descriptor->isExtension)))) { - - /* Count the initial number of pushed nils acting as temp initializers. We can't tell - whether an initial pushNil is an operand reference or a temp initializer, except - when the pushNil is a jump target (has a fixup), which never happens: - self systemNavigation browseAllSelect: - [:m| | ebc | - (ebc := m embeddedBlockClosures - select: [:ea| ea decompile statements first isMessage] - thenCollect: [:ea| ea decompile statements first selector]) notEmpty - and: [(#(whileTrue whileFalse whileTrue: whileFalse:) intersection: ebc) notEmpty]] - or if the bytecode set has a push multiple nils bytecode. We simply count initial nils. - Rarely we may end up over-estimating. We will correct by checking the stack depth - at the end of the block in compileBlockBodies. */ - if (((numPushNils = numPushNilsFunction(descriptor, pc, nExts, methodObj))) > 0) { - assert(((descriptor->numBytes)) == 1); - (blockStart->numInitialNils = ((blockStart->numInitialNils)) + numPushNils); - } - else { - pushingNils = 0; - } - } - /* begin nextBytecodePCFor:at:exts:in: */ - pc = (pc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? ((descriptor->spanFunction))(descriptor, pc, nExts, methodObj) - : 0)); - if ((descriptor->isExtension)) { - nExts += 1; - } - else { - nExts = (extA = (numExtB = (extB = 0))); - } - prevBCDescriptor = descriptor; - } - if (!needsFrame) { - assert((framelessStackDelta >= 0) - && (((blockStart->numInitialNils)) >= framelessStackDelta)); - (blockStart->numInitialNils = ((blockStart->numInitialNils)) - framelessStackDelta); - } - return 0; -} - - -/* Scan the method (and all embedded blocks) to determine - - what the last bytecode is; extra bytes at the end of a method are used - to encode things like source pointers or temp names - - if the method needs a frame or not - - what are the targets of any backward branches. - - how many blocks it creates - Answer the block count or on error a negative error code */ - - /* StackToRegisterMappingCogit>>#scanMethod */ -static sqInt -scanMethod(void) -{ - BytecodeDescriptor *descriptor; - sqInt distance; - BytecodeFixup * fixup; - sqInt framelessStackDelta; - sqInt latestContinuation; - sqInt nExts; - sqInt numBlocks; - sqInt pc; - sqInt seenInstVarStore; - sqInt targetPC; - - needsFrame = (useTwoPaths = (seenInstVarStore = 0)); - prevBCDescriptor = null; - if ((primitiveIndex > 0) - && (isQuickPrimitiveIndex(primitiveIndex))) { - return 0; - } - pc = (latestContinuation = initialPC); - numBlocks = (framelessStackDelta = (nExts = (extA = (numExtB = (extB = 0))))); - while (pc <= endPC) { - byte0 = (fetchByteofObject(pc, methodObj)) + bytecodeSetOffset; - descriptor = generatorAt(byte0); - if ((descriptor->isExtension)) { - if (((descriptor->opcode)) == Nop) { - - /* unknown bytecode tag; see Cogit class>>#generatorTableFrom: */ - return EncounteredUnknownBytecode; - } - loadSubsequentBytesForDescriptorat(descriptor, pc); - ((descriptor->generator))(); - } - if (((descriptor->isReturn)) - && (pc >= latestContinuation)) { - endPC = pc; - } - if (!needsFrame) { - if ((((descriptor->needsFrameFunction)) == null) - || (((descriptor->needsFrameFunction))(framelessStackDelta))) { - - /* With immutability we win simply by avoiding a frame build if the receiver is young and not immutable. */ -# if IMMUTABILITY - if ((descriptor->is1ByteInstVarStore)) { - useTwoPaths = 1; - } - else { - needsFrame = 1; - useTwoPaths = 0; - } -# else // IMMUTABILITY - needsFrame = 1; - useTwoPaths = 0; -# endif - } - else { - - /* Without immutability we win if there are two or more stores and the receiver is new. */ - framelessStackDelta += (descriptor->stackDelta); -# if IMMUTABILITY -# else - if ((descriptor->is1ByteInstVarStore)) { - if (seenInstVarStore) { - useTwoPaths = 1; - } - else { - seenInstVarStore = 1; - } - } -# endif // IMMUTABILITY - } - } - if (isBranch(descriptor)) { - /* begin spanFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, pc, nExts, methodObj); - targetPC = (pc + ((descriptor->numBytes))) + distance; - if ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, pc, nExts, methodObj)) < 0)) { - /* begin initializeFixupAt: */ - fixup = fixupAtIndex(targetPC - initialPC); - /* begin initializeFixup: */ - (fixup->targetInstruction) = ((AbstractInstruction *) NeedsMergeFixupFlag); - /* begin setIsBackwardBranchFixup */ - (fixup->isTargetOfBackwardBranch) = 1; - } - else { - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - } - /* begin maybeDealWithUnsafeJumpForDescriptor:pc:latestContinuation: */ - /* latestContinuation = */ latestContinuation; - if ((descriptor->isBlockCreation)) { - numBlocks += 1; - /* begin spanFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, pc, nExts, methodObj); - targetPC = (pc + ((descriptor->numBytes))) + distance; - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - pc += (descriptor->numBytes); - nExts = ((descriptor->isExtension) - ? nExts + 1 - : (extA = (numExtB = (extB = 0)))); - prevBCDescriptor = descriptor; - } - return numBlocks; -} - - /* StackToRegisterMappingCogit>>#squeakV3orSistaV1PushNilSize:numInitialNils: */ -static sqInt NoDbgRegParms -squeakV3orSistaV1PushNilSizenumInitialNils(sqInt aMethodObj, sqInt numInitialNils) -{ - return (methodUsesAlternateBytecodeSet(aMethodObj) - ? /* begin sistaV1PushNilSize:numInitialNils: */ numInitialNils - : numInitialNils); -} - - /* StackToRegisterMappingCogit>>#squeakV3orSistaV1:Num:Push:Nils: */ -static sqInt NoDbgRegParms -squeakV3orSistaV1NumPushNils(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - return (bytecodeSetOffset == 0 - ? (((descriptor->generator)) == genPushConstantNilBytecode - ? 1 - : 0) - : (/* begin sistaV1:Num:Push:Nils: */ - (((descriptor->generator)) == genPushConstantNilBytecode - ? 1 - : 0))); -} - - /* StackToRegisterMappingCogit>>#ssAllocateRequiredRegMask:upThrough:upThroughNative: */ -static void NoDbgRegParms -ssAllocateRequiredRegMaskupThroughupThroughNative(sqInt requiredRegsMask, sqInt stackPtr, sqInt nativeStackPtr) -{ - sqInt i; - sqInt i1; - sqInt lastRequired; - sqInt lastRequiredNative; - sqInt liveRegs; - - lastRequired = -1; - - /* compute live regs while noting the last occurrence of required regs. - If these are not free we must spill from simSpillBase to last occurrence. - Note we are conservative here; we could allocate FPReg in frameless methods. */ - lastRequiredNative = -1; - /* begin registerMaskFor:and: */ - liveRegs = (1U << FPReg) | (1U << SPReg); - for (i = (((simSpillBase < 0) ? 0 : simSpillBase)); i <= stackPtr; i += 1) { - liveRegs = liveRegs | (registerMask(simStackAt(i))); - if ((((registerMask(simStackAt(i))) & requiredRegsMask) != 0)) { - lastRequired = i; - } - } - if (((liveRegs & requiredRegsMask) != 0)) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= lastRequired) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < lastRequired) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : lastRequired)); i1 <= lastRequired; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = lastRequired + 1; - } - assert(!(((((liveRegisters()) & requiredRegsMask) != 0)))); - } -} - - -/* Any occurrences on the stack of the value being stored (which is the top - of stack) - must be flushed, and hence any values colder than them stack. */ - - /* StackToRegisterMappingCogit>>#ssFlushUpThroughReceiverVariable: */ -static void NoDbgRegParms -ssFlushUpThroughReceiverVariable(sqInt slotIndex) -{ - sqInt i; - sqInt index; - - /* begin ssFlushUpThrough: */ - assert(simSpillBase >= 0); - for (index = (simStackPtr - 1); index >= simSpillBase; index += -1) { - if (((((simStackAt(index))->type)) == SSBaseOffset) - && (((((simStackAt(index))->registerr)) == ReceiverResultReg) - && ((((simStackAt(index))->offset)) == (slotOffsetOfInstVarIndex(slotIndex))))) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= index) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < index) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : index)); i <= index; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = index + 1; - } - goto l1; - } - } - l1: /* end ssFlushUpThrough: */; -} - - -/* Any occurrences on the stack of the value being stored (which is the top - of stack) - must be flushed, and hence any values colder than them stack. */ - - /* StackToRegisterMappingCogit>>#ssFlushUpThroughTemporaryVariable: */ -static void NoDbgRegParms -ssFlushUpThroughTemporaryVariable(sqInt tempIndex) -{ - sqInt i; - sqInt index; - sqInt offset; - - offset = ((simStackAt(tempIndex + 1))->offset); - assert(offset == (frameOffsetOfTemporary(tempIndex))); - /* begin ssFlushUpThrough: */ - assert(simSpillBase >= 0); - for (index = (simStackPtr - 1); index >= simSpillBase; index += -1) { - if (((((simStackAt(index))->type)) == SSBaseOffset) - && (((((simStackAt(index))->registerr)) == FPReg) - && ((((simStackAt(index))->offset)) == offset))) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= index) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < index) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : index)); i <= index; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = index + 1; - } - goto l1; - } - } - l1: /* end ssFlushUpThrough: */; -} - - /* StackToRegisterMappingCogit>>#ssPop: */ -static void NoDbgRegParms -ssPop(sqInt n) -{ - sqInt i; - - assert(((simStackPtr - n) >= methodOrBlockNumTemps) - || (((!needsFrame) - && ((simStackPtr - n) >= 0)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil()))); - simStackPtr -= n; - /* begin updateSimSpillBase */ - assert(((simSpillBase > methodOrBlockNumTemps) - && (simStackPtr >= methodOrBlockNumTemps)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - if (simSpillBase > simStackPtr) { - simSpillBase = simStackPtr + 1; - while (((simSpillBase - 1) > methodOrBlockNumTemps) - && (!(((simStackAt(simSpillBase - 1))->spilled)))) { - simSpillBase -= 1; - } - } - else { - while ((((simStackAt(simSpillBase))->spilled)) - && (simSpillBase <= simStackPtr)) { - simSpillBase += 1; - } - } - for (i = (methodOrBlockNumTemps + 1); i <= ((((simSpillBase - 1) < simStackPtr) ? (simSpillBase - 1) : simStackPtr)); i += 1) { - assert((((simStackAt(i))->spilled)) == 1); - } - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); -} - - /* StackToRegisterMappingCogit>>#ssPushAnnotatedConstant: */ -static sqInt NoDbgRegParms -ssPushAnnotatedConstant(sqInt literal) -{ - AbstractInstruction *abstractInstruction; - - ssPushConstant(literal); - /* begin annotateInstructionForBytecode */ - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (abstractInstruction->annotation = HasBytecodePC); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushBase:offset: */ -static sqInt NoDbgRegParms -ssPushBaseoffset(sqInt reg, sqInt offset) -{ - CogSimStackEntry * cascade0; - sqInt i; - - ssPush(1); - cascade0 = ssTop(); - (cascade0->type = SSBaseOffset); - (cascade0->spilled = 0); - (cascade0->registerr = reg); - (cascade0->offset = offset); - (cascade0->bcptr = bytecodePC); - /* begin updateSimSpillBase */ - assert(((simSpillBase > methodOrBlockNumTemps) - && (simStackPtr >= methodOrBlockNumTemps)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - if (simSpillBase > simStackPtr) { - simSpillBase = simStackPtr + 1; - while (((simSpillBase - 1) > methodOrBlockNumTemps) - && (!(((simStackAt(simSpillBase - 1))->spilled)))) { - simSpillBase -= 1; - } - } - else { - while ((((simStackAt(simSpillBase))->spilled)) - && (simSpillBase <= simStackPtr)) { - simSpillBase += 1; - } - } - for (i = (methodOrBlockNumTemps + 1); i <= ((((simSpillBase - 1) < simStackPtr) ? (simSpillBase - 1) : simStackPtr)); i += 1) { - assert((((simStackAt(i))->spilled)) == 1); - } - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushConstant: */ -static sqInt NoDbgRegParms -ssPushConstant(sqInt literal) -{ - CogSimStackEntry * cascade0; - sqInt i; - - ssPush(1); - cascade0 = ssTop(); - (cascade0->type = SSConstant); - (cascade0->spilled = 0); - (cascade0->constant = literal); - (cascade0->bcptr = bytecodePC); - /* begin updateSimSpillBase */ - assert(((simSpillBase > methodOrBlockNumTemps) - && (simStackPtr >= methodOrBlockNumTemps)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - if (simSpillBase > simStackPtr) { - simSpillBase = simStackPtr + 1; - while (((simSpillBase - 1) > methodOrBlockNumTemps) - && (!(((simStackAt(simSpillBase - 1))->spilled)))) { - simSpillBase -= 1; - } - } - else { - while ((((simStackAt(simSpillBase))->spilled)) - && (simSpillBase <= simStackPtr)) { - simSpillBase += 1; - } - } - for (i = (methodOrBlockNumTemps + 1); i <= ((((simSpillBase - 1) < simStackPtr) ? (simSpillBase - 1) : simStackPtr)); i += 1) { - assert((((simStackAt(i))->spilled)) == 1); - } - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushDesc: */ -static sqInt NoDbgRegParms -ssPushDesc(SimStackEntry simStackEntry) -{ - sqInt i; - - if (((simStackEntry.type)) == SSSpill) { - (simStackEntry.type = SSBaseOffset); - } - (simStackEntry.spilled = 0); - (simStackEntry.bcptr = bytecodePC); - simStack[(simStackPtr += 1)] = simStackEntry; - /* begin updateSimSpillBase */ - assert(((simSpillBase > methodOrBlockNumTemps) - && (simStackPtr >= methodOrBlockNumTemps)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - if (simSpillBase > simStackPtr) { - simSpillBase = simStackPtr + 1; - while (((simSpillBase - 1) > methodOrBlockNumTemps) - && (!(((simStackAt(simSpillBase - 1))->spilled)))) { - simSpillBase -= 1; - } - } - else { - while ((((simStackAt(simSpillBase))->spilled)) - && (simSpillBase <= simStackPtr)) { - simSpillBase += 1; - } - } - for (i = (methodOrBlockNumTemps + 1); i <= ((((simSpillBase - 1) < simStackPtr) ? (simSpillBase - 1) : simStackPtr)); i += 1) { - assert((((simStackAt(i))->spilled)) == 1); - } - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushRegister: */ -static sqInt NoDbgRegParms -ssPushRegister(sqInt reg) -{ - CogSimStackEntry * cascade0; - sqInt i; - - ssPush(1); - cascade0 = ssTop(); - (cascade0->type = SSRegister); - (cascade0->spilled = 0); - (cascade0->registerr = reg); - (cascade0->bcptr = bytecodePC); - /* begin updateSimSpillBase */ - assert(((simSpillBase > methodOrBlockNumTemps) - && (simStackPtr >= methodOrBlockNumTemps)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - if (simSpillBase > simStackPtr) { - simSpillBase = simStackPtr + 1; - while (((simSpillBase - 1) > methodOrBlockNumTemps) - && (!(((simStackAt(simSpillBase - 1))->spilled)))) { - simSpillBase -= 1; - } - } - else { - while ((((simStackAt(simSpillBase))->spilled)) - && (simSpillBase <= simStackPtr)) { - simSpillBase += 1; - } - } - for (i = (methodOrBlockNumTemps + 1); i <= ((((simSpillBase - 1) < simStackPtr) ? (simSpillBase - 1) : simStackPtr)); i += 1) { - assert((((simStackAt(i))->spilled)) == 1); - } - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPush: */ -static void NoDbgRegParms -ssPush(sqInt n) -{ - simStackPtr += n; -} - - /* StackToRegisterMappingCogit>>#ssSelfDescriptor */ -static SimStackEntry -ssSelfDescriptor(void) -{ - return simStack[0]; -} - - -/* In addition to ssStorePop:toReg:, if this is a store and not - a popInto I change the simulated stack to use the register - for the top value */ - - /* StackToRegisterMappingCogit>>#ssStoreAndReplacePop:toReg: */ -static void NoDbgRegParms -ssStoreAndReplacePoptoReg(sqInt popBoolean, sqInt reg) -{ - char topSpilled; - - topSpilled = ((ssTop())->spilled); - ssStorePoptoReg(popBoolean - || (topSpilled), reg); - if (!popBoolean) { - if (!topSpilled) { - ssPop(1); - } - ssPushRegister(reg); - } -} - - -/* Store or pop the top simulated stack entry to a register. - Use preferredReg if the entry is not itself a register. - Answer the actual register the result ends up in. */ - - /* StackToRegisterMappingCogit>>#ssStorePop:toPreferredReg: */ -static sqInt NoDbgRegParms -ssStorePoptoPreferredReg(sqInt popBoolean, sqInt preferredReg) -{ - sqInt actualReg; - - actualReg = preferredReg; - if ((((ssTop())->type)) == SSRegister) { - assert(!(((ssTop())->spilled))); - actualReg = ((ssTop())->registerr); - } - ssStorePoptoReg(popBoolean, actualReg); - return actualReg; -} - - -/* Store or pop the top simulated stack entry to a register. - N.B.: popToReg: and storeToReg: does not generate anything if - it moves a register to the same register. */ - - /* StackToRegisterMappingCogit>>#ssStorePop:toReg: */ -static void NoDbgRegParms -ssStorePoptoReg(sqInt popBoolean, sqInt reg) -{ - if (popBoolean) { - popToReg(ssTop(), reg); - ssPop(1); - } - else { - storeToReg(ssTop(), reg); - } -} - - /* StackToRegisterMappingCogit>>#ssTop */ -static CogSimStackEntry * -ssTop(void) -{ - return simStackAt(simStackPtr); -} - - /* StackToRegisterMappingCogit>>#ssValue: */ -static CogSimStackEntry * NoDbgRegParms -ssValue(sqInt n) -{ - return simStackAt(simStackPtr - n); -} - - /* StackToRegisterMappingCogit>>#stackEntryIsBoolean: */ -static sqInt NoDbgRegParms -stackEntryIsBoolean(CogSimStackEntry *simStackEntry) -{ - return (((simStackEntry->type)) == SSConstant) - && ((((simStackEntry->constant)) == (trueObject())) - || (((simStackEntry->constant)) == (falseObject()))); -} - - -/* Answer if the stack is valid up to, but not including, simSpillBase. */ - - /* StackToRegisterMappingCogit>>#tempsValidAndVolatileEntriesSpilled */ -static sqInt -tempsValidAndVolatileEntriesSpilled(void) -{ - sqInt culprit; - sqInt i; - - culprit = 0; - for (i = 1; i <= methodOrBlockNumTemps; i += 1) { - if (!(((((simStackAt(i))->type)) == SSBaseOffset) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil()))) { - if (!culprit) { - culprit = i; - } - return 0; - } - } - for (i = (methodOrBlockNumTemps + 1); i < simSpillBase; i += 1) { - if (!(((simStackAt(i))->spilled))) { - if (!culprit) { - culprit = i; - } - return 0; - } - } - return 1; -} - - -/* If the sequence of bytecodes is - push: (Array new: 1) - popIntoTemp: tempIndex - pushConstant: const or pushTemp: n - popIntoTemp: 0 inVectorAt: tempIndex - collapse this into - tempAt: tempIndex put: {const or temp} - and answer true, otherwise answer false. - One might think that we should look for a sequence of more than - one pushes and pops but this is extremely rare. - Exclude pushRcvr: n to avoid potential complications with context inst - vars. */ - - /* StackToRegisterMappingCogit>>#tryCollapseTempVectorInitializationOfSize: */ -static sqInt NoDbgRegParms -tryCollapseTempVectorInitializationOfSize(sqInt slots) -{ - sqInt pc; - sqInt pc1; - sqInt pc2; - BytecodeDescriptor *pushArrayDesc; - BytecodeDescriptor *pushValueDesc; - sqInt reg; - sqInt remoteTempIndex; - BytecodeDescriptor *storeArrayDesc; - BytecodeDescriptor *storeValueDesc; - sqInt tempIndex; - - if (slots != 1) { - return 0; - } - /* begin generatorForPC: */ - pushArrayDesc = generatorAt(bytecodeSetOffset + (fetchByteofObject(bytecodePC, methodObj))); - assert(((pushArrayDesc->generator)) == genPushNewArrayBytecode); - /* begin generatorForPC: */ - pc = bytecodePC + ((pushArrayDesc->numBytes)); - storeArrayDesc = generatorAt(bytecodeSetOffset + (fetchByteofObject(pc, methodObj))); - if (((storeArrayDesc->generator)) == genStoreAndPopTemporaryVariableBytecode) { - tempIndex = (fetchByteofObject(bytecodePC + ((pushArrayDesc->numBytes)), methodObj)) & 7; - } - else { - if (!(((storeArrayDesc->generator)) == genLongStoreAndPopTemporaryVariableBytecode)) { - return 0; - } - tempIndex = fetchByteofObject((bytecodePC + ((pushArrayDesc->numBytes))) + 1, methodObj); - } - /* begin generatorForPC: */ - pc1 = (bytecodePC + ((pushArrayDesc->numBytes))) + ((storeArrayDesc->numBytes)); - pushValueDesc = generatorAt(bytecodeSetOffset + (fetchByteofObject(pc1, methodObj))); - if (!((((pushValueDesc->generator)) == genPushLiteralConstantBytecode) - || ((((pushValueDesc->generator)) == genPushQuickIntegerConstantBytecode) - || (((pushValueDesc->generator)) == genPushTemporaryVariableBytecode)))) { - return 0; - } - /* begin generatorForPC: */ - pc2 = ((bytecodePC + ((pushArrayDesc->numBytes))) + ((storeArrayDesc->numBytes))) + ((pushValueDesc->numBytes)); - storeValueDesc = generatorAt(bytecodeSetOffset + (fetchByteofObject(pc2, methodObj))); - remoteTempIndex = fetchByteofObject((((bytecodePC + ((pushArrayDesc->numBytes))) + ((storeArrayDesc->numBytes))) + ((pushValueDesc->numBytes))) + 2, methodObj); - if (!((((storeValueDesc->generator)) == genStoreAndPopRemoteTempLongBytecode) - && (tempIndex == remoteTempIndex))) { - return 0; - } - genNewArrayOfSizeinitialized(1, 0); - evaluateat(pushValueDesc, (bytecodePC + ((pushArrayDesc->numBytes))) + ((storeArrayDesc->numBytes))); - reg = ssStorePoptoPreferredReg(1, TempReg); - genStoreSourceRegslotIndexintoNewObjectInDestReg(reg, 0, ReceiverResultReg); - ssPushRegister(ReceiverResultReg); - evaluateat(storeArrayDesc, bytecodePC + ((pushArrayDesc->numBytes))); - - /* + pushArrayDesc numBytes this gets added by nextBytecodePCFor:at:exts:in: */ - bytecodePC = ((bytecodePC + ((storeArrayDesc->numBytes))) + ((pushValueDesc->numBytes))) + ((storeValueDesc->numBytes)); - return 1; -} - - /* StackToRegisterMappingCogit>>#violatesEnsureSpilledSpillAssert */ -static sqInt -violatesEnsureSpilledSpillAssert(void) -{ - return 1; -} - - -/* Used when ReceiverResultReg is allocated for other than simSelf, and - there may be references to ReceiverResultReg which need to be spilled. */ - - /* StackToRegisterMappingCogit>>#voidReceiverResultRegContainsSelf */ -static void -voidReceiverResultRegContainsSelf(void) -{ - sqInt i; - sqInt i1; - sqInt spillIndex; - - /* begin voidReceiverOptStatus */ - ((simSelf())->liveRegister = NoReg); - spillIndex = 0; - for (i = ((((methodOrBlockNumTemps + 1) < simSpillBase) ? simSpillBase : (methodOrBlockNumTemps + 1))); i <= simStackPtr; i += 1) { - if ((registerOrNone(simStackAt(i))) == ReceiverResultReg) { - spillIndex = i; - } - } - if (spillIndex > 0) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= spillIndex) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < spillIndex) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : spillIndex)); i1 <= spillIndex; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = spillIndex + 1; - } - } -} diff --git a/spursrc/vm/cointerp.c b/spursrc/vm/cointerp.c index 0aa0b282b6..e85814437b 100644 --- a/spursrc/vm/cointerp.c +++ b/spursrc/vm/cointerp.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - CoInterpreter VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CoInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 " __DATE__ ; +static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -486,6 +486,7 @@ extern void ceSendaboveClassBindingtonumArgs(sqInt selector, sqInt methodClassBi extern sqInt ceSendabovetonumArgs(sqInt selector, sqInt methodClass, sqInt rcvr, sqInt numArgs); extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethod); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); @@ -661,7 +662,6 @@ static void primitiveExitCriticalSection(void); static void primitiveFlushCacheByMethod(void); static void primitiveFlushCacheBySelector(void); extern usqInt primitiveFunctionPointerAddress(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); EXPORT(sqInt) primitiveMethodPCData(void); static void primitiveMethodXray(void); EXPORT(void) primitiveMinimumUnusedHeadroom(void); @@ -1182,7 +1182,6 @@ static sqInt NoDbgRegParms isPureBitsFormat(sqInt format); extern sqInt isReallyYoung(sqInt oop); static sqInt NoDbgRegParms isRemembered(sqInt objOop); static sqInt NoDbgRegParms isSegmentBridge(sqInt objOop); -static sqInt NoDbgRegParms isSemaphoreOop(sqInt anOop); extern sqInt isShorts(sqInt oop); extern sqInt isUnambiguouslyForwarder(sqInt objOop); extern sqInt isUnmarked(sqInt objOop); @@ -1246,7 +1245,7 @@ static sqInt noUnscannedEphemerons(void); static sqInt NoDbgRegParms numBytesOfBitsformat(sqInt objOop, sqInt format); static sqInt NoDbgRegParms numBytesOfBytes(sqInt objOop); extern sqInt numBytesOf(sqInt objOop); -extern sqInt numPointerSlotsOf(sqInt objOop); +extern usqInt numPointerSlotsOf(sqInt objOop); static usqInt NoDbgRegParms numSlotsOfAny(sqInt objOop); extern usqInt numSlotsOf(sqInt objOop); static sqInt NoDbgRegParms numStrongSlotsOfInephemeral(sqInt objOop); @@ -1408,7 +1407,6 @@ EXPORT(sqInt) callbackLeave(sqInt cbID); extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHeader); extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkForEventsMayContextSwitch(sqInt mayContextSwitch); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); @@ -1690,7 +1688,6 @@ static sqInt NoDbgRegParms updateDisplayLeftTopRightBottom(sqInt l, sqInt t, sqI static sqInt NoDbgRegParms validBCPCinMethod(sqInt thePC, usqInt aMethod); static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, char *fp); static sqInt validStackPageBaseFrames(void); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt wakeHighestPriority(void); static sqInt NeverInline writeImageFileIO(void); static usqInt NoDbgRegParms cloneContext(sqInt aContext); @@ -1713,7 +1710,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1788,15 +1784,14 @@ _iss usqInt lastMobileObject; _iss sqInt tempOop; _iss sqInt numClassTablePages; _iss sqInt lkupClass; -_iss sqInt futureSurvivorStart; _iss sqInt profileProcess; -_iss sqInt profileSemaphore; +_iss sqInt futureSurvivorStart; _iss sqInt mournQueue; _iss sqInt numRememberedEphemerons; +_iss sqInt profileMethod; _iss sqInt jmpDepth; _iss sqInt mobileStart; -_iss sqInt profileMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; +_iss sqInt profileSemaphore; _iss sqInt growHeadroom; _iss sqInt tenureThreshold; _iss sqInt lastCoggableInterpretedBlockMethod; @@ -1804,7 +1799,6 @@ _iss sqInt lastUncoggableInterpretedBlockMethod; _iss char * objStackInvalidBecause; _iss sqInt sweepIndex; _iss sqInt ephemeronList; -_iss sqInt longRunningPrimitiveCheckMethod; _iss sqInt tenureCriterion; _iss usqInt totalHeapSizeIncludingBridges; _iss sqInt becomeEffectsFlags; @@ -1860,7 +1854,6 @@ _iss sqInt freeSpaceCheckOopToIgnore; _iss usqInt heapSizeAtPreviousGC; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss sqInt methodDictLinearSearchLimit; _iss sqInt statGrowMemory; _iss sqInt statMaxPageCountWhenMapping; @@ -1872,7 +1865,6 @@ _iss sqInt extraFramesToMoveOnOverflow; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; _iss sqInt inFFIFlags; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss sqInt refCountToShrinkRT; _iss sqInt signalLowSpace; @@ -1902,16 +1894,14 @@ _iss sqInt preferredPinningSegment; _iss sqInt statCoalesces; _iss sqInt theUnknownShort; _iss usqLong nextWakeupUsecs; -_iss usqLong statGCEndUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; -_iss usqLong statCheckForEvents; -_iss usqLong gcStartUsecs; _iss sqLong oldSpaceUsePriorToScavenge; +_iss usqLong statGCEndUsecs; _iss usqLong statIOProcessEvents; +_iss usqLong gcStartUsecs; _iss usqLong statAllocatedBytes; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statCompactionUsecs; _iss usqLong statForceInterruptCheck; _iss usqLong statFullGCUsecs; @@ -1925,9 +1915,11 @@ _iss usqLong statSweepUsecs; _iss usqLong statCodeCompactionUsecs; _iss usqLong statSGCDeltaUsecs; _iss usqLong gcSweepEndUsecs; -_iss usqLong longRunningPrimitiveGCUsecs; _iss usqLong statIGCDeltaUsecs; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; _iss usqLong statFGCDeltaUsecs; _iss usqLong statIncrGCUsecs; _iss SpurContiguousObjStack savedFirstFieldsSpace; @@ -2604,7 +2596,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Open Smalltalk Cog[Spur] VM [CoInterpreterPrimitives VMMaker.oscog-eem.3024]"; +const char *interpreterVersion = "Open Smalltalk Cog[Spur] VM [CoInterpreterPrimitives VMMaker.oscog-eem.3031]"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */; char primitiveDoMixedArithmetic = 1; char expensiveAsserts = 0; @@ -15278,6 +15270,27 @@ ceStackOverflow(sqInt contextSwitchIfNotNil) error("should not be reached"); } + +/* A primitive has succeeded and the nextProfileTick has been reached (all + done in machine code). + Now take a sample. c.f. checkProfileTick: */ + + /* CoInterpreter>>#ceTakeProfileSample: */ +void +ceTakeProfileSample(CogMethod *aCogMethod) +{ DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt objOop; + sqInt objOop1; + + /* begin fetchPointer:ofObject: */ + objOop1 = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(SchedulerAssociation) << (shiftForWord()))))); + objOop = longAt((objOop1 + BaseHeaderSize) + (((int)((usqInt)(ValueIndex) << (shiftForWord()))))); + GIV(profileProcess) = longAt((objOop + BaseHeaderSize) + (((int)((usqInt)(ActiveProcessIndex) << (shiftForWord()))))); + GIV(profileMethod) = (aCogMethod->methodObject); + forceInterruptCheck(); + GIV(nextProfileTick) = 0; +} + /* CoInterpreter>>#ceTraceBlockActivation */ void ceTraceBlockActivation(void) @@ -17273,24 +17286,6 @@ void forceInterruptCheckFromHeartbeat(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; sqLowLevelMFence(); if (GIV(deferSmash)) { GIV(deferredSmash) = 1; @@ -23686,56 +23681,6 @@ primitiveFunctionPointerAddress(void) return ((usqInt)((&primitiveFunctionPointer))); } - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* CoInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; - int flushState; - sqInt sema; - char *sp; - - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (sema == GIV(nilObj)) { - flushState = GIV(longRunningPrimitiveCheckSemaphore) != null; - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - flushState = GIV(longRunningPrimitiveCheckSemaphore) == null; - if (!(((!(sema & (tagMask())))) - && (((longAt(sema)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(ClassSemaphore) << (shiftForWord())))))))))) { - return (GIV(primFailCode) = PrimErrBadArgument); - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(longRunningPrimitiveCheckSemaphore) == null)) - || (((stackValue(0)) == GIV(longRunningPrimitiveCheckSemaphore)) - && (isSemaphoreOop(sema)))); - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - if (flushState) { - ceInvokeInterpret(); - } - return 0; -} - /* CoInterpreterPrimitives>>#primitiveMethodPCData */ EXPORT(sqInt) primitiveMethodPCData(void) @@ -24048,14 +23993,9 @@ primitiveObjectAtPut(void) EXPORT(sqInt) primitiveProfileSemaphore(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; int flushState; sqInt sema; - char *sp; - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); if (sema == GIV(nilObj)) { flushState = GIV(profileSemaphore) != GIV(nilObj); @@ -24067,28 +24007,21 @@ primitiveProfileSemaphore(void) return (GIV(primFailCode) = PrimErrBadArgument); } } + GIV(profileSemaphore) = sema; /* If we've switched profiling on or off we must void machine code (and machine code pcs in contexts) since we will start or stop testing the profile clock in machine code primitive invocations, and so generate slightly different code from here on in. */ - GIV(profileSemaphore) = sema; - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(profileSemaphore) == (nilObject()))) - || (((stackValue(0)) == GIV(profileSemaphore)) - && (isSemaphoreOop(sema)))); - } GIV(profileProcess) = (GIV(profileMethod) = GIV(nilObj)); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; if (flushState) { - ceInvokeInterpret(); + flushExternalPrimitives(); + } + else { + /* begin methodReturnReceiver */ + assert(!((failed()))); + /* begin pop: */ + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; } return 0; } @@ -32787,26 +32720,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -35512,15 +35447,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -35538,15 +35468,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -35570,39 +35495,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((integerPointer & 1)) { - deltaTicks = (integerPointer >> 1); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((deltaTicks & 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 1)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -39039,7 +38943,7 @@ followForwardedObjectFieldstoDepth(sqInt objOop, sqInt depth) sqInt header1; sqInt i; sqInt numLiterals; - sqInt numSlots; + usqInt numSlots; usqInt numSlots1; sqInt oop; sqInt referent; @@ -46343,7 +46247,7 @@ copyObjtoAddrstopAtsavedFirstFieldsindex(sqInt objOop, sqInt segAddr, sqInt endS sqInt iLimiT; sqInt methodHeader; sqInt numLiterals; - sqInt numMediatedSlots; + usqInt numMediatedSlots; usqInt numSlots; usqInt numSlots1; sqInt oop; @@ -46375,7 +46279,7 @@ copyObjtoAddrstopAtsavedFirstFieldsindex(sqInt objOop, sqInt segAddr, sqInt endS here but that requires access to framePointer. */ /* begin numSlotsOfMarriedContext: */ contextSize = stackPointerIndexForFrame(frameOfMarriedContext(objOop)); - numMediatedSlots = CtxtTempFrameStart + contextSize; + numMediatedSlots = ((sqInt) (CtxtTempFrameStart + contextSize)); for (i1 = 0; i1 < numMediatedSlots; i1 += 1) { oop = fetchPointerofMarriedContext(i1, objOop); assert(!(isOopForwarded(copy))); @@ -49721,14 +49625,6 @@ isSegmentBridge(sqInt objOop) return ((longAt(objOop)) & (classIndexMask())) == (segmentBridgePun()); } - /* SpurMemoryManager>>#isSemaphoreOop: */ -static sqInt NoDbgRegParms -isSemaphoreOop(sqInt anOop) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - return ((!(anOop & (tagMask())))) - && (((longAt(anOop)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(ClassSemaphore) << (shiftForWord())))))))); -} - /* Answer if the argument contains only indexable 16-bit half words (no oops). See comment in formatOf: @@ -51996,8 +51892,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) sqInt referent; sqInt referent1; sqInt referent2; - sqInt referent3; - sqInt referent4; sqInt sizeOfUnusedEden; StackPage *thePage; @@ -52125,38 +52019,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - if ((!((longAt(GIV(longRunningPrimitiveCheckMethod))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckMethod))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((GIV(longRunningPrimitiveCheckMethod) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent3 & (tagMask())))) - && ((!((longAt(referent3)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((referent3 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckMethod) = referent3; - } - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - if ((!((longAt(GIV(longRunningPrimitiveCheckSemaphore))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckSemaphore))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((GIV(longRunningPrimitiveCheckSemaphore) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent4 & (tagMask())))) - && ((!((longAt(referent4)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((referent4 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckSemaphore) = referent4; - } - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -52808,7 +52670,7 @@ numBytesOf(sqInt objOop) Works with CompiledMethods, as well as ordinary objects. */ /* SpurMemoryManager>>#numPointerSlotsOf: */ -sqInt +usqInt numPointerSlotsOf(sqInt objOop) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt contextSize; @@ -55803,7 +55665,7 @@ printReferencesTo(sqInt anOop) assert((ReceiverIndex + ((sp >> 1))) < (lengthOf(obj1))); contextSize = (sp >> 1); l9: /* end fetchStackPointerOf: */; - i = CtxtTempFrameStart + contextSize; + i = ((usqInt) (CtxtTempFrameStart + contextSize)); goto l10; } /* begin numSlotsOf: */ @@ -55836,7 +55698,7 @@ printReferencesTo(sqInt anOop) /* begin literalCountOfMethodHeader: */ assert((header & 1)); numLiterals = ((header >> 1)) & AlternateHeaderNumLiteralsMask; - i = numLiterals + LiteralStart; + i = ((usqInt) (numLiterals + LiteralStart)); l10: /* end numPointerSlotsOf: */; while (((i -= 1)) >= 0) { if (anOop == (longAt((obj1 + BaseHeaderSize) + (((sqInt)((usqInt)(i) << (shiftForWord()))))))) { @@ -58980,10 +58842,10 @@ updatePointers(void) sqInt numLiterals1; sqInt numLiterals2; sqInt numLiterals3; - sqInt numPointerSlots; - sqInt numPointerSlots1; - sqInt numPointerSlots2; - sqInt numPointerSlots3; + usqInt numPointerSlots; + usqInt numPointerSlots1; + usqInt numPointerSlots2; + usqInt numPointerSlots3; usqInt numSlots; usqInt numSlots1; usqInt numSlots11; @@ -59561,7 +59423,7 @@ updatePointersInsavedFirstFieldPointer(sqInt obj, sqInt firstFieldPtr) assert((ReceiverIndex + ((sp >> 1))) < (lengthOf(obj))); contextSize = (sp >> 1); l6: /* end fetchStackPointerOf: */; - numPointerSlots = CtxtTempFrameStart + contextSize; + numPointerSlots = ((usqInt) (CtxtTempFrameStart + contextSize)); goto l10; } /* begin numSlotsOf: */ @@ -59591,7 +59453,7 @@ updatePointersInsavedFirstFieldPointer(sqInt obj, sqInt firstFieldPtr) /* begin literalCountOfMethodHeader: */ assert((header & 1)); numLiterals = ((header >> 1)) & AlternateHeaderNumLiteralsMask; - numPointerSlots = numLiterals + LiteralStart; + numPointerSlots = ((usqInt) (numLiterals + LiteralStart)); l10: /* end numPointerSlotsWhileCompactingOf:withFormat:savedFirstFieldPointer: */; if ((fmt <= 5 /* lastPointerFormat */) && (numPointerSlots > 0)) { @@ -60142,7 +60004,7 @@ prepareForSnapshot(void) sqInt limit; sqInt newEndOfMemory; sqInt next; - sqInt node; + usqInt node; SpurSegmentInfo *seg; sqInt smallChild; sqInt treeNode; @@ -60973,33 +60835,6 @@ checkAllAccessibleObjectsOkay(void) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -61090,9 +60925,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { /* begin signalLowSpace: */ GIV(signalLowSpace) = 0; @@ -66114,23 +65946,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i = 1; i <= GIV(jmpDepth); i += 1) { oop = GIV(suspendedCallbacks)[i]; @@ -70038,8 +69853,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -70068,18 +69883,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -73289,22 +73106,6 @@ validStackPageBaseFrames(void) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Return the highest priority process that is ready to run. To save time looking at many empty lists before finding a runnable process the VM maintains a variable holding the @@ -75934,74 +75735,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((addressCouldBeObj(lrpcm)) - && ((!(((longAt(lrpcm)) & (classIndexMask())) == (isFreeObjectClassIndexPun()))) - && (((((usqInt)((longAt(lrpcm)))) >> (formatShift())) & (formatMask())) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - assert(!(isForwarded(result))); - if ((assert(isNonImmediate(result)), - oopisGreaterThanOrEqualTo(result, GIV(oldSpaceStart)))) { - - /* most stores into young objects */ - if (((!(lrpcm & (tagMask())))) - && (oopisLessThan(lrpcm, GIV(newSpaceLimit)))) { - /* begin possibleRootStoreInto: */ - if (!(((((usqInt)((longAt(result)))) >> (rememberedBitShift())) & 1) != 0)) { - remember(result); - } - } - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 1) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 1) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -78493,15 +78226,13 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveGreaterOrEqualLargeIntegers\000\377\000", (void*)primitiveGreaterOrEqualLargeIntegers}, {(void*)_m, "primitiveGreaterThanLargeIntegers\000\377\000", (void*)primitiveGreaterThanLargeIntegers}, {(void*)_m, "primitiveHeartbeatFrequency\000\377\000", (void*)primitiveHeartbeatFrequency}, - {(void*)_m, "primitiveHighResClock\000\377\000", (void*)primitiveHighResClock}, + {(void*)_m, "primitiveHighResClock\000\377\001", (void*)primitiveHighResClock}, {(void*)_m, "primitiveImageFormatVersion\000\377\000", (void*)primitiveImageFormatVersion}, {(void*)_m, "primitiveInterruptChecksPerMSec\000\377\000", (void*)primitiveInterruptChecksPerMSec}, {(void*)_m, "primitiveIsBigEnder\000\377\000", (void*)primitiveIsBigEnder}, {(void*)_m, "primitiveIsWindowObscured\000\377\000", (void*)primitiveIsWindowObscured}, {(void*)_m, "primitiveLessOrEqualLargeIntegers\000\377\000", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers\000\377\000", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive\000\377\000", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore\000\000\000", (void*)primitiveLongRunningPrimitiveSemaphore}, {(void*)_m, "primitiveMethodPCData\000\000\000", (void*)primitiveMethodPCData}, {(void*)_m, "primitiveMillisecondClockMask\000\377\000", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveMinimumUnusedHeadroom\000\377\000", (void*)primitiveMinimumUnusedHeadroom}, @@ -78509,10 +78240,10 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveMultiplyLargeIntegers\000\000\000", (void*)primitiveMultiplyLargeIntegers}, {(void*)_m, "primitiveNotEqualLargeIntegers\000\377\000", (void*)primitiveNotEqualLargeIntegers}, {(void*)_m, "primitivePathToUsing\000\000\000", (void*)primitivePathToUsing}, - {(void*)_m, "primitiveProfilePrimitive\000\377\000", (void*)primitiveProfilePrimitive}, - {(void*)_m, "primitiveProfileSample\000\377\000", (void*)primitiveProfileSample}, + {(void*)_m, "primitiveProfilePrimitive\000\377\001", (void*)primitiveProfilePrimitive}, + {(void*)_m, "primitiveProfileSample\000\377\001", (void*)primitiveProfileSample}, {(void*)_m, "primitiveProfileSemaphore\000\000\000", (void*)primitiveProfileSemaphore}, - {(void*)_m, "primitiveProfileStart\000\000\000", (void*)primitiveProfileStart}, + {(void*)_m, "primitiveProfileStart\000\000\001", (void*)primitiveProfileStart}, {(void*)_m, "primitiveQuoLargeIntegers\000\000\000", (void*)primitiveQuoLargeIntegers}, {(void*)_m, "primitiveRemLargeIntegers\000\000\000", (void*)primitiveRemLargeIntegers}, {(void*)_m, "primitiveScreenDepth\000\377\000", (void*)primitiveScreenDepth}, diff --git a/spursrc/vm/cointerp.h b/spursrc/vm/cointerp.h index d4c4c523c2..cb24eef853 100644 --- a/spursrc/vm/cointerp.h +++ b/spursrc/vm/cointerp.h @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ @@ -49,6 +49,7 @@ extern void ceSendaboveClassBindingtonumArgs(sqInt selector, sqInt methodClassBi extern sqInt ceSendabovetonumArgs(sqInt selector, sqInt methodClass, sqInt rcvr, sqInt numArgs); extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethod); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); @@ -245,7 +246,7 @@ extern sqInt minSlotsForShortening(void); extern sqInt nilObject(void); extern sqInt nonIndexablePointerFormat(void); extern sqInt numBytesOf(sqInt objOop); -extern sqInt numPointerSlotsOf(sqInt objOop); +extern usqInt numPointerSlotsOf(sqInt objOop); extern usqInt numSlotsOf(sqInt objOop); extern sqInt numStrongSlotsOfWeakling(sqInt objOop); extern sqInt objectAfter(sqInt objOop); diff --git a/spursrc/vm/cointerpmt.c b/spursrc/vm/cointerpmt.c index 8a46f58cf5..756269fe20 100644 --- a/spursrc/vm/cointerpmt.c +++ b/spursrc/vm/cointerpmt.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - CoInterpreterMT VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CoInterpreterMT VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "CoInterpreterMT VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 " __DATE__ ; +static char __buildInfo[] = "CoInterpreterMT VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -542,6 +542,7 @@ extern void ceSendaboveClassBindingtonumArgs(sqInt selector, sqInt methodClassBi extern sqInt ceSendabovetonumArgs(sqInt selector, sqInt methodClass, sqInt rcvr, sqInt numArgs); extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethod); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); @@ -741,7 +742,6 @@ static void primitiveExitCriticalSection(void); static void primitiveFlushCacheByMethod(void); static void primitiveFlushCacheBySelector(void); extern usqInt primitiveFunctionPointerAddress(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); EXPORT(sqInt) primitiveMethodPCData(void); static void primitiveMethodXray(void); EXPORT(void) primitiveMinimumUnusedHeadroom(void); @@ -1262,7 +1262,6 @@ static sqInt NoDbgRegParms isPureBitsFormat(sqInt format); extern sqInt isReallyYoung(sqInt oop); static sqInt NoDbgRegParms isRemembered(sqInt objOop); static sqInt NoDbgRegParms isSegmentBridge(sqInt objOop); -static sqInt NoDbgRegParms isSemaphoreOop(sqInt anOop); extern sqInt isShorts(sqInt oop); extern sqInt isUnambiguouslyForwarder(sqInt objOop); extern sqInt isUnmarked(sqInt objOop); @@ -1488,7 +1487,6 @@ EXPORT(sqInt) callbackLeave(sqInt cbID); extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHeader); extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); static sqInt checkInterpreterIntegrity(void); @@ -1765,7 +1763,6 @@ static sqInt NoDbgRegParms updateDisplayLeftTopRightBottom(sqInt l, sqInt t, sqI static sqInt NoDbgRegParms validBCPCinMethod(sqInt thePC, usqInt aMethod); static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, char *fp); static sqInt validStackPageBaseFrames(void); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt NeverInline writeImageFileIO(void); static usqInt NoDbgRegParms cloneContext(sqInt aContext); static sqInt NoDbgRegParms fieldOrSenderFPofContext(sqInt index, sqInt contextObj); @@ -1787,7 +1784,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1863,17 +1859,16 @@ _iss usqInt lastMobileObject; _iss sqInt tempOop; _iss sqInt numClassTablePages; _iss sqInt lkupClass; +_iss sqInt profileProcess; _iss sqInt futureSurvivorStart; _iss sqInt numThreads; -_iss sqInt profileProcess; -_iss sqInt profileSemaphore; _iss CogVMThread * disowningVMThread; _iss sqInt mournQueue; _iss sqInt numRememberedEphemerons; +_iss sqInt profileMethod; +_iss sqInt profileSemaphore; _iss sqInt jmpDepth; _iss sqInt mobileStart; -_iss sqInt profileMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; _iss CogVMThread ** threads; _iss sqInt growHeadroom; _iss sqInt processHasThreadId; @@ -1883,7 +1878,6 @@ _iss sqInt lastUncoggableInterpretedBlockMethod; _iss char * objStackInvalidBecause; _iss sqInt sweepIndex; _iss sqInt ephemeronList; -_iss sqInt longRunningPrimitiveCheckMethod; _iss sqInt tenureCriterion; _iss usqInt totalHeapSizeIncludingBridges; _iss sqInt becomeEffectsFlags; @@ -1948,7 +1942,6 @@ _iss sqInt freeSpaceCheckOopToIgnore; _iss usqInt heapSizeAtPreviousGC; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss sqInt memoryIsScarce; _iss sqInt methodDictLinearSearchLimit; _iss sqInt statGrowMemory; @@ -1960,7 +1953,6 @@ _iss sqInt deferredSmash; _iss sqInt extraFramesToMoveOnOverflow; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss sqInt refCountToShrinkRT; _iss sqInt signalLowSpace; @@ -1991,17 +1983,15 @@ _iss sqInt preferredPinningSegment; _iss sqInt statCoalesces; _iss sqInt theUnknownShort; _iss usqLong nextWakeupUsecs; -_iss usqLong statGCEndUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; -_iss usqLong statCheckForEvents; -_iss usqLong gcStartUsecs; _iss sqLong oldSpaceUsePriorToScavenge; +_iss usqLong statGCEndUsecs; _iss usqLong statIOProcessEvents; _iss usqLong statProcessSwitch; +_iss usqLong gcStartUsecs; _iss usqLong statAllocatedBytes; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statCompactionUsecs; _iss usqLong statForceInterruptCheck; _iss usqLong statFullGCUsecs; @@ -2014,9 +2004,11 @@ _iss usqLong statSweepUsecs; _iss usqLong statCodeCompactionUsecs; _iss usqLong statSGCDeltaUsecs; _iss usqLong gcSweepEndUsecs; -_iss usqLong longRunningPrimitiveGCUsecs; _iss usqLong statIGCDeltaUsecs; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; _iss usqLong statFGCDeltaUsecs; _iss usqLong statIncrGCUsecs; _iss SpurContiguousObjStack savedFirstFieldsSpace; @@ -2697,7 +2689,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Open Smalltalk Cog MT VM [CoInterpreterMT VMMaker.oscog-eem.3024]"; +const char *interpreterVersion = "Open Smalltalk Cog MT VM [CoInterpreterMT VMMaker.oscog-eem.3031]"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */; char primitiveDoMixedArithmetic = 1; char expensiveAsserts = 0; @@ -15705,6 +15697,27 @@ ceStackOverflow(sqInt contextSwitchIfNotNil) error("should not be reached"); } + +/* A primitive has succeeded and the nextProfileTick has been reached (all + done in machine code). + Now take a sample. c.f. checkProfileTick: */ + + /* CoInterpreter>>#ceTakeProfileSample: */ +void +ceTakeProfileSample(CogMethod *aCogMethod) +{ DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt objOop; + sqInt objOop1; + + /* begin fetchPointer:ofObject: */ + objOop1 = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(SchedulerAssociation) << (shiftForWord()))))); + objOop = longAt((objOop1 + BaseHeaderSize) + (((int)((usqInt)(ValueIndex) << (shiftForWord()))))); + GIV(profileProcess) = longAt((objOop + BaseHeaderSize) + (((int)((usqInt)(ActiveProcessIndex) << (shiftForWord()))))); + GIV(profileMethod) = (aCogMethod->methodObject); + forceInterruptCheck(); + GIV(nextProfileTick) = 0; +} + /* CoInterpreter>>#ceTraceBlockActivation */ void ceTraceBlockActivation(void) @@ -20664,7 +20677,7 @@ printFrameWithSP(char *theFP, char *theSP) usqInt index; sqInt methodField; usqInt numArgs; - usqInt numTemps; + sqInt numTemps; char *rcvrAddress; sqInt rcvrOrClosure; CogBlockMethod * self_in_cmHomeMethod; @@ -23241,9 +23254,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { GIV(signalLowSpace) = 0; /* begin fetchPointer:ofObject: */ @@ -23565,24 +23575,6 @@ void forceInterruptCheckFromHeartbeat(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; sqLowLevelMFence(); if (GIV(deferSmash)) { GIV(deferredSmash) = 1; @@ -23775,23 +23767,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i1 = 1; i1 <= GIV(jmpDepth); i1 += 1) { oop = GIV(suspendedCallbacks)[i1]; @@ -26148,56 +26123,6 @@ primitiveFunctionPointerAddress(void) return ((usqInt)((&primitiveFunctionPointer))); } - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* CoInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; - int flushState; - sqInt sema; - char *sp; - - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (sema == GIV(nilObj)) { - flushState = GIV(longRunningPrimitiveCheckSemaphore) != null; - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - flushState = GIV(longRunningPrimitiveCheckSemaphore) == null; - if (!(((!(sema & (tagMask())))) - && (((longAt(sema)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(ClassSemaphore) << (shiftForWord())))))))))) { - return (GIV(primFailCode) = PrimErrBadArgument); - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(longRunningPrimitiveCheckSemaphore) == null)) - || (((stackValue(0)) == GIV(longRunningPrimitiveCheckSemaphore)) - && (isSemaphoreOop(sema)))); - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - if (flushState) { - ceInvokeInterpret(); - } - return 0; -} - /* CoInterpreterPrimitives>>#primitiveMethodPCData */ EXPORT(sqInt) primitiveMethodPCData(void) @@ -26510,14 +26435,9 @@ primitiveObjectAtPut(void) EXPORT(sqInt) primitiveProfileSemaphore(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; int flushState; sqInt sema; - char *sp; - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); if (sema == GIV(nilObj)) { flushState = GIV(profileSemaphore) != GIV(nilObj); @@ -26529,28 +26449,21 @@ primitiveProfileSemaphore(void) return (GIV(primFailCode) = PrimErrBadArgument); } } + GIV(profileSemaphore) = sema; /* If we've switched profiling on or off we must void machine code (and machine code pcs in contexts) since we will start or stop testing the profile clock in machine code primitive invocations, and so generate slightly different code from here on in. */ - GIV(profileSemaphore) = sema; - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(profileSemaphore) == (nilObject()))) - || (((stackValue(0)) == GIV(profileSemaphore)) - && (isSemaphoreOop(sema)))); - } GIV(profileProcess) = (GIV(profileMethod) = GIV(nilObj)); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; if (flushState) { - ceInvokeInterpret(); + flushExternalPrimitives(); + } + else { + /* begin methodReturnReceiver */ + assert(!((failed()))); + /* begin pop: */ + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; } return 0; } @@ -35249,26 +35162,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -37974,15 +37889,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -38000,15 +37910,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -38032,39 +37937,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((integerPointer & 1)) { - deltaTicks = (integerPointer >> 1); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((deltaTicks & 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 1)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -52154,14 +52038,6 @@ isSegmentBridge(sqInt objOop) return ((longAt(objOop)) & (classIndexMask())) == (segmentBridgePun()); } - /* SpurMemoryManager>>#isSemaphoreOop: */ -static sqInt NoDbgRegParms -isSemaphoreOop(sqInt anOop) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - return ((!(anOop & (tagMask())))) - && (((longAt(anOop)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(ClassSemaphore) << (shiftForWord())))))))); -} - /* Answer if the argument contains only indexable 16-bit half words (no oops). See comment in formatOf: @@ -54431,8 +54307,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) sqInt referent; sqInt referent1; sqInt referent2; - sqInt referent3; - sqInt referent4; sqInt sizeOfUnusedEden; StackPage *thePage; CogVMThread *vmThread; @@ -54561,38 +54435,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - if ((!((longAt(GIV(longRunningPrimitiveCheckMethod))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckMethod))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((GIV(longRunningPrimitiveCheckMethod) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent3 & (tagMask())))) - && ((!((longAt(referent3)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((referent3 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckMethod) = referent3; - } - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - if ((!((longAt(GIV(longRunningPrimitiveCheckSemaphore))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckSemaphore))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((GIV(longRunningPrimitiveCheckSemaphore) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent4 & (tagMask())))) - && ((!((longAt(referent4)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((referent4 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckSemaphore) = referent4; - } - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -63424,33 +63266,6 @@ checkAllAccessibleObjectsOkay(void) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -72161,8 +71976,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -72191,18 +72006,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -75412,22 +75229,6 @@ validStackPageBaseFrames(void) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Write the image header and heap contents to imageFile for snapshot. c.f. writeImageFileIOSimulation. The game below is to maintain 64-bit alignment for all putLong:toFile: occurrences. */ @@ -77974,74 +77775,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((addressCouldBeObj(lrpcm)) - && ((!(((longAt(lrpcm)) & (classIndexMask())) == (isFreeObjectClassIndexPun()))) - && (((((usqInt)((longAt(lrpcm)))) >> (formatShift())) & (formatMask())) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - assert(!(isForwarded(result))); - if ((assert(isNonImmediate(result)), - oopisGreaterThanOrEqualTo(result, GIV(oldSpaceStart)))) { - - /* most stores into young objects */ - if (((!(lrpcm & (tagMask())))) - && (oopisLessThan(lrpcm, GIV(newSpaceLimit)))) { - /* begin possibleRootStoreInto: */ - if (!(((((usqInt)((longAt(result)))) >> (rememberedBitShift())) & 1) != 0)) { - remember(result); - } - } - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 1) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 1) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -80527,15 +80260,13 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveGreaterOrEqualLargeIntegers\000\377\000", (void*)primitiveGreaterOrEqualLargeIntegers}, {(void*)_m, "primitiveGreaterThanLargeIntegers\000\377\000", (void*)primitiveGreaterThanLargeIntegers}, {(void*)_m, "primitiveHeartbeatFrequency\000\377\000", (void*)primitiveHeartbeatFrequency}, - {(void*)_m, "primitiveHighResClock\000\377\000", (void*)primitiveHighResClock}, + {(void*)_m, "primitiveHighResClock\000\377\001", (void*)primitiveHighResClock}, {(void*)_m, "primitiveImageFormatVersion\000\377\000", (void*)primitiveImageFormatVersion}, {(void*)_m, "primitiveInterruptChecksPerMSec\000\377\000", (void*)primitiveInterruptChecksPerMSec}, {(void*)_m, "primitiveIsBigEnder\000\377\000", (void*)primitiveIsBigEnder}, {(void*)_m, "primitiveIsWindowObscured\000\377\000", (void*)primitiveIsWindowObscured}, {(void*)_m, "primitiveLessOrEqualLargeIntegers\000\377\000", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers\000\377\000", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive\000\377\000", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore\000\000\000", (void*)primitiveLongRunningPrimitiveSemaphore}, {(void*)_m, "primitiveMethodPCData\000\000\000", (void*)primitiveMethodPCData}, {(void*)_m, "primitiveMillisecondClockMask\000\377\000", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveMinimumUnusedHeadroom\000\377\000", (void*)primitiveMinimumUnusedHeadroom}, @@ -80545,10 +80276,10 @@ void* vm_exports[][3] = { {(void*)_m, "primitivePathToUsing\000\000\000", (void*)primitivePathToUsing}, {(void*)_m, "primitiveProcessBindToThreadId\000\000\000", (void*)primitiveProcessBindToThreadId}, {(void*)_m, "primitiveProcessBoundThreadId\000\000\000", (void*)primitiveProcessBoundThreadId}, - {(void*)_m, "primitiveProfilePrimitive\000\377\000", (void*)primitiveProfilePrimitive}, - {(void*)_m, "primitiveProfileSample\000\377\000", (void*)primitiveProfileSample}, + {(void*)_m, "primitiveProfilePrimitive\000\377\001", (void*)primitiveProfilePrimitive}, + {(void*)_m, "primitiveProfileSample\000\377\001", (void*)primitiveProfileSample}, {(void*)_m, "primitiveProfileSemaphore\000\000\000", (void*)primitiveProfileSemaphore}, - {(void*)_m, "primitiveProfileStart\000\000\000", (void*)primitiveProfileStart}, + {(void*)_m, "primitiveProfileStart\000\000\001", (void*)primitiveProfileStart}, {(void*)_m, "primitiveQuoLargeIntegers\000\000\000", (void*)primitiveQuoLargeIntegers}, {(void*)_m, "primitiveRemLargeIntegers\000\000\000", (void*)primitiveRemLargeIntegers}, {(void*)_m, "primitiveScreenDepth\000\377\000", (void*)primitiveScreenDepth}, diff --git a/spursrc/vm/cointerpmt.h b/spursrc/vm/cointerpmt.h index e09cbd9049..aba7a81b32 100644 --- a/spursrc/vm/cointerpmt.h +++ b/spursrc/vm/cointerpmt.h @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ @@ -51,6 +51,7 @@ extern void ceSendaboveClassBindingtonumArgs(sqInt selector, sqInt methodClassBi extern sqInt ceSendabovetonumArgs(sqInt selector, sqInt methodClass, sqInt rcvr, sqInt numArgs); extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethod); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); diff --git a/spursrc/vm/gcc3x-cointerp.c b/spursrc/vm/gcc3x-cointerp.c index b7185fd13f..17f2089986 100644 --- a/spursrc/vm/gcc3x-cointerp.c +++ b/spursrc/vm/gcc3x-cointerp.c @@ -2,11 +2,11 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - CoInterpreter VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CoInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 " __DATE__ ; +static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -489,6 +489,7 @@ extern void ceSendaboveClassBindingtonumArgs(sqInt selector, sqInt methodClassBi extern sqInt ceSendabovetonumArgs(sqInt selector, sqInt methodClass, sqInt rcvr, sqInt numArgs); extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethod); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); @@ -664,7 +665,6 @@ static void primitiveExitCriticalSection(void); static void primitiveFlushCacheByMethod(void); static void primitiveFlushCacheBySelector(void); extern usqInt primitiveFunctionPointerAddress(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); EXPORT(sqInt) primitiveMethodPCData(void); static void primitiveMethodXray(void); EXPORT(void) primitiveMinimumUnusedHeadroom(void); @@ -1185,7 +1185,6 @@ static sqInt NoDbgRegParms isPureBitsFormat(sqInt format); extern sqInt isReallyYoung(sqInt oop); static sqInt NoDbgRegParms isRemembered(sqInt objOop); static sqInt NoDbgRegParms isSegmentBridge(sqInt objOop); -static sqInt NoDbgRegParms isSemaphoreOop(sqInt anOop); extern sqInt isShorts(sqInt oop); extern sqInt isUnambiguouslyForwarder(sqInt objOop); extern sqInt isUnmarked(sqInt objOop); @@ -1249,7 +1248,7 @@ static sqInt noUnscannedEphemerons(void); static sqInt NoDbgRegParms numBytesOfBitsformat(sqInt objOop, sqInt format); static sqInt NoDbgRegParms numBytesOfBytes(sqInt objOop); extern sqInt numBytesOf(sqInt objOop); -extern sqInt numPointerSlotsOf(sqInt objOop); +extern usqInt numPointerSlotsOf(sqInt objOop); static usqInt NoDbgRegParms numSlotsOfAny(sqInt objOop); extern usqInt numSlotsOf(sqInt objOop); static sqInt NoDbgRegParms numStrongSlotsOfInephemeral(sqInt objOop); @@ -1411,7 +1410,6 @@ EXPORT(sqInt) callbackLeave(sqInt cbID); extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHeader); extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkForEventsMayContextSwitch(sqInt mayContextSwitch); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); @@ -1693,7 +1691,6 @@ static sqInt NoDbgRegParms updateDisplayLeftTopRightBottom(sqInt l, sqInt t, sqI static sqInt NoDbgRegParms validBCPCinMethod(sqInt thePC, usqInt aMethod); static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, char *fp); static sqInt validStackPageBaseFrames(void); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt wakeHighestPriority(void); static sqInt NeverInline writeImageFileIO(void); static usqInt NoDbgRegParms cloneContext(sqInt aContext); @@ -1716,7 +1713,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1791,15 +1787,14 @@ _iss usqInt lastMobileObject; _iss sqInt tempOop; _iss sqInt numClassTablePages; _iss sqInt lkupClass; -_iss sqInt futureSurvivorStart; _iss sqInt profileProcess; -_iss sqInt profileSemaphore; +_iss sqInt futureSurvivorStart; _iss sqInt mournQueue; _iss sqInt numRememberedEphemerons; +_iss sqInt profileMethod; _iss sqInt jmpDepth; _iss sqInt mobileStart; -_iss sqInt profileMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; +_iss sqInt profileSemaphore; _iss sqInt growHeadroom; _iss sqInt tenureThreshold; _iss sqInt lastCoggableInterpretedBlockMethod; @@ -1807,7 +1802,6 @@ _iss sqInt lastUncoggableInterpretedBlockMethod; _iss char * objStackInvalidBecause; _iss sqInt sweepIndex; _iss sqInt ephemeronList; -_iss sqInt longRunningPrimitiveCheckMethod; _iss sqInt tenureCriterion; _iss usqInt totalHeapSizeIncludingBridges; _iss sqInt becomeEffectsFlags; @@ -1863,7 +1857,6 @@ _iss sqInt freeSpaceCheckOopToIgnore; _iss usqInt heapSizeAtPreviousGC; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss sqInt methodDictLinearSearchLimit; _iss sqInt statGrowMemory; _iss sqInt statMaxPageCountWhenMapping; @@ -1875,7 +1868,6 @@ _iss sqInt extraFramesToMoveOnOverflow; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; _iss sqInt inFFIFlags; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss sqInt refCountToShrinkRT; _iss sqInt signalLowSpace; @@ -1905,16 +1897,14 @@ _iss sqInt preferredPinningSegment; _iss sqInt statCoalesces; _iss sqInt theUnknownShort; _iss usqLong nextWakeupUsecs; -_iss usqLong statGCEndUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; -_iss usqLong statCheckForEvents; -_iss usqLong gcStartUsecs; _iss sqLong oldSpaceUsePriorToScavenge; +_iss usqLong statGCEndUsecs; _iss usqLong statIOProcessEvents; +_iss usqLong gcStartUsecs; _iss usqLong statAllocatedBytes; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statCompactionUsecs; _iss usqLong statForceInterruptCheck; _iss usqLong statFullGCUsecs; @@ -1928,9 +1918,11 @@ _iss usqLong statSweepUsecs; _iss usqLong statCodeCompactionUsecs; _iss usqLong statSGCDeltaUsecs; _iss usqLong gcSweepEndUsecs; -_iss usqLong longRunningPrimitiveGCUsecs; _iss usqLong statIGCDeltaUsecs; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; _iss usqLong statFGCDeltaUsecs; _iss usqLong statIncrGCUsecs; _iss SpurContiguousObjStack savedFirstFieldsSpace; @@ -2607,7 +2599,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Open Smalltalk Cog[Spur] VM [CoInterpreterPrimitives VMMaker.oscog-eem.3024]"; +const char *interpreterVersion = "Open Smalltalk Cog[Spur] VM [CoInterpreterPrimitives VMMaker.oscog-eem.3031]"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */; char primitiveDoMixedArithmetic = 1; char expensiveAsserts = 0; @@ -15287,6 +15279,27 @@ ceStackOverflow(sqInt contextSwitchIfNotNil) error("should not be reached"); } + +/* A primitive has succeeded and the nextProfileTick has been reached (all + done in machine code). + Now take a sample. c.f. checkProfileTick: */ + + /* CoInterpreter>>#ceTakeProfileSample: */ +void +ceTakeProfileSample(CogMethod *aCogMethod) +{ DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt objOop; + sqInt objOop1; + + /* begin fetchPointer:ofObject: */ + objOop1 = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(SchedulerAssociation) << (shiftForWord()))))); + objOop = longAt((objOop1 + BaseHeaderSize) + (((int)((usqInt)(ValueIndex) << (shiftForWord()))))); + GIV(profileProcess) = longAt((objOop + BaseHeaderSize) + (((int)((usqInt)(ActiveProcessIndex) << (shiftForWord()))))); + GIV(profileMethod) = (aCogMethod->methodObject); + forceInterruptCheck(); + GIV(nextProfileTick) = 0; +} + /* CoInterpreter>>#ceTraceBlockActivation */ void ceTraceBlockActivation(void) @@ -17282,24 +17295,6 @@ void forceInterruptCheckFromHeartbeat(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; sqLowLevelMFence(); if (GIV(deferSmash)) { GIV(deferredSmash) = 1; @@ -23695,56 +23690,6 @@ primitiveFunctionPointerAddress(void) return ((usqInt)((&primitiveFunctionPointer))); } - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* CoInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; - int flushState; - sqInt sema; - char *sp; - - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (sema == GIV(nilObj)) { - flushState = GIV(longRunningPrimitiveCheckSemaphore) != null; - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - flushState = GIV(longRunningPrimitiveCheckSemaphore) == null; - if (!(((!(sema & (tagMask())))) - && (((longAt(sema)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(ClassSemaphore) << (shiftForWord())))))))))) { - return (GIV(primFailCode) = PrimErrBadArgument); - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(longRunningPrimitiveCheckSemaphore) == null)) - || (((stackValue(0)) == GIV(longRunningPrimitiveCheckSemaphore)) - && (isSemaphoreOop(sema)))); - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - if (flushState) { - ceInvokeInterpret(); - } - return 0; -} - /* CoInterpreterPrimitives>>#primitiveMethodPCData */ EXPORT(sqInt) primitiveMethodPCData(void) @@ -24057,14 +24002,9 @@ primitiveObjectAtPut(void) EXPORT(sqInt) primitiveProfileSemaphore(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; int flushState; sqInt sema; - char *sp; - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); if (sema == GIV(nilObj)) { flushState = GIV(profileSemaphore) != GIV(nilObj); @@ -24076,28 +24016,21 @@ primitiveProfileSemaphore(void) return (GIV(primFailCode) = PrimErrBadArgument); } } + GIV(profileSemaphore) = sema; /* If we've switched profiling on or off we must void machine code (and machine code pcs in contexts) since we will start or stop testing the profile clock in machine code primitive invocations, and so generate slightly different code from here on in. */ - GIV(profileSemaphore) = sema; - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(profileSemaphore) == (nilObject()))) - || (((stackValue(0)) == GIV(profileSemaphore)) - && (isSemaphoreOop(sema)))); - } GIV(profileProcess) = (GIV(profileMethod) = GIV(nilObj)); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; if (flushState) { - ceInvokeInterpret(); + flushExternalPrimitives(); + } + else { + /* begin methodReturnReceiver */ + assert(!((failed()))); + /* begin pop: */ + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; } return 0; } @@ -32796,26 +32729,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -35521,15 +35456,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -35547,15 +35477,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -35579,39 +35504,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((integerPointer & 1)) { - deltaTicks = (integerPointer >> 1); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((deltaTicks & 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 1)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -39048,7 +38952,7 @@ followForwardedObjectFieldstoDepth(sqInt objOop, sqInt depth) sqInt header1; sqInt i; sqInt numLiterals; - sqInt numSlots; + usqInt numSlots; usqInt numSlots1; sqInt oop; sqInt referent; @@ -46352,7 +46256,7 @@ copyObjtoAddrstopAtsavedFirstFieldsindex(sqInt objOop, sqInt segAddr, sqInt endS sqInt iLimiT; sqInt methodHeader; sqInt numLiterals; - sqInt numMediatedSlots; + usqInt numMediatedSlots; usqInt numSlots; usqInt numSlots1; sqInt oop; @@ -46384,7 +46288,7 @@ copyObjtoAddrstopAtsavedFirstFieldsindex(sqInt objOop, sqInt segAddr, sqInt endS here but that requires access to framePointer. */ /* begin numSlotsOfMarriedContext: */ contextSize = stackPointerIndexForFrame(frameOfMarriedContext(objOop)); - numMediatedSlots = CtxtTempFrameStart + contextSize; + numMediatedSlots = ((sqInt) (CtxtTempFrameStart + contextSize)); for (i1 = 0; i1 < numMediatedSlots; i1 += 1) { oop = fetchPointerofMarriedContext(i1, objOop); assert(!(isOopForwarded(copy))); @@ -49730,14 +49634,6 @@ isSegmentBridge(sqInt objOop) return ((longAt(objOop)) & (classIndexMask())) == (segmentBridgePun()); } - /* SpurMemoryManager>>#isSemaphoreOop: */ -static sqInt NoDbgRegParms -isSemaphoreOop(sqInt anOop) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - return ((!(anOop & (tagMask())))) - && (((longAt(anOop)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(ClassSemaphore) << (shiftForWord())))))))); -} - /* Answer if the argument contains only indexable 16-bit half words (no oops). See comment in formatOf: @@ -52005,8 +51901,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) sqInt referent; sqInt referent1; sqInt referent2; - sqInt referent3; - sqInt referent4; sqInt sizeOfUnusedEden; StackPage *thePage; @@ -52134,38 +52028,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - if ((!((longAt(GIV(longRunningPrimitiveCheckMethod))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckMethod))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((GIV(longRunningPrimitiveCheckMethod) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent3 & (tagMask())))) - && ((!((longAt(referent3)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((referent3 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckMethod) = referent3; - } - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - if ((!((longAt(GIV(longRunningPrimitiveCheckSemaphore))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckSemaphore))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((GIV(longRunningPrimitiveCheckSemaphore) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent4 & (tagMask())))) - && ((!((longAt(referent4)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((referent4 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckSemaphore) = referent4; - } - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -52817,7 +52679,7 @@ numBytesOf(sqInt objOop) Works with CompiledMethods, as well as ordinary objects. */ /* SpurMemoryManager>>#numPointerSlotsOf: */ -sqInt +usqInt numPointerSlotsOf(sqInt objOop) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt contextSize; @@ -55812,7 +55674,7 @@ printReferencesTo(sqInt anOop) assert((ReceiverIndex + ((sp >> 1))) < (lengthOf(obj1))); contextSize = (sp >> 1); l9: /* end fetchStackPointerOf: */; - i = CtxtTempFrameStart + contextSize; + i = ((usqInt) (CtxtTempFrameStart + contextSize)); goto l10; } /* begin numSlotsOf: */ @@ -55845,7 +55707,7 @@ printReferencesTo(sqInt anOop) /* begin literalCountOfMethodHeader: */ assert((header & 1)); numLiterals = ((header >> 1)) & AlternateHeaderNumLiteralsMask; - i = numLiterals + LiteralStart; + i = ((usqInt) (numLiterals + LiteralStart)); l10: /* end numPointerSlotsOf: */; while (((i -= 1)) >= 0) { if (anOop == (longAt((obj1 + BaseHeaderSize) + (((sqInt)((usqInt)(i) << (shiftForWord()))))))) { @@ -58989,10 +58851,10 @@ updatePointers(void) sqInt numLiterals1; sqInt numLiterals2; sqInt numLiterals3; - sqInt numPointerSlots; - sqInt numPointerSlots1; - sqInt numPointerSlots2; - sqInt numPointerSlots3; + usqInt numPointerSlots; + usqInt numPointerSlots1; + usqInt numPointerSlots2; + usqInt numPointerSlots3; usqInt numSlots; usqInt numSlots1; usqInt numSlots11; @@ -59570,7 +59432,7 @@ updatePointersInsavedFirstFieldPointer(sqInt obj, sqInt firstFieldPtr) assert((ReceiverIndex + ((sp >> 1))) < (lengthOf(obj))); contextSize = (sp >> 1); l6: /* end fetchStackPointerOf: */; - numPointerSlots = CtxtTempFrameStart + contextSize; + numPointerSlots = ((usqInt) (CtxtTempFrameStart + contextSize)); goto l10; } /* begin numSlotsOf: */ @@ -59600,7 +59462,7 @@ updatePointersInsavedFirstFieldPointer(sqInt obj, sqInt firstFieldPtr) /* begin literalCountOfMethodHeader: */ assert((header & 1)); numLiterals = ((header >> 1)) & AlternateHeaderNumLiteralsMask; - numPointerSlots = numLiterals + LiteralStart; + numPointerSlots = ((usqInt) (numLiterals + LiteralStart)); l10: /* end numPointerSlotsWhileCompactingOf:withFormat:savedFirstFieldPointer: */; if ((fmt <= 5 /* lastPointerFormat */) && (numPointerSlots > 0)) { @@ -60151,7 +60013,7 @@ prepareForSnapshot(void) sqInt limit; sqInt newEndOfMemory; sqInt next; - sqInt node; + usqInt node; SpurSegmentInfo *seg; sqInt smallChild; sqInt treeNode; @@ -60982,33 +60844,6 @@ checkAllAccessibleObjectsOkay(void) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -61099,9 +60934,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { /* begin signalLowSpace: */ GIV(signalLowSpace) = 0; @@ -66123,23 +65955,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i = 1; i <= GIV(jmpDepth); i += 1) { oop = GIV(suspendedCallbacks)[i]; @@ -70047,8 +69862,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -70077,18 +69892,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -73298,22 +73115,6 @@ validStackPageBaseFrames(void) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Return the highest priority process that is ready to run. To save time looking at many empty lists before finding a runnable process the VM maintains a variable holding the @@ -75943,74 +75744,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((addressCouldBeObj(lrpcm)) - && ((!(((longAt(lrpcm)) & (classIndexMask())) == (isFreeObjectClassIndexPun()))) - && (((((usqInt)((longAt(lrpcm)))) >> (formatShift())) & (formatMask())) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - assert(!(isForwarded(result))); - if ((assert(isNonImmediate(result)), - oopisGreaterThanOrEqualTo(result, GIV(oldSpaceStart)))) { - - /* most stores into young objects */ - if (((!(lrpcm & (tagMask())))) - && (oopisLessThan(lrpcm, GIV(newSpaceLimit)))) { - /* begin possibleRootStoreInto: */ - if (!(((((usqInt)((longAt(result)))) >> (rememberedBitShift())) & 1) != 0)) { - remember(result); - } - } - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 1) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 1) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -78502,15 +78235,13 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveGreaterOrEqualLargeIntegers\000\377\000", (void*)primitiveGreaterOrEqualLargeIntegers}, {(void*)_m, "primitiveGreaterThanLargeIntegers\000\377\000", (void*)primitiveGreaterThanLargeIntegers}, {(void*)_m, "primitiveHeartbeatFrequency\000\377\000", (void*)primitiveHeartbeatFrequency}, - {(void*)_m, "primitiveHighResClock\000\377\000", (void*)primitiveHighResClock}, + {(void*)_m, "primitiveHighResClock\000\377\001", (void*)primitiveHighResClock}, {(void*)_m, "primitiveImageFormatVersion\000\377\000", (void*)primitiveImageFormatVersion}, {(void*)_m, "primitiveInterruptChecksPerMSec\000\377\000", (void*)primitiveInterruptChecksPerMSec}, {(void*)_m, "primitiveIsBigEnder\000\377\000", (void*)primitiveIsBigEnder}, {(void*)_m, "primitiveIsWindowObscured\000\377\000", (void*)primitiveIsWindowObscured}, {(void*)_m, "primitiveLessOrEqualLargeIntegers\000\377\000", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers\000\377\000", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive\000\377\000", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore\000\000\000", (void*)primitiveLongRunningPrimitiveSemaphore}, {(void*)_m, "primitiveMethodPCData\000\000\000", (void*)primitiveMethodPCData}, {(void*)_m, "primitiveMillisecondClockMask\000\377\000", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveMinimumUnusedHeadroom\000\377\000", (void*)primitiveMinimumUnusedHeadroom}, @@ -78518,10 +78249,10 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveMultiplyLargeIntegers\000\000\000", (void*)primitiveMultiplyLargeIntegers}, {(void*)_m, "primitiveNotEqualLargeIntegers\000\377\000", (void*)primitiveNotEqualLargeIntegers}, {(void*)_m, "primitivePathToUsing\000\000\000", (void*)primitivePathToUsing}, - {(void*)_m, "primitiveProfilePrimitive\000\377\000", (void*)primitiveProfilePrimitive}, - {(void*)_m, "primitiveProfileSample\000\377\000", (void*)primitiveProfileSample}, + {(void*)_m, "primitiveProfilePrimitive\000\377\001", (void*)primitiveProfilePrimitive}, + {(void*)_m, "primitiveProfileSample\000\377\001", (void*)primitiveProfileSample}, {(void*)_m, "primitiveProfileSemaphore\000\000\000", (void*)primitiveProfileSemaphore}, - {(void*)_m, "primitiveProfileStart\000\000\000", (void*)primitiveProfileStart}, + {(void*)_m, "primitiveProfileStart\000\000\001", (void*)primitiveProfileStart}, {(void*)_m, "primitiveQuoLargeIntegers\000\000\000", (void*)primitiveQuoLargeIntegers}, {(void*)_m, "primitiveRemLargeIntegers\000\000\000", (void*)primitiveRemLargeIntegers}, {(void*)_m, "primitiveScreenDepth\000\377\000", (void*)primitiveScreenDepth}, diff --git a/spursrc/vm/gcc3x-cointerpmt.c b/spursrc/vm/gcc3x-cointerpmt.c index e3bb96df68..e74a938eaf 100644 --- a/spursrc/vm/gcc3x-cointerpmt.c +++ b/spursrc/vm/gcc3x-cointerpmt.c @@ -2,11 +2,11 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - CoInterpreterMT VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CoInterpreterMT VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "CoInterpreterMT VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 " __DATE__ ; +static char __buildInfo[] = "CoInterpreterMT VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -545,6 +545,7 @@ extern void ceSendaboveClassBindingtonumArgs(sqInt selector, sqInt methodClassBi extern sqInt ceSendabovetonumArgs(sqInt selector, sqInt methodClass, sqInt rcvr, sqInt numArgs); extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethod); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); @@ -744,7 +745,6 @@ static void primitiveExitCriticalSection(void); static void primitiveFlushCacheByMethod(void); static void primitiveFlushCacheBySelector(void); extern usqInt primitiveFunctionPointerAddress(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); EXPORT(sqInt) primitiveMethodPCData(void); static void primitiveMethodXray(void); EXPORT(void) primitiveMinimumUnusedHeadroom(void); @@ -1265,7 +1265,6 @@ static sqInt NoDbgRegParms isPureBitsFormat(sqInt format); extern sqInt isReallyYoung(sqInt oop); static sqInt NoDbgRegParms isRemembered(sqInt objOop); static sqInt NoDbgRegParms isSegmentBridge(sqInt objOop); -static sqInt NoDbgRegParms isSemaphoreOop(sqInt anOop); extern sqInt isShorts(sqInt oop); extern sqInt isUnambiguouslyForwarder(sqInt objOop); extern sqInt isUnmarked(sqInt objOop); @@ -1491,7 +1490,6 @@ EXPORT(sqInt) callbackLeave(sqInt cbID); extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHeader); extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); static sqInt checkInterpreterIntegrity(void); @@ -1768,7 +1766,6 @@ static sqInt NoDbgRegParms updateDisplayLeftTopRightBottom(sqInt l, sqInt t, sqI static sqInt NoDbgRegParms validBCPCinMethod(sqInt thePC, usqInt aMethod); static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, char *fp); static sqInt validStackPageBaseFrames(void); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt NeverInline writeImageFileIO(void); static usqInt NoDbgRegParms cloneContext(sqInt aContext); static sqInt NoDbgRegParms fieldOrSenderFPofContext(sqInt index, sqInt contextObj); @@ -1790,7 +1787,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1866,17 +1862,16 @@ _iss usqInt lastMobileObject; _iss sqInt tempOop; _iss sqInt numClassTablePages; _iss sqInt lkupClass; +_iss sqInt profileProcess; _iss sqInt futureSurvivorStart; _iss sqInt numThreads; -_iss sqInt profileProcess; -_iss sqInt profileSemaphore; _iss CogVMThread * disowningVMThread; _iss sqInt mournQueue; _iss sqInt numRememberedEphemerons; +_iss sqInt profileMethod; +_iss sqInt profileSemaphore; _iss sqInt jmpDepth; _iss sqInt mobileStart; -_iss sqInt profileMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; _iss CogVMThread ** threads; _iss sqInt growHeadroom; _iss sqInt processHasThreadId; @@ -1886,7 +1881,6 @@ _iss sqInt lastUncoggableInterpretedBlockMethod; _iss char * objStackInvalidBecause; _iss sqInt sweepIndex; _iss sqInt ephemeronList; -_iss sqInt longRunningPrimitiveCheckMethod; _iss sqInt tenureCriterion; _iss usqInt totalHeapSizeIncludingBridges; _iss sqInt becomeEffectsFlags; @@ -1951,7 +1945,6 @@ _iss sqInt freeSpaceCheckOopToIgnore; _iss usqInt heapSizeAtPreviousGC; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss sqInt memoryIsScarce; _iss sqInt methodDictLinearSearchLimit; _iss sqInt statGrowMemory; @@ -1963,7 +1956,6 @@ _iss sqInt deferredSmash; _iss sqInt extraFramesToMoveOnOverflow; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss sqInt refCountToShrinkRT; _iss sqInt signalLowSpace; @@ -1994,17 +1986,15 @@ _iss sqInt preferredPinningSegment; _iss sqInt statCoalesces; _iss sqInt theUnknownShort; _iss usqLong nextWakeupUsecs; -_iss usqLong statGCEndUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; -_iss usqLong statCheckForEvents; -_iss usqLong gcStartUsecs; _iss sqLong oldSpaceUsePriorToScavenge; +_iss usqLong statGCEndUsecs; _iss usqLong statIOProcessEvents; _iss usqLong statProcessSwitch; +_iss usqLong gcStartUsecs; _iss usqLong statAllocatedBytes; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statCompactionUsecs; _iss usqLong statForceInterruptCheck; _iss usqLong statFullGCUsecs; @@ -2017,9 +2007,11 @@ _iss usqLong statSweepUsecs; _iss usqLong statCodeCompactionUsecs; _iss usqLong statSGCDeltaUsecs; _iss usqLong gcSweepEndUsecs; -_iss usqLong longRunningPrimitiveGCUsecs; _iss usqLong statIGCDeltaUsecs; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; _iss usqLong statFGCDeltaUsecs; _iss usqLong statIncrGCUsecs; _iss SpurContiguousObjStack savedFirstFieldsSpace; @@ -2700,7 +2692,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Open Smalltalk Cog MT VM [CoInterpreterMT VMMaker.oscog-eem.3024]"; +const char *interpreterVersion = "Open Smalltalk Cog MT VM [CoInterpreterMT VMMaker.oscog-eem.3031]"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */; char primitiveDoMixedArithmetic = 1; char expensiveAsserts = 0; @@ -15714,6 +15706,27 @@ ceStackOverflow(sqInt contextSwitchIfNotNil) error("should not be reached"); } + +/* A primitive has succeeded and the nextProfileTick has been reached (all + done in machine code). + Now take a sample. c.f. checkProfileTick: */ + + /* CoInterpreter>>#ceTakeProfileSample: */ +void +ceTakeProfileSample(CogMethod *aCogMethod) +{ DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt objOop; + sqInt objOop1; + + /* begin fetchPointer:ofObject: */ + objOop1 = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(SchedulerAssociation) << (shiftForWord()))))); + objOop = longAt((objOop1 + BaseHeaderSize) + (((int)((usqInt)(ValueIndex) << (shiftForWord()))))); + GIV(profileProcess) = longAt((objOop + BaseHeaderSize) + (((int)((usqInt)(ActiveProcessIndex) << (shiftForWord()))))); + GIV(profileMethod) = (aCogMethod->methodObject); + forceInterruptCheck(); + GIV(nextProfileTick) = 0; +} + /* CoInterpreter>>#ceTraceBlockActivation */ void ceTraceBlockActivation(void) @@ -20673,7 +20686,7 @@ printFrameWithSP(char *theFP, char *theSP) usqInt index; sqInt methodField; usqInt numArgs; - usqInt numTemps; + sqInt numTemps; char *rcvrAddress; sqInt rcvrOrClosure; CogBlockMethod * self_in_cmHomeMethod; @@ -23250,9 +23263,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { GIV(signalLowSpace) = 0; /* begin fetchPointer:ofObject: */ @@ -23574,24 +23584,6 @@ void forceInterruptCheckFromHeartbeat(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; sqLowLevelMFence(); if (GIV(deferSmash)) { GIV(deferredSmash) = 1; @@ -23784,23 +23776,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i1 = 1; i1 <= GIV(jmpDepth); i1 += 1) { oop = GIV(suspendedCallbacks)[i1]; @@ -26157,56 +26132,6 @@ primitiveFunctionPointerAddress(void) return ((usqInt)((&primitiveFunctionPointer))); } - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* CoInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; - int flushState; - sqInt sema; - char *sp; - - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (sema == GIV(nilObj)) { - flushState = GIV(longRunningPrimitiveCheckSemaphore) != null; - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - flushState = GIV(longRunningPrimitiveCheckSemaphore) == null; - if (!(((!(sema & (tagMask())))) - && (((longAt(sema)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(ClassSemaphore) << (shiftForWord())))))))))) { - return (GIV(primFailCode) = PrimErrBadArgument); - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(longRunningPrimitiveCheckSemaphore) == null)) - || (((stackValue(0)) == GIV(longRunningPrimitiveCheckSemaphore)) - && (isSemaphoreOop(sema)))); - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - if (flushState) { - ceInvokeInterpret(); - } - return 0; -} - /* CoInterpreterPrimitives>>#primitiveMethodPCData */ EXPORT(sqInt) primitiveMethodPCData(void) @@ -26519,14 +26444,9 @@ primitiveObjectAtPut(void) EXPORT(sqInt) primitiveProfileSemaphore(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; int flushState; sqInt sema; - char *sp; - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); if (sema == GIV(nilObj)) { flushState = GIV(profileSemaphore) != GIV(nilObj); @@ -26538,28 +26458,21 @@ primitiveProfileSemaphore(void) return (GIV(primFailCode) = PrimErrBadArgument); } } + GIV(profileSemaphore) = sema; /* If we've switched profiling on or off we must void machine code (and machine code pcs in contexts) since we will start or stop testing the profile clock in machine code primitive invocations, and so generate slightly different code from here on in. */ - GIV(profileSemaphore) = sema; - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(profileSemaphore) == (nilObject()))) - || (((stackValue(0)) == GIV(profileSemaphore)) - && (isSemaphoreOop(sema)))); - } GIV(profileProcess) = (GIV(profileMethod) = GIV(nilObj)); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; if (flushState) { - ceInvokeInterpret(); + flushExternalPrimitives(); + } + else { + /* begin methodReturnReceiver */ + assert(!((failed()))); + /* begin pop: */ + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; } return 0; } @@ -35258,26 +35171,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -37983,15 +37898,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -38009,15 +37919,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -38041,39 +37946,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((integerPointer & 1)) { - deltaTicks = (integerPointer >> 1); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((deltaTicks & 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 1)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -52163,14 +52047,6 @@ isSegmentBridge(sqInt objOop) return ((longAt(objOop)) & (classIndexMask())) == (segmentBridgePun()); } - /* SpurMemoryManager>>#isSemaphoreOop: */ -static sqInt NoDbgRegParms -isSemaphoreOop(sqInt anOop) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - return ((!(anOop & (tagMask())))) - && (((longAt(anOop)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(ClassSemaphore) << (shiftForWord())))))))); -} - /* Answer if the argument contains only indexable 16-bit half words (no oops). See comment in formatOf: @@ -54440,8 +54316,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) sqInt referent; sqInt referent1; sqInt referent2; - sqInt referent3; - sqInt referent4; sqInt sizeOfUnusedEden; StackPage *thePage; CogVMThread *vmThread; @@ -54570,38 +54444,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - if ((!((longAt(GIV(longRunningPrimitiveCheckMethod))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckMethod))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((GIV(longRunningPrimitiveCheckMethod) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent3 & (tagMask())))) - && ((!((longAt(referent3)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((referent3 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckMethod) = referent3; - } - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - if ((!((longAt(GIV(longRunningPrimitiveCheckSemaphore))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckSemaphore))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((GIV(longRunningPrimitiveCheckSemaphore) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent4 & (tagMask())))) - && ((!((longAt(referent4)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((referent4 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckSemaphore) = referent4; - } - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -63433,33 +63275,6 @@ checkAllAccessibleObjectsOkay(void) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -72170,8 +71985,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -72200,18 +72015,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -75421,22 +75238,6 @@ validStackPageBaseFrames(void) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Write the image header and heap contents to imageFile for snapshot. c.f. writeImageFileIOSimulation. The game below is to maintain 64-bit alignment for all putLong:toFile: occurrences. */ @@ -77983,74 +77784,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((addressCouldBeObj(lrpcm)) - && ((!(((longAt(lrpcm)) & (classIndexMask())) == (isFreeObjectClassIndexPun()))) - && (((((usqInt)((longAt(lrpcm)))) >> (formatShift())) & (formatMask())) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - assert(!(isForwarded(result))); - if ((assert(isNonImmediate(result)), - oopisGreaterThanOrEqualTo(result, GIV(oldSpaceStart)))) { - - /* most stores into young objects */ - if (((!(lrpcm & (tagMask())))) - && (oopisLessThan(lrpcm, GIV(newSpaceLimit)))) { - /* begin possibleRootStoreInto: */ - if (!(((((usqInt)((longAt(result)))) >> (rememberedBitShift())) & 1) != 0)) { - remember(result); - } - } - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 1) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 1) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -80536,15 +80269,13 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveGreaterOrEqualLargeIntegers\000\377\000", (void*)primitiveGreaterOrEqualLargeIntegers}, {(void*)_m, "primitiveGreaterThanLargeIntegers\000\377\000", (void*)primitiveGreaterThanLargeIntegers}, {(void*)_m, "primitiveHeartbeatFrequency\000\377\000", (void*)primitiveHeartbeatFrequency}, - {(void*)_m, "primitiveHighResClock\000\377\000", (void*)primitiveHighResClock}, + {(void*)_m, "primitiveHighResClock\000\377\001", (void*)primitiveHighResClock}, {(void*)_m, "primitiveImageFormatVersion\000\377\000", (void*)primitiveImageFormatVersion}, {(void*)_m, "primitiveInterruptChecksPerMSec\000\377\000", (void*)primitiveInterruptChecksPerMSec}, {(void*)_m, "primitiveIsBigEnder\000\377\000", (void*)primitiveIsBigEnder}, {(void*)_m, "primitiveIsWindowObscured\000\377\000", (void*)primitiveIsWindowObscured}, {(void*)_m, "primitiveLessOrEqualLargeIntegers\000\377\000", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers\000\377\000", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive\000\377\000", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore\000\000\000", (void*)primitiveLongRunningPrimitiveSemaphore}, {(void*)_m, "primitiveMethodPCData\000\000\000", (void*)primitiveMethodPCData}, {(void*)_m, "primitiveMillisecondClockMask\000\377\000", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveMinimumUnusedHeadroom\000\377\000", (void*)primitiveMinimumUnusedHeadroom}, @@ -80554,10 +80285,10 @@ void* vm_exports[][3] = { {(void*)_m, "primitivePathToUsing\000\000\000", (void*)primitivePathToUsing}, {(void*)_m, "primitiveProcessBindToThreadId\000\000\000", (void*)primitiveProcessBindToThreadId}, {(void*)_m, "primitiveProcessBoundThreadId\000\000\000", (void*)primitiveProcessBoundThreadId}, - {(void*)_m, "primitiveProfilePrimitive\000\377\000", (void*)primitiveProfilePrimitive}, - {(void*)_m, "primitiveProfileSample\000\377\000", (void*)primitiveProfileSample}, + {(void*)_m, "primitiveProfilePrimitive\000\377\001", (void*)primitiveProfilePrimitive}, + {(void*)_m, "primitiveProfileSample\000\377\001", (void*)primitiveProfileSample}, {(void*)_m, "primitiveProfileSemaphore\000\000\000", (void*)primitiveProfileSemaphore}, - {(void*)_m, "primitiveProfileStart\000\000\000", (void*)primitiveProfileStart}, + {(void*)_m, "primitiveProfileStart\000\000\001", (void*)primitiveProfileStart}, {(void*)_m, "primitiveQuoLargeIntegers\000\000\000", (void*)primitiveQuoLargeIntegers}, {(void*)_m, "primitiveRemLargeIntegers\000\000\000", (void*)primitiveRemLargeIntegers}, {(void*)_m, "primitiveScreenDepth\000\377\000", (void*)primitiveScreenDepth}, diff --git a/spurstack64src/vm/gcc3x-interp.c b/spurstack64src/vm/gcc3x-interp.c index b1fdfc31fe..f252976889 100644 --- a/spurstack64src/vm/gcc3x-interp.c +++ b/spurstack64src/vm/gcc3x-interp.c @@ -2,11 +2,11 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - StackInterpreter VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 + StackInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 " __DATE__ ; +static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -1140,7 +1140,6 @@ extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHea extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); static sqInt NoDbgRegParms checkCodeIntegrity(sqInt fullGCFlag); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkForEventsMayContextSwitch(sqInt mayContextSwitch); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); @@ -1456,7 +1455,6 @@ static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, extern sqInt validInstructionPointerinMethodframePointer(usqInt theInstrPointer, usqInt aMethod, char *fp); static sqInt validStackPageBaseFrames(void); static sqInt NoDbgRegParms validStackPageBaseFrame(StackPage *aPage); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt NoDbgRegParms voidVMStateForSnapshotFlushingExternalPrimitivesIf(sqInt flushExtPrims); static sqInt wakeHighestPriority(void); EXPORT(char *) whereIs(sqInt anOop); @@ -1487,8 +1485,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1572,8 +1568,6 @@ _iss char * objStackInvalidBecause; _iss sqInt sweepIndex; _iss sqInt ephemeronList; _iss sqInt imageHeaderFlags; -_iss sqInt longRunningPrimitiveCheckMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; _iss sqInt profileSemaphore; _iss sqInt tenureCriterion; _iss usqInt totalHeapSizeIncludingBridges; @@ -1595,20 +1589,16 @@ _iss sqInt numSegInfos; _iss sqInt savedFirstFieldsSpaceNotInOldSpace; _iss sqInt highestRunnableProcessPriority; _iss usqLong nextWakeupUsecs; -_iss usqLong statGCEndUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; _iss sqInt metaclassNumSlots; _iss sqInt shrinkThreshold; -_iss usqLong statCheckForEvents; _iss sqInt statTenures; _iss sqInt weakList; _iss sqInt externalPrimitiveTableFirstFreeIndex; -_iss usqLong gcStartUsecs; _iss sqInt marking; _iss sqLong oldSpaceUsePriorToScavenge; _iss sqInt preemptionYields; _iss sqInt rememberedSetLimit; +_iss usqLong statGCEndUsecs; _iss sqInt statSurvivorCount; _iss sqInt thisClassIndex; _iss sqInt firstFieldOfRememberedSet; @@ -1622,6 +1612,7 @@ _iss sqInt statShrinkMemory; _iss sqInt biasForGC; _iss sqInt edenBytes; _iss sqInt fullScreenFlag; +_iss usqLong gcStartUsecs; _iss usqInt lastHash; _iss sqInt lastMethodCacheProbeWrite; _iss sqInt newFinalization; @@ -1635,9 +1626,9 @@ _iss sqInt freeSpaceCheckOopToIgnore; _iss usqInt heapSizeAtPreviousGC; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statCompactionUsecs; _iss usqLong statForceInterruptCheck; _iss usqLong statFullGCUsecs; @@ -1657,7 +1648,6 @@ _iss sqInt gcSemaphoreIndex; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; _iss sqInt inFFIFlags; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss sqInt methodDictLinearSearchLimit; _iss sqInt refCountToShrinkRT; @@ -1669,7 +1659,6 @@ _iss sqInt bogon; _iss sqInt classByteArrayCompactIndex; _iss usqInt exceptionPC; _iss usqLong gcSweepEndUsecs; -_iss usqLong longRunningPrimitiveGCUsecs; _iss sqInt overflowLimit; _iss StackPage * overflowedPage; _iss sqInt statCompactPassCount; @@ -1688,6 +1677,9 @@ _iss usqInt suspendedCallbacks[MaxJumpBuf + 1 /* 33 */]; _iss usqInt suspendedMethods[MaxJumpBuf + 1 /* 33 */]; _iss jmp_buf jmpBuf[MaxJumpBuf + 1 /* 33 */]; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; _iss sqInt preferredPinningSegment; _iss sqInt statCoalesces; _iss usqLong statFGCDeltaUsecs; @@ -2359,7 +2351,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Open Smalltalk Stack VM [StackInterpreterPrimitives VMMaker.oscog-eem.3022]"; +const char *interpreterVersion = "Open Smalltalk Stack VM [StackInterpreterPrimitives VMMaker.oscog-eem.3031]"; sqInt suppressHeartbeatFlag; int displayWidth; int displayDepth; @@ -19883,26 +19875,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -22934,15 +22928,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -22960,15 +22949,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -23021,39 +23005,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((((integerPointer) & 7) == 1)) { - deltaTicks = (integerPointer >> 3); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((((deltaTicks) & 7) == 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 3)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -41014,8 +40977,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) sqInt referent; sqInt referent1; sqInt referent2; - sqInt referent3; - sqInt referent4; sqInt sizeOfUnusedEden; StackPage *thePage; @@ -41152,38 +41113,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - if ((!((longAt(GIV(longRunningPrimitiveCheckMethod))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckMethod))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((GIV(longRunningPrimitiveCheckMethod) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent3 & (tagMask())))) - && ((!((longAt(referent3)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((referent3 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckMethod) = referent3; - } - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - if ((!((longAt(GIV(longRunningPrimitiveCheckSemaphore))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckSemaphore))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((GIV(longRunningPrimitiveCheckSemaphore) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent4 & (tagMask())))) - && ((!((longAt(referent4)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((referent4 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckSemaphore) = referent4; - } - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -50245,33 +50174,6 @@ checkCodeIntegrity(sqInt fullGCFlag) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -50358,9 +50260,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { /* begin signalLowSpace: */ GIV(signalLowSpace) = 0; @@ -53172,26 +53071,8 @@ forceInterruptCheck(void) /* StackInterpreter>>#forceInterruptCheckFromHeartbeat */ void forceInterruptCheckFromHeartbeat(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT +{ if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; forceInterruptCheck(); } } @@ -55623,23 +55504,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i = 1; i <= GIV(jmpDepth); i += 1) { oop = GIV(suspendedCallbacks)[i]; @@ -59830,8 +59694,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -59860,18 +59724,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -64185,22 +64051,6 @@ validStackPageBaseFrame(StackPage *aPage) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Make sure that all VM state that affects the heap contents is voided so that the heap is ready to be snapshotted. If flushExtPrims is true, flush references to @@ -67295,115 +67145,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((addressCouldBeObj(lrpcm)) - && ((!(((longAt(lrpcm)) & (classIndexMask())) == (isFreeObjectClassIndexPun()))) - && (((((usqInt)((longAt(lrpcm)))) >> (formatShift())) & (formatMask())) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - assert(!(isForwarded(result))); - if ((assert(isNonImmediate(result)), - oopisGreaterThanOrEqualTo(result, GIV(oldSpaceStart)))) { - - /* most stores into young objects */ - if (((!(lrpcm & (tagMask())))) - && (oopisLessThan(lrpcm, GIV(newSpaceLimit)))) { - /* begin possibleRootStoreInto: */ - if (!(((((usqInt)((longAt(result)))) >> (rememberedBitShift())) & 1) != 0)) { - remember(result); - } - } - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 3) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 3) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt sema; - - /* begin stackValue: */ - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (((((sema) & 7) == 1)) - || (GIV(argumentCount) != 1)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - if (sema == GIV(nilObj)) { - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - if (!(((!(sema & (tagMask())))) - && (((longAt(sema)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(ClassSemaphore) << (shiftForWord())))))))))) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -70327,24 +70068,22 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveGreaterOrEqualLargeIntegers\000\377\000", (void*)primitiveGreaterOrEqualLargeIntegers}, {(void*)_m, "primitiveGreaterThanLargeIntegers\000\377\000", (void*)primitiveGreaterThanLargeIntegers}, {(void*)_m, "primitiveHeartbeatFrequency\000\377\000", (void*)primitiveHeartbeatFrequency}, - {(void*)_m, "primitiveHighResClock\000\377\000", (void*)primitiveHighResClock}, + {(void*)_m, "primitiveHighResClock\000\377\001", (void*)primitiveHighResClock}, {(void*)_m, "primitiveImageFormatVersion\000\377\000", (void*)primitiveImageFormatVersion}, {(void*)_m, "primitiveInterruptChecksPerMSec\000\377\000", (void*)primitiveInterruptChecksPerMSec}, {(void*)_m, "primitiveIsBigEnder\000\377\000", (void*)primitiveIsBigEnder}, {(void*)_m, "primitiveIsWindowObscured\000\377\000", (void*)primitiveIsWindowObscured}, {(void*)_m, "primitiveLessOrEqualLargeIntegers\000\377\000", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers\000\377\000", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive\000\377\000", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore\000\000\000", (void*)primitiveLongRunningPrimitiveSemaphore}, {(void*)_m, "primitiveMillisecondClockMask\000\377\000", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveModLargeIntegers\000\000\000", (void*)primitiveModLargeIntegers}, {(void*)_m, "primitiveMultiplyLargeIntegers\000\000\000", (void*)primitiveMultiplyLargeIntegers}, {(void*)_m, "primitiveNotEqualLargeIntegers\000\377\000", (void*)primitiveNotEqualLargeIntegers}, {(void*)_m, "primitivePathToUsing\000\000\000", (void*)primitivePathToUsing}, - {(void*)_m, "primitiveProfilePrimitive\000\377\000", (void*)primitiveProfilePrimitive}, - {(void*)_m, "primitiveProfileSample\000\377\000", (void*)primitiveProfileSample}, + {(void*)_m, "primitiveProfilePrimitive\000\377\001", (void*)primitiveProfilePrimitive}, + {(void*)_m, "primitiveProfileSample\000\377\001", (void*)primitiveProfileSample}, {(void*)_m, "primitiveProfileSemaphore\000\000\000", (void*)primitiveProfileSemaphore}, - {(void*)_m, "primitiveProfileStart\000\000\000", (void*)primitiveProfileStart}, + {(void*)_m, "primitiveProfileStart\000\000\001", (void*)primitiveProfileStart}, {(void*)_m, "primitiveQuoLargeIntegers\000\000\000", (void*)primitiveQuoLargeIntegers}, {(void*)_m, "primitiveRemLargeIntegers\000\000\000", (void*)primitiveRemLargeIntegers}, {(void*)_m, "primitiveScreenDepth\000\377\000", (void*)primitiveScreenDepth}, diff --git a/spurstack64src/vm/interp.c b/spurstack64src/vm/interp.c index 611623e955..7877f16e2b 100644 --- a/spurstack64src/vm/interp.c +++ b/spurstack64src/vm/interp.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - StackInterpreter VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 + StackInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 " __DATE__ ; +static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -1137,7 +1137,6 @@ extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHea extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); static sqInt NoDbgRegParms checkCodeIntegrity(sqInt fullGCFlag); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkForEventsMayContextSwitch(sqInt mayContextSwitch); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); @@ -1453,7 +1452,6 @@ static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, extern sqInt validInstructionPointerinMethodframePointer(usqInt theInstrPointer, usqInt aMethod, char *fp); static sqInt validStackPageBaseFrames(void); static sqInt NoDbgRegParms validStackPageBaseFrame(StackPage *aPage); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt NoDbgRegParms voidVMStateForSnapshotFlushingExternalPrimitivesIf(sqInt flushExtPrims); static sqInt wakeHighestPriority(void); EXPORT(char *) whereIs(sqInt anOop); @@ -1484,8 +1482,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1569,8 +1565,6 @@ _iss char * objStackInvalidBecause; _iss sqInt sweepIndex; _iss sqInt ephemeronList; _iss sqInt imageHeaderFlags; -_iss sqInt longRunningPrimitiveCheckMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; _iss sqInt profileSemaphore; _iss sqInt tenureCriterion; _iss usqInt totalHeapSizeIncludingBridges; @@ -1592,20 +1586,16 @@ _iss sqInt numSegInfos; _iss sqInt savedFirstFieldsSpaceNotInOldSpace; _iss sqInt highestRunnableProcessPriority; _iss usqLong nextWakeupUsecs; -_iss usqLong statGCEndUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; _iss sqInt metaclassNumSlots; _iss sqInt shrinkThreshold; -_iss usqLong statCheckForEvents; _iss sqInt statTenures; _iss sqInt weakList; _iss sqInt externalPrimitiveTableFirstFreeIndex; -_iss usqLong gcStartUsecs; _iss sqInt marking; _iss sqLong oldSpaceUsePriorToScavenge; _iss sqInt preemptionYields; _iss sqInt rememberedSetLimit; +_iss usqLong statGCEndUsecs; _iss sqInt statSurvivorCount; _iss sqInt thisClassIndex; _iss sqInt firstFieldOfRememberedSet; @@ -1619,6 +1609,7 @@ _iss sqInt statShrinkMemory; _iss sqInt biasForGC; _iss sqInt edenBytes; _iss sqInt fullScreenFlag; +_iss usqLong gcStartUsecs; _iss usqInt lastHash; _iss sqInt lastMethodCacheProbeWrite; _iss sqInt newFinalization; @@ -1632,9 +1623,9 @@ _iss sqInt freeSpaceCheckOopToIgnore; _iss usqInt heapSizeAtPreviousGC; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statCompactionUsecs; _iss usqLong statForceInterruptCheck; _iss usqLong statFullGCUsecs; @@ -1654,7 +1645,6 @@ _iss sqInt gcSemaphoreIndex; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; _iss sqInt inFFIFlags; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss sqInt methodDictLinearSearchLimit; _iss sqInt refCountToShrinkRT; @@ -1666,7 +1656,6 @@ _iss sqInt bogon; _iss sqInt classByteArrayCompactIndex; _iss usqInt exceptionPC; _iss usqLong gcSweepEndUsecs; -_iss usqLong longRunningPrimitiveGCUsecs; _iss sqInt overflowLimit; _iss StackPage * overflowedPage; _iss sqInt statCompactPassCount; @@ -1685,6 +1674,9 @@ _iss usqInt suspendedCallbacks[MaxJumpBuf + 1 /* 33 */]; _iss usqInt suspendedMethods[MaxJumpBuf + 1 /* 33 */]; _iss jmp_buf jmpBuf[MaxJumpBuf + 1 /* 33 */]; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; _iss sqInt preferredPinningSegment; _iss sqInt statCoalesces; _iss usqLong statFGCDeltaUsecs; @@ -2356,7 +2348,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Open Smalltalk Stack VM [StackInterpreterPrimitives VMMaker.oscog-eem.3022]"; +const char *interpreterVersion = "Open Smalltalk Stack VM [StackInterpreterPrimitives VMMaker.oscog-eem.3031]"; sqInt suppressHeartbeatFlag; int displayWidth; int displayDepth; @@ -19874,26 +19866,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -22925,15 +22919,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -22951,15 +22940,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -23012,39 +22996,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((((integerPointer) & 7) == 1)) { - deltaTicks = (integerPointer >> 3); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((((deltaTicks) & 7) == 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 3)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -41005,8 +40968,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) sqInt referent; sqInt referent1; sqInt referent2; - sqInt referent3; - sqInt referent4; sqInt sizeOfUnusedEden; StackPage *thePage; @@ -41143,38 +41104,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - if ((!((longAt(GIV(longRunningPrimitiveCheckMethod))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckMethod))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((GIV(longRunningPrimitiveCheckMethod) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent3 & (tagMask())))) - && ((!((longAt(referent3)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((referent3 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckMethod) = referent3; - } - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - if ((!((longAt(GIV(longRunningPrimitiveCheckSemaphore))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckSemaphore))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((GIV(longRunningPrimitiveCheckSemaphore) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent4 & (tagMask())))) - && ((!((longAt(referent4)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((referent4 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckSemaphore) = referent4; - } - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -50236,33 +50165,6 @@ checkCodeIntegrity(sqInt fullGCFlag) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -50349,9 +50251,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { /* begin signalLowSpace: */ GIV(signalLowSpace) = 0; @@ -53163,26 +53062,8 @@ forceInterruptCheck(void) /* StackInterpreter>>#forceInterruptCheckFromHeartbeat */ void forceInterruptCheckFromHeartbeat(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT +{ if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; forceInterruptCheck(); } } @@ -55614,23 +55495,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i = 1; i <= GIV(jmpDepth); i += 1) { oop = GIV(suspendedCallbacks)[i]; @@ -59821,8 +59685,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -59851,18 +59715,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -64176,22 +64042,6 @@ validStackPageBaseFrame(StackPage *aPage) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Make sure that all VM state that affects the heap contents is voided so that the heap is ready to be snapshotted. If flushExtPrims is true, flush references to @@ -67286,115 +67136,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((addressCouldBeObj(lrpcm)) - && ((!(((longAt(lrpcm)) & (classIndexMask())) == (isFreeObjectClassIndexPun()))) - && (((((usqInt)((longAt(lrpcm)))) >> (formatShift())) & (formatMask())) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - assert(!(isForwarded(result))); - if ((assert(isNonImmediate(result)), - oopisGreaterThanOrEqualTo(result, GIV(oldSpaceStart)))) { - - /* most stores into young objects */ - if (((!(lrpcm & (tagMask())))) - && (oopisLessThan(lrpcm, GIV(newSpaceLimit)))) { - /* begin possibleRootStoreInto: */ - if (!(((((usqInt)((longAt(result)))) >> (rememberedBitShift())) & 1) != 0)) { - remember(result); - } - } - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 3) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 3) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt sema; - - /* begin stackValue: */ - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (((((sema) & 7) == 1)) - || (GIV(argumentCount) != 1)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - if (sema == GIV(nilObj)) { - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - if (!(((!(sema & (tagMask())))) - && (((longAt(sema)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(ClassSemaphore) << (shiftForWord())))))))))) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -70318,24 +70059,22 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveGreaterOrEqualLargeIntegers\000\377\000", (void*)primitiveGreaterOrEqualLargeIntegers}, {(void*)_m, "primitiveGreaterThanLargeIntegers\000\377\000", (void*)primitiveGreaterThanLargeIntegers}, {(void*)_m, "primitiveHeartbeatFrequency\000\377\000", (void*)primitiveHeartbeatFrequency}, - {(void*)_m, "primitiveHighResClock\000\377\000", (void*)primitiveHighResClock}, + {(void*)_m, "primitiveHighResClock\000\377\001", (void*)primitiveHighResClock}, {(void*)_m, "primitiveImageFormatVersion\000\377\000", (void*)primitiveImageFormatVersion}, {(void*)_m, "primitiveInterruptChecksPerMSec\000\377\000", (void*)primitiveInterruptChecksPerMSec}, {(void*)_m, "primitiveIsBigEnder\000\377\000", (void*)primitiveIsBigEnder}, {(void*)_m, "primitiveIsWindowObscured\000\377\000", (void*)primitiveIsWindowObscured}, {(void*)_m, "primitiveLessOrEqualLargeIntegers\000\377\000", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers\000\377\000", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive\000\377\000", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore\000\000\000", (void*)primitiveLongRunningPrimitiveSemaphore}, {(void*)_m, "primitiveMillisecondClockMask\000\377\000", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveModLargeIntegers\000\000\000", (void*)primitiveModLargeIntegers}, {(void*)_m, "primitiveMultiplyLargeIntegers\000\000\000", (void*)primitiveMultiplyLargeIntegers}, {(void*)_m, "primitiveNotEqualLargeIntegers\000\377\000", (void*)primitiveNotEqualLargeIntegers}, {(void*)_m, "primitivePathToUsing\000\000\000", (void*)primitivePathToUsing}, - {(void*)_m, "primitiveProfilePrimitive\000\377\000", (void*)primitiveProfilePrimitive}, - {(void*)_m, "primitiveProfileSample\000\377\000", (void*)primitiveProfileSample}, + {(void*)_m, "primitiveProfilePrimitive\000\377\001", (void*)primitiveProfilePrimitive}, + {(void*)_m, "primitiveProfileSample\000\377\001", (void*)primitiveProfileSample}, {(void*)_m, "primitiveProfileSemaphore\000\000\000", (void*)primitiveProfileSemaphore}, - {(void*)_m, "primitiveProfileStart\000\000\000", (void*)primitiveProfileStart}, + {(void*)_m, "primitiveProfileStart\000\000\001", (void*)primitiveProfileStart}, {(void*)_m, "primitiveQuoLargeIntegers\000\000\000", (void*)primitiveQuoLargeIntegers}, {(void*)_m, "primitiveRemLargeIntegers\000\000\000", (void*)primitiveRemLargeIntegers}, {(void*)_m, "primitiveScreenDepth\000\377\000", (void*)primitiveScreenDepth}, diff --git a/spurstack64src/vm/validImage.c b/spurstack64src/vm/validImage.c index 083345427f..0c7e720ee2 100644 --- a/spurstack64src/vm/validImage.c +++ b/spurstack64src/vm/validImage.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - ImageLeakChecker VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 + ImageLeakChecker VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "ImageLeakChecker VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 " __DATE__ ; +static char __buildInfo[] = "ImageLeakChecker VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -797,11 +797,7 @@ _iss char * localFP; _iss char * localIP; _iss sqInt localReturnValue; _iss char * localSP; -_iss sqInt longRunningPrimitiveCheckMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss usqLong longRunningPrimitiveGCUsecs; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss usqLong longRunningPrimitiveStartUsecs; _iss usqLong longRunningPrimitiveStopUsecs; _iss usqInt lowSpaceThreshold; @@ -933,7 +929,7 @@ sqInt extraVMMemory; sqInt ffiExceptionResponse; sqInt inIOProcessEvents; struct VirtualMachine* interpreterProxy; -const char *interpreterVersion = "Open Smalltalk ImageChecker VM [ImageLeakChecker VMMaker.oscog-eem.3022]"; +const char *interpreterVersion = "Open Smalltalk ImageChecker VM [ImageLeakChecker VMMaker.oscog-eem.3031]"; sqInt suppressHeartbeatFlag; int displayDepth; int displayHeight; @@ -11356,6 +11352,7 @@ static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -11382,16 +11379,18 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((fetchByteofObject(i, oop)) == 13) { - - /* Character cr asInteger */ + code = fetchByteofObject(i, oop); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + printChar(code); + } - printChar(fetchByteofObject(i, oop)); i += 1; } } diff --git a/spurstacksrc/vm/gcc3x-interp.c b/spurstacksrc/vm/gcc3x-interp.c index 997ba0e14f..9ffdc26488 100644 --- a/spurstacksrc/vm/gcc3x-interp.c +++ b/spurstacksrc/vm/gcc3x-interp.c @@ -2,11 +2,11 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - StackInterpreter VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 + StackInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 " __DATE__ ; +static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -1118,7 +1118,6 @@ extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHea extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); static sqInt NoDbgRegParms checkCodeIntegrity(sqInt fullGCFlag); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkForEventsMayContextSwitch(sqInt mayContextSwitch); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); @@ -1435,7 +1434,6 @@ static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, extern sqInt validInstructionPointerinMethodframePointer(usqInt theInstrPointer, usqInt aMethod, char *fp); static sqInt validStackPageBaseFrames(void); static sqInt NoDbgRegParms validStackPageBaseFrame(StackPage *aPage); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt NoDbgRegParms voidVMStateForSnapshotFlushingExternalPrimitivesIf(sqInt flushExtPrims); static sqInt wakeHighestPriority(void); EXPORT(char *) whereIs(sqInt anOop); @@ -1466,8 +1464,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1550,8 +1546,6 @@ _iss char * objStackInvalidBecause; _iss sqInt sweepIndex; _iss sqInt ephemeronList; _iss sqInt imageHeaderFlags; -_iss sqInt longRunningPrimitiveCheckMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; _iss sqInt profileSemaphore; _iss sqInt tenureCriterion; _iss usqInt totalHeapSizeIncludingBridges; @@ -1604,7 +1598,6 @@ _iss sqInt freeSpaceCheckOopToIgnore; _iss usqInt heapSizeAtPreviousGC; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss sqInt statGrowMemory; _iss sqInt statMaxPageCountWhenMapping; _iss sqInt statPageCountWhenMappingSum; @@ -1614,7 +1607,6 @@ _iss sqInt gcSemaphoreIndex; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; _iss sqInt inFFIFlags; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss sqInt methodDictLinearSearchLimit; _iss sqInt refCountToShrinkRT; @@ -1644,16 +1636,14 @@ _iss sqInt preferredPinningSegment; _iss sqInt statCoalesces; _iss sqLong nextProfileTick; _iss usqLong nextWakeupUsecs; -_iss usqLong statGCEndUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; -_iss usqLong statCheckForEvents; -_iss usqLong gcStartUsecs; _iss sqLong oldSpaceUsePriorToScavenge; +_iss usqLong statGCEndUsecs; _iss usqLong statIOProcessEvents; +_iss usqLong gcStartUsecs; _iss usqLong statAllocatedBytes; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statCompactionUsecs; _iss usqLong statForceInterruptCheck; _iss usqLong statFullGCUsecs; @@ -1666,9 +1656,11 @@ _iss usqLong statStackPageDivorce; _iss usqLong statSweepUsecs; _iss usqLong statSGCDeltaUsecs; _iss usqLong gcSweepEndUsecs; -_iss usqLong longRunningPrimitiveGCUsecs; _iss usqLong statIGCDeltaUsecs; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; _iss usqLong statFGCDeltaUsecs; _iss usqLong statIncrGCUsecs; _iss SpurContiguousObjStack savedFirstFieldsSpace; @@ -2341,7 +2333,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Open Smalltalk Stack VM [StackInterpreterPrimitives VMMaker.oscog-eem.3022]"; +const char *interpreterVersion = "Open Smalltalk Stack VM [StackInterpreterPrimitives VMMaker.oscog-eem.3031]"; sqInt suppressHeartbeatFlag; char primitiveDoMixedArithmetic = 1; char expensiveAsserts = 0; @@ -20075,26 +20067,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -23191,15 +23185,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -23217,15 +23206,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -23278,39 +23262,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((integerPointer & 1)) { - deltaTicks = (integerPointer >> 1); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((deltaTicks & 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 1)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -40034,8 +39997,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) sqInt referent; sqInt referent1; sqInt referent2; - sqInt referent3; - sqInt referent4; sqInt sizeOfUnusedEden; StackPage *thePage; @@ -40161,38 +40122,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - if ((!((longAt(GIV(longRunningPrimitiveCheckMethod))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckMethod))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((GIV(longRunningPrimitiveCheckMethod) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent3 & (tagMask())))) - && ((!((longAt(referent3)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((referent3 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckMethod) = referent3; - } - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - if ((!((longAt(GIV(longRunningPrimitiveCheckSemaphore))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckSemaphore))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((GIV(longRunningPrimitiveCheckSemaphore) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent4 & (tagMask())))) - && ((!((longAt(referent4)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((referent4 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckSemaphore) = referent4; - } - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -49192,33 +49121,6 @@ checkCodeIntegrity(sqInt fullGCFlag) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -49305,9 +49207,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { /* begin signalLowSpace: */ GIV(signalLowSpace) = 0; @@ -52132,26 +52031,8 @@ forceInterruptCheck(void) /* StackInterpreter>>#forceInterruptCheckFromHeartbeat */ void forceInterruptCheckFromHeartbeat(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT +{ if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; forceInterruptCheck(); } } @@ -54593,23 +54474,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i = 1; i <= GIV(jmpDepth); i += 1) { oop = GIV(suspendedCallbacks)[i]; @@ -58736,8 +58600,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -58766,18 +58630,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -63168,22 +63034,6 @@ validStackPageBaseFrame(StackPage *aPage) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Make sure that all VM state that affects the heap contents is voided so that the heap is ready to be snapshotted. If flushExtPrims is true, flush references to @@ -66397,115 +66247,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((addressCouldBeObj(lrpcm)) - && ((!(((longAt(lrpcm)) & (classIndexMask())) == (isFreeObjectClassIndexPun()))) - && (((((usqInt)((longAt(lrpcm)))) >> (formatShift())) & (formatMask())) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - assert(!(isForwarded(result))); - if ((assert(isNonImmediate(result)), - oopisGreaterThanOrEqualTo(result, GIV(oldSpaceStart)))) { - - /* most stores into young objects */ - if (((!(lrpcm & (tagMask())))) - && (oopisLessThan(lrpcm, GIV(newSpaceLimit)))) { - /* begin possibleRootStoreInto: */ - if (!(((((usqInt)((longAt(result)))) >> (rememberedBitShift())) & 1) != 0)) { - remember(result); - } - } - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 1) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 1) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt sema; - - /* begin stackValue: */ - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (((sema & 1)) - || (GIV(argumentCount) != 1)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - if (sema == GIV(nilObj)) { - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - if (!(((!(sema & (tagMask())))) - && (((longAt(sema)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(ClassSemaphore) << (shiftForWord())))))))))) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -69450,24 +69191,22 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveGreaterOrEqualLargeIntegers\000\377\000", (void*)primitiveGreaterOrEqualLargeIntegers}, {(void*)_m, "primitiveGreaterThanLargeIntegers\000\377\000", (void*)primitiveGreaterThanLargeIntegers}, {(void*)_m, "primitiveHeartbeatFrequency\000\377\000", (void*)primitiveHeartbeatFrequency}, - {(void*)_m, "primitiveHighResClock\000\377\000", (void*)primitiveHighResClock}, + {(void*)_m, "primitiveHighResClock\000\377\001", (void*)primitiveHighResClock}, {(void*)_m, "primitiveImageFormatVersion\000\377\000", (void*)primitiveImageFormatVersion}, {(void*)_m, "primitiveInterruptChecksPerMSec\000\377\000", (void*)primitiveInterruptChecksPerMSec}, {(void*)_m, "primitiveIsBigEnder\000\377\000", (void*)primitiveIsBigEnder}, {(void*)_m, "primitiveIsWindowObscured\000\377\000", (void*)primitiveIsWindowObscured}, {(void*)_m, "primitiveLessOrEqualLargeIntegers\000\377\000", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers\000\377\000", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive\000\377\000", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore\000\000\000", (void*)primitiveLongRunningPrimitiveSemaphore}, {(void*)_m, "primitiveMillisecondClockMask\000\377\000", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveModLargeIntegers\000\000\000", (void*)primitiveModLargeIntegers}, {(void*)_m, "primitiveMultiplyLargeIntegers\000\000\000", (void*)primitiveMultiplyLargeIntegers}, {(void*)_m, "primitiveNotEqualLargeIntegers\000\377\000", (void*)primitiveNotEqualLargeIntegers}, {(void*)_m, "primitivePathToUsing\000\000\000", (void*)primitivePathToUsing}, - {(void*)_m, "primitiveProfilePrimitive\000\377\000", (void*)primitiveProfilePrimitive}, - {(void*)_m, "primitiveProfileSample\000\377\000", (void*)primitiveProfileSample}, + {(void*)_m, "primitiveProfilePrimitive\000\377\001", (void*)primitiveProfilePrimitive}, + {(void*)_m, "primitiveProfileSample\000\377\001", (void*)primitiveProfileSample}, {(void*)_m, "primitiveProfileSemaphore\000\000\000", (void*)primitiveProfileSemaphore}, - {(void*)_m, "primitiveProfileStart\000\000\000", (void*)primitiveProfileStart}, + {(void*)_m, "primitiveProfileStart\000\000\001", (void*)primitiveProfileStart}, {(void*)_m, "primitiveQuoLargeIntegers\000\000\000", (void*)primitiveQuoLargeIntegers}, {(void*)_m, "primitiveRemLargeIntegers\000\000\000", (void*)primitiveRemLargeIntegers}, {(void*)_m, "primitiveScreenDepth\000\377\000", (void*)primitiveScreenDepth}, diff --git a/spurstacksrc/vm/interp.c b/spurstacksrc/vm/interp.c index c3342f8a6d..77fecca242 100644 --- a/spurstacksrc/vm/interp.c +++ b/spurstacksrc/vm/interp.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - StackInterpreter VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 + StackInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 " __DATE__ ; +static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -1115,7 +1115,6 @@ extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHea extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); static sqInt NoDbgRegParms checkCodeIntegrity(sqInt fullGCFlag); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkForEventsMayContextSwitch(sqInt mayContextSwitch); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); @@ -1432,7 +1431,6 @@ static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, extern sqInt validInstructionPointerinMethodframePointer(usqInt theInstrPointer, usqInt aMethod, char *fp); static sqInt validStackPageBaseFrames(void); static sqInt NoDbgRegParms validStackPageBaseFrame(StackPage *aPage); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt NoDbgRegParms voidVMStateForSnapshotFlushingExternalPrimitivesIf(sqInt flushExtPrims); static sqInt wakeHighestPriority(void); EXPORT(char *) whereIs(sqInt anOop); @@ -1463,8 +1461,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1547,8 +1543,6 @@ _iss char * objStackInvalidBecause; _iss sqInt sweepIndex; _iss sqInt ephemeronList; _iss sqInt imageHeaderFlags; -_iss sqInt longRunningPrimitiveCheckMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; _iss sqInt profileSemaphore; _iss sqInt tenureCriterion; _iss usqInt totalHeapSizeIncludingBridges; @@ -1601,7 +1595,6 @@ _iss sqInt freeSpaceCheckOopToIgnore; _iss usqInt heapSizeAtPreviousGC; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss sqInt statGrowMemory; _iss sqInt statMaxPageCountWhenMapping; _iss sqInt statPageCountWhenMappingSum; @@ -1611,7 +1604,6 @@ _iss sqInt gcSemaphoreIndex; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; _iss sqInt inFFIFlags; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss sqInt methodDictLinearSearchLimit; _iss sqInt refCountToShrinkRT; @@ -1641,16 +1633,14 @@ _iss sqInt preferredPinningSegment; _iss sqInt statCoalesces; _iss sqLong nextProfileTick; _iss usqLong nextWakeupUsecs; -_iss usqLong statGCEndUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; -_iss usqLong statCheckForEvents; -_iss usqLong gcStartUsecs; _iss sqLong oldSpaceUsePriorToScavenge; +_iss usqLong statGCEndUsecs; _iss usqLong statIOProcessEvents; +_iss usqLong gcStartUsecs; _iss usqLong statAllocatedBytes; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statCompactionUsecs; _iss usqLong statForceInterruptCheck; _iss usqLong statFullGCUsecs; @@ -1663,9 +1653,11 @@ _iss usqLong statStackPageDivorce; _iss usqLong statSweepUsecs; _iss usqLong statSGCDeltaUsecs; _iss usqLong gcSweepEndUsecs; -_iss usqLong longRunningPrimitiveGCUsecs; _iss usqLong statIGCDeltaUsecs; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; _iss usqLong statFGCDeltaUsecs; _iss usqLong statIncrGCUsecs; _iss SpurContiguousObjStack savedFirstFieldsSpace; @@ -2338,7 +2330,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Open Smalltalk Stack VM [StackInterpreterPrimitives VMMaker.oscog-eem.3022]"; +const char *interpreterVersion = "Open Smalltalk Stack VM [StackInterpreterPrimitives VMMaker.oscog-eem.3031]"; sqInt suppressHeartbeatFlag; char primitiveDoMixedArithmetic = 1; char expensiveAsserts = 0; @@ -20066,26 +20058,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -23182,15 +23176,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -23208,15 +23197,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -23269,39 +23253,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((integerPointer & 1)) { - deltaTicks = (integerPointer >> 1); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((deltaTicks & 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 1)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -40025,8 +39988,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) sqInt referent; sqInt referent1; sqInt referent2; - sqInt referent3; - sqInt referent4; sqInt sizeOfUnusedEden; StackPage *thePage; @@ -40152,38 +40113,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - if ((!((longAt(GIV(longRunningPrimitiveCheckMethod))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckMethod))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((GIV(longRunningPrimitiveCheckMethod) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent3 & (tagMask())))) - && ((!((longAt(referent3)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((referent3 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckMethod) = referent3; - } - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - if ((!((longAt(GIV(longRunningPrimitiveCheckSemaphore))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckSemaphore))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((GIV(longRunningPrimitiveCheckSemaphore) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent4 & (tagMask())))) - && ((!((longAt(referent4)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((referent4 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckSemaphore) = referent4; - } - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -49183,33 +49112,6 @@ checkCodeIntegrity(sqInt fullGCFlag) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -49296,9 +49198,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { /* begin signalLowSpace: */ GIV(signalLowSpace) = 0; @@ -52123,26 +52022,8 @@ forceInterruptCheck(void) /* StackInterpreter>>#forceInterruptCheckFromHeartbeat */ void forceInterruptCheckFromHeartbeat(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT +{ if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; forceInterruptCheck(); } } @@ -54584,23 +54465,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i = 1; i <= GIV(jmpDepth); i += 1) { oop = GIV(suspendedCallbacks)[i]; @@ -58727,8 +58591,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -58757,18 +58621,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -63159,22 +63025,6 @@ validStackPageBaseFrame(StackPage *aPage) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Make sure that all VM state that affects the heap contents is voided so that the heap is ready to be snapshotted. If flushExtPrims is true, flush references to @@ -66388,115 +66238,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((addressCouldBeObj(lrpcm)) - && ((!(((longAt(lrpcm)) & (classIndexMask())) == (isFreeObjectClassIndexPun()))) - && (((((usqInt)((longAt(lrpcm)))) >> (formatShift())) & (formatMask())) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - assert(!(isForwarded(result))); - if ((assert(isNonImmediate(result)), - oopisGreaterThanOrEqualTo(result, GIV(oldSpaceStart)))) { - - /* most stores into young objects */ - if (((!(lrpcm & (tagMask())))) - && (oopisLessThan(lrpcm, GIV(newSpaceLimit)))) { - /* begin possibleRootStoreInto: */ - if (!(((((usqInt)((longAt(result)))) >> (rememberedBitShift())) & 1) != 0)) { - remember(result); - } - } - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 1) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 1) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt sema; - - /* begin stackValue: */ - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (((sema & 1)) - || (GIV(argumentCount) != 1)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - if (sema == GIV(nilObj)) { - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - if (!(((!(sema & (tagMask())))) - && (((longAt(sema)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(ClassSemaphore) << (shiftForWord())))))))))) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -69441,24 +69182,22 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveGreaterOrEqualLargeIntegers\000\377\000", (void*)primitiveGreaterOrEqualLargeIntegers}, {(void*)_m, "primitiveGreaterThanLargeIntegers\000\377\000", (void*)primitiveGreaterThanLargeIntegers}, {(void*)_m, "primitiveHeartbeatFrequency\000\377\000", (void*)primitiveHeartbeatFrequency}, - {(void*)_m, "primitiveHighResClock\000\377\000", (void*)primitiveHighResClock}, + {(void*)_m, "primitiveHighResClock\000\377\001", (void*)primitiveHighResClock}, {(void*)_m, "primitiveImageFormatVersion\000\377\000", (void*)primitiveImageFormatVersion}, {(void*)_m, "primitiveInterruptChecksPerMSec\000\377\000", (void*)primitiveInterruptChecksPerMSec}, {(void*)_m, "primitiveIsBigEnder\000\377\000", (void*)primitiveIsBigEnder}, {(void*)_m, "primitiveIsWindowObscured\000\377\000", (void*)primitiveIsWindowObscured}, {(void*)_m, "primitiveLessOrEqualLargeIntegers\000\377\000", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers\000\377\000", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive\000\377\000", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore\000\000\000", (void*)primitiveLongRunningPrimitiveSemaphore}, {(void*)_m, "primitiveMillisecondClockMask\000\377\000", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveModLargeIntegers\000\000\000", (void*)primitiveModLargeIntegers}, {(void*)_m, "primitiveMultiplyLargeIntegers\000\000\000", (void*)primitiveMultiplyLargeIntegers}, {(void*)_m, "primitiveNotEqualLargeIntegers\000\377\000", (void*)primitiveNotEqualLargeIntegers}, {(void*)_m, "primitivePathToUsing\000\000\000", (void*)primitivePathToUsing}, - {(void*)_m, "primitiveProfilePrimitive\000\377\000", (void*)primitiveProfilePrimitive}, - {(void*)_m, "primitiveProfileSample\000\377\000", (void*)primitiveProfileSample}, + {(void*)_m, "primitiveProfilePrimitive\000\377\001", (void*)primitiveProfilePrimitive}, + {(void*)_m, "primitiveProfileSample\000\377\001", (void*)primitiveProfileSample}, {(void*)_m, "primitiveProfileSemaphore\000\000\000", (void*)primitiveProfileSemaphore}, - {(void*)_m, "primitiveProfileStart\000\000\000", (void*)primitiveProfileStart}, + {(void*)_m, "primitiveProfileStart\000\000\001", (void*)primitiveProfileStart}, {(void*)_m, "primitiveQuoLargeIntegers\000\000\000", (void*)primitiveQuoLargeIntegers}, {(void*)_m, "primitiveRemLargeIntegers\000\000\000", (void*)primitiveRemLargeIntegers}, {(void*)_m, "primitiveScreenDepth\000\377\000", (void*)primitiveScreenDepth}, diff --git a/spurstacksrc/vm/validImage.c b/spurstacksrc/vm/validImage.c index 7af1dbe386..6a7043369c 100644 --- a/spurstacksrc/vm/validImage.c +++ b/spurstacksrc/vm/validImage.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - ImageLeakChecker VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 + ImageLeakChecker VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "ImageLeakChecker VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 " __DATE__ ; +static char __buildInfo[] = "ImageLeakChecker VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -783,10 +783,6 @@ _iss char * localFP; _iss char * localIP; _iss sqInt localReturnValue; _iss char * localSP; -_iss sqInt longRunningPrimitiveCheckMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss usqInt lowSpaceThreshold; _iss sqInt maxExtSemTabSizeSet; _iss sqInt messageSelector; @@ -927,7 +923,7 @@ sqInt extraVMMemory; sqInt ffiExceptionResponse; sqInt inIOProcessEvents; struct VirtualMachine* interpreterProxy; -const char *interpreterVersion = "Open Smalltalk ImageChecker VM [ImageLeakChecker VMMaker.oscog-eem.3022]"; +const char *interpreterVersion = "Open Smalltalk ImageChecker VM [ImageLeakChecker VMMaker.oscog-eem.3031]"; sqInt suppressHeartbeatFlag; char primitiveDoMixedArithmetic = 1; char expensiveAsserts = 0; @@ -11167,6 +11163,7 @@ static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -11193,16 +11190,18 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((fetchByteofObject(i, oop)) == 13) { - - /* Character cr asInteger */ + code = fetchByteofObject(i, oop); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + printChar(code); + } - printChar(fetchByteofObject(i, oop)); i += 1; } } diff --git a/src/vm/cogit.c b/src/vm/cogit.c index 6b394d06cd..8d71e53f42 100644 --- a/src/vm/cogit.c +++ b/src/vm/cogit.c @@ -1,5 +1,5 @@ /* Automatically generated by - Cogit VMMaker.oscog-eem.2535 uuid: e4217d2b-77f4-4947-ad0a-eabe9fa6b911 + Cogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ #if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7__) || defined(__arm__) || defined(__arm32__) || defined(ARM32) || defined(_M_ARM) @@ -10,10 +10,6 @@ # include "cogitIA32.c" -#elif defined(__MIPSEL__) - -# include "cogitMIPSEL.c" - #else # error As yet no Cogit implementation appears to exist for your platform. # error Consider implementing it, starting by adding a subclass of CogAbstractInstruction. diff --git a/src/vm/cogit.h b/src/vm/cogit.h index 71890ceb07..c76a3356b4 100644 --- a/src/vm/cogit.h +++ b/src/vm/cogit.h @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + CCodeGenerator VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ diff --git a/src/vm/cogitARMv5.c b/src/vm/cogitARMv5.c index 38074bf742..70be906388 100644 --- a/src/vm/cogitARMv5.c +++ b/src/vm/cogitARMv5.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + CCodeGenerator VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + StackToRegisterMappingCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 " __DATE__ ; +static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__cogitBuildInfo = __buildInfo; @@ -81,7 +81,7 @@ char *__cogitBuildInfo = __buildInfo; #define CMMaxUsageCount 7 #define CMMethod 2 #define CMOpenPIC 5 -#define CMPSMULL 165 +#define CMPSMULL 167 #define CmpC32R 113 #define CmpCqR 105 #define CmpCwR 112 @@ -232,6 +232,8 @@ char *__cogitBuildInfo = __buildInfo; #define MoveMwrR 50 #define MoveNotOpcode 15 #define MoveOpcode 13 +#define MovePerfCnt64RL 159 +#define MovePerfCnt64RRL 158 #define MoveRAb 49 #define MoveRAw 46 #define MoveRdM64r 76 @@ -244,7 +246,7 @@ char *__cogitBuildInfo = __buildInfo; #define MoveRXwrR 53 #define MoveXbrRR 67 #define MoveXwrRR 52 -#define MSR 159 +#define MSR 161 #define MULTIPLEBYTECODESETS 0 #define MulRdRd 134 #define NativePopR 84 @@ -272,7 +274,7 @@ char *__cogitBuildInfo = __buildInfo; #define PC 15 #define PCReg 15 #define PL 5 -#define PopLDM 161 +#define PopLDM 163 #define PopR 80 #define PrefetchAw 87 #define PrimCallCollectsProfileSamples 8 @@ -288,7 +290,7 @@ char *__cogitBuildInfo = __buildInfo; #define PushCq 82 #define PushCw 83 #define PushR 81 -#define PushSTM 162 +#define PushSTM 164 #define ReceiverIndex 5 #define ReceiverResultReg 5 #define RetN 9 @@ -305,7 +307,7 @@ char *__cogitBuildInfo = __buildInfo; #define SistaVM 0 #define Size4Bit 0 #define SizeMask 0xFC -#define SMULL 158 +#define SMULL 160 #define SP 13 #define SPReg 13 #define SPURVM 0 @@ -315,6 +317,7 @@ char *__cogitBuildInfo = __buildInfo; #define SSRegister 3 #define SSSpill 4 #define Stop 11 +#define SubbRR 121 #define SubCqR 107 #define SubCwR 115 #define SubOpcode 2 @@ -459,7 +462,7 @@ static void NoDbgRegParms cloneLiteralFrom(AbstractInstruction * self_in_cloneLi static sqInt NoDbgRegParms genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer); static sqInt NoDbgRegParms genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers); static sqInt NoDbgRegParms genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers); -static sqInt NoDbgRegParms genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg); +static sqInt NoDbgRegParms genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg); static sqInt NoDbgRegParms genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers); static AbstractInstruction * NoDbgRegParms genSwapRRScratch(AbstractInstruction * self_in_genSwapRRScratch, sqInt regA, sqInt regB, sqInt regTmp); static void NoDbgRegParms genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister); @@ -716,6 +719,8 @@ static void NoDbgRegParms loadSubsequentBytesForDescriptorat(BytecodeDescriptor static AbstractInstruction * NoDbgRegParms gMoveAwR(sqInt address, sqInt reg); static AbstractInstruction * NoDbgRegParms gMoveCwR(sqInt wordConstant, sqInt reg); static AbstractInstruction * NoDbgRegParms gMoveMwrR(sqInt offset, sqInt baseReg, sqInt destReg); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters); static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg); static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC); @@ -764,6 +769,7 @@ static void NoDbgRegParms recordGeneratedRunTimeaddress(char *aString, sqInt add extern sqInt recordPrimTraceFunc(void); static void recordRunTimeObjectReferences(void); static sqInt NoDbgRegParms registerMaskFor(sqInt reg); +static sqInt NoDbgRegParms registerMaskForand(sqInt reg1, sqInt reg2); static void NoDbgRegParms relocateCallsAndSelfReferencesInMethod(CogMethod *cogMethod); static void NoDbgRegParms relocateCallsInClosedPIC(CogMethod *cPIC); static sqInt NoDbgRegParms relocateIfCallOrMethodReferencemcpcdelta(sqInt annotation, char *mcpc, CogMethod *refDeltaArg); @@ -1032,6 +1038,7 @@ static sqInt genStoreAndPopReceiverVariableBytecode(void); static sqInt genStoreAndPopRemoteTempLongBytecode(void); static sqInt genStoreAndPopTemporaryVariableBytecode(void); static sqInt genStoreRemoteTempLongBytecode(void); +static void genTakeProfileSample(void); extern sqInt mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj); static sqInt numSpecialSelectors(void); static usqInt NoDbgRegParms pcDataForBlockEntryMethod(sqInt blockEntryMcpc, sqInt cogMethod); @@ -2305,28 +2312,28 @@ addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *an static sqInt NoDbgRegParms availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << DPFPReg0)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg0))) != 0))) { return DPFPReg0; } - if (!(((liveRegsMask & (1U << DPFPReg1)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg1))) != 0))) { return DPFPReg1; } - if (!(((liveRegsMask & (1U << DPFPReg2)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg2))) != 0))) { return DPFPReg2; } - if (!(((liveRegsMask & (1U << DPFPReg3)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg3))) != 0))) { return DPFPReg3; } - if (!(((liveRegsMask & (1U << DPFPReg4)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg4))) != 0))) { return DPFPReg4; } - if (!(((liveRegsMask & (1U << DPFPReg5)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg5))) != 0))) { return DPFPReg5; } - if (!(((liveRegsMask & (1U << DPFPReg6)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg6))) != 0))) { return DPFPReg6; } - if (!(((liveRegsMask & (1U << DPFPReg7)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg7))) != 0))) { return DPFPReg7; } return NoReg; @@ -2426,11 +2433,11 @@ genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers) used immediately afterwards. */ - /* CogAbstractInstruction>>#genLoadStackPointersForFastPrimCall: */ + /* CogAbstractInstruction>>#genLoadStackPointersForPrimCall: */ static sqInt NoDbgRegParms -genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg) +genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg) { - genLoadStackPointers(self_in_genLoadStackPointersForFastPrimCall); + genLoadStackPointers(self_in_genLoadStackPointersForPrimCall); return 0; } @@ -2696,28 +2703,28 @@ andrnimmror(AbstractInstruction * self_in_andrnimmror, sqInt destReg, sqInt srcR static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << Extra0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra0Reg))) != 0))) { return Extra0Reg; } - if (!(((liveRegsMask & (1U << Extra1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra1Reg))) != 0))) { return Extra1Reg; } - if (!(((liveRegsMask & (1U << Extra2Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra2Reg))) != 0))) { return Extra2Reg; } - if (!(((liveRegsMask & (1U << Arg1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg1Reg))) != 0))) { return Arg1Reg; } - if (!(((liveRegsMask & (1U << Arg0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg0Reg))) != 0))) { return Arg0Reg; } - if (!(((liveRegsMask & (1U << SendNumArgsReg)) != 0))) { + if (!(((liveRegsMask & ((1U << SendNumArgsReg))) != 0))) { return SendNumArgsReg; } - if (!(((liveRegsMask & (1U << ClassReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ClassReg))) != 0))) { return ClassReg; } - if (!(((liveRegsMask & (1U << ReceiverResultReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ReceiverResultReg))) != 0))) { return ReceiverResultReg; } return NoReg; @@ -9629,7 +9636,7 @@ compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numAr regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1U << resultRegOrNone)) - (1U << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1U << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1U << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ regMaskCopy = ((usqInt)regsToSave); @@ -10876,7 +10883,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) startAddress = methodZoneBase; callerSavedReg = 0; pushedVarBaseReg = 0; - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { /* VarBaseReg is not caller-saved; must save and restore it, either by using an available caller-saved reg or push/pop. */ @@ -10926,7 +10933,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) operandTwo2 = cStackPointerAddress(); checkLiteralforInstruction(operandTwo2, genoperandoperand(MoveRAw, NativeSPReg, operandTwo2)); } - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { if (pushedVarBaseReg) { gNativePopR(VarBaseReg); } @@ -12213,6 +12220,22 @@ gMoveMwrR(sqInt offset, sqInt baseReg, sqInt destReg) return anInstruction; } + /* Cogit>>#MovePerfCnt64R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters) +{ + assert(0); + return genoperandoperand(MovePerfCnt64RL, destReg, liveRegisters); +} + + /* Cogit>>#MovePerfCnt64R:R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters) +{ + assert(0); + return genoperandoperandoperand(MovePerfCnt64RRL, destRegLo, destRegHi, liveRegisters); +} + /* Answer the address of the null byte at the end of the method map. */ @@ -13739,11 +13762,21 @@ recordRunTimeObjectReferences(void) } } + +/* N.B. (self registerMaskFor: NoReg) = 0 */ + /* Cogit>>#registerMaskFor: */ static sqInt NoDbgRegParms registerMaskFor(sqInt reg) { - return 1U << reg; + return ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); +} + + /* Cogit>>#registerMaskFor:and: */ +static sqInt NoDbgRegParms +registerMaskForand(sqInt reg1, sqInt reg2) +{ + return (1U << reg1) | (1U << reg2); } /* Cogit>>#relocateCallsAndSelfReferencesInMethod: */ @@ -17555,20 +17588,20 @@ generateObjectRepresentationTrampolines(void) sqInt resultReg; /* begin genTrampolineFor:called:arg:regsToSave:result: */ - regMask = ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)); - resultReg = (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + regMask = ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))); + resultReg = (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg); ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceStoreCheck, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, regMask, 1, resultReg, 0); /* begin genTrampolineFor:called:arg:regsToSave:result: */ - regMask1 = ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)); + regMask1 = ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))); ceCreateNewArrayTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewArraySlotSize, "ceCreateNewArrayTrampoline", 1, SendNumArgsReg, null, null, null, regMask1, 1, ReceiverResultReg, 0); /* begin genTrampolineFor:called:arg:regsToSave:result: */ - regMask2 = ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)); + regMask2 = ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))); cePositive32BitIntegerTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(positive32BitIntegerFor, "cePositive32BitIntegerTrampoline", 1, ReceiverResultReg, null, null, null, regMask2, 1, TempReg, 0); ceActiveContextTrampoline = genActiveContextTrampoline(); /* begin genTrampolineFor:called:arg:regsToSave:result: */ - regMask3 = ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)); + regMask3 = ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))); ceClosureCopyTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceClosureCopyDescriptor, "ceClosureCopyTrampoline", 1, SendNumArgsReg, null, null, null, regMask3, 1, ReceiverResultReg, 0); } @@ -19737,7 +19770,7 @@ registerMask(SimStackEntry * self_in_registerMask) || (((self_in_registerMask->type)) == SSRegister) ? (/* begin registerMaskFor: */ (reg = (self_in_registerMask->registerr)), - 1U << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg))) : 0); } @@ -19750,7 +19783,7 @@ registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone) return (((self_in_registerMaskOrNone->type)) == SSRegister ? (/* begin registerMaskFor: */ (reg = (self_in_registerMaskOrNone->registerr)), - 1U << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg))) : 0); } @@ -20139,40 +20172,24 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) { sqInt address; sqInt address1; - sqInt address10; - sqInt address11; - sqInt address12; - sqInt address13; - sqInt address3; - sqInt address4; - sqInt address5; + sqInt address2; sqInt address6; + sqInt address7; sqInt address8; sqInt address9; + AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; AbstractInstruction *anInstruction4; AbstractInstruction *anInstruction5; AbstractInstruction *anInstruction6; AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction * continuePostSampleNonPrim; - AbstractInstruction * continuePostSamplePrim; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; - AbstractInstruction * jmpSampleNonPrim; - AbstractInstruction * jmpSamplePrim; sqInt offset; sqInt offset1; sqInt offset2; - sqInt operand1; - sqInt operand3; - sqInt reg; sqInt retpc; - continuePostSampleNonPrim = ((AbstractInstruction *) 0); - continuePostSamplePrim = ((AbstractInstruction *) 0); - jmpSampleNonPrim = ((AbstractInstruction *) 0); - jmpSamplePrim = ((AbstractInstruction *) 0); assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); genExternalizePointersForPrimitiveCall(); /* begin genLoadCStackPointersForPrimCall */ @@ -20182,54 +20199,36 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) else { genLoadCStackPointer(backEnd); } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick if so */ - /* begin MoveAw:R: */ - address = nextProfileTickAddress(); - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address, genoperandoperand(MoveAwR, address, TempReg)); - /* begin MoveAw:R: */ - address1 = (nextProfileTickAddress()) + BytesPerWord; - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address1, genoperandoperand(MoveAwR, address1, ClassReg)); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSampleNonPrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSampleNonPrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } if (recordPrimTraceForMethod(methodObj)) { genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(MoveCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction8)) { - (anInstruction8->dependent = locateLiteral(0)); + anInstruction4 = genoperandoperand(MoveCqR, 0, TempReg); + if (usesOutOfLineLiteral(anInstruction4)) { + (anInstruction4->dependent = locateLiteral(0)); } /* begin MoveR:Aw: */ - address11 = primFailCodeAddress(); + address6 = primFailCodeAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address11, genoperandoperand(MoveRAw, TempReg, address11)); + checkLiteralforInstruction(address6, genoperandoperand(MoveRAw, TempReg, address6)); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); - if (usesOutOfLineLiteral(anInstruction1)) { - (anInstruction1->dependent = locateLiteral(methodOrBlockNumArgs)); + anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); + if (usesOutOfLineLiteral(anInstruction)) { + (anInstruction->dependent = locateLiteral(methodOrBlockNumArgs)); } } /* begin MoveR:Aw: */ - address12 = argumentCountAddress(); + address7 = argumentCountAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address12, genoperandoperand(MoveRAw, TempReg, address12)); + checkLiteralforInstruction(address7, genoperandoperand(MoveRAw, TempReg, address7)); if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { /* begin MoveCw:R: */ checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg)); /* begin MoveR:Aw: */ - address3 = primitiveFunctionPointerAddress(); + address = primitiveFunctionPointerAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address3, genoperandoperand(MoveRAw, TempReg, address3)); + checkLiteralforInstruction(address, genoperandoperand(MoveRAw, TempReg, address)); } if (((flags & (PrimCallNeedsNewMethod + PrimCallMayEndureCodeCompaction)) != 0)) { @@ -20241,22 +20240,21 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) /* begin MoveMw:r:R: */ offset = offsetof(CogMethod, methodObject); /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - if (usesOutOfLineLiteral(anInstruction2)) { - (anInstruction2->dependent = locateLiteral(offset)); + anInstruction1 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); + if (usesOutOfLineLiteral(anInstruction1)) { + (anInstruction1->dependent = locateLiteral(offset)); } /* begin MoveR:Aw: */ - address4 = newMethodAddress(); + address1 = newMethodAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address4, genoperandoperand(MoveRAw, TempReg, address4)); + checkLiteralforInstruction(address1, genoperandoperand(MoveRAw, TempReg, address1)); } /* begin PrefetchAw: */ - address13 = primFailCodeAddress(); + address8 = primFailCodeAddress(); /* begin gen:literal: */ - checkLiteralforInstruction(address13, genoperand(PrefetchAw, address13)); + checkLiteralforInstruction(address8, genoperand(PrefetchAw, address8)); if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - /* Sideways call the C primitive routine so that we return through cePrimReturnEnterCogCode. */ /* On Spur ceActivateFailingPrimitiveMethod: would like to retry if forwarders are found. So insist on PrimCallNeedsPrimitiveFunction being set too. */ genMarshallNArgsargargargarg(backEnd, 0, null, null, null, null); @@ -20268,102 +20266,47 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) checkLiteralforInstruction(retpc, genoperandoperand(MoveCwR, retpc, LR)); /* begin gen:literal: */ checkLiteralforInstruction(((sqInt)(((sqInt)primitiveRoutine))), genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine))))); - jmp = (jmpSamplePrim = (continuePostSamplePrim = null)); + return 0; } - else { - - /* Call the C primitive routine. */ - genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); - /* begin gen:literal: */ - checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperand(CallFull, ((sqInt)primitiveRoutine))); - /* begin genRemoveNArgsFromStack: */ - assert(0 <= 4); - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin MoveAw:R: */ - address5 = nextProfileTickAddress(); - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address5, genoperandoperand(MoveAwR, address5, TempReg)); - /* begin MoveAw:R: */ - address6 = (nextProfileTickAddress()) + BytesPerWord; - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address6, genoperandoperand(MoveAwR, address6, ClassReg)); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSamplePrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSamplePrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - /* begin MoveAw:R: */ - address8 = instructionPointerAddress(); - reg = LinkReg; - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address8, genoperandoperand(MoveAwR, address8, reg)); - genLoadStackPointers(backEnd); - /* begin MoveAw:R: */ - address9 = primFailCodeAddress(); - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address9, genoperandoperand(MoveAwR, address9, TempReg)); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction4)) { - (anInstruction4->dependent = locateLiteral(0)); - } - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset1 = 0; - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); - if (usesOutOfLineLiteral(anInstruction5)) { - (anInstruction5->dependent = locateLiteral(offset1)); - } - /* begin RetN: */ - genoperand(RetN, BytesPerWord); + genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); + /* begin gen:literal: */ + checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperand(CallFull, ((sqInt)primitiveRoutine))); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 4); + genLoadStackPointersForPrimCall(backEnd, ClassReg); + /* begin MoveAw:R: */ + address2 = instructionPointerAddress(); + /* begin gen:literal:operand: */ + checkLiteralforInstruction(address2, genoperandoperand(MoveAwR, address2, LinkReg)); + /* begin MoveAw:R: */ + address9 = primFailCodeAddress(); + /* begin gen:literal:operand: */ + checkLiteralforInstruction(address9, genoperandoperand(MoveAwR, address9, TempReg)); + flag("ask concrete code gen if move sets condition codes?"); + /* begin checkQuickConstant:forInstruction: */ + anInstruction5 = genoperandoperand(CmpCqR, 0, TempReg); + if (usesOutOfLineLiteral(anInstruction5)) { + (anInstruction5->dependent = locateLiteral(0)); } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* The sample is collected by cePrimReturnEnterCogCode for external calls */ - if (!(jmpSamplePrim == null)) { - - /* Call ceCheckProfileTick: to record sample and then continue. */ - jmpTarget(jmpSamplePrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin gen:literal: */ - operand1 = ((usqIntptr_t)ceCheckProfileTick); - checkLiteralforInstruction(operand1, genoperand(CallFull, operand1)); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSamplePrim)); - } - jmpTarget(jmpSampleNonPrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(MoveCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction6)) { - (anInstruction6->dependent = locateLiteral(0)); - } - /* begin MoveR:Aw: */ - address10 = newMethodAddress(); - /* begin gen:operand:literal: */ - checkLiteralforInstruction(address10, genoperandoperand(MoveRAw, TempReg, address10)); - /* begin gen:literal: */ - operand3 = ((usqIntptr_t)ceCheckProfileTick); - checkLiteralforInstruction(operand3, genoperand(CallFull, operand3)); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSampleNonPrim)); + /* begin JumpNonZero: */ + jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + /* begin MoveMw:r:R: */ + offset1 = 0; + /* begin checkQuickConstant:forInstruction: */ + anInstruction6 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); + if (usesOutOfLineLiteral(anInstruction6)) { + (anInstruction6->dependent = locateLiteral(offset1)); } - if (!(jmp == null)) { - - /* Jump to restore of receiver reg and proceed to frame build for failure. */ - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin MoveMw:r:R: */ - offset2 = BytesPerWord * (methodOrBlockNumArgs + (0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); - if (usesOutOfLineLiteral(anInstruction7)) { - (anInstruction7->dependent = locateLiteral(offset2)); - } + continueAfterProfileSample = anInstruction6; + /* begin RetN: */ + genoperand(RetN, BytesPerWord); + jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + /* begin MoveMw:r:R: */ + offset2 = BytesPerWord * (methodOrBlockNumArgs + (0)); + /* begin checkQuickConstant:forInstruction: */ + anInstruction7 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); + if (usesOutOfLineLiteral(anInstruction7)) { + (anInstruction7->dependent = locateLiteral(offset2)); } return 0; } @@ -20393,7 +20336,7 @@ compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)) if ((methodOrBlockNumArgs > 1 /* numRegArgs */) || (methodOrBlockNumArgs == 0)) { /* begin registerMaskFor: */ - liveRegsMask = 1U << ReceiverResultReg; + liveRegsMask = (1U << ReceiverResultReg); } else { /* begin registerMaskFor:and: */ @@ -21148,24 +21091,16 @@ static void NoDbgRegParms genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) { sqInt address; - sqInt address1; sqInt address3; - sqInt address6; - sqInt address7; - sqInt address8; + sqInt address4; + sqInt address5; AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction7; - sqInt callTarget; - AbstractInstruction *continuePostSample; - AbstractInstruction * inst; + AbstractInstruction *anInstruction4; + AbstractInstruction *anInstruction6; AbstractInstruction *jmpFail; - AbstractInstruction *jmpSample; sqInt quickConstant; sqInt reg; - continuePostSample = ((AbstractInstruction *) 0); - jmpSample = ((AbstractInstruction *) 0); zeroOpcodeIndex(); /* begin MoveCq:R: */ quickConstant = varBaseAddress(); @@ -21174,34 +21109,15 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) if (usesOutOfLineLiteral(anInstruction)) { (anInstruction->dependent = locateLiteral(quickConstant)); } - if (profiling) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick: if so. - N.B. nextProfileTick is 64-bits so 32-bit systems need to test both halves. */ - /* begin MoveAw:R: */ - address = nextProfileTickAddress(); - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address, genoperandoperand(MoveAwR, address, TempReg)); - /* begin MoveAw:R: */ - address1 = (nextProfileTickAddress()) + BytesPerWord; - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address1, genoperandoperand(MoveAwR, address1, ClassReg)); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSample = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } /* begin MoveAw:R: */ - address6 = primFailCodeAddress(); + address3 = primFailCodeAddress(); /* begin gen:literal:operand: */ - checkLiteralforInstruction(address6, genoperandoperand(MoveAwR, address6, TempReg)); + checkLiteralforInstruction(address3, genoperandoperand(MoveAwR, address3, TempReg)); flag("ask concrete code gen if move sets condition codes?"); /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(CmpCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction7)) { - (anInstruction7->dependent = locateLiteral(0)); + anInstruction6 = genoperandoperand(CmpCqR, 0, TempReg); + if (usesOutOfLineLiteral(anInstruction6)) { + (anInstruction6->dependent = locateLiteral(0)); } /* begin JumpNonZero: */ jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); @@ -21209,44 +21125,29 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) /* begin PopR: */ genoperand(PopR, ReceiverResultReg); /* begin MoveAw:R: */ - address3 = instructionPointerAddress(); + address = instructionPointerAddress(); /* begin gen:literal:operand: */ - checkLiteralforInstruction(address3, genoperandoperand(MoveAwR, address3, PCReg)); + checkLiteralforInstruction(address, genoperandoperand(MoveAwR, address, PCReg)); jmpTarget(jmpFail, gMoveAwR(newMethodAddress(), SendNumArgsReg)); /* begin MoveAw:R: */ - address7 = cStackPointerAddress(); + address4 = cStackPointerAddress(); /* begin gen:literal:operand: */ - checkLiteralforInstruction(address7, genoperandoperand(MoveAwR, address7, SPReg)); + checkLiteralforInstruction(address4, genoperandoperand(MoveAwR, address4, SPReg)); compileCallFornumArgsargargargargresultRegregsToSave(ceActivateFailingPrimitiveMethod, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); /* begin MoveAw:R: */ - address8 = instructionPointerAddress(); + address5 = instructionPointerAddress(); reg = LinkReg; /* begin gen:literal:operand: */ - checkLiteralforInstruction(address8, genoperandoperand(MoveAwR, address8, reg)); + checkLiteralforInstruction(address5, genoperandoperand(MoveAwR, address5, reg)); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); - if (usesOutOfLineLiteral(anInstruction5)) { - (anInstruction5->dependent = locateLiteral(0)); + anInstruction4 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); + if (usesOutOfLineLiteral(anInstruction4)) { + (anInstruction4->dependent = locateLiteral(0)); } /* begin RetN: */ genoperand(RetN, BytesPerWord); - if (profiling) { - - /* Call ceCheckProfileTick: to record sample and then continue. newMethod - should be up-to-date. Need to save and restore the link reg around this call. */ - jmpTarget(jmpSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - /* begin CallFullRT: */ - callTarget = (usqIntptr_t)ceCheckProfileTick; - /* begin gen:literal: */ - checkLiteralforInstruction(callTarget, genoperand(CallFull, callTarget)); - genoperand(PopR, LinkReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSample)); } -} /* SimpleStackBasedCogit>>#genPushConstantFalseBytecode */ static sqInt @@ -21547,6 +21448,21 @@ genStoreRemoteTempLongBytecode(void) && (shouldAnnotateObjectReference(((ssTop())->constant))))); } + /* SimpleStackBasedCogit>>#genTakeProfileSample */ +static void +genTakeProfileSample(void) +{ + sqInt operand1; + + addDependent(methodLabel, annotateAbsolutePCRef(gMoveCwR(((sqInt)methodLabel), ClassReg))); + genMarshallNArgsargargargarg(backEnd, 1, ClassReg, null, null, null); + /* begin gen:literal: */ + operand1 = ((usqIntptr_t)ceTakeProfileSample); + checkLiteralforInstruction(operand1, genoperand(CallFull, operand1)); + /* begin genRemoveNArgsFromStack: */ + assert(1 <= 4); + } + /* Collect the branch and send data for cogMethod, storing it into arrayObj. */ @@ -21861,7 +21777,7 @@ primitiveGeneratorOrNil(void) static sqInt NoDbgRegParms registerisInMask(sqInt reg, sqInt mask) { - return ((mask & (1U << reg)) != 0); + return ((mask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)))) != 0); } /* SimpleStackBasedCogit>>#v3:Block:Code:Size: */ @@ -22071,7 +21987,7 @@ anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n) sqInt regMask; /* begin registerMaskFor: */ - regMask = 1U << reg; + regMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { if ((((registerMask(simStackAt(i))) & regMask) != 0)) { return 1; @@ -22938,7 +22854,7 @@ ensureReceiverResultRegContainsSelf(void) if (needsFrame) { if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin putSelfInReceiverResultReg */ storeToReg(simSelf(), ReceiverResultReg); ((simSelf())->liveRegister = ReceiverResultReg); @@ -23070,7 +22986,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) && (index < simStackPtr)) { desc = simStackAt(index); if (((desc->type)) == SSRegister) { - if (!(((regMask & (1U << ((desc->registerr)))) != 0))) { + if (!(((regMask & (((((desc->registerr)) < 0) ? (((usqInt)(1)) >> (-((desc->registerr)))) : (1U << ((desc->registerr)))))) != 0))) { reg = (desc->registerr); } } @@ -23078,7 +22994,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) } assert(!((reg == NoReg))); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << reg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)), simStackPtr, simNativeStackPtr); return reg; } @@ -23994,7 +23910,7 @@ genPushActiveContextBytecode(void) assert(needsFrame); voidReceiverResultRegContainsSelf(); /* begin ssAllocateCallReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); genGetActiveContextNumArgslargeinBlock(methodOrBlockNumArgs, methodNeedsLargeContext(methodObj), inBlock); return ssPushRegister(ReceiverResultReg); } @@ -24033,7 +23949,7 @@ genPushClosureCopyCopiedValuesBytecode(void) } voidReceiverResultRegContainsSelf(); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << SendNumArgsReg)) | ((1U << ReceiverResultReg))), simStackPtr, simNativeStackPtr); genCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(startpc + 1, numArgs, numCopied, methodOrBlockNumArgs, methodNeedsLargeContext(methodObj), inBlock); if (numCopied > 0) { ssPop(numCopied); @@ -24110,11 +24026,11 @@ genPushMaybeContextReceiverVariable(sqInt slotIndex) AbstractInstruction *jmpSingle; /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ensureReceiverResultRegContainsSelf(); /* begin genPushMaybeContextSlotIndex: */ assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ voidReceiverResultRegContainsSelf(); @@ -24172,7 +24088,7 @@ genPushNewArrayBytecode(void) } else { /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << SendNumArgsReg)) | ((1U << ReceiverResultReg))), simStackPtr, simNativeStackPtr); } size = byte1 & 0x7F; if (!popValues) { @@ -24248,7 +24164,7 @@ genPushRemoteTempLongBytecode(void) (anInstruction->dependent = locateLiteral(offset)); } /* begin availableRegOrNoneNotConflictingWith: */ - regMask = 1U << tempVectReg; + regMask = ((tempVectReg < 0) ? (((usqInt)(1)) >> (-tempVectReg)) : (1U << tempVectReg)); remoteTempReg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); if (remoteTempReg == NoReg) { remoteTempReg = tempVectReg; @@ -24609,11 +24525,11 @@ genSpecialSelectorClass(void) || (topReg == ClassReg)) { /* begin ssAllocateRequiredReg:and: */ requiredReg1 = (topReg = SendNumArgsReg); - ssAllocateRequiredRegMaskupThroughupThroughNative((1U << requiredReg1) | (1U << ClassReg), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((((requiredReg1 < 0) ? (((usqInt)(1)) >> (-requiredReg1)) : (1U << requiredReg1))) | ((1U << ClassReg)), simStackPtr, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr, simNativeStackPtr); } ssPush(1); popToReg(ssTop(), topReg); @@ -24852,7 +24768,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean association = getLiteral(litVarIndex); voidReceiverResultRegContainsSelf(); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin genMoveConstant:R: */ if (shouldAnnotateObjectReference(association)) { annotateobjRef(gMoveCwR(association, ReceiverResultReg), association); @@ -24868,7 +24784,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean # if IMMUTABILITY if (needsImmCheck) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -24882,7 +24798,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -24923,7 +24839,7 @@ genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqI # endif // IMMUTABILITY ssPop(1); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ClassReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ssPush(1); genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); @@ -24971,7 +24887,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea # if IMMUTABILITY if (needsImmCheck1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -24985,7 +24901,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck1, 1); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck1); } @@ -25009,7 +24925,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt assert(needsFrame); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); /* begin MoveMw:r:R: */ offset = frameOffsetOfTemporary(remoteTempIndex); @@ -25022,7 +24938,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt # if IMMUTABILITY # endif - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -25213,13 +25129,13 @@ genVanillaInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -25482,10 +25398,10 @@ liveRegisters(void) } else { /* begin registerMaskFor: */ - regsSet = 1U << ReceiverResultReg; + regsSet = (1U << ReceiverResultReg); if ((methodOrBlockNumArgs <= 1 /* numRegArgs */) && (methodOrBlockNumArgs > 0)) { - regsSet = regsSet | (1U << Arg0Reg); + regsSet = regsSet | ((1U << Arg0Reg)); } } for (i = (((simSpillBase < 0) ? 0 : simSpillBase)); i <= simStackPtr; i += 1) { @@ -25586,7 +25502,7 @@ marshallSendArguments(sqInt numArgs) Also check for any arg registers in use by other args. */ if (numArgs > 0) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 1, simNativeStackPtr); } if (numArgs > 0) { popToReg(simStackAt((simStackPtr - numArgs) + 1), Arg0Reg); diff --git a/src/vm/cogitIA32.c b/src/vm/cogitIA32.c index 7b71605c92..b73ad9f5e3 100644 --- a/src/vm/cogitIA32.c +++ b/src/vm/cogitIA32.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + CCodeGenerator VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 + StackToRegisterMappingCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 " __DATE__ ; +static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__cogitBuildInfo = __buildInfo; @@ -52,14 +52,14 @@ char *__cogitBuildInfo = __buildInfo; #define ArithmeticShiftRightRR 92 #define BadRegisterSet 1 #define BlockCreationBytecodeSize 4 -#define BSR 168 +#define BSR 170 #define BytecodeSetHasDirectedSuperSend 0 #define Call 6 #define CallerSavedRegisterMask 0x6 #define CallFull 7 #define CallR 8 -#define CDQ 159 -#define CLD 164 +#define CDQ 161 +#define CLD 166 #define ClassArray 7 #define ClassFloatCompactIndex 6 #define ClassLargePositiveIntegerCompactIndex 5 @@ -76,7 +76,7 @@ char *__cogitBuildInfo = __buildInfo; #define CMMaxUsageCount 7 #define CMMethod 2 #define CMOpenPIC 5 -#define CMPXCHGRAw 174 +#define CMPXCHGRAw 176 #define CmpC32R 113 #define CmpCqR 105 #define CmpCwR 112 @@ -92,7 +92,7 @@ char *__cogitBuildInfo = __buildInfo; #define ConvertRRs 150 #define ConvertRsR 149 #define ConvertRsRd 147 -#define CPUID 158 +#define CPUID 160 #define Debug DEBUGVM #define DisplacementMask 0x1F #define DisplacementX2N 0 @@ -129,8 +129,8 @@ char *__cogitBuildInfo = __buildInfo; #define FoxMFReceiver -12 #define FoxThisContext -8 #define FPReg 5 -#define FSTPD 163 -#define FSTPS 162 +#define FSTPD 165 +#define FSTPS 164 #define GCModeBecome 8 #define GCModeFull 1 #define GCModeNewSpace 2 @@ -142,11 +142,11 @@ char *__cogitBuildInfo = __buildInfo; #define HeaderIndex 0 #define HeaderTypeShort 3 #define HeaderTypeSizeAndClass 0 -#define IDIVR 160 +#define IDIVR 162 #if !defined(IMMUTABILITY) /* Allow this to be overridden on the compiler command line */ # define IMMUTABILITY 0 #endif -#define IMULRR 161 +#define IMULRR 163 #define InstanceSpecificationIndex 2 #define InstructionPointerIndex 1 #define InsufficientCodeSpace -2 @@ -195,10 +195,10 @@ char *__cogitBuildInfo = __buildInfo; #define JumpZero 17 #define Label 1 #define LastJump 42 -#define LFENCE 170 +#define LFENCE 172 #undef LinkReg #define Literal 2 -#define LOCK 173 +#define LOCK 175 #define LoadEffectiveAddressMwrR 88 #define LogicalShiftLeftCqR 95 #define LogicalShiftLeftCqRR 129 @@ -221,11 +221,11 @@ char *__cogitBuildInfo = __buildInfo; #define MethodCacheSelector 1 #define MethodIndex 3 #define MethodTooBig -4 -#define MFENCE 171 +#define MFENCE 173 #define MFMethodFlagHasContextFlag 1 #define MFMethodFlagIsBlockFlag 2 -#define MOVSB 166 -#define MOVSD 167 +#define MOVSB 168 +#define MOVSD 169 #define ModReg 3 #define ModRegInd 0 #define ModRegRegDisp32 2 @@ -242,6 +242,8 @@ char *__cogitBuildInfo = __buildInfo; #define MoveM8rR 54 #define MoveMbrR 65 #define MoveMwrR 50 +#define MovePerfCnt64RL 159 +#define MovePerfCnt64RRL 158 #define MoveRAb 49 #define MoveRAw 46 #define MoveRdM64r 76 @@ -298,19 +300,19 @@ char *__cogitBuildInfo = __buildInfo; #define PushCq 82 #define PushCw 83 #define PushR 81 -#define REP 165 +#define REP 167 #define ReceiverIndex 5 #define ReceiverResultReg 2 #define RetN 9 #undef RISCTempReg #define RootBit 0x40000000 #define RootBitDigitLength 4 -#define SETE 175 +#define SETE 177 #define SelectorCannotInterpret 34 #define SelectorDoesNotUnderstand 20 #define SenderIndex 0 #define SendNumArgsReg 3 -#define SFENCE 172 +#define SFENCE 174 #define ShouldNotJIT -8 #define SIB1 0 #define SIB4 2 @@ -343,7 +345,7 @@ char *__cogitBuildInfo = __buildInfo; #define UnimplementedPrimitive -7 #define ValueIndex 1 #undef VarBaseReg -#define XCHGRR 169 +#define XCHGRR 171 #define XorCwR 118 #define XorRdRd 137 #define XorRR 104 @@ -473,7 +475,7 @@ static sqInt NoDbgRegParms concretizeAt(AbstractInstruction * self_in_concretize static sqInt NoDbgRegParms genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer); static sqInt NoDbgRegParms genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers); static sqInt NoDbgRegParms genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers); -static sqInt NoDbgRegParms genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg); +static sqInt NoDbgRegParms genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg); static sqInt NoDbgRegParms genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers); static void NoDbgRegParms genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister); static sqInt NoDbgRegParms hasVarBaseRegister(AbstractInstruction * self_in_hasVarBaseRegister); @@ -498,6 +500,7 @@ static sqInt NoDbgRegParms cmpC32RTempByteSize(AbstractInstruction * self_in_cmp static sqInt NoDbgRegParms computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize); static sqInt NoDbgRegParms computeShiftRRSize(AbstractInstruction * self_in_computeShiftRRSize); static sqInt NoDbgRegParms concretizeFill32(AbstractInstruction * self_in_concretizeFill32); +static sqInt NoDbgRegParms concretizeMovePerfCnt64RRL(AbstractInstruction * self_in_concretizeMovePerfCnt64RRL); static sqInt NoDbgRegParms concretizeOpRR(AbstractInstruction * self_in_concretizeOpRR, sqInt x86opcode); static sqInt NoDbgRegParms concretizeReverseOpRR(AbstractInstruction * self_in_concretizeReverseOpRR, sqInt x86opcode); static sqInt NoDbgRegParms concretizeSet(AbstractInstruction * self_in_concretizeSet, sqInt conditionCode); @@ -698,6 +701,8 @@ static BytecodeDescriptor * loadBytesAndGetDescriptor(void); static void NoDbgRegParms loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc); static AbstractInstruction * NoDbgRegParms gMoveCwR(sqInt wordConstant, sqInt reg); static AbstractInstruction * NoDbgRegParms gMoveMwrR(sqInt offset, sqInt baseReg, sqInt destReg); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters); static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg); static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC); @@ -989,6 +994,7 @@ static sqInt genStoreAndPopReceiverVariableBytecode(void); static sqInt genStoreAndPopRemoteTempLongBytecode(void); static sqInt genStoreAndPopTemporaryVariableBytecode(void); static sqInt genStoreRemoteTempLongBytecode(void); +static void genTakeProfileSample(void); extern sqInt mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj); static sqInt numSpecialSelectors(void); static usqInt NoDbgRegParms pcDataForBlockEntryMethod(sqInt blockEntryMcpc, sqInt cogMethod); @@ -2265,28 +2271,28 @@ addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *an static sqInt NoDbgRegParms availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << DPFPReg0)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg0))) != 0))) { return DPFPReg0; } - if (!(((liveRegsMask & (1U << DPFPReg1)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg1))) != 0))) { return DPFPReg1; } - if (!(((liveRegsMask & (1U << DPFPReg2)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg2))) != 0))) { return DPFPReg2; } - if (!(((liveRegsMask & (1U << DPFPReg3)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg3))) != 0))) { return DPFPReg3; } - if (!(((liveRegsMask & (1U << DPFPReg4)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg4))) != 0))) { return DPFPReg4; } - if (!(((liveRegsMask & (1U << DPFPReg5)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg5))) != 0))) { return DPFPReg5; } - if (!(((liveRegsMask & (1U << DPFPReg6)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg6))) != 0))) { return DPFPReg6; } - if (!(((liveRegsMask & (1U << DPFPReg7)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg7))) != 0))) { return DPFPReg7; } return NoReg; @@ -2301,19 +2307,19 @@ availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegi static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << Arg1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg1Reg))) != 0))) { return Arg1Reg; } - if (!(((liveRegsMask & (1U << Arg0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg0Reg))) != 0))) { return Arg0Reg; } - if (!(((liveRegsMask & (1U << SendNumArgsReg)) != 0))) { + if (!(((liveRegsMask & ((1U << SendNumArgsReg))) != 0))) { return SendNumArgsReg; } - if (!(((liveRegsMask & (1U << ClassReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ClassReg))) != 0))) { return ClassReg; } - if (!(((liveRegsMask & (1U << ReceiverResultReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ReceiverResultReg))) != 0))) { return ReceiverResultReg; } return NoReg; @@ -2428,9 +2434,9 @@ genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers) used immediately afterwards. */ - /* CogAbstractInstruction>>#genLoadStackPointersForFastPrimCall: */ + /* CogAbstractInstruction>>#genLoadStackPointersForPrimCall: */ static sqInt NoDbgRegParms -genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg) +genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg) { AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; @@ -2764,6 +2770,7 @@ computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize) case OrRR: case XorRR: case SubRR: + case SubbRR: case NegateR: case NotR: case MoveRR: @@ -3002,6 +3009,11 @@ computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize) ? 7 : 0); + case MovePerfCnt64RRL: + + /* it is easier to calculate the right value by concretizing. We concretize twice, but so what? */ + return concretizeMovePerfCnt64RRL(self_in_computeMaximumSize); + default: error("Case not found and no otherwise clause"); } @@ -3041,6 +3053,63 @@ concretizeFill32(AbstractInstruction * self_in_concretizeFill32) return 4; } + +/* Generate code for + 0x0: 50 pushl %eax + 0x1: 52 pushl %edx + 0x2: 0f 31 rdtsc + 0x4: 89 f8 movl %edi, %eax + 0x6: 89 f2 movl %esi, %edx + 0x8: 5a popl %edx + et al */ + + /* CogIA32Compiler>>#concretizeMovePerfCnt64RRL */ +static sqInt NoDbgRegParms +concretizeMovePerfCnt64RRL(AbstractInstruction * self_in_concretizeMovePerfCnt64RRL) +{ + usqInt liveRegisters; + sqInt offset; + usqInt regHi; + usqInt regLo; + + regLo = ((self_in_concretizeMovePerfCnt64RRL->operands))[0]; + regHi = ((self_in_concretizeMovePerfCnt64RRL->operands))[1]; + liveRegisters = ((self_in_concretizeMovePerfCnt64RRL->operands))[2]; + offset = 0; + if (((liveRegisters & ((1U << EAX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[0] = 80; + offset += 1; + } + if (((liveRegisters & ((1U << EDX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset] = 82; + offset += 1; + } + assert(!(((regLo == EDX) + || (regHi == EAX)))); + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset] = 15; + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset + 1] = 49; + offset += 2; + if (regHi != EDX) { + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset] = 137; + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset + 1] = (modRMRO(self_in_concretizeMovePerfCnt64RRL, ModReg, regHi, EDX)); + offset += 2; + } + if (regLo != EAX) { + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset + 4] = 137; + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset + 5] = (modRMRO(self_in_concretizeMovePerfCnt64RRL, ModReg, regLo, EAX)); + offset += 2; + } + if (((liveRegisters & ((1U << EDX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset] = 90; + offset += 1; + } + if (((liveRegisters & ((1U << EAX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RRL->machineCode))[offset] = 88; + offset += 1; + } + return offset; +} + /* CogIA32Compiler>>#concretizeOpRR: */ static sqInt NoDbgRegParms concretizeOpRR(AbstractInstruction * self_in_concretizeOpRR, sqInt x86opcode) @@ -3384,7 +3453,6 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) usqInt regLHS10; usqInt regLHS11; usqInt regLHS12; - usqInt regLHS13; usqInt regLHS2; usqInt regLHS3; usqInt regLHS4; @@ -3398,7 +3466,6 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) usqInt regRHS10; usqInt regRHS11; usqInt regRHS12; - usqInt regRHS13; usqInt regRHS2; usqInt regRHS3; usqInt regRHS4; @@ -4549,31 +4616,26 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) return concretizeOpRR(self_in_dispatchConcretize, 43); case SubbRR: - /* begin concretizeSubbRR */ - regLHS9 = ((self_in_dispatchConcretize->operands))[0]; - regRHS9 = ((self_in_dispatchConcretize->operands))[1]; - ((self_in_dispatchConcretize->machineCode))[0] = 27; - ((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, regLHS9, regRHS9)); - return 2; + return concretizeOpRR(self_in_dispatchConcretize, 27); case SubRdRd: /* begin concretizeSEE2OpRdRd: */ - regRHS10 = ((self_in_dispatchConcretize->operands))[0]; - regLHS10 = ((self_in_dispatchConcretize->operands))[1]; + regRHS9 = ((self_in_dispatchConcretize->operands))[0]; + regLHS9 = ((self_in_dispatchConcretize->operands))[1]; ((self_in_dispatchConcretize->machineCode))[0] = 242; ((self_in_dispatchConcretize->machineCode))[1] = 15; ((self_in_dispatchConcretize->machineCode))[2] = 92; - ((self_in_dispatchConcretize->machineCode))[3] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS10, regLHS10)); + ((self_in_dispatchConcretize->machineCode))[3] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS9, regLHS9)); return 4; case SubRsRs: /* begin concretizeSEEOpRsRs: */ - regRHS11 = ((self_in_dispatchConcretize->operands))[0]; - regLHS11 = ((self_in_dispatchConcretize->operands))[1]; + regRHS10 = ((self_in_dispatchConcretize->operands))[0]; + regLHS10 = ((self_in_dispatchConcretize->operands))[1]; ((self_in_dispatchConcretize->machineCode))[0] = 243; ((self_in_dispatchConcretize->machineCode))[1] = 15; ((self_in_dispatchConcretize->machineCode))[2] = 92; - ((self_in_dispatchConcretize->machineCode))[3] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS11, regLHS11)); + ((self_in_dispatchConcretize->machineCode))[3] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS10, regLHS10)); return 4; case SqrtRd: @@ -4619,21 +4681,21 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) case XorRdRd: /* begin concretizeXorRdRd */ - regRHS12 = ((self_in_dispatchConcretize->operands))[0]; - regLHS12 = ((self_in_dispatchConcretize->operands))[1]; + regRHS11 = ((self_in_dispatchConcretize->operands))[0]; + regLHS11 = ((self_in_dispatchConcretize->operands))[1]; ((self_in_dispatchConcretize->machineCode))[0] = 102; ((self_in_dispatchConcretize->machineCode))[1] = 15; ((self_in_dispatchConcretize->machineCode))[2] = 87; - ((self_in_dispatchConcretize->machineCode))[3] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS12, regLHS12)); + ((self_in_dispatchConcretize->machineCode))[3] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS11, regLHS11)); return 4; case XorRsRs: /* begin concretizeXorRsRs */ - regRHS13 = ((self_in_dispatchConcretize->operands))[0]; - regLHS13 = ((self_in_dispatchConcretize->operands))[1]; + regRHS12 = ((self_in_dispatchConcretize->operands))[0]; + regLHS12 = ((self_in_dispatchConcretize->operands))[1]; ((self_in_dispatchConcretize->machineCode))[0] = 15; ((self_in_dispatchConcretize->machineCode))[1] = 87; - ((self_in_dispatchConcretize->machineCode))[2] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS13, regLHS13)); + ((self_in_dispatchConcretize->machineCode))[2] = (modRMRO(self_in_dispatchConcretize, ModReg, regRHS12, regLHS12)); return 3; case NegateR: @@ -5627,6 +5689,9 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) case ZeroExtend16RR: return concretizeZeroExtend16RR(self_in_dispatchConcretize); + case MovePerfCnt64RRL: + return concretizeMovePerfCnt64RRL(self_in_dispatchConcretize); + default: error("Case not found and no otherwise clause"); } @@ -6280,7 +6345,7 @@ genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask) assert(!((((regMask & (registerMaskForand(ESP, EBP))) != 0)))); for (reg = EAX; reg <= EDI; reg += 1) { - if (((regMask & (1U << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)))) != 0)) { genoperand(PopR, reg); } } @@ -6301,7 +6366,7 @@ genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask) assert(((EDI - EAX) + 1) == 8); assert(!((((regMask & (registerMaskForand(ESP, EBP))) != 0)))); for (reg = EDI; reg >= EAX; reg += -1) { - if (((regMask & (1U << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)))) != 0)) { genoperand(PushR, reg); } } @@ -9228,7 +9293,7 @@ compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numAr regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1U << resultRegOrNone)) - (1U << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1U << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1U << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ regMaskCopy = ((usqInt)regsToSave); @@ -11683,6 +11748,22 @@ gMoveMwrR(sqInt offset, sqInt baseReg, sqInt destReg) return anInstruction; } + /* Cogit>>#MovePerfCnt64R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisters) +{ + assert(BytesPerWord == 8); + return genoperandoperand(MovePerfCnt64RL, destReg, liveRegisters); +} + + /* Cogit>>#MovePerfCnt64R:R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisters) +{ + assert(BytesPerWord == 4); + return genoperandoperandoperand(MovePerfCnt64RRL, destRegLo, destRegHi, liveRegisters); +} + /* Answer the address of the null byte at the end of the method map. */ @@ -13206,11 +13287,14 @@ recordRunTimeObjectReferences(void) } } + +/* N.B. (self registerMaskFor: NoReg) = 0 */ + /* Cogit>>#registerMaskFor: */ static sqInt NoDbgRegParms registerMaskFor(sqInt reg) { - return 1U << reg; + return ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } /* Cogit>>#registerMaskFor:and: */ @@ -16900,20 +16984,20 @@ generateObjectRepresentationTrampolines(void) sqInt resultReg; /* begin genTrampolineFor:called:arg:regsToSave:result: */ - regMask = ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)); - resultReg = (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + regMask = ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))); + resultReg = (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg); ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceStoreCheck, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, regMask, 1, resultReg, 0); /* begin genTrampolineFor:called:arg:regsToSave:result: */ - regMask1 = ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)); + regMask1 = ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))); ceCreateNewArrayTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewArraySlotSize, "ceCreateNewArrayTrampoline", 1, SendNumArgsReg, null, null, null, regMask1, 1, ReceiverResultReg, 0); /* begin genTrampolineFor:called:arg:regsToSave:result: */ - regMask2 = ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)); + regMask2 = ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))); cePositive32BitIntegerTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(positive32BitIntegerFor, "cePositive32BitIntegerTrampoline", 1, ReceiverResultReg, null, null, null, regMask2, 1, TempReg, 0); ceActiveContextTrampoline = genActiveContextTrampoline(); /* begin genTrampolineFor:called:arg:regsToSave:result: */ - regMask3 = ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)); + regMask3 = ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))); ceClosureCopyTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceClosureCopyDescriptor, "ceClosureCopyTrampoline", 1, SendNumArgsReg, null, null, null, regMask3, 1, ReceiverResultReg, 0); } @@ -18249,7 +18333,7 @@ registerMask(SimStackEntry * self_in_registerMask) || (((self_in_registerMask->type)) == SSRegister) ? (/* begin registerMaskFor: */ (reg = (self_in_registerMask->registerr)), - 1U << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg))) : 0); } @@ -18262,7 +18346,7 @@ registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone) return (((self_in_registerMaskOrNone->type)) == SSRegister ? (/* begin registerMaskFor: */ (reg = (self_in_registerMaskOrNone->registerr)), - 1U << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg))) : 0); } @@ -18440,54 +18524,43 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) { AbstractInstruction *abstractInstruction; AbstractInstruction *abstractInstruction1; - AbstractInstruction *abstractInstruction2; - AbstractInstruction *abstractInstruction3; sqInt address; - sqInt address1; - sqInt address2; AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; + AbstractInstruction *anInstruction10; AbstractInstruction *anInstruction11; + AbstractInstruction *anInstruction110; AbstractInstruction *anInstruction13; AbstractInstruction *anInstruction14; + AbstractInstruction *anInstruction15; + AbstractInstruction *anInstruction16; AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction18; AbstractInstruction *anInstruction19; + AbstractInstruction *anInstruction2; AbstractInstruction *anInstruction20; AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction25; + AbstractInstruction *anInstruction210; + AbstractInstruction *anInstruction22; AbstractInstruction *anInstruction26; AbstractInstruction *anInstruction27; - AbstractInstruction *anInstruction28; - AbstractInstruction *anInstruction29; - AbstractInstruction *anInstruction30; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction35; - AbstractInstruction *anInstruction36; + AbstractInstruction *anInstruction3; AbstractInstruction *anInstruction4; AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - AbstractInstruction * continuePostSampleNonPrim; - AbstractInstruction * continuePostSamplePrim; + AbstractInstruction * continueAfterProfileSample; + sqInt effectiveLiveRegisters; AbstractInstruction * jmp; - AbstractInstruction * jmpSampleNonPrim; - AbstractInstruction * jmpSamplePrim; + AbstractInstruction * jumpToTakeSample; + sqInt liveRegisters; sqInt offset; sqInt offset1; sqInt offset2; - sqInt operand; - sqInt operand2; - sqInt reg; + sqInt regHi; + sqInt regLo; sqInt retpc; - continuePostSampleNonPrim = ((AbstractInstruction *) 0); - continuePostSamplePrim = ((AbstractInstruction *) 0); - jmpSampleNonPrim = ((AbstractInstruction *) 0); - jmpSamplePrim = ((AbstractInstruction *) 0); + jumpToTakeSample = ((AbstractInstruction *) 0); assert(!((0))); genExternalizePointersForPrimitiveCall(); /* begin genLoadCStackPointersForPrimCall */ @@ -18497,45 +18570,28 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) else { genLoadCStackPointer(backEnd); } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick if so */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin MoveAw:R: */ - address = (nextProfileTickAddress()) + BytesPerWord; - /* begin checkLiteral:forInstruction: */ - anInstruction1 = genoperandoperand(MoveAwR, address, ClassReg); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSampleNonPrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSampleNonPrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } if (recordPrimTraceForMethod(methodObj)) { genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction28 = genoperandoperand(MoveCqR, 0, TempReg); + anInstruction15 = genoperandoperand(MoveCqR, 0, TempReg); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction29 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); + anInstruction16 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); + anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); } /* begin checkLiteral:forInstruction: */ argumentCountAddress(); - anInstruction30 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); + anInstruction17 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { /* begin checkLiteral:forInstruction: */ ((sqInt)primitiveRoutine); - anInstruction5 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); + anInstruction1 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); /* begin checkLiteral:forInstruction: */ primitiveFunctionPointerAddress(); - anInstruction6 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); + anInstruction2 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); } if (((flags & (PrimCallNeedsNewMethod + PrimCallMayEndureCodeCompaction)) != 0)) { @@ -18547,133 +18603,118 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) /* begin MoveMw:r:R: */ offset = offsetof(CogMethod, methodObject); /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); + anInstruction3 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); /* begin checkLiteral:forInstruction: */ newMethodAddress(); - anInstruction8 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); + anInstruction4 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); } /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction31 = genoperand(PrefetchAw, primFailCodeAddress()); + anInstruction18 = genoperand(PrefetchAw, primFailCodeAddress()); if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - /* Sideways call the C primitive routine so that we return through cePrimReturnEnterCogCode. */ /* On Spur ceActivateFailingPrimitiveMethod: would like to retry if forwarders are found. So insist on PrimCallNeedsPrimitiveFunction being set too. */ /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l23; + goto l11; if (null < NoReg) { /* begin checkQuickConstant:forInstruction: */ - anInstruction35 = genoperand(PushCq, -2 - null); + anInstruction26 = genoperand(PushCq, -2 - null); } else { genoperand(PushR, null); } - l23: /* end genMarshallNArgs:arg:arg:arg:arg: */; + l11: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin genSubstituteReturnAddress: */ retpc = (((flags & PrimCallCollectsProfileSamples) != 0) ? cePrimReturnEnterCogCodeProfiling : cePrimReturnEnterCogCode); /* begin checkLiteral:forInstruction: */ - anInstruction36 = genoperand(PushCw, retpc); + anInstruction27 = genoperand(PushCw, retpc); /* begin annotateCall: */ - anInstruction9 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); - abstractInstruction = anInstruction9; + anInstruction5 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); + abstractInstruction = anInstruction5; (abstractInstruction->annotation = IsRelativeCall); - jmp = (jmpSamplePrim = (continuePostSamplePrim = null)); + return 0; } - else { - - /* Call the C primitive routine. */ - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l31; - genoperand(PushR, 0); - l31: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin annotateCall: */ - anInstruction11 = genoperand(CallFull, ((sqInt)primitiveRoutine)); - abstractInstruction1 = anInstruction11; - (abstractInstruction1->annotation = IsRelativeCall); - /* begin genRemoveNArgsFromStack: */ - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction13 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin MoveAw:R: */ - address1 = (nextProfileTickAddress()) + BytesPerWord; - /* begin checkLiteral:forInstruction: */ - anInstruction14 = genoperandoperand(MoveAwR, address1, ClassReg); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSamplePrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSamplePrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + goto l25; + genoperand(PushR, 0); + l25: /* end genMarshallNArgs:arg:arg:arg:arg: */; + /* begin annotateCall: */ + anInstruction7 = genoperand(CallFull, ((sqInt)primitiveRoutine)); + abstractInstruction1 = anInstruction7; + (abstractInstruction1->annotation = IsRelativeCall); + /* begin genRemoveNArgsFromStack: */ + genLoadStackPointersForPrimCall(backEnd, ClassReg); + /* begin checkLiteral:forInstruction: */ + instructionPointerAddress(); + anInstruction10 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); + /* begin checkQuickConstant:forInstruction: */ + anInstruction11 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + /* begin checkLiteral:forInstruction: */ + primFailCodeAddress(); + anInstruction19 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + flag("ask concrete code gen if move sets condition codes?"); + /* begin checkQuickConstant:forInstruction: */ + anInstruction20 = genoperandoperand(CmpCqR, 0, TempReg); + /* begin JumpNonZero: */ + jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + flag("endianness"); + assert(!(((((registerMaskForand(ClassReg, SendNumArgsReg)) & liveRegisters) != 0)))); + effectiveLiveRegisters = liveRegisters | ((1U << ClassReg) | (1U << SendNumArgsReg)); + regLo = Arg0Reg; + regHi = Arg1Reg; + /* begin preferredRegisterPairForMovePerfCnt64RRLInto: */ + if (!(((liveRegisters & ((1U << EAX))) != 0))) { + regLo = EAX; + } + if (!(((liveRegisters & ((1U << EDX))) != 0))) { + regHi = EDX; } - /* begin MoveAw:R: */ - address2 = instructionPointerAddress(); - reg = ClassReg; /* begin checkLiteral:forInstruction: */ - anInstruction17 = genoperandoperand(MoveAwR, address2, reg); - genLoadStackPointers(backEnd); + nextProfileTickAddress(); + anInstruction110 = genoperandoperand(MoveAwR, nextProfileTickAddress(), ClassReg); + /* begin MoveAw:R: */ + address = (nextProfileTickAddress()) + 4; /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction18 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - /* begin PushR: */ - genoperand(PushR, ClassReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset1 = BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, BytesPerWord); + anInstruction210 = genoperandoperand(MoveAwR, address, SendNumArgsReg); + gMovePerfCnt64RRL(regLo, regHi, liveRegisters); + /* begin SubR:R: */ + genoperandoperand(SubRR, regLo, ClassReg); + /* begin SubbR:R: */ + genoperandoperand(SubbRR, regHi, SendNumArgsReg); + /* begin JumpGreaterOrEqual: */ + jumpToTakeSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l47; + l47: /* end genCheckForProfileTimerTick: */; } + /* begin MoveMw:r:R: */ + offset1 = BytesPerWord; + /* begin checkQuickConstant:forInstruction: */ + anInstruction21 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); + continueAfterProfileSample = anInstruction21; + /* begin RetN: */ + genoperand(RetN, BytesPerWord); if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* The sample is collected by cePrimReturnEnterCogCode for external calls */ - if (!(jmpSamplePrim == null)) { - - /* Call ceCheckProfileTick: to record sample and then continue. */ - jmpTarget(jmpSamplePrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin annotateCall: */ - operand = ((usqIntptr_t)ceCheckProfileTick); - /* begin checkLiteral:forInstruction: */ - anInstruction21 = genoperand(CallFull, operand); - abstractInstruction2 = anInstruction21; - (abstractInstruction2->annotation = IsRelativeCall); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSamplePrim)); - } - jmpTarget(jmpSampleNonPrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction25 = genoperandoperand(MoveCqR, 0, TempReg); - /* begin checkLiteral:forInstruction: */ - newMethodAddress(); - anInstruction26 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); - /* begin annotateCall: */ - operand2 = ((usqIntptr_t)ceCheckProfileTick); + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); /* begin checkLiteral:forInstruction: */ - anInstruction23 = genoperand(CallFull, operand2); - abstractInstruction3 = anInstruction23; - (abstractInstruction3->annotation = IsRelativeCall); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSampleNonPrim)); - } - if (!(jmp == null)) { - - /* Jump to restore of receiver reg and proceed to frame build for failure. */ - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin MoveMw:r:R: */ - offset2 = BytesPerWord * (methodOrBlockNumArgs + (1)); + instructionPointerAddress(); + anInstruction13 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction27 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); + anInstruction14 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + /* begin Jump: */ + genoperand(Jump, ((sqInt)continueAfterProfileSample)); } + jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + /* begin MoveMw:r:R: */ + offset2 = BytesPerWord * (methodOrBlockNumArgs + (1)); + /* begin checkQuickConstant:forInstruction: */ + anInstruction22 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); return 0; } @@ -18703,7 +18744,7 @@ compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)) if ((methodOrBlockNumArgs > 1 /* numRegArgs */) || (methodOrBlockNumArgs == 0)) { /* begin registerMaskFor: */ - liveRegsMask = 1U << ReceiverResultReg; + liveRegsMask = (1U << ReceiverResultReg); } else { /* begin registerMaskFor:and: */ @@ -19390,79 +19431,101 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) sqInt address; sqInt address1; AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; + AbstractInstruction *anInstruction11; AbstractInstruction *anInstruction12; AbstractInstruction *anInstruction13; AbstractInstruction *anInstruction14; AbstractInstruction *anInstruction15; AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction2; + AbstractInstruction *anInstruction7; AbstractInstruction *anInstruction8; AbstractInstruction *anInstruction9; sqInt callTarget; AbstractInstruction *continuePostSample; + sqInt effectiveLiveRegisters; AbstractInstruction *jmpFail; AbstractInstruction *jmpSample; - sqInt reg; + sqInt liveRegisters; + sqInt reg1; + sqInt regHi; + sqInt regLo; continuePostSample = ((AbstractInstruction *) 0); jmpSample = ((AbstractInstruction *) 0); zeroOpcodeIndex(); - if (profiling) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick: if so. - N.B. nextProfileTick is 64-bits so 32-bit systems need to test both halves. */ + /* begin checkLiteral:forInstruction: */ + primFailCodeAddress(); + anInstruction12 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + flag("ask concrete code gen if move sets condition codes?"); + /* begin checkQuickConstant:forInstruction: */ + anInstruction13 = genoperandoperand(CmpCqR, 0, TempReg); + /* begin JumpNonZero: */ + jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (profiling + && (1)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisters = (0); + flag("endianness"); + assert(!(((((registerMaskForand(ClassReg, SendNumArgsReg)) & liveRegisters) != 0)))); + effectiveLiveRegisters = liveRegisters | ((1U << ClassReg) | (1U << SendNumArgsReg)); + regLo = Arg0Reg; + regHi = Arg1Reg; + /* begin preferredRegisterPairForMovePerfCnt64RRLInto: */ + if (!(((liveRegisters & ((1U << EAX))) != 0))) { + regLo = EAX; + } + if (!(((liveRegisters & ((1U << EDX))) != 0))) { + regHi = EDX; + } /* begin checkLiteral:forInstruction: */ nextProfileTickAddress(); - anInstruction1 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); + anInstruction1 = genoperandoperand(MoveAwR, nextProfileTickAddress(), ClassReg); /* begin MoveAw:R: */ - address = (nextProfileTickAddress()) + BytesPerWord; + address = (nextProfileTickAddress()) + 4; /* begin checkLiteral:forInstruction: */ - anInstruction2 = genoperandoperand(MoveAwR, address, ClassReg); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSample = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + anInstruction2 = genoperandoperand(MoveAwR, address, SendNumArgsReg); + gMovePerfCnt64RRL(regLo, regHi, liveRegisters); + /* begin SubR:R: */ + genoperandoperand(SubRR, regLo, ClassReg); + /* begin SubbR:R: */ + genoperandoperand(SubbRR, regHi, SendNumArgsReg); + /* begin JumpGreaterOrEqual: */ + jmpSample = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); + goto l17; + l17: /* end genCheckForProfileTimerTick: */; /* begin Label */ continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); } /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction13 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkLiteral:forInstruction: */ instructionPointerAddress(); - anInstruction8 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); + anInstruction7 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); + anInstruction8 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + anInstruction9 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jmpFail, checkLiteralforInstruction(newMethodAddress(), genoperandoperand(MoveAwR, newMethodAddress(), SendNumArgsReg))); /* begin checkLiteral:forInstruction: */ cStackPointerAddress(); - anInstruction15 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); + anInstruction14 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); compileCallFornumArgsargargargargresultRegregsToSave(ceActivateFailingPrimitiveMethod, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); /* begin MoveAw:R: */ address1 = instructionPointerAddress(); - reg = ClassReg; + reg1 = ClassReg; /* begin checkLiteral:forInstruction: */ - anInstruction16 = genoperandoperand(MoveAwR, address1, reg); + anInstruction15 = genoperandoperand(MoveAwR, address1, reg1); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperandoperand(MoveMwrR, BytesPerWord, SPReg, ReceiverResultReg); + anInstruction11 = genoperandoperandoperand(MoveMwrR, BytesPerWord, SPReg, ReceiverResultReg); /* begin PushR: */ genoperand(PushR, ClassReg); /* begin RetN: */ genoperand(RetN, BytesPerWord); - if (profiling) { + if (profiling + && (1)) { /* Call ceCheckProfileTick: to record sample and then continue. newMethod should be up-to-date. Need to save and restore the link reg around this call. */ @@ -19471,8 +19534,8 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) /* begin CallFullRT: */ callTarget = (usqIntptr_t)ceCheckProfileTick; /* begin annotateCall: */ - anInstruction17 = genoperand(CallFull, callTarget); - abstractInstruction = anInstruction17; + anInstruction16 = genoperand(CallFull, callTarget); + abstractInstruction = anInstruction16; (abstractInstruction->annotation = IsRelativeCall); /* begin Jump: */ genoperand(Jump, ((sqInt)continuePostSample)); @@ -19766,6 +19829,30 @@ genStoreRemoteTempLongBytecode(void) && (shouldAnnotateObjectReference(((ssTop())->constant))))); } + /* SimpleStackBasedCogit>>#genTakeProfileSample */ +static void +genTakeProfileSample(void) +{ + AbstractInstruction *abstractInstruction; + AbstractInstruction *anInstruction; + AbstractInstruction *anInstruction6; + sqInt operand; + + addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + genoperand(PushR, ClassReg); + l3: /* end genMarshallNArgs:arg:arg:arg:arg: */; + /* begin annotateCall: */ + operand = ((usqIntptr_t)ceTakeProfileSample); + /* begin checkLiteral:forInstruction: */ + anInstruction = genoperand(CallFull, operand); + abstractInstruction = anInstruction; + (abstractInstruction->annotation = IsRelativeCall); + /* begin genRemoveNArgsFromStack: */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction6 = genoperandoperand(AddCqR, 4, ESP); + } + /* Collect the branch and send data for cogMethod, storing it into arrayObj. */ @@ -20080,7 +20167,7 @@ primitiveGeneratorOrNil(void) static sqInt NoDbgRegParms registerisInMask(sqInt reg, sqInt mask) { - return ((mask & (1U << reg)) != 0); + return ((mask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)))) != 0); } /* SimpleStackBasedCogit>>#v3:Block:Code:Size: */ @@ -20283,7 +20370,7 @@ anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n) sqInt regMask; /* begin registerMaskFor: */ - regMask = 1U << reg; + regMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { if ((((registerMask(simStackAt(i))) & regMask) != 0)) { return 1; @@ -21121,7 +21208,7 @@ ensureReceiverResultRegContainsSelf(void) if (needsFrame) { if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin putSelfInReceiverResultReg */ storeToReg(simSelf(), ReceiverResultReg); ((simSelf())->liveRegister = ReceiverResultReg); @@ -21253,7 +21340,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) && (index < simStackPtr)) { desc = simStackAt(index); if (((desc->type)) == SSRegister) { - if (!(((regMask & (1U << ((desc->registerr)))) != 0))) { + if (!(((regMask & (((((desc->registerr)) < 0) ? (((usqInt)(1)) >> (-((desc->registerr)))) : (1U << ((desc->registerr)))))) != 0))) { reg = (desc->registerr); } } @@ -21261,7 +21348,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) } assert(!((reg == NoReg))); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << reg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)), simStackPtr, simNativeStackPtr); return reg; } @@ -22108,7 +22195,7 @@ genPushActiveContextBytecode(void) assert(needsFrame); voidReceiverResultRegContainsSelf(); /* begin ssAllocateCallReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); genGetActiveContextNumArgslargeinBlock(methodOrBlockNumArgs, methodNeedsLargeContext(methodObj), inBlock); return ssPushRegister(ReceiverResultReg); } @@ -22147,7 +22234,7 @@ genPushClosureCopyCopiedValuesBytecode(void) } voidReceiverResultRegContainsSelf(); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << SendNumArgsReg)) | ((1U << ReceiverResultReg))), simStackPtr, simNativeStackPtr); genCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(startpc + 1, numArgs, numCopied, methodOrBlockNumArgs, methodNeedsLargeContext(methodObj), inBlock); if (numCopied > 0) { ssPop(numCopied); @@ -22221,11 +22308,11 @@ genPushMaybeContextReceiverVariable(sqInt slotIndex) AbstractInstruction *jmpSingle; /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ensureReceiverResultRegContainsSelf(); /* begin genPushMaybeContextSlotIndex: */ assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ voidReceiverResultRegContainsSelf(); @@ -22277,7 +22364,7 @@ genPushNewArrayBytecode(void) } else { /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << SendNumArgsReg)) | ((1U << ReceiverResultReg))), simStackPtr, simNativeStackPtr); } size = byte1 & 0x7F; if (!popValues) { @@ -22350,7 +22437,7 @@ genPushRemoteTempLongBytecode(void) /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperandoperand(MoveMwrR, offset, FPReg, tempVectReg); /* begin availableRegOrNoneNotConflictingWith: */ - regMask = 1U << tempVectReg; + regMask = ((tempVectReg < 0) ? (((usqInt)(1)) >> (-tempVectReg)) : (1U << tempVectReg)); remoteTempReg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); if (remoteTempReg == NoReg) { remoteTempReg = tempVectReg; @@ -22683,11 +22770,11 @@ genSpecialSelectorClass(void) || (topReg == ClassReg)) { /* begin ssAllocateRequiredReg:and: */ requiredReg1 = (topReg = SendNumArgsReg); - ssAllocateRequiredRegMaskupThroughupThroughNative((1U << requiredReg1) | (1U << ClassReg), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((((requiredReg1 < 0) ? (((usqInt)(1)) >> (-requiredReg1)) : (1U << requiredReg1))) | ((1U << ClassReg)), simStackPtr, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr, simNativeStackPtr); } ssPush(1); popToReg(ssTop(), topReg); @@ -22920,7 +23007,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean association = getLiteral(litVarIndex); voidReceiverResultRegContainsSelf(); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin genMoveConstant:R: */ if (shouldAnnotateObjectReference(association)) { annotateobjRef(checkLiteralforInstruction(association, genoperandoperand(MoveCwR, association, ReceiverResultReg)), association); @@ -22933,7 +23020,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean # if IMMUTABILITY if (needsImmCheck) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -22947,7 +23034,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -22988,7 +23075,7 @@ genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqI # endif // IMMUTABILITY ssPop(1); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ClassReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ssPush(1); genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); @@ -23033,7 +23120,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea # if IMMUTABILITY if (needsImmCheck1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -23047,7 +23134,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck1, 1); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck1); } @@ -23071,7 +23158,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt assert(needsFrame); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); /* begin MoveMw:r:R: */ offset = frameOffsetOfTemporary(remoteTempIndex); @@ -23081,7 +23168,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt # if IMMUTABILITY # endif - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -23267,13 +23354,13 @@ genVanillaInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1U << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1U << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -23527,10 +23614,10 @@ liveRegisters(void) } else { /* begin registerMaskFor: */ - regsSet = 1U << ReceiverResultReg; + regsSet = (1U << ReceiverResultReg); if ((methodOrBlockNumArgs <= 1 /* numRegArgs */) && (methodOrBlockNumArgs > 0)) { - regsSet = regsSet | (1U << Arg0Reg); + regsSet = regsSet | ((1U << Arg0Reg)); } } for (i = (((simSpillBase < 0) ? 0 : simSpillBase)); i <= simStackPtr; i += 1) { @@ -23631,7 +23718,7 @@ marshallSendArguments(sqInt numArgs) Also check for any arg registers in use by other args. */ if (numArgs > 0) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 1, simNativeStackPtr); } if (numArgs > 0) { popToReg(simStackAt((simStackPtr - numArgs) + 1), Arg0Reg); diff --git a/src/vm/cogitMIPSEL.c b/src/vm/cogitMIPSEL.c deleted file mode 100644 index 08cb4ec070..0000000000 --- a/src/vm/cogitMIPSEL.c +++ /dev/null @@ -1,24288 +0,0 @@ -/* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 - from - StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 - */ -static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3026 uuid: 88faccd6-8d42-4e14-9ad3-104e5a5bc8d9 " __DATE__ ; -char *__cogitBuildInfo = __buildInfo; - - - -#include "sqConfig.h" -#include -#include -#include -#include -#include "sqPlatformSpecific.h" -#include "sqMemoryAccess.h" -#include "sqCogStackAlignment.h" -#include "dispdbg.h" -#include "cogmethod.h" -#if COGMTVM -#include "cointerpmt.h" -#else -#include "cointerp.h" -#endif -#include "cogit.h" -#include - - -/*** Constants ***/ -#define A0 4 -#define A1 5 -#define A2 6 -#define A3 7 -#define ABICallerSavedRegisterMask 0x300FF00 -#define ABIResultReg 2 -#define ADDIU 9 -#define ADDU 33 -#define AddCheckOverflowCqR 162 -#define AddCheckOverflowRR 163 -#define AddCqR 106 -#define AddCwR 114 -#define AddRdRd 132 -#define AddRR 100 -#define AddRRR 126 -#define AlignmentNops 3 -#define AllButTypeMask 0xFFFFFFFCU -#define AltBlockCreationBytecodeSize 3 -#define AltFirstSpecialSelector 96 -#define AltNumSpecialSelectors 32 -#define AND 36 -#define ANDI 12 -#define AndCqR 108 -#define AndCqRR 124 -#define AndCwR 116 -#define AndRR 102 -#define AnnotationShift 5 -#define Arg0Reg 17 -#define Arg1Reg 18 -#define ArithmeticShiftRightCqR 91 -#define ArithmeticShiftRightCqRR 128 -#define ArithmeticShiftRightRR 92 -#define AT 1 -#define BadRegisterSet 1 -#define BEQ 4 -#define BGEZ 1 -#define BGTZ 7 -#define BLEZ 6 -#define BLTZ 0 -#define BlockCreationBytecodeSize 4 -#define BNE 5 -#define BREAK 13 -#define BranchTemp 11 -#define BrEqualRR 167 -#define BrLongEqualRR 177 -#define BrLongNotEqualRR 178 -#define BrNotEqualRR 168 -#define BrSignedGreaterEqualRR 176 -#define BrSignedGreaterRR 175 -#define BrSignedLessEqualRR 174 -#define BrSignedLessRR 173 -#define BrUnsignedGreaterEqualRR 172 -#define BrUnsignedGreaterRR 171 -#define BrUnsignedLessEqualRR 170 -#define BrUnsignedLessRR 169 -#define BytecodeSetHasDirectedSuperSend 0 -#define Call 6 -#define CallerSavedRegisterMask 0x0 -#define CallFull 7 -#define ClassArray 7 -#define ClassFloatCompactIndex 6 -#define ClassLargePositiveIntegerCompactIndex 5 -#define ClassMethodContextCompactIndex 14 -#define ClassReg 19 -#define ClosureFirstCopiedValueIndex 3 -#define ClosureNumArgsIndex 2 -#define ClosureOuterContextIndex 0 -#define ClosureStartPCIndex 1 -#define ClzRR 157 -#define CMBlock 3 -#define CMClosedPIC 4 -#define CMFree 1 -#define CMMaxUsageCount 7 -#define CMMethod 2 -#define CMOpenPIC 5 -#define Cmp 8 -#define CmpC32R 113 -#define CmpCqR 105 -#define CmpCwR 112 -#define CmpRdRd 131 -#define CmpRR 99 -#define CompactClasses 28 -#define CompletePrimitive 4 -#define ConcreteVarBaseReg 22 -#define ConstZero 1 -#define ConvertRRd 145 -#define Debug DEBUGVM -#define DIV 26 -#define DisplacementMask 0x1F -#define DisplacementX2N 0 -#define DivRdRd 135 -#define DivRR 159 -#undef DPFPReg0 -#undef DPFPReg1 -#undef DPFPReg2 -#undef DPFPReg3 -#undef DPFPReg4 -#undef DPFPReg5 -#undef DPFPReg6 -#undef DPFPReg7 -#define EncounteredUnknownBytecode -6 -#undef Extra0Reg -#undef Extra2Reg -#define FastCPrimitiveUseCABIFlag 4 -#define Fill32 4 -#define FirstAnnotation 64 -#define FirstJump 12 -#define FirstSpecialSelector 176 -#define FoxCallerSavedIP 4 -#define FoxIFSavedIP -16 -#define FoxMethod -4 -#define FoxMFReceiver -12 -#define FoxThisContext -8 -#define FP 30 -#define FPReg 30 -#define GCModeBecome 8 -#define GCModeFull 1 -#define GCModeNewSpace 2 -#define HasBytecodePC 5 -#define HashBitsOffset 17 -#define HashMaskUnshifted 0xFFF -#define HashMultiplyConstant 1664525 -#define HashMultiplyMask 0xFFFFFFF -#define HeaderIndex 0 -#define HeaderTypeSizeAndClass 0 -#define HintLoad 0 -#define HintStore 1 -#if !defined(IMMUTABILITY) /* Allow this to be overridden on the compiler command line */ -# define IMMUTABILITY 0 -#endif -#define InstanceSpecificationIndex 2 -#define InstructionPointerIndex 1 -#define InsufficientCodeSpace -2 -#define InVanillaBlock 1 -#define IsAbsPCReference 3 -#define IsAnnotationExtension 1 -#define IsDirectedSuperBindingSend null -#define IsDirectedSuperSend null -#define IsDisplacementX2N 0 -#define IsNSDynamicSuperSend null -#define IsNSSelfSend null -#define IsNSSendCall null -#define IsObjectReference 2 -#define IsRelativeCall 4 -#define IsSendCall 7 -#define IsSuperSend 8 -#define J 2 -#define JAL 3 -#define JALR 9 -#define JR 8 -#define Jump 16 -#define JumpAbove 33 -#define JumpAboveOrEqual 32 -#define JumpBelow 31 -#define JumpBelowOrEqual 34 -#define JumpCarry 25 -#define JumpFPEqual 35 -#define JumpFPGreater 39 -#define JumpFPGreaterOrEqual 40 -#define JumpFPLess 37 -#define JumpFPLessOrEqual 38 -#define JumpFPNotEqual 36 -#define JumpFPOrdered 41 -#define JumpFPUnordered 42 -#define JumpFull 12 -#define JumpGreater 29 -#define JumpGreaterOrEqual 28 -#define JumpLess 27 -#define JumpLessOrEqual 30 -#define JumpLong 13 -#define JumpLongNonZero 15 -#define JumpLongZero 14 -#define JumpNegative 19 -#define JumpNoCarry 26 -#define JumpNonNegative 20 -#define JumpNonZero 18 -#define JumpNoOverflow 22 -#define JumpOverflow 21 -#define JumpR 10 -#define JumpZero 17 -#define Label 1 -#define LastJump 42 -#define LB 32 -#define LBU 36 -#define LH 33 -#define LHU 37 -#define LinkReg 31 -#define Literal 2 -#define LoadEffectiveAddressMwrR 88 -#define LogicalShiftLeftCqR 95 -#define LogicalShiftLeftCqRR 129 -#define LogicalShiftLeftRR 96 -#define LogicalShiftRightCqR 93 -#define LogicalShiftRightRR 94 -#define LongSizeMask 0xFFFFFFFCU -#define LowcodeVM 0 -#define LUI 15 -#define LW 35 -#define MapEnd 0 -#define MaxCompiledPrimitiveIndex 575 -#define MaxCPICCases 6 -#define MaxMethodSize 65535 -#define MaxNegativeErrorCode -8 -#define MaxStackAllocSize 1572864 -#define MaxStackCheckOffset 0xFFF -#define MaxX2NDisplacement 992 -#define MethodCacheClass 2 -#define MethodCacheMask 0xFFC -#define MethodCacheMethod 3 -#define MethodCacheSelector 1 -#define MethodIndex 3 -#define MethodTooBig -4 -#define MFHI 16 -#define MFLO 18 -#define MFMethodFlagHasContextFlag 1 -#define MFMethodFlagIsBlockFlag 2 -#define MoveAbR 48 -#define MoveAwR 44 -#define MoveC32R 71 -#define MoveCqR 69 -#define MoveCwR 70 -#define MoveHighR 161 -#define MoveLowR 160 -#define MoveM16rR 57 -#define MoveM64rRd 75 -#define MoveMbrR 65 -#define MoveMwrR 50 -#define MoveRAb 49 -#define MoveRAw 46 -#define MoveRdM64r 76 -#define MoveRdRd 74 -#define MoveRM16r 58 -#define MoveRMbr 66 -#define MoveRMwr 51 -#define MoveRR 43 -#define MoveRXbrR 68 -#define MoveRXwrR 53 -#define MoveXbrRR 67 -#define MoveXwrRR 52 -#define MULT 24 -#define MULTIPLEBYTECODESETS 0 -#define MulCheckOverflowRR 164 -#define MulRdRd 134 -#define MulRR 158 -#define NativePopR 84 -#define NativePushR 85 -#define NativeRetN 86 -#define NativeSPReg 29 -#define NeedsMergeFixupFlag 2 -#define NeedsNonMergeFixupFlag 1 -#define NegateR 89 -#define NewspeakVM 0 -#define Nop 5 -#define NoReg -1 -#define NotFullyInitialized -1 -#define NumObjRefsInRuntime 0 -#define NumOopsPerNSC 6 -#define NumSendTrampolines 4 -#define NumSpecialSelectors 32 -#define NumTrampolines (54 + (COGMTVM ? 1 : 0) + (IMMUTABILITY ? 0 : 0)) -#define OneInstruction 4 -#define OR 37 -#define ORI 13 -#define OrCqR 109 -#define OrCqRR 125 -#define OrCwR 117 -#define OrRR 103 -#define Overflow 8 -#define OverflowTemp1 9 -#define OverflowTemp2 10 -#undef PCReg -#define PopR 80 -#define PREF 51 -#define PrefetchAw 87 -#define PrimCallCollectsProfileSamples 8 -#define PrimCallDoNotJIT 16 -#define PrimCallMayEndureCodeCompaction 4 -#define PrimCallNeedsNewMethod 1 -#define PrimCallNeedsPrimitiveFunction 2 -#define PrimCallOnSmalltalkStack 64 -#define PrimCallOnSmalltalkStackAlign2x 128 -#define PrimErrNoMemory 9 -#define PrimNumberExternalCall 117 -#define PrimNumberFFICall 120 -#define PushCq 82 -#define PushCw 83 -#define PushR 81 -#define R0 0 -#define R28 28 -#define RA 31 -#define REGIMM 1 -#define ReceiverIndex 5 -#define ReceiverResultReg 16 -#define RetN 9 -#define RISCTempReg 1 -#define RootBit 0x40000000 -#define RootBitDigitLength 4 -#define SB 40 -#define SelectorCannotInterpret 34 -#define SelectorDoesNotUnderstand 20 -#define SenderIndex 0 -#define SendNumArgsReg 20 -#define SH 41 -#define ShouldNotJIT -8 -#define SistaV1BytecodeSet 0 -#define SistaVM 0 -#define Size4Bit 0 -#define SizeMask 0xFC -#define SLL 0 -#define SLLV 4 -#define SLT 42 -#define SLTI 10 -#define SLTIU 11 -#define SLTU 43 -#define SP 29 -#define SPECIAL 0 -#define SPReg 29 -#define SPURVM 0 -#define SqrtRd 136 -#define SRA 3 -#define SRAV 7 -#define SRL 2 -#define SRLV 6 -#define SSBaseOffset 1 -#define SSConstant 2 -#define SSRegister 3 -#define SSSpill 4 -#define Stop 11 -#define SUBU 35 -#define SubCheckOverflowCqR 165 -#define SubCheckOverflowRR 166 -#define SubCqR 107 -#define SubCwR 115 -#define SubRdRd 133 -#define SubRR 101 -#define SubRRR 127 -#define SW 43 -#define TargetReg 25 -#define TempReg 21 -#define TempVectReadBarrier 0 -#define TstCqR 110 -#define TypeMask 0x3 -#define UnfailingPrimitive 3 -#define UnimplementedPrimitive -7 -#define ValueIndex 1 -#define VarBaseReg 22 -#define XOR 38 -#define XORI 14 -#define XorCqR 111 -#define XorCwR 118 -#define XorRR 104 -#define YoungSelectorInPIC -5 -#define ZR 0 - -typedef struct _AbstractInstruction { - unsigned char opcode; - unsigned char machineCodeSize; - unsigned char maxSize; - unsigned char annotation; - unsigned int machineCode[7]; - usqInt operands[3]; - usqInt address; - struct _AbstractInstruction *dependent; - } AbstractInstruction; - -#define CogMIPSELCompiler AbstractInstruction -#define CogAbstractInstruction AbstractInstruction - - -typedef struct { - AbstractInstruction *fakeHeader; - AbstractInstruction *fillInstruction; - sqInt numArgs; - sqInt numCopied; - sqInt numInitialNils; - sqInt startpc; - AbstractInstruction *entryLabel; - AbstractInstruction *stackCheckLabel; - sqInt span; - sqInt hasInstVarRef; - } BlockStart; - -#define CogBlockStart BlockStart - - -typedef struct _BytecodeDescriptor { - sqInt (*generator)(void); - sqInt NoDbgRegParms (*spanFunction)(struct _BytecodeDescriptor *,sqInt,sqInt,sqInt); - sqInt NoDbgRegParms (*needsFrameFunction)(sqInt); - signed char stackDelta; - unsigned char opcode; - unsigned char numBytes; - unsigned isBranchTrue : 1; - unsigned isBranchFalse : 1; - unsigned isReturn : 1; - unsigned isBlockCreation : 1; - unsigned isMapped : 1; - unsigned isMappedInBlock : 1; - unsigned isExtension : 1; - unsigned isInstVarRef : 1; - unsigned is1ByteInstVarStore : 1; - unsigned hasUnsafeJump : 1; - } BytecodeDescriptor; - -#define CogBytecodeDescriptor BytecodeDescriptor - - -typedef struct { - sqInt (*primitiveGenerator)(void); - sqInt primNumArgs; - } PrimitiveDescriptor; - -#define CogPrimitiveDescriptor PrimitiveDescriptor - - -typedef struct { - char type; - char spilled; - signed char liveRegister; - signed char registerr; - sqInt offset; - sqInt constant; - sqInt bcptr; - } SimStackEntry; - -#define CogSimStackEntry SimStackEntry - - -typedef struct { - AbstractInstruction *targetInstruction; - unsigned char simStackPtr; - char isTargetOfBackwardBranch; - unsigned short instructionIndex; -#if LowcodeVM - short simNativeStackPtr; - unsigned short simNativeStackSize; -#endif - } BytecodeFixup; - -#define CogSSBytecodeFixup BytecodeFixup -#define CogBytecodeFixup BytecodeFixup - - -typedef struct { - sqInt isReceiverResultRegLive; - CogSimStackEntry *ssEntry; - } CogSSOptStatus; - - - -/*** Function Prototypes ***/ - - -#if !PRODUCTION && defined(PlatformNoDbgRegParms) -# define NoDbgRegParms PlatformNoDbgRegParms -#endif - -#if !defined(NoDbgRegParms) -# define NoDbgRegParms /*empty*/ -#endif - - - -#if !defined(NeverInline) -# define NeverInline /*empty*/ -#endif - -static AbstractInstruction * NoDbgRegParms addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *anInstruction); -static sqInt NoDbgRegParms availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask); -static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask); -static void NoDbgRegParms cloneLiteralFrom(AbstractInstruction * self_in_cloneLiteralFrom, AbstractInstruction *existingLiteral); -static sqInt NoDbgRegParms genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer); -static sqInt NoDbgRegParms genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers); -static sqInt NoDbgRegParms genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers); -static sqInt NoDbgRegParms genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg); -static sqInt NoDbgRegParms genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers); -static AbstractInstruction * NoDbgRegParms genSwapRRScratch(AbstractInstruction * self_in_genSwapRRScratch, sqInt regA, sqInt regB, sqInt regTmp); -static void NoDbgRegParms genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister); -static void NoDbgRegParms initializeSharableLiteral(AbstractInstruction * self_in_initializeSharableLiteral, sqInt literal); -static void NoDbgRegParms initializeUniqueLiteral(AbstractInstruction * self_in_initializeUniqueLiteral, sqInt literal); -static AbstractInstruction * NoDbgRegParms jmpTarget(AbstractInstruction * self_in_jmpTarget, AbstractInstruction *anAbstractInstruction); -static void NoDbgRegParms resolveJumpTarget(AbstractInstruction * self_in_resolveJumpTarget); -static sqInt NoDbgRegParms rewriteCallFullAttarget(AbstractInstruction * self_in_rewriteCallFullAttarget, sqInt callSiteReturnAddress, sqInt callTargetAddress); -static sqInt NoDbgRegParms rewriteJumpFullAttarget(AbstractInstruction * self_in_rewriteJumpFullAttarget, sqInt callSiteReturnAddress, sqInt callTargetAddress); -static CogMethod * NoDbgRegParms cmHomeMethod(CogBlockMethod * self_in_cmHomeMethod); -static sqInt NoDbgRegParms isBranch(BytecodeDescriptor * self_in_isBranch); -static AbstractInstruction * NoDbgRegParms gArithmeticShiftRightCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); -extern sqInt abortOffset(void); -static void addCleanBlockStarts(void); -extern void addCogMethodsToHeapMap(void); -static sqInt NoDbgRegParms addressIsInCurrentCompilation(sqInt address); -static sqInt NoDbgRegParms addressIsInFixups(BytecodeFixup *address); -static sqInt NoDbgRegParms addressOfEndOfCaseinCPIC(sqInt n, CogMethod *cPIC); -static void alignMethodZoneBase(void); -static sqInt NoDbgRegParms alignUptoRoutineBoundary(sqInt anAddress); -static sqInt allMachineCodeObjectReferencesValid(void); -static sqInt allMethodsHaveCorrectHeader(void); -static AbstractInstruction * NoDbgRegParms annotateAbsolutePCRef(AbstractInstruction *abstractInstruction); -static AbstractInstruction * NoDbgRegParms annotateBytecode(AbstractInstruction *abstractInstruction); -static AbstractInstruction * NoDbgRegParms annotateobjRef(AbstractInstruction *abstractInstruction, sqInt anOop); -static void NoDbgRegParms assertSaneJumpTarget(AbstractInstruction *jumpTarget); -static void assertValidDualZone(void); -static sqInt NoDbgRegParms availableRegisterOrNoneIn(sqInt liveRegsMask); -static sqInt NoDbgRegParms blockDispatchTargetsForperformarg(CogMethod *cogMethod, usqInt (*binaryFunction)(sqInt mcpc, sqInt arg), sqInt arg); -extern sqInt bytecodePCForstartBcpcin(sqInt mcpc, sqInt startbcpc, CogBlockMethod *cogMethod); -static AbstractInstruction * NoDbgRegParms CallRT(sqInt callTarget); -static AbstractInstruction * NoDbgRegParms gCall(sqInt callTarget); -extern void callCogCodePopReceiver(void); -extern void callCogCodePopReceiverAndClassRegs(void); -static sqInt NoDbgRegParms ceCPICMissreceiver(CogMethod *cPIC, sqInt receiver); -extern void ceFree(void *pointer); -static void* NoDbgRegParms ceMalloc(size_t size); -static sqInt NoDbgRegParms ceSICMiss(sqInt receiver); -static sqInt NoDbgRegParms checkIfValidOopRefAndTargetpccogMethod(sqInt annotation, char *mcpc, CogMethod *cogMethod); -static sqInt NoDbgRegParms checkIfValidOopRefpccogMethod(sqInt annotation, char *mcpc, CogMethod *cogMethod); -extern sqInt checkIntegrityOfObjectReferencesInCode(sqInt gcModes); -static sqInt NoDbgRegParms checkMaybeObjRefInClosedPIC(sqInt maybeObject); -static sqInt NoDbgRegParms checkValidObjectReferencesInClosedPIC(CogMethod *cPIC); -static sqInt NoDbgRegParms NeverInline cleanUpFailingCogCodeConstituents(CogMethod *cogMethodArg); -static sqInt NoDbgRegParms closedPICRefersToUnmarkedObject(CogMethod *cPIC); -extern char * codeEntryFor(char *address); -extern char * codeEntryNameFor(char *address); -extern sqInt cogCodeBase(void); -extern sqInt cogCodeConstituents(sqInt withDetails); -static void NoDbgRegParms cogExtendPICCaseNMethodtagisMNUCase(CogMethod *cPIC, sqInt caseNMethod, sqInt caseNTag, sqInt isMNUCase); -extern void cogitPostGCAction(sqInt gcMode); -extern sqInt cogMethodDoesntLookKosher(CogMethod *cogMethod); -extern CogMethod * cogMNUPICSelectorreceivermethodOperandnumArgs(sqInt selector, sqInt rcvr, sqInt methodOperand, sqInt numArgs); -static CogMethod * NoDbgRegParms cogOpenPICSelectornumArgs(sqInt selector, sqInt numArgs); -static CogMethod * NoDbgRegParms cogPICSelectornumArgsCase0MethodCase1MethodtagisMNUCase(sqInt selector, sqInt numArgs, CogMethod *case0CogMethod, sqInt case1MethodOrNil, sqInt case1Tag, sqInt isMNUCase); -extern CogMethod * cogselector(sqInt aMethodObj, sqInt aSelectorOop); -static sqInt NoDbgRegParms collectCogConstituentForAnnotationMcpcBcpcMethod(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *cogMethodArg); -static sqInt NoDbgRegParms collectCogMethodConstituent(CogMethod *cogMethod); -extern void compactCogCompiledCode(void); -static void compactPICsWithFreedTargets(void); -static AbstractInstruction * compileAbort(void); -static sqInt NoDbgRegParms compileBlockDispatchFromto(sqInt lowBlockStartIndex, sqInt highBlockStartIndex); -static void NoDbgRegParms compileBlockEntry(BlockStart *blockStart); -static void NoDbgRegParms compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt resultRegOrNone, sqInt regMask); -static AbstractInstruction * compileCPICEntry(void); -static void compileEntry(void); -static sqInt compileMethodBody(void); -static sqInt NoDbgRegParms compilePICAbort(sqInt numArgs); -static AbstractInstruction * NoDbgRegParms compileStackOverflowCheck(sqInt canContextSwitch); -static void NoDbgRegParms compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone); -static void computeEntryOffsets(void); -static void computeFullBlockEntryOffsets(void); -static usqInt computeGoodVarBaseAddress(void); -static void computeMaximumSizes(void); -static sqInt NoDbgRegParms configureCPICCase0Case1MethodtagisMNUCasenumArgsdelta(CogMethod *cPIC, CogMethod *case0CogMethod, sqInt case1Method, sqInt case1Tag, sqInt isMNUCase, sqInt numArgs, sqInt addrDelta); -static sqInt NoDbgRegParms configureMNUCPICmethodOperandnumArgsdelta(CogMethod *cPIC, sqInt methodOperand, sqInt numArgs, sqInt addrDelta); -static sqInt NoDbgRegParms cPICCompactAndIsNowEmpty(CogMethod *cPIC); -static sqInt NoDbgRegParms cPICHasFreedTargets(CogMethod *cPIC); -static usqInt cPICPrototypeCaseOffset(void); -static sqInt NoDbgRegParms cPICHasTarget(CogMethod *cPIC, CogMethod *targetMethod); -static sqInt NoDbgRegParms createCPICData(CogMethod *cPIC); -static AbstractInstruction * NoDbgRegParms gDivRRQuoRem(sqInt rDivisor, sqInt rDividend, sqInt rQuotient, sqInt rRemainder); -extern sqInt defaultCogCodeSize(void); -static sqInt NoDbgRegParms deltaToSkipPrimAndErrorStoreInheader(sqInt aMethodObj, sqInt aMethodHeader); -static sqInt NoDbgRegParms endPCOf(sqInt aMethod); -extern void enterCogCodePopReceiver(void); -static sqInt NoDbgRegParms entryPointTagIsSelector(sqInt entryPoint); -static sqInt NoDbgRegParms expectedClosedPICPrototype(CogMethod *cPIC); -static sqInt NoDbgRegParms fillInBlockHeadersAt(sqInt startAddress); -static void NoDbgRegParms fillInMethodHeadersizeselector(CogMethod *method, sqInt size, sqInt selector); -static sqInt NoDbgRegParms findBackwardBranchIsBackwardBranchMcpcBcpcMatchingBcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *targetBcpc); -static usqInt NoDbgRegParms findBlockMethodWithEntrystartBcpc(sqInt blockEntryMcpc, sqInt startBcpc); -static usqInt NoDbgRegParms findMapLocationForMcpcinMethod(usqInt targetMcpc, CogMethod *cogMethod); -extern CogBlockMethod * findMethodForStartBcpcinHomeMethod(sqInt startbcpc, CogMethod *cogMethod); -static sqInt NoDbgRegParms findIsBackwardBranchMcpcBcpcMatchingMcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *targetMcpc); -static sqInt NoDbgRegParms firstMappedPCFor(CogMethod *cogMethod); -static sqInt firstPrototypeMethodOop(void); -static BytecodeFixup * NoDbgRegParms fixupAt(sqInt fixupPC); -extern void freeCogMethod(CogMethod *cogMethod); -static AbstractInstruction * NoDbgRegParms genCallMustBeBooleanFor(sqInt boolean); -static AbstractInstruction * NoDbgRegParms genConditionalBranchoperand(sqInt opcode, sqInt operandOne); -static void (*genEnilopmartForandandforCallcalled(sqInt regArg1, sqInt regArg2OrNone, sqInt regArg3OrNone, sqInt forCall, char *trampolineName))(void) ; -static void NoDbgRegParms genEnilopmartReturn(sqInt forCall); -static void NoDbgRegParms NeverInline generateCaptureCStackPointers(sqInt captureFramePointer); -static void generateClosedPICPrototype(void); -static CogMethod * NoDbgRegParms generateCogMethod(sqInt selector); -static sqInt NoDbgRegParms generateMapAtstart(usqInt addressOrNull, usqInt startAddress); -static void generateOpenPICPrototype(void); -static void generateRunTimeTrampolines(void); -static void generateStackPointerCapture(void); -static void generateTrampolines(void); -static BytecodeDescriptor * NoDbgRegParms generatorForPC(sqInt pc); -static void genGetLeafCallStackPointers(void); -static usqInt NoDbgRegParms genInnerPICAbortTrampoline(char *name); -static void (*genInvokeInterpretTrampoline(void))(void) ; -static void NoDbgRegParms genLoadInlineCacheWithSelector(sqInt selectorIndex); -static usqInt genReturnToInterpreterTrampoline(void); -static sqInt NoDbgRegParms genSmalltalkToCStackSwitch(sqInt pushLinkReg); -static usqInt NoDbgRegParms genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(void *aRoutine, char *trampolineName, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone, sqInt appendBoolean); -static void NoDbgRegParms genTrampolineReturn(sqInt lnkRegWasPushed); -static AbstractInstruction * NoDbgRegParms gen(sqInt opcode); -static AbstractInstruction * NoDbgRegParms genoperand(sqInt opcode, sqInt operand); -static AbstractInstruction * NoDbgRegParms genoperandoperand(sqInt opcode, sqInt operandOne, sqInt operandTwo); -static AbstractInstruction * NoDbgRegParms genoperandoperandoperand(sqInt opcode, sqInt operandOne, sqInt operandTwo, sqInt operandThree); -static sqInt NoDbgRegParms getLiteral(sqInt litIndex); -static sqInt NoDbgRegParms incrementUsageOfTargetIfLinkedSendmcpcignored(sqInt annotation, char *mcpc, sqInt superfluity); -static sqInt initialClosedPICUsageCount(void); -static void initializeBackend(void); -extern void initializeCodeZoneFromupTo(sqInt startAddress, sqInt endAddress); -static sqInt initialMethodUsageCount(void); -static sqInt initialOpenPICUsageCount(void); -static sqInt NoDbgRegParms inverseBranchFor(sqInt opcode); -static sqInt NoDbgRegParms isPCMappedAnnotation(sqInt annotation); -extern sqInt isPCWithinMethodZone(void *address); -extern sqInt isSendReturnPC(sqInt retpc); -static AbstractInstruction * NoDbgRegParms gJumpFPEqual(void *jumpTarget); -static AbstractInstruction * NoDbgRegParms gJumpFPGreaterOrEqual(void *jumpTarget); -static AbstractInstruction * NoDbgRegParms gJumpFPGreater(void *jumpTarget); -static AbstractInstruction * NoDbgRegParms gJumpFPNotEqual(void *jumpTarget); -static AbstractInstruction * NoDbgRegParms gLogicalShiftLeftCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); -static AbstractInstruction * lastOpcode(void); -extern void linkSendAtintooffsetreceiver(sqInt callSiteReturnAddress, CogMethod *sendingMethod, CogMethod *targetMethod, sqInt theEntryOffset, sqInt receiver); -static BytecodeDescriptor * loadBytesAndGetDescriptor(void); -static void NoDbgRegParms loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc); -static AbstractInstruction * NoDbgRegParms gMoveCwR(sqInt wordConstant, sqInt reg); -static AbstractInstruction * NoDbgRegParms gMoveMwrR(sqInt offset, sqInt baseReg, sqInt destReg); -static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); -static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg); -static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC); -static void mapObjectReferencesInGeneratedRuntime(void); -static void mapObjectReferencesInMachineCodeForBecome(void); -static void mapObjectReferencesInMachineCodeForFullGC(void); -static void mapObjectReferencesInMachineCodeForYoungGC(void); -extern void mapObjectReferencesInMachineCode(sqInt gcMode); -static void markAndTraceMachineCodeForNewSpaceGC(void); -static void markAndTraceObjectReferencesInGeneratedRuntime(void); -extern void markAndTraceObjectsOrFreeMachineCode(sqInt inFullGC); -static sqInt NoDbgRegParms markAndTraceOrFreeCogMethodfirstVisit(CogMethod *cogMethod, sqInt firstVisit); -static void markAndTraceOrFreeMachineCodeForFullGC(void); -static sqInt NoDbgRegParms markAndTraceOrFreePICTargetin(sqInt entryPoint, CogMethod *cPIC); -static sqInt NoDbgRegParms markLiteralsAndUnlinkIfUnmarkedSendpcmethod(sqInt annotation, char *mcpc, sqInt cogMethod); -extern void markMethodAndReferents(CogBlockMethod *aCogMethod); -static sqInt NoDbgRegParms markYoungObjectspcmethod(sqInt annotation, char *mcpc, sqInt cogMethod); -extern usqInt maxCogMethodAddress(void); -static sqInt maybeAllocAndInitIRCs(void); -static sqInt NoDbgRegParms maybeFreeCogMethodDoesntLookKosher(CogMethod *cogMethod); -static sqInt mclassIsSmallInteger(void); -extern usqInt mcPCForBackwardBranchstartBcpcin(sqInt bcpc, sqInt startbcpc, CogBlockMethod *cogMethod); -static sqInt NoDbgRegParms methodhasSameCodeAscheckPenultimate(sqInt methodA, sqInt methodB, sqInt comparePenultimateLiteral); -extern sqInt mnuOffset(void); -static AbstractInstruction * NoDbgRegParms gNativePopR(sqInt reg); -static AbstractInstruction * NoDbgRegParms gNativePushR(sqInt reg); -static AbstractInstruction * NoDbgRegParms gNativeRetN(sqInt offset); -static sqInt NoDbgRegParms needsFrameIfImmutability(sqInt stackDelta); -static sqInt NoDbgRegParms needsFrameIfInBlock(sqInt stackDelta); -static sqInt NoDbgRegParms needsFrameNever(sqInt stackDelta); -static sqInt NoDbgRegParms noAssertMethodClassAssociationOf(sqInt methodPointer); -static sqInt noCogMethodsMaximallyMarked(void); -static sqInt NoDbgRegParms noTargetsFreeInClosedPIC(CogMethod *cPIC); -static AbstractInstruction * NoDbgRegParms gOrCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); -static sqInt NoDbgRegParms outputInstructionsAt(sqInt startAddress); -static sqInt NoDbgRegParms outputInstructionsForGeneratedRuntimeAt(sqInt startAddress); -static AbstractInstruction * NoDbgRegParms gPushCw(sqInt wordConstant); -extern sqInt patchToOpenPICFornumArgsreceiver(sqInt selector, sqInt numArgs, sqInt receiver); -static sqInt picAbortDiscriminatorValue(void); -static sqInt picInterpretAbortOffset(void); -static AbstractInstruction * previousInstruction(void); -extern void printCogMethodFor(void *address); -extern void printTrampolineTable(void); -static sqInt processorHasDivQuoRemAndMClassIsSmallInteger(void); -static sqInt processorHasMultiplyAndMClassIsSmallInteger(void); -static void NoDbgRegParms recordGeneratedRunTimeaddress(char *aString, sqInt address); -extern sqInt recordPrimTraceFunc(void); -static void recordRunTimeObjectReferences(void); -static sqInt NoDbgRegParms registerMaskFor(sqInt reg); -static sqInt NoDbgRegParms registerMaskForandand(sqInt reg1, sqInt reg2, sqInt reg3); -static void NoDbgRegParms relocateCallsAndSelfReferencesInMethod(CogMethod *cogMethod); -static void NoDbgRegParms relocateCallsInClosedPIC(CogMethod *cPIC); -static sqInt NoDbgRegParms relocateIfCallOrMethodReferencemcpcdelta(sqInt annotation, char *mcpc, CogMethod *refDeltaArg); -static sqInt NoDbgRegParms remapIfObjectRefpchasYoung(sqInt annotation, char *mcpc, CogMethod *hasYoungPtr); -static sqInt NoDbgRegParms remapMaybeObjRefInClosedPICAt(sqInt mcpc); -static void NoDbgRegParms rewriteCPICCaseAttagobjReftarget(sqInt followingAddress, sqInt newTag, sqInt newObjRef, sqInt newTarget); -static sqInt scanForCleanBlocks(void); -extern void setBreakMethod(sqInt anObj); -extern void setSelectorOfto(CogMethod *cogMethod, sqInt aSelectorOop); -static sqInt NoDbgRegParms spanForCleanBlockStartingAt(sqInt startPC); -static usqInt NoDbgRegParms stackCheckOffsetOfBlockAtisMcpc(sqInt blockEntryMcpc, sqInt mcpc); -static sqInt subsequentPrototypeMethodOop(void); -extern sqInt traceLinkedSendOffset(void); -static sqInt NoDbgRegParms trampolineArgConstant(sqInt booleanOrInteger); -static char * NoDbgRegParms trampolineNamenumArgs(char *routinePrefix, sqInt numArgs); -static char * NoDbgRegParms trampolineNamenumRegArgs(char *routinePrefix, sqInt numArgs); -static sqInt unknownBytecode(void); -extern void unlinkAllSends(void); -static sqInt NoDbgRegParms unlinkIfFreeOrLinkedSendpcof(sqInt annotation, char *mcpc, CogMethod *theSelector); -static sqInt NoDbgRegParms unlinkIfLinkedSendToFreepcignored(sqInt annotation, char *mcpc, sqInt superfluity); -static sqInt NoDbgRegParms unlinkIfLinkedSendpcif(sqInt annotation, char *mcpc, CogMethod *criterionArg); -static sqInt NoDbgRegParms unlinkIfLinkedSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity); -static sqInt NoDbgRegParms unlinkIfLinkedSendpcto(sqInt annotation, char *mcpc, sqInt theCogMethod); -extern void unlinkSendsOfisMNUSelector(sqInt selector, sqInt isMNUSelector); -extern void unlinkSendsToFree(void); -extern void unlinkSendsToMethodsSuchThatAndFreeIf(sqInt (*criterion)(CogMethod *), sqInt freeIfTrue); -extern void unlinkSendsToandFreeIf(sqInt targetMethodObject, sqInt freeIfTrue); -extern void voidCogCompiledCode(void); -static void zeroOpcodeIndex(void); -static void zeroOpcodeIndexForNewOpcodes(void); -static sqInt NoDbgRegParms counters(CogMethod * self_in_counters); -static void NoDbgRegParms addToOpenPICList(CogMethod *anOpenPIC); -static void NoDbgRegParms addToYoungReferrers(CogMethod *cogMethod); -static usqInt NoDbgRegParms allocate(sqInt numBytes); -extern CogMethod * cogMethodContaining(usqInt mcpc); -static void compactCompiledCode(void); -static void NoDbgRegParms ensureInYoungReferrers(CogMethod *cogMethod); -static void NoDbgRegParms freeMethod(CogMethod *cogMethod); -static void freeOlderMethodsForCompaction(void); -extern sqInt kosherYoungReferrers(void); -static sqInt NoDbgRegParms mcpcisAtStackCheckOfBlockMethodIn(sqInt mcpc, CogMethod *cogMethod); -extern CogMethod * methodFor(void *address); -extern sqInt methodsCompiledToMachineCodeInto(sqInt arrayObj); -extern sqInt numMethods(void); -extern sqInt numMethodsOfType(sqInt cogMethodType); -static sqInt NoDbgRegParms occurrencesInYoungReferrers(CogMethod *cogMethod); -static CogMethod * NoDbgRegParms openPICWithSelector(sqInt aSelector); -static void planCompaction(void); -extern void printCogMethods(void); -extern void printCogMethodsOfType(sqInt cmType); -extern void printCogMethodsWithMethod(sqInt methodOop); -extern void printCogMethodsWithPrimitive(sqInt primIdx); -extern void printCogMethodsWithSelector(sqInt selectorOop); -extern void printCogYoungReferrers(void); -extern sqInt printOpenPICList(void); -extern sqInt pruneYoungReferrers(void); -static sqInt relocateAndPruneYoungReferrers(void); -static sqInt relocateMethodsPreCompaction(void); -static sqInt NoDbgRegParms removeFromOpenPICList(CogMethod *anOpenPIC); -static sqInt NoDbgRegParms roundUpLength(sqInt numBytes); -static void voidOpenPICList(void); -static void voidUnpairedMethodList(void); -static void voidYoungReferrersPostTenureAll(void); -EXPORT(char *) whereIsMaybeCodeThing(sqInt anOop); -static sqInt NoDbgRegParms addiuRRC(AbstractInstruction * self_in_addiuRRC, sqInt destReg, sqInt srcReg, sqInt imm); -static sqInt NoDbgRegParms adduRRR(AbstractInstruction * self_in_adduRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms andiRRC(AbstractInstruction * self_in_andiRRC, sqInt destReg, sqInt srcReg, sqInt imm); -static sqInt NoDbgRegParms andRRR(AbstractInstruction * self_in_andRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms beqRRoffset(AbstractInstruction * self_in_beqRRoffset, sqInt leftReg, sqInt rightReg, sqInt offset); -static sqInt NoDbgRegParms bgezRoffset(AbstractInstruction * self_in_bgezRoffset, sqInt cmpReg, sqInt offset); -static sqInt NoDbgRegParms bgtzRoffset(AbstractInstruction * self_in_bgtzRoffset, sqInt cmpReg, sqInt offset); -static sqInt NoDbgRegParms blezRoffset(AbstractInstruction * self_in_blezRoffset, sqInt cmpReg, sqInt offset); -static sqInt NoDbgRegParms bltzRoffset(AbstractInstruction * self_in_bltzRoffset, sqInt cmpReg, sqInt offset); -static sqInt NoDbgRegParms bneRRoffset(AbstractInstruction * self_in_bneRRoffset, sqInt leftReg, sqInt rightReg, sqInt offset); -static sqInt NoDbgRegParms callInstructionByteSize(AbstractInstruction * self_in_callInstructionByteSize); -static usqInt NoDbgRegParms callTargetFromReturnAddress(AbstractInstruction * self_in_callTargetFromReturnAddress, sqInt callSiteReturnAddress); -static sqInt NoDbgRegParms clzRRR(AbstractInstruction * self_in_clzRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms cmpC32RTempByteSize(AbstractInstruction * self_in_cmpC32RTempByteSize); -static sqInt NoDbgRegParms computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize); -static sqInt NoDbgRegParms concretizeAddCheckOverflowCqR(AbstractInstruction * self_in_concretizeAddCheckOverflowCqR); -static sqInt NoDbgRegParms concretizeAddCheckOverflowRR(AbstractInstruction * self_in_concretizeAddCheckOverflowRR); -static sqInt NoDbgRegParms concretizeAddCqR(AbstractInstruction * self_in_concretizeAddCqR); -static sqInt NoDbgRegParms concretizeAddCwR(AbstractInstruction * self_in_concretizeAddCwR); -static sqInt NoDbgRegParms concretizeAddRRDest(AbstractInstruction * self_in_concretizeAddRRDest, sqInt destReg); -static usqInt NoDbgRegParms concretizeAlignmentNops(AbstractInstruction * self_in_concretizeAlignmentNops); -static sqInt NoDbgRegParms concretizeAndCqR(AbstractInstruction * self_in_concretizeAndCqR); -static sqInt NoDbgRegParms concretizeAndCqRDest(AbstractInstruction * self_in_concretizeAndCqRDest, sqInt destReg); -static sqInt NoDbgRegParms concretizeAndCwR(AbstractInstruction * self_in_concretizeAndCwR); -static sqInt NoDbgRegParms concretizeAndRR(AbstractInstruction * self_in_concretizeAndRR); -static sqInt NoDbgRegParms concretizeArithmeticShiftRightCqR(AbstractInstruction * self_in_concretizeArithmeticShiftRightCqR); -static sqInt NoDbgRegParms concretizeArithmeticShiftRightRR(AbstractInstruction * self_in_concretizeArithmeticShiftRightRR); -static sqInt NoDbgRegParms concretizeAt(AbstractInstruction * self_in_concretizeAt, sqInt actualAddress); -static sqInt NoDbgRegParms concretizeBrEqualRR(AbstractInstruction * self_in_concretizeBrEqualRR); -static sqInt NoDbgRegParms concretizeBrLongEqualRR(AbstractInstruction * self_in_concretizeBrLongEqualRR); -static sqInt NoDbgRegParms concretizeBrLongNotEqualRR(AbstractInstruction * self_in_concretizeBrLongNotEqualRR); -static sqInt NoDbgRegParms concretizeBrNotEqualRR(AbstractInstruction * self_in_concretizeBrNotEqualRR); -static sqInt NoDbgRegParms concretizeBrSignedGreaterEqualRR(AbstractInstruction * self_in_concretizeBrSignedGreaterEqualRR); -static sqInt NoDbgRegParms concretizeBrSignedGreaterRR(AbstractInstruction * self_in_concretizeBrSignedGreaterRR); -static sqInt NoDbgRegParms concretizeBrSignedLessEqualRR(AbstractInstruction * self_in_concretizeBrSignedLessEqualRR); -static sqInt NoDbgRegParms concretizeBrSignedLessRR(AbstractInstruction * self_in_concretizeBrSignedLessRR); -static sqInt NoDbgRegParms concretizeBrUnsignedGreaterEqualRR(AbstractInstruction * self_in_concretizeBrUnsignedGreaterEqualRR); -static sqInt NoDbgRegParms concretizeBrUnsignedGreaterRR(AbstractInstruction * self_in_concretizeBrUnsignedGreaterRR); -static sqInt NoDbgRegParms concretizeBrUnsignedLessEqualRR(AbstractInstruction * self_in_concretizeBrUnsignedLessEqualRR); -static sqInt NoDbgRegParms concretizeBrUnsignedLessRR(AbstractInstruction * self_in_concretizeBrUnsignedLessRR); -static sqInt NoDbgRegParms concretizeCall(AbstractInstruction * self_in_concretizeCall); -static sqInt NoDbgRegParms concretizeCallFull(AbstractInstruction * self_in_concretizeCallFull); -static sqInt NoDbgRegParms concretizeClzRR(AbstractInstruction * self_in_concretizeClzRR); -static sqInt NoDbgRegParms concretizeCmpCqR(AbstractInstruction * self_in_concretizeCmpCqR); -static sqInt NoDbgRegParms concretizeCmpCwR(AbstractInstruction * self_in_concretizeCmpCwR); -static sqInt NoDbgRegParms concretizeCmpRR(AbstractInstruction * self_in_concretizeCmpRR); -static sqInt NoDbgRegParms concretizeDivRR(AbstractInstruction * self_in_concretizeDivRR); -static sqInt NoDbgRegParms concretizeFill32(AbstractInstruction * self_in_concretizeFill32); -static sqInt NoDbgRegParms concretizeJump(AbstractInstruction * self_in_concretizeJump); -static sqInt NoDbgRegParms concretizeJumpFull(AbstractInstruction * self_in_concretizeJumpFull); -static sqInt NoDbgRegParms concretizeJumpLong(AbstractInstruction * self_in_concretizeJumpLong); -static sqInt NoDbgRegParms concretizeJumpLongNonZero(AbstractInstruction * self_in_concretizeJumpLongNonZero); -static sqInt NoDbgRegParms concretizeJumpLongZero(AbstractInstruction * self_in_concretizeJumpLongZero); -static sqInt NoDbgRegParms concretizeJumpNonZero(AbstractInstruction * self_in_concretizeJumpNonZero); -static sqInt NoDbgRegParms concretizeJumpNoOverflow(AbstractInstruction * self_in_concretizeJumpNoOverflow); -static sqInt NoDbgRegParms concretizeJumpOverflow(AbstractInstruction * self_in_concretizeJumpOverflow); -static sqInt NoDbgRegParms concretizeJumpR(AbstractInstruction * self_in_concretizeJumpR); -static sqInt NoDbgRegParms concretizeJumpSignedGreaterEqual(AbstractInstruction * self_in_concretizeJumpSignedGreaterEqual); -static sqInt NoDbgRegParms concretizeJumpSignedGreaterThan(AbstractInstruction * self_in_concretizeJumpSignedGreaterThan); -static sqInt NoDbgRegParms concretizeJumpSignedLessEqual(AbstractInstruction * self_in_concretizeJumpSignedLessEqual); -static sqInt NoDbgRegParms concretizeJumpSignedLessThan(AbstractInstruction * self_in_concretizeJumpSignedLessThan); -static sqInt NoDbgRegParms concretizeJumpUnsignedGreaterEqual(AbstractInstruction * self_in_concretizeJumpUnsignedGreaterEqual); -static sqInt NoDbgRegParms concretizeJumpUnsignedGreaterThan(AbstractInstruction * self_in_concretizeJumpUnsignedGreaterThan); -static sqInt NoDbgRegParms concretizeJumpUnsignedLessEqual(AbstractInstruction * self_in_concretizeJumpUnsignedLessEqual); -static sqInt NoDbgRegParms concretizeJumpUnsignedLessThan(AbstractInstruction * self_in_concretizeJumpUnsignedLessThan); -static sqInt NoDbgRegParms concretizeJumpZero(AbstractInstruction * self_in_concretizeJumpZero); -static sqInt NoDbgRegParms concretizeLoadEffectiveAddressMwrR(AbstractInstruction * self_in_concretizeLoadEffectiveAddressMwrR); -static sqInt NoDbgRegParms concretizeLogicalShiftLeftCqR(AbstractInstruction * self_in_concretizeLogicalShiftLeftCqR); -static sqInt NoDbgRegParms concretizeLogicalShiftLeftRR(AbstractInstruction * self_in_concretizeLogicalShiftLeftRR); -static sqInt NoDbgRegParms concretizeLogicalShiftRightCqR(AbstractInstruction * self_in_concretizeLogicalShiftRightCqR); -static sqInt NoDbgRegParms concretizeLogicalShiftRightRR(AbstractInstruction * self_in_concretizeLogicalShiftRightRR); -static sqInt NoDbgRegParms concretizeMoveAbR(AbstractInstruction * self_in_concretizeMoveAbR); -static sqInt NoDbgRegParms concretizeMoveAwR(AbstractInstruction * self_in_concretizeMoveAwR); -static sqInt NoDbgRegParms concretizeMoveCqR(AbstractInstruction * self_in_concretizeMoveCqR); -static sqInt NoDbgRegParms concretizeMoveCwR(AbstractInstruction * self_in_concretizeMoveCwR); -static sqInt NoDbgRegParms concretizeMoveHighR(AbstractInstruction * self_in_concretizeMoveHighR); -static sqInt NoDbgRegParms concretizeMoveLowR(AbstractInstruction * self_in_concretizeMoveLowR); -static sqInt NoDbgRegParms concretizeMoveM16rR(AbstractInstruction * self_in_concretizeMoveM16rR); -static sqInt NoDbgRegParms concretizeMoveMbrR(AbstractInstruction * self_in_concretizeMoveMbrR); -static sqInt NoDbgRegParms concretizeMoveMwrR(AbstractInstruction * self_in_concretizeMoveMwrR); -static sqInt NoDbgRegParms concretizeMoveRAb(AbstractInstruction * self_in_concretizeMoveRAb); -static sqInt NoDbgRegParms concretizeMoveRAw(AbstractInstruction * self_in_concretizeMoveRAw); -static sqInt NoDbgRegParms concretizeMoveRM16r(AbstractInstruction * self_in_concretizeMoveRM16r); -static sqInt NoDbgRegParms concretizeMoveRMbr(AbstractInstruction * self_in_concretizeMoveRMbr); -static sqInt NoDbgRegParms concretizeMoveRMwr(AbstractInstruction * self_in_concretizeMoveRMwr); -static sqInt NoDbgRegParms concretizeMoveRR(AbstractInstruction * self_in_concretizeMoveRR); -static sqInt NoDbgRegParms concretizeMoveRXbrR(AbstractInstruction * self_in_concretizeMoveRXbrR); -static sqInt NoDbgRegParms concretizeMoveRXwrR(AbstractInstruction * self_in_concretizeMoveRXwrR); -static sqInt NoDbgRegParms concretizeMoveXbrRR(AbstractInstruction * self_in_concretizeMoveXbrRR); -static sqInt NoDbgRegParms concretizeMoveXwrRR(AbstractInstruction * self_in_concretizeMoveXwrRR); -static sqInt NoDbgRegParms concretizeMulCheckOverflowRR(AbstractInstruction * self_in_concretizeMulCheckOverflowRR); -static sqInt NoDbgRegParms concretizeNegateR(AbstractInstruction * self_in_concretizeNegateR); -static sqInt NoDbgRegParms concretizeNop(AbstractInstruction * self_in_concretizeNop); -static sqInt NoDbgRegParms concretizeOrCqR(AbstractInstruction * self_in_concretizeOrCqR); -static sqInt NoDbgRegParms concretizeOrCqRR(AbstractInstruction * self_in_concretizeOrCqRR); -static sqInt NoDbgRegParms concretizeOrCwR(AbstractInstruction * self_in_concretizeOrCwR); -static sqInt NoDbgRegParms concretizeOrRR(AbstractInstruction * self_in_concretizeOrRR); -static sqInt NoDbgRegParms concretizePopR(AbstractInstruction * self_in_concretizePopR); -static sqInt NoDbgRegParms concretizePrefetchAw(AbstractInstruction * self_in_concretizePrefetchAw); -static sqInt NoDbgRegParms concretizePushCq(AbstractInstruction * self_in_concretizePushCq); -static sqInt NoDbgRegParms concretizePushCw(AbstractInstruction * self_in_concretizePushCw); -static sqInt NoDbgRegParms concretizePushR(AbstractInstruction * self_in_concretizePushR); -static sqInt NoDbgRegParms concretizeRetN(AbstractInstruction * self_in_concretizeRetN); -static sqInt NoDbgRegParms concretizeStop(AbstractInstruction * self_in_concretizeStop); -static sqInt NoDbgRegParms concretizeSubCheckOverflowCqR(AbstractInstruction * self_in_concretizeSubCheckOverflowCqR); -static sqInt NoDbgRegParms concretizeSubCheckOverflowRR(AbstractInstruction * self_in_concretizeSubCheckOverflowRR); -static sqInt NoDbgRegParms concretizeSubCqR(AbstractInstruction * self_in_concretizeSubCqR); -static sqInt NoDbgRegParms concretizeSubCwR(AbstractInstruction * self_in_concretizeSubCwR); -static sqInt NoDbgRegParms concretizeSubRRDest(AbstractInstruction * self_in_concretizeSubRRDest, sqInt destReg); -static sqInt NoDbgRegParms concretizeTstCqR(AbstractInstruction * self_in_concretizeTstCqR); -static sqInt NoDbgRegParms concretizeTstCwR(AbstractInstruction * self_in_concretizeTstCwR); -static sqInt NoDbgRegParms concretizeUnimplemented(AbstractInstruction * self_in_concretizeUnimplemented); -static sqInt NoDbgRegParms concretizeXorCwR(AbstractInstruction * self_in_concretizeXorCwR); -static sqInt NoDbgRegParms concretizeXorRR(AbstractInstruction * self_in_concretizeXorRR); -static sqInt NoDbgRegParms dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize); -static sqInt NoDbgRegParms divRR(AbstractInstruction * self_in_divRR, sqInt dividendReg, sqInt divisorReg); -static sqInt NoDbgRegParms fullCallsAreRelative(AbstractInstruction * self_in_fullCallsAreRelative); -static sqInt NoDbgRegParms functionAtAddress(AbstractInstruction * self_in_functionAtAddress, sqInt mcpc); -static sqInt NoDbgRegParms genDivRRQuoRem(AbstractInstruction * self_in_genDivRRQuoRem, sqInt abstractRegDivisor, sqInt abstractRegDividend, sqInt abstractRegQuotient, sqInt abstractRegRemainder); -static AbstractInstruction * NoDbgRegParms genMulRR(AbstractInstruction * self_in_genMulRR, sqInt regSource, sqInt regDest); -static void NoDbgRegParms genPushRegisterArgsForAbortMissNumArgs(AbstractInstruction * self_in_genPushRegisterArgsForAbortMissNumArgs, sqInt numArgs); -static void NoDbgRegParms genPushRegisterArgsForNumArgsscratchReg(AbstractInstruction * self_in_genPushRegisterArgsForNumArgsscratchReg, sqInt numArgs, sqInt ignored); -static sqInt NoDbgRegParms genRemoveNArgsFromStack(AbstractInstruction * self_in_genRemoveNArgsFromStack, sqInt n); -static sqInt NoDbgRegParms genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask); -static sqInt NoDbgRegParms genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask); -static AbstractInstruction * NoDbgRegParms genSubstituteReturnAddress(AbstractInstruction * self_in_genSubstituteReturnAddress, sqInt retpc); -static sqInt NoDbgRegParms hasVarBaseRegister(AbstractInstruction * self_in_hasVarBaseRegister); -static usqInt NoDbgRegParms high16BitsOf(AbstractInstruction * self_in_high16BitsOf, usqInt word); -static usqInt NoDbgRegParms inlineCacheTagAt(AbstractInstruction * self_in_inlineCacheTagAt, usqInt callSiteReturnAddress); -static sqInt NoDbgRegParms instructionSizeAt(AbstractInstruction * self_in_instructionSizeAt, sqInt pc); -static sqInt NoDbgRegParms isCallPrecedingReturnPC(AbstractInstruction * self_in_isCallPrecedingReturnPC, sqInt mcpc); -static sqInt NoDbgRegParms isJump(AbstractInstruction * self_in_isJump); -static sqInt NoDbgRegParms isJumpAt(AbstractInstruction * self_in_isJumpAt, sqInt pc); -static sqInt NoDbgRegParms isPCDependent(AbstractInstruction * self_in_isPCDependent); -static sqInt NoDbgRegParms isShortOffset(AbstractInstruction * self_in_isShortOffset, sqInt offset); -static sqInt NoDbgRegParms itypersrteitherImmediate(AbstractInstruction * self_in_itypersrteitherImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate); -static sqInt NoDbgRegParms itypersrtsignedImmediate(AbstractInstruction * self_in_itypersrtsignedImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate); -static sqInt NoDbgRegParms itypersrtunsignedImmediate(AbstractInstruction * self_in_itypersrtunsignedImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate); -static sqInt NoDbgRegParms jA(AbstractInstruction * self_in_jA, sqInt target); -static sqInt NoDbgRegParms jalA(AbstractInstruction * self_in_jalA, sqInt target); -static sqInt NoDbgRegParms jalR(AbstractInstruction * self_in_jalR, sqInt targetReg); -static sqInt NoDbgRegParms jR(AbstractInstruction * self_in_jR, sqInt targetReg); -static sqInt NoDbgRegParms jtypetarget(AbstractInstruction * self_in_jtypetarget, sqInt op, sqInt target); -static sqInt NoDbgRegParms jumpLongByteSize(AbstractInstruction * self_in_jumpLongByteSize); -static sqInt NoDbgRegParms jumpLongConditionalByteSize(AbstractInstruction * self_in_jumpLongConditionalByteSize); -static usqInt NoDbgRegParms jumpLongConditionalTargetBeforeFollowingAddress(AbstractInstruction * self_in_jumpLongConditionalTargetBeforeFollowingAddress, sqInt mcpc); -static usqInt NoDbgRegParms jumpLongTargetBeforeFollowingAddress(AbstractInstruction * self_in_jumpLongTargetBeforeFollowingAddress, sqInt mcpc); -static sqInt NoDbgRegParms jumpShortByteSize(AbstractInstruction * self_in_jumpShortByteSize); -static usqInt NoDbgRegParms jumpTargetPCAt(AbstractInstruction * self_in_jumpTargetPCAt, sqInt pc); -static sqInt NoDbgRegParms lbRbaseoffset(AbstractInstruction * self_in_lbRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset); -static sqInt NoDbgRegParms lbuRbaseoffset(AbstractInstruction * self_in_lbuRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset); -static sqInt NoDbgRegParms lhRbaseoffset(AbstractInstruction * self_in_lhRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset); -static sqInt NoDbgRegParms lhuRbaseoffset(AbstractInstruction * self_in_lhuRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset); -static usqInt NoDbgRegParms literalAtAddress(AbstractInstruction * self_in_literalAtAddress, sqInt mcpc); -static sqInt NoDbgRegParms literalAtAddressput(AbstractInstruction * self_in_literalAtAddressput, sqInt mcpc, sqInt newLiteral); -static usqInt NoDbgRegParms literalBeforeFollowingAddress(AbstractInstruction * self_in_literalBeforeFollowingAddress, sqInt followingAddress); -static sqInt NoDbgRegParms loadLiteralByteSize(AbstractInstruction * self_in_loadLiteralByteSize); -static sqInt NoDbgRegParms loadPICLiteralByteSize(AbstractInstruction * self_in_loadPICLiteralByteSize); -static usqInt NoDbgRegParms low16BitsOf(AbstractInstruction * self_in_low16BitsOf, usqInt word); -static sqInt NoDbgRegParms luiRC(AbstractInstruction * self_in_luiRC, sqInt destReg, sqInt imm); -static sqInt NoDbgRegParms lwRbaseoffset(AbstractInstruction * self_in_lwRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset); -static sqInt NoDbgRegParms machineCodeBytes(AbstractInstruction * self_in_machineCodeBytes); -static sqInt NoDbgRegParms machineCodeWords(AbstractInstruction * self_in_machineCodeWords); -static sqInt NoDbgRegParms mfhiR(AbstractInstruction * self_in_mfhiR, sqInt destReg); -static sqInt NoDbgRegParms mfloR(AbstractInstruction * self_in_mfloR, sqInt destReg); -static sqInt NoDbgRegParms mipsbreak(AbstractInstruction * self_in_mipsbreak, sqInt code); -static sqInt NoDbgRegParms multRR(AbstractInstruction * self_in_multRR, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms nop(AbstractInstruction * self_in_nop); -static AbstractInstruction * NoDbgRegParms noteFollowingConditionalBranch(AbstractInstruction * self_in_noteFollowingConditionalBranch, AbstractInstruction *branch); -static AbstractInstruction * NoDbgRegParms noteFollowingOverflowBranch(AbstractInstruction * self_in_noteFollowingOverflowBranch, AbstractInstruction *branch); -static sqInt NoDbgRegParms numIntRegArgs(AbstractInstruction * self_in_numIntRegArgs); -static sqInt NoDbgRegParms opcodeAtAddress(AbstractInstruction * self_in_opcodeAtAddress, sqInt mcpc); -static sqInt NoDbgRegParms oriRRC(AbstractInstruction * self_in_oriRRC, sqInt destReg, sqInt srcReg, sqInt imm); -static sqInt NoDbgRegParms orRRR(AbstractInstruction * self_in_orRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static void NoDbgRegParms padIfPossibleWithStopsFromto(AbstractInstruction * self_in_padIfPossibleWithStopsFromto, sqInt startAddr, sqInt endAddr); -static sqInt NoDbgRegParms prefRoffsethint(AbstractInstruction * self_in_prefRoffsethint, sqInt baseReg, sqInt offset, sqInt hint); -static sqInt NoDbgRegParms pushLinkRegisterByteSize(AbstractInstruction * self_in_pushLinkRegisterByteSize); -static AbstractInstruction * NoDbgRegParms relocateCallBeforeReturnPCby(AbstractInstruction * self_in_relocateCallBeforeReturnPCby, sqInt retpc, sqInt delta); -static AbstractInstruction * NoDbgRegParms relocateJumpLongBeforeFollowingAddressby(AbstractInstruction * self_in_relocateJumpLongBeforeFollowingAddressby, sqInt pc, sqInt delta); -static void NoDbgRegParms relocateJumpLongConditionalBeforeFollowingAddressby(AbstractInstruction * self_in_relocateJumpLongConditionalBeforeFollowingAddressby, sqInt pc, sqInt delta); -static AbstractInstruction * NoDbgRegParms relocateMethodReferenceBeforeAddressby(AbstractInstruction * self_in_relocateMethodReferenceBeforeAddressby, sqInt pc, sqInt delta); -static sqInt NoDbgRegParms rewriteCallAttarget(AbstractInstruction * self_in_rewriteCallAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress); -static void NoDbgRegParms rewriteConditionalJumpLongAttarget(AbstractInstruction * self_in_rewriteConditionalJumpLongAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress); -static void NoDbgRegParms rewriteCPICJumpAttarget(AbstractInstruction * self_in_rewriteCPICJumpAttarget, usqInt addressFollowingJump, usqInt jumpTargetAddr); -static sqInt NoDbgRegParms rewriteInlineCacheAttagtarget(AbstractInstruction * self_in_rewriteInlineCacheAttagtarget, usqInt callSiteReturnAddress, sqInt cacheTag, usqInt callTargetAddress); -static void NoDbgRegParms rewriteInlineCacheTagat(AbstractInstruction * self_in_rewriteInlineCacheTagat, sqInt cacheTag, usqInt callSiteReturnAddress); -static void NoDbgRegParms rewriteITypeBranchAtAddresstarget(AbstractInstruction * self_in_rewriteITypeBranchAtAddresstarget, sqInt mcpc, sqInt newTarget); -static void NoDbgRegParms rewriteJTypeAtAddressdelta(AbstractInstruction * self_in_rewriteJTypeAtAddressdelta, sqInt mcpc, sqInt delta); -static void NoDbgRegParms rewriteJTypeAtAddresstarget(AbstractInstruction * self_in_rewriteJTypeAtAddresstarget, sqInt mcpc, sqInt newTarget); -static sqInt NoDbgRegParms rewriteJumpLongAttarget(AbstractInstruction * self_in_rewriteJumpLongAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress); -static sqInt NoDbgRegParms rtAtAddress(AbstractInstruction * self_in_rtAtAddress, sqInt mcpc); -static sqInt NoDbgRegParms rtypersrtrdsafunct(AbstractInstruction * self_in_rtypersrtrdsafunct, sqInt op, sqInt rs, sqInt rt, sqInt rd, sqInt sa, sqInt funct); -static sqInt NoDbgRegParms sbRbaseoffset(AbstractInstruction * self_in_sbRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset); -static sqInt NoDbgRegParms setsConditionCodesFor(AbstractInstruction * self_in_setsConditionCodesFor, sqInt aConditionalJumpOpcode); -static sqInt NoDbgRegParms shRbaseoffset(AbstractInstruction * self_in_shRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset); -static usqInt NoDbgRegParms sizePCDependentInstructionAt(AbstractInstruction * self_in_sizePCDependentInstructionAt, sqInt eventualAbsoluteAddress); -static sqInt NoDbgRegParms sllRRC(AbstractInstruction * self_in_sllRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount); -static sqInt NoDbgRegParms sllvRRR(AbstractInstruction * self_in_sllvRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms sltiRRC(AbstractInstruction * self_in_sltiRRC, sqInt destReg, sqInt leftReg, sqInt imm); -static sqInt NoDbgRegParms sltiuRRC(AbstractInstruction * self_in_sltiuRRC, sqInt destReg, sqInt leftReg, sqInt imm); -static sqInt NoDbgRegParms sltRRR(AbstractInstruction * self_in_sltRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms sltuRRR(AbstractInstruction * self_in_sltuRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms sraRRC(AbstractInstruction * self_in_sraRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount); -static sqInt NoDbgRegParms sravRRR(AbstractInstruction * self_in_sravRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms srlRRC(AbstractInstruction * self_in_srlRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount); -static sqInt NoDbgRegParms srlvRRR(AbstractInstruction * self_in_srlvRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms stop(AbstractInstruction * self_in_stop); -static void NoDbgRegParms stopsFromto(AbstractInstruction * self_in_stopsFromto, sqInt startAddr, sqInt endAddr); -static sqInt NoDbgRegParms storeLiteralbeforeFollowingAddress(AbstractInstruction * self_in_storeLiteralbeforeFollowingAddress, sqInt literal, sqInt followingAddress); -static sqInt NoDbgRegParms subuRRR(AbstractInstruction * self_in_subuRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms swRbaseoffset(AbstractInstruction * self_in_swRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset); -static usqInt NoDbgRegParms targetFromITypeAtAddress(AbstractInstruction * self_in_targetFromITypeAtAddress, usqInt mcpc); -static usqInt NoDbgRegParms targetFromJTypeAtAddress(AbstractInstruction * self_in_targetFromJTypeAtAddress, usqInt mcpc); -static sqInt NoDbgRegParms xoriRRC(AbstractInstruction * self_in_xoriRRC, sqInt destReg, sqInt srcReg, sqInt imm); -static sqInt NoDbgRegParms xorRRR(AbstractInstruction * self_in_xorRRR, sqInt destReg, sqInt leftReg, sqInt rightReg); -static sqInt NoDbgRegParms zoneCallsAreRelative(AbstractInstruction * self_in_zoneCallsAreRelative); -static sqInt NoDbgRegParms checkValidObjectReference(sqInt anOop); -static AbstractInstruction * NoDbgRegParms genCmpClassFloatCompactIndexR(sqInt reg); -static AbstractInstruction * NoDbgRegParms genCmpClassMethodContextCompactIndexR(sqInt reg); -static sqInt NoDbgRegParms genLoadSlotsourceRegdestReg(sqInt index, sqInt sourceReg, sqInt destReg); -static sqInt genPrimitiveAdd(void); -static sqInt genPrimitiveAsCharacter(void); -static sqInt genPrimitiveAtPut(void); -static sqInt genPrimitiveBitAnd(void); -static sqInt genPrimitiveBitOr(void); -static sqInt genPrimitiveBitShift(void); -static sqInt genPrimitiveBitXor(void); -static sqInt genPrimitiveClass(void); -static sqInt genPrimitiveDiv(void); -static sqInt genPrimitiveDivide(void); -static sqInt genPrimitiveEqual(void); -static sqInt genPrimitiveGreaterOrEqual(void); -static sqInt genPrimitiveGreaterThan(void); -static sqInt genPrimitiveHighBit(void); -static sqInt genPrimitiveIdentical(void); -static sqInt genPrimitiveImmediateAsInteger(void); -static sqInt genPrimitiveIntegerAt(void); -static sqInt genPrimitiveIntegerAtPut(void); -static sqInt genPrimitiveLessOrEqual(void); -static sqInt genPrimitiveLessThan(void); -static sqInt genPrimitiveMakePoint(void); -static sqInt genPrimitiveMod(void); -static sqInt genPrimitiveMultiply(void); -static sqInt genPrimitiveNew(void); -static sqInt genPrimitiveNewMethod(void); -static sqInt genPrimitiveNewWithArg(void); -static sqInt genPrimitiveNotEqual(void); -static sqInt genPrimitiveNotIdentical(void); -static sqInt genPrimitiveObjectAt(void); -static sqInt genPrimitiveQuo(void); -static sqInt genPrimitiveShallowCopy(void); -static sqInt genPrimitiveStringAtPut(void); -static sqInt genPrimitiveStringCompareWith(void); -static sqInt genPrimitiveStringReplace(void); -static sqInt genPrimitiveSubtract(void); -static sqInt NoDbgRegParms genSmallIntegerComparison(sqInt jumpOpcode); -static sqInt NoDbgRegParms genSmallIntegerComparisonorDoubleComparisoninvert(sqInt jumpOpcode, AbstractInstruction * NoDbgRegParms (*jumpFPOpcodeGenerator)(void *), sqInt invertComparison); -static sqInt getActiveContextAllocatesInMachineCode(void); -static sqInt NoDbgRegParms isUnannotatableConstant(CogSimStackEntry *simStackEntry); -static sqInt NoDbgRegParms cacheTagIsMarked(sqInt cacheTag); -static sqInt NoDbgRegParms checkValidOopReference(sqInt anOop); -static sqInt NoDbgRegParms classForInlineCacheTag(sqInt inlineCacheTag); -static sqInt compactClassFieldMask(void); -static sqInt NoDbgRegParms couldBeObject(sqInt oop); -static usqInt genActiveContextTrampoline(void); -static sqInt NoDbgRegParms genAddSmallIntegerTagsTo(sqInt aRegister); -static sqInt NoDbgRegParms genClearAndSetSmallIntegerTagsIn(sqInt scratchReg); -static sqInt NoDbgRegParms genConvertIntegerInRegtoSmallIntegerInReg(sqInt srcReg, sqInt destReg); -static sqInt NoDbgRegParms genConvertIntegerToSmallIntegerInReg(sqInt reg); -static sqInt NoDbgRegParms genConvertSmallIntegerToIntegerInReg(sqInt reg); -static sqInt NoDbgRegParms genCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(sqInt bcpc, sqInt numArgs, sqInt numCopied, sqInt ctxtNumArgs, sqInt isLargeCtxt, sqInt isInBlock); -static void generateObjectRepresentationTrampolines(void); -static void NoDbgRegParms genGetActiveContextNumArgslargeinBlock(sqInt numArgs, sqInt isLargeContext, sqInt isInBlock); -static sqInt NoDbgRegParms genGetClassFormatOfNonIntintoscratchReg(sqInt instReg, sqInt destReg, sqInt scratchReg); -static sqInt NoDbgRegParms genGetClassObjectOfintoscratchRegmayBeAForwarder(sqInt instReg, sqInt destReg, sqInt scratchReg, sqInt mayBeAForwarder); -static AbstractInstruction * NoDbgRegParms genGetClassTagOfintoscratchReg(sqInt instReg, sqInt destReg, sqInt scratchReg); -static sqInt NoDbgRegParms genGetCompactClassIndexNonImmOfinto(sqInt instReg, sqInt destReg); -static sqInt NoDbgRegParms genGetDoubleValueOfinto(sqInt srcReg, sqInt destFPReg); -static sqInt NoDbgRegParms genGetFixedFieldsOfPointerNonIntintoscratchReg(sqInt instReg, sqInt destReg, sqInt scratchReg); -static sqInt NoDbgRegParms genGetHashFieldNonImmOfasSmallIntegerInto(sqInt instReg, sqInt destReg); -static AbstractInstruction * NoDbgRegParms genGetInlineCacheClassTagFromintoforEntry(sqInt sourceReg, sqInt destReg, sqInt forEntry); -static AbstractInstruction * NoDbgRegParms genJumpImmediate(sqInt aRegister); -static AbstractInstruction * NoDbgRegParms genJumpIsSmallIntegerValuescratch(sqInt aRegister, sqInt scratchReg); -static AbstractInstruction * NoDbgRegParms genJumpNotSmallIntegerInScratchReg(sqInt aRegister); -static AbstractInstruction * NoDbgRegParms genJumpNotSmallIntegerValuescratch(sqInt aRegister, sqInt scratchReg); -static AbstractInstruction * NoDbgRegParms genJumpNotSmallInteger(sqInt aRegister); -static AbstractInstruction * NoDbgRegParms genJumpSmallInteger(sqInt aRegister); -static void NoDbgRegParms genNewArrayOfSizeinitialized(sqInt size, sqInt initialize); -static sqInt genPrimitiveAt(void); -static sqInt NoDbgRegParms genPrimitiveIdenticalOrNotIf(sqInt orNot); -static sqInt genPrimitiveIdentityHash(void); -static sqInt genPrimitiveSize(void); -static sqInt genPrimitiveStringAt(void); -static sqInt NoDbgRegParms genRemoveSmallIntegerTagsInScratchReg(sqInt scratchReg); -static sqInt NoDbgRegParms genSetSmallIntegerTagsIn(sqInt scratchReg); -static sqInt NoDbgRegParms genShiftAwaySmallIntegerTagsInScratchReg(sqInt scratchReg); -static sqInt NoDbgRegParms genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt inFrame, sqInt needsStoreCheck); -static sqInt NoDbgRegParms genStoreSourceRegslotIndexintoNewObjectInDestReg(sqInt sourceReg, sqInt index, sqInt destReg); -static sqInt NoDbgRegParms inlineCacheTagForInstance(sqInt oop); -static sqInt NoDbgRegParms inlineCacheTagIsYoung(sqInt cacheTag); -static void NoDbgRegParms markAndTraceLiteralIfYoung(sqInt literal); -static void NoDbgRegParms markAndTraceLiteral(sqInt literal); -extern sqInt numRegArgs(void); -static sqInt NoDbgRegParms remapObject(sqInt objOop); -static sqInt NoDbgRegParms remapOop(sqInt oop); -static sqInt NoDbgRegParms shouldAnnotateObjectReference(sqInt anOop); -static sqInt NoDbgRegParms slotOffsetOfInstVarIndex(sqInt index); -static sqInt NoDbgRegParms validInlineCacheTag(sqInt cacheTag); -static SimStackEntry * NoDbgRegParms ensureSpilledAtfrom(SimStackEntry * self_in_ensureSpilledAtfrom, sqInt baseOffset, sqInt baseRegister); -static sqInt NoDbgRegParms isSameEntryAs(SimStackEntry * self_in_isSameEntryAs, CogSimStackEntry *ssEntry); -static sqInt NoDbgRegParms mayBeAForwarder(SimStackEntry * self_in_mayBeAForwarder); -static void NoDbgRegParms popToReg(SimStackEntry * self_in_popToReg, sqInt reg); -static sqInt NoDbgRegParms registerMask(SimStackEntry * self_in_registerMask); -static sqInt NoDbgRegParms registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone); -static sqInt NoDbgRegParms registerOrNone(SimStackEntry * self_in_registerOrNone); -static void NoDbgRegParms storeToReg(SimStackEntry * self_in_storeToReg, sqInt reg); -static sqInt NoDbgRegParms isMergeFixup(BytecodeFixup * self_in_isMergeFixup); -static AbstractInstruction * NoDbgRegParms checkLiteralforInstruction(sqInt literal, AbstractInstruction *anInstruction); -static AbstractInstruction * NoDbgRegParms checkQuickConstantforInstruction(sqInt literal, AbstractInstruction *anInstruction); -static sqInt NoDbgRegParms ceClosureCopyDescriptor(sqInt descriptor); -extern sqInt cogMethodHasExternalPrim(CogMethod *aCogMethod); -extern sqInt cogMethodHasMachineCodePrim(CogMethod *aCogMethod); -static sqInt compileBlockDispatch(void); -static void compileGetErrorCode(void); -static sqInt NoDbgRegParms compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags); -static sqInt NoDbgRegParms compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)); -static AbstractInstruction * NoDbgRegParms compileOpenPICMethodCacheProbeForwithShiftbaseRegOrNone(sqInt selector, sqInt shift, sqInt baseRegOrNone); -static void NoDbgRegParms compileOpenPICnumArgs(sqInt selector, sqInt numArgs); -static AbstractInstruction * NoDbgRegParms compilePerformMethodCacheProbeForwithShiftbaseRegOrNone(sqInt selectorReg, sqInt shift, sqInt baseRegOrNone); -static sqInt compilePrimitive(void); -static sqInt extendedPushBytecode(void); -static sqInt extendedStoreAndPopBytecode(void); -static sqInt extendedStoreBytecode(void); -static sqInt NoDbgRegParms frameOffsetOfTemporary(sqInt index); -static sqInt genExtendedSendBytecode(void); -static sqInt genExtendedSuperBytecode(void); -static sqInt genExtSendSuperBytecode(void); -static sqInt genFastPrimFail(void); -static void NoDbgRegParms genFastPrimTraceUsingand(sqInt r1, sqInt r2); -static sqInt genLongJumpIfFalse(void); -static sqInt genLongJumpIfTrue(void); -static sqInt genLongStoreAndPopTemporaryVariableBytecode(void); -static sqInt genLongUnconditionalBackwardJump(void); -static sqInt genLongUnconditionalForwardJump(void); -static sqInt NoDbgRegParms genLookupForPerformNumArgs(sqInt numArgs); -static usqInt NoDbgRegParms genMustBeBooleanTrampolineForcalled(sqInt boolean, char *trampolineName); -static sqInt genPrimitiveHashMultiply(void); -static void NoDbgRegParms genPrimReturnEnterCogCodeEnilopmart(sqInt profiling); -static sqInt genPushConstantFalseBytecode(void); -static sqInt genPushConstantNilBytecode(void); -static sqInt genPushConstantTrueBytecode(void); -static sqInt genPushLiteralConstantBytecode(void); -static sqInt genPushLiteralVariableBytecode(void); -static sqInt genPushQuickIntegerConstantBytecode(void); -static sqInt genPushReceiverVariableBytecode(void); -static sqInt genPushTemporaryVariableBytecode(void); -extern sqInt genQuickReturnConst(void); -extern sqInt genQuickReturnInstVar(void); -extern sqInt genQuickReturnSelf(void); -static sqInt genReturnFalse(void); -static sqInt genReturnNil(void); -static sqInt genReturnTrue(void); -static sqInt genSecondExtendedSendBytecode(void); -static sqInt genSendLiteralSelector0ArgsBytecode(void); -static sqInt genSendLiteralSelector1ArgBytecode(void); -static sqInt genSendLiteralSelector2ArgsBytecode(void); -static sqInt genShortJumpIfFalse(void); -static sqInt genShortUnconditionalJump(void); -static sqInt genSpecialSelectorEqualsEquals(void); -static sqInt genSpecialSelectorNotEqualsEquals(void); -static sqInt genSpecialSelectorSend(void); -static sqInt genStoreAndPopReceiverVariableBytecode(void); -static sqInt genStoreAndPopRemoteTempLongBytecode(void); -static sqInt genStoreAndPopTemporaryVariableBytecode(void); -static sqInt genStoreRemoteTempLongBytecode(void); -extern sqInt mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj); -static sqInt numSpecialSelectors(void); -static usqInt NoDbgRegParms pcDataForBlockEntryMethod(sqInt blockEntryMcpc, sqInt cogMethod); -static sqInt NoDbgRegParms pcDataForAnnotationMcpcBcpcMethod(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *cogMethodArg); -static PrimitiveDescriptor * primitiveGeneratorOrNil(void); -static sqInt NoDbgRegParms registerisInMask(sqInt reg, sqInt mask); -static sqInt NoDbgRegParms v3BlockCodeSize(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt NoDbgRegParms v3LongForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt NoDbgRegParms v3LongBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt NoDbgRegParms v3ShortForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static BlockStart * NoDbgRegParms addBlockStartAtnumArgsnumCopiedspan(sqInt bytecodepc, sqInt numArgs, sqInt numCopied, sqInt span); -static void NoDbgRegParms adjustArgumentsForPerform(sqInt numArgs); -static sqInt NoDbgRegParms allocateRegForStackEntryAtnotConflictingWith(sqInt index, sqInt regMask); -static sqInt NoDbgRegParms allocateRegNotConflictingWith(sqInt regMask); -static sqInt NoDbgRegParms anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n); -extern void callCogCodePopReceiverArg0Regs(void); -extern void callCogCodePopReceiverArg1Arg0Regs(void); -static sqInt NoDbgRegParms compileAbstractInstructionsFromthrough(sqInt start, sqInt end); -static sqInt compileBlockBodies(void); -static void NoDbgRegParms compileBlockFrameBuild(BlockStart *blockStart); -static void NoDbgRegParms compileBlockFramelessEntry(BlockStart *blockStart); -static CogMethod * NoDbgRegParms compileCogMethod(sqInt selector); -static sqInt compileEntireMethod(void); -static void compileFrameBuild(void); -#if IMMUTABILITY -static void compileTwoPathFrameBuild(void); -#endif /* IMMUTABILITY */ -static void compileTwoPathFramelessInit(void); -static sqInt NoDbgRegParms cPICMissTrampolineFor(sqInt numArgs); -static sqInt doubleExtendedDoAnythingBytecode(void); -static sqInt duplicateTopBytecode(void); -static BytecodeFixup * NoDbgRegParms ensureFixupAt(sqInt targetPC); -static BytecodeFixup * NoDbgRegParms ensureNonMergeFixupAt(sqInt targetPC); -static void ensureReceiverResultRegContainsSelf(void); -static void NoDbgRegParms evaluateat(BytecodeDescriptor *descriptor, sqInt pc); -static sqInt NoDbgRegParms eventualTargetOf(sqInt targetBytecodePC); -static sqInt NoDbgRegParms freeAnyRegNotConflictingWith(sqInt regMask); -static sqInt genBlockReturn(void); -static void (*genCallPICEnilopmartNumArgs(sqInt numArgs))(void) ; -static sqInt genExternalizePointersForPrimitiveCall(void); -static void generateEnilopmarts(void); -static sqInt NoDbgRegParms generateInstructionsAt(sqInt eventualAbsoluteAddress); -static void generateMissAbortTrampolines(void); -static void generateSendTrampolines(void); -static void generateTracingTrampolines(void); -static sqInt NoDbgRegParms genIdenticalNoBranchArgIsConstantrcvrIsConstantargRegrcvrRegorNotIf(sqInt argIsConstant, sqInt rcvrIsConstant, sqInt argReg, sqInt rcvrRegOrNone, sqInt orNot); -static sqInt NoDbgRegParms genInlinedIdenticalOrNotIf(sqInt orNot); -static sqInt NoDbgRegParms genJumpBackTo(sqInt targetBytecodePC); -static sqInt NoDbgRegParms genJumpIfto(sqInt boolean, sqInt targetBytecodePC); -static sqInt NoDbgRegParms genJumpTo(sqInt targetBytecodePC); -static sqInt NoDbgRegParms genMarshalledSendnumArgssendTable(sqInt selectorIndex, sqInt numArgs, sqInt *sendTable); -static usqInt NoDbgRegParms genMethodAbortTrampolineFor(sqInt numArgs); -static usqInt NoDbgRegParms genPICAbortTrampolineFor(sqInt numArgs); -static usqInt NoDbgRegParms genPICMissTrampolineFor(sqInt numArgs); -static sqInt genPopStackBytecode(void); -static sqInt genPrimitiveClosureValue(void); -static sqInt genPrimitivePerform(void); -static sqInt genPushActiveContextBytecode(void); -static sqInt genPushClosureCopyCopiedValuesBytecode(void); -static sqInt NoDbgRegParms genPushLiteralIndex(sqInt literalIndex); -static sqInt NoDbgRegParms genPushLiteralVariable(sqInt literalIndex); -static sqInt NoDbgRegParms genPushLiteral(sqInt literal); -static sqInt NoDbgRegParms genPushMaybeContextReceiverVariable(sqInt slotIndex); -static sqInt genPushNewArrayBytecode(void); -static sqInt genPushReceiverBytecode(void); -static sqInt NoDbgRegParms genPushReceiverVariable(sqInt index); -static void genPushRegisterArgs(void); -static sqInt genPushRemoteTempLongBytecode(void); -static sqInt NoDbgRegParms genPushTemporaryVariable(sqInt index); -static sqInt genReturnReceiver(void); -static sqInt genReturnTopFromBlock(void); -static sqInt genReturnTopFromMethod(void); -static sqInt NoDbgRegParms genSendSupernumArgs(sqInt selectorIndex, sqInt numArgs); -static usqInt NoDbgRegParms genSendTrampolineFornumArgscalledargargargarg(void *aRoutine, sqInt numArgs, char *aString, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3); -static sqInt NoDbgRegParms genSendnumArgs(sqInt selectorIndex, sqInt numArgs); -static sqInt genSpecialSelectorArithmetic(void); -static sqInt genSpecialSelectorClass(void); -static sqInt genSpecialSelectorComparison(void); -static sqInt genStaticallyResolvedSpecialSelectorComparison(void); -static sqInt NoDbgRegParms genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt litVarIndex, sqInt needsStoreCheck, sqInt needsImmCheck); -static sqInt NoDbgRegParms genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt slotIndex, sqInt needsStoreCheck, sqInt needsImmCheck); -static sqInt NoDbgRegParms genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt slotIndex, sqInt needsStoreCheck, sqInt needsImmCheck); -static sqInt NoDbgRegParms genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt remoteTempIndex, sqInt needsStoreCheck); -static sqInt NoDbgRegParms genStorePopTemporaryVariable(sqInt popBoolean, sqInt tempIndex); -static sqInt genUpArrowReturn(void); -static sqInt NoDbgRegParms genVanillaInlinedIdenticalOrNotIf(sqInt orNot); -static void NoDbgRegParms initSimStackForFramefulMethod(sqInt startpc); -static void NoDbgRegParms initSimStackForFramelessBlock(sqInt startpc); -static void NoDbgRegParms initSimStackForFramelessMethod(sqInt startpc); -static sqInt NoDbgRegParms isNonForwarderReceiver(sqInt reg); -static sqInt liveRegisters(void); -static sqInt NoDbgRegParms mapDeadDescriptorIfNeeded(BytecodeDescriptor *descriptor); -static void NoDbgRegParms marshallSendArguments(sqInt numArgs); -static sqInt maybeCompilingFirstPassOfBlockWithInitialPushNil(void); -static sqInt NoDbgRegParms mergeWithFixupIfRequired(BytecodeFixup *fixup); -static sqInt NoDbgRegParms methodAbortTrampolineFor(sqInt numArgs); -static sqInt methodFoundInvalidPostScan(void); -static sqInt NoDbgRegParms needsFrameIfMod16GENumArgs(sqInt stackDelta); -static sqInt NoDbgRegParms needsFrameIfStackGreaterThanOne(sqInt stackDelta); -static sqInt NoDbgRegParms numberOfSpillsInTopNItems(sqInt n); -static sqInt NoDbgRegParms picAbortTrampolineFor(sqInt numArgs); -static sqInt prevInstIsPCAnnotated(void); -static sqInt receiverIsInReceiverResultReg(void); -static void NoDbgRegParms reinitializeFixupsFromthrough(sqInt start, sqInt end); -static sqInt NoDbgRegParms scanBlock(BlockStart *blockStart); -static sqInt scanMethod(void); -static void NoDbgRegParms ssAllocateRequiredRegMaskupThroughupThroughNative(sqInt requiredRegsMask, sqInt stackPtr, sqInt nativeStackPtr); -static void NoDbgRegParms ssFlushUpThroughReceiverVariable(sqInt slotIndex); -static void NoDbgRegParms ssFlushUpThroughTemporaryVariable(sqInt tempIndex); -static void NoDbgRegParms ssPop(sqInt n); -static sqInt NoDbgRegParms ssPushAnnotatedConstant(sqInt literal); -static sqInt NoDbgRegParms ssPushBaseoffset(sqInt reg, sqInt offset); -static sqInt NoDbgRegParms ssPushConstant(sqInt literal); -static sqInt NoDbgRegParms ssPushDesc(SimStackEntry simStackEntry); -static sqInt NoDbgRegParms ssPushRegister(sqInt reg); -static void NoDbgRegParms ssPush(sqInt n); -static SimStackEntry ssSelfDescriptor(void); -static void NoDbgRegParms ssStoreAndReplacePoptoReg(sqInt popBoolean, sqInt reg); -static sqInt NoDbgRegParms ssStorePoptoPreferredReg(sqInt popBoolean, sqInt preferredReg); -static void NoDbgRegParms ssStorePoptoReg(sqInt popBoolean, sqInt reg); -static CogSimStackEntry * ssTop(void); -static CogSimStackEntry * NoDbgRegParms ssValue(sqInt n); -static sqInt NoDbgRegParms stackEntryIsBoolean(CogSimStackEntry *simStackEntry); -static sqInt tempsValidAndVolatileEntriesSpilled(void); -static sqInt NoDbgRegParms tryCollapseTempVectorInitializationOfSize(sqInt slots); -static sqInt NoDbgRegParms v3PushNilSizenumInitialNils(sqInt aMethodObj, sqInt numInitialNils); -static sqInt NoDbgRegParms v3NumPushNils(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); -static sqInt violatesEnsureSpilledSpillAssert(void); -static void voidReceiverResultRegContainsSelf(void); - - -/*** Variables ***/ -static AbstractInstruction * abstractOpcodes; -static usqInt baseAddress; -static sqInt blockCount; -static AbstractInstruction * blockEntryLabel; -static AbstractInstruction * blockEntryNoContextSwitch; -static BlockStart * blockStarts; -static sqInt breakBlock; -static sqInt breakMethod; -static sqInt byte0; -static sqInt byte1; -static sqInt byte2; -static sqInt byte3; -static sqInt bytecodePC; -static sqInt bytecodeSetOffset; -static sqInt ceActiveContextTrampoline; -static sqInt ceByteSizeOfTrampoline; -static sqInt ceClosureCopyTrampoline; -static sqInt ceCPICMissTrampoline; -static sqInt ceCreateNewArrayTrampoline; -static sqInt ceFetchContextInstVarTrampoline; -static sqInt ceFFICalloutTrampoline; -static sqInt ceFloatObjectOfTrampoline; -static sqInt ceFloatValueOfTrampoline; -static sqInt ceFlushICache; -static sqInt ceFreeTrampoline; -static sqInt ceInstantiateClassIndexableSizeTrampoline; -static sqInt ceInstantiateClassTrampoline; -static sqInt ceMallocTrampoline; -static sqInt ceMethodAbortTrampoline; -static sqInt ceNonLocalReturnTrampoline; -static sqInt cePICAbortTrampoline; -static sqInt cePositive32BitIntegerTrampoline; -static sqInt cePositive32BitValueOfTrampoline; -static sqInt cePositive64BitIntegerTrampoline; -static sqInt cePositive64BitValueOfTrampoline; -static sqInt cePrimReturnEnterCogCode; -static sqInt cePrimReturnEnterCogCodeProfiling; -static sqInt ceReapAndResetErrorCodeTrampoline; -static sqInt ceSendMustBeBooleanAddFalseTrampoline; -static sqInt ceSendMustBeBooleanAddTrueTrampoline; -static sqInt ceSigned32BitIntegerTrampoline; -static sqInt ceSigned32BitValueOfTrampoline; -static sqInt ceSigned64BitIntegerTrampoline; -static sqInt ceSigned64BitValueOfTrampoline; -static sqInt ceStoreCheckTrampoline; -static sqInt ceStoreContextInstVarTrampoline; -static sqInt ceTraceBlockActivationTrampoline; -static sqInt ceTraceLinkedSendTrampoline; -static sqInt ceTraceStoreTrampoline; -static sqInt checkedEntryAlignment; -static sqInt closedPICSize; -static sqInt codeBase; -static sqInt codeModified; -static sqInt cogConstituentIndex; -static sqInt compactionInProgress; -static sqInt compilationPass; -static sqInt compilationTrace; -static sqInt cPICCaseSize; -static sqInt cPICEndOfCodeOffset; -static sqInt cPICEndSize; -static CogMethod * cPICPrototype; -static sqInt currentCallCleanUpSize; -static sqInt deadCode; -static sqInt debugBytecodePointers; -static sqInt debugFixupBreaks; -static sqInt debugOpcodeIndices; -static sqInt debugStackPointers; -static sqInt directedSendUsesBinding; -static sqInt directedSuperBindingSendTrampolines; -static sqInt directedSuperSendTrampolines; -static sqInt disassemblingMethod; -static AbstractInstruction * endCPICCase0; -static sqInt endPC; -static AbstractInstruction * entry; -static sqInt entryPointMask; -static CogMethod * enumeratingCogMethod; -static sqInt expectedFPAlignment; -static sqInt expectedSPAlignment; -static sqInt extA; -static sqInt extB; -static sqInt firstCPICCaseOffset; -static sqInt firstSend; -static BytecodeFixup * fixups; -static AbstractInstruction * fullBlockEntry; -static AbstractInstruction * fullBlockNoContextSwitchEntry; -static BytecodeDescriptor generatorTable[256] = { - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushLiteralVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopReceiverVariableBytecode, 0, needsFrameIfImmutability, -1, 0, 1, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 1, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushReceiverBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantTrueBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantFalseBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushConstantNilBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushQuickIntegerConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushQuickIntegerConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushQuickIntegerConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushQuickIntegerConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genReturnReceiver, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnTrue, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnFalse, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnNil, 0, needsFrameIfInBlock, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnTopFromMethod, 0, needsFrameIfInBlock, -1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 }, - { genReturnTopFromBlock, 0, needsFrameNever, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { extendedPushBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { extendedStoreBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 0, 0 }, - { extendedStoreAndPopBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, IMMUTABILITY, 0, 0, 1, 0, 0 }, - { genExtendedSendBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { doubleExtendedDoAnythingBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genExtendedSuperBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0 }, - { genSecondExtendedSendBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genPopStackBytecode, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { duplicateTopBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushActiveContextBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushNewArrayBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, - { genPushRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genStoreAndPopRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushClosureCopyCopiedValuesBytecode, v3BlockCodeSize, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortUnconditionalJump, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genShortJumpIfFalse, v3ShortForwardBranchDistance, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongUnconditionalBackwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongUnconditionalBackwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongUnconditionalBackwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongUnconditionalBackwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongUnconditionalForwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genLongUnconditionalForwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genLongUnconditionalForwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genLongUnconditionalForwardJump, v3LongBranchDistance, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genLongJumpIfTrue, v3LongForwardBranchDistance, 0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongJumpIfTrue, v3LongForwardBranchDistance, 0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongJumpIfTrue, v3LongForwardBranchDistance, 0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongJumpIfTrue, v3LongForwardBranchDistance, 0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongJumpIfFalse, v3LongForwardBranchDistance, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongJumpIfFalse, v3LongForwardBranchDistance, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongJumpIfFalse, v3LongForwardBranchDistance, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genLongJumpIfFalse, v3LongForwardBranchDistance, 0, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, AddRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, SubRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpLess, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpGreater, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpLessOrEqual, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpGreaterOrEqual, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpZero, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorComparison, 0, 0, 0, JumpNonZero, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, AndRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorArithmetic, 0, 0, 0, OrRR, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorEqualsEquals, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorClass, 0, needsFrameIfStackGreaterThanOne, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorNotEqualsEquals, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector0ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector1ArgBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { genSendLiteralSelector2ArgsBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 } -}; -static sqInt guardPageSize; -static sqInt hasMovableLiteral; -static sqInt hasYoungReferent; -static sqInt inBlock; -static sqInt initialPC; -static sqInt introspectionData; -static sqInt introspectionDataIndex; -static int labelCounter; -static sqInt lastSend; -static usqInt limitAddress; -static sqInt maxLitIndex; -static sqInt methodAbortTrampolines[4]; -static sqInt methodBytesFreedSinceLastCompaction; -static sqInt methodCount; -static sqInt methodHeader; -static sqInt methodObj; -static sqInt methodOrBlockNumArgs; -static sqInt methodOrBlockNumTemps; -static usqIntptr_t minValidCallAddress; -static usqInt mzFreeStart; -static sqInt needsFrame; -static AbstractInstruction * noCheckEntry; -static sqInt numAbstractOpcodes; -static sqInt numExtB; -static usqInt objectReferencesInRuntime[NumObjRefsInRuntime+1]; -static sqInt opcodeIndex; -static CogMethod *openPICList = 0; -static sqInt openPICSize; -static sqInt ordinarySendTrampolines[NumSendTrampolines]; -static sqInt picAbortTrampolines[4]; -static AbstractInstruction * picInterpretAbort; -static sqInt picMissTrampolines[4]; -static AbstractInstruction * picMNUAbort; -static BytecodeDescriptor * prevBCDescriptor; -static PrimitiveDescriptor primitiveGeneratorTable[MaxCompiledPrimitiveIndex+1] = { - { 0, -1 }, - { genPrimitiveAdd, 1 }, - { genPrimitiveSubtract, 1 }, - { genPrimitiveLessThan, 1 }, - { genPrimitiveGreaterThan, 1 }, - { genPrimitiveLessOrEqual, 1 }, - { genPrimitiveGreaterOrEqual, 1 }, - { genPrimitiveEqual, 1 }, - { genPrimitiveNotEqual, 1 }, - { genPrimitiveMultiply, 1 }, - { genPrimitiveDivide, 1 }, - { genPrimitiveMod, 1 }, - { genPrimitiveDiv, 1 }, - { genPrimitiveQuo, 1 }, - { genPrimitiveBitAnd, 1 }, - { genPrimitiveBitOr, 1 }, - { genPrimitiveBitXor, 1 }, - { genPrimitiveBitShift, 1 }, - { genPrimitiveMakePoint, 1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveAt, 1 }, - { genPrimitiveAtPut, 2 }, - { genPrimitiveSize, 0 }, - { genPrimitiveStringAt, 1 }, - { genPrimitiveStringAtPut, 2 }, - { genFastPrimFail, -1 }, - { genFastPrimFail, -1 }, - { genFastPrimFail, -1 }, - { genPrimitiveObjectAt, 1 }, - { 0, -1 }, - { genPrimitiveNew, 0 }, - { genPrimitiveNewWithArg, 1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveIdentityHash, 0 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveNewMethod, 2 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitivePerform, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveStringReplace, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveIdentical, 1 }, - { genPrimitiveClass, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveShallowCopy, 0 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveStringCompareWith, 1 }, - { genPrimitiveHashMultiply, 0 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveIntegerAt, 1 }, - { genPrimitiveIntegerAtPut, 2 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveNotIdentical, 1 }, - { genPrimitiveAsCharacter, -1 }, - { genPrimitiveImmediateAsInteger, 0 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveIdentityHash, 0 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genFastPrimFail, -1 }, - { genFastPrimFail, -1 }, - { 0, -1 }, - { genPrimitiveClosureValue, 0 }, - { genPrimitiveClosureValue, 1 }, - { genPrimitiveClosureValue, 2 }, - { genPrimitiveClosureValue, 3 }, - { genPrimitiveClosureValue, 4 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveClosureValue, 0 }, - { genPrimitiveClosureValue, 1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { 0, -1 }, - { genPrimitiveHighBit, 0 } -}; -static sqInt primitiveIndex; -static sqInt processorLock; -static sqInt receiverTags; -static sqInt regArgsHaveBeenPushed; -static sqInt runtimeObjectRefIndex; -static AbstractInstruction * sendMiss; -static sqInt simNativeStackPtr; -static sqInt simSpillBase; -static SimStackEntry simStack[70]; -static sqInt simStackPtr; -static AbstractInstruction * stackCheckLabel; -static AbstractInstruction * stackOverflowCall; -static sqInt superSendTrampolines[NumSendTrampolines]; -static sqInt tempOop; -static char *trampolineAddresses[NumTrampolines*2]; -static sqInt trampolineTableIndex; -static sqInt uncheckedEntryAlignment; -static usqInt unpairedMethodList; -static sqInt useTwoPaths; -static sqInt varBaseAddress; -static usqInt youngReferrers; -static AbstractInstruction aMethodLabel; -static AbstractInstruction * const backEnd = &aMethodLabel; -#if DUAL_MAPPED_CODE_ZONE -static void (*ceFlushDCache)(usqIntptr_t from, usqIntptr_t to); -#endif -#if DUAL_MAPPED_CODE_ZONE -static sqInt codeToDataDelta; -#else -# define codeToDataDelta 0 -#endif -static AbstractInstruction * const methodLabel = &aMethodLabel; -sqInt blockNoContextSwitchOffset; -sqInt breakPC; -sqInt cbEntryOffset; -sqInt cbNoSwitchEntryOffset; -sqInt ceBaseFrameReturnTrampoline; -sqInt ceCannotResumeTrampoline; -sqInt ceCheckForInterruptTrampoline; -sqInt ceReturnToInterpreterTrampoline; -sqInt cFramePointerInUse; -sqInt cmEntryOffset; -sqInt cmNoCheckEntryOffset; -usqInt methodZoneBase; -sqInt missOffset; -int traceFlags = 8 /* prim trace log on by default */; -sqInt traceStores; -void (*ceCall0ArgsPIC)(void); -void (*ceCall1ArgsPIC)(void); -void (*ceCall2ArgsPIC)(void); -void (*ceCallCogCodePopReceiverAndClassRegs)(void); -void (*ceCallCogCodePopReceiverArg0Regs)(void); -void (*ceCallCogCodePopReceiverArg1Arg0Regs)(void); -void (*ceCallCogCodePopReceiverReg)(void); -void (*ceCaptureCStackPointers)(void); -void (*ceEnterCogCodePopReceiverReg)(void); -usqIntptr_t (*ceGetFP)(void); -usqIntptr_t (*ceGetSP)(void); -void (*ceInvokeInterpret)(void); -#if COGMTVM -usqIntptr_t (*ceTryLockVMOwner)(usqIntptr_t); -#endif -void (*realCECallCogCodePopReceiverAndClassRegs)(void); -void (*realCECallCogCodePopReceiverArg0Regs)(void); -void (*realCECallCogCodePopReceiverArg1Arg0Regs)(void); -void (*realCECallCogCodePopReceiverReg)(void); -void (*realCEEnterCogCodePopReceiverReg)(void); - - -/*** Macros ***/ -#define inlineCacheValueForSelectorin(backEnd,selector,aCogMethod) (selector) -#define roundUpToMethodAlignment(ignored,numBytes) ((numBytes) + 7 & -8) -#define cPICNumCases stackCheckOffset -#define cPICNumCasesHack hack hack hack i.e. the getter macro does all the work -#define abstractInstructionAt(index) (&abstractOpcodes[index]) -#define addressIsInInstructions(address) (!((usqInt)(address) & (BytesPerWord-1)) \ - && (address) >= &abstractOpcodes[0] \ - && (address) < &abstractOpcodes[opcodeIndex]) -#define allocateBlockStarts(numBlocks) do { \ - blockStarts = (numBlocks) ? alloca(sizeof(BlockStart) * (numBlocks)) : 0; \ -} while (0) -#define assertValidDualZoneReadAddress(address) 0 -#define assertValidDualZoneWriteAddress(address) 0 -#define backEnd() backEnd -#define blockAlignment() 8 -#define blockStartAt(index) (&blockStarts[index]) -#define breakOnImplicitReceiver() (traceFlags & 64) -#define ceBaseFrameReturnPC() ceBaseFrameReturnTrampoline -#define ceCannotResumePC() ((usqInt)ceCannotResumeTrampoline) -#define ceCheckForInterruptTrampoline() ceCheckForInterruptTrampoline -#define ceReturnToInterpreterPC() ((usqInt)ceReturnToInterpreterTrampoline) -#define codeByteAtput(address,value) byteAtput((address) + codeToDataDelta, value) -#define codeLong32Atput(address,value) long32Atput((address) + codeToDataDelta, value) -#define codeLong64Atput(address,value) long64Atput((address) + codeToDataDelta, value) -#define codeLongAtput(address,value) longAtput((address) + codeToDataDelta, value) -#define codeMemcpy(dest,src,bytes) memcpy(dest,src,bytes) -#define codeMemmove(dest,src,bytes) memmove((char *)(dest)+codeToDataDelta,src,bytes) -#define cr() putchar('\n') -#define entryOffset() cmEntryOffset -#define generatorAt(index) (&generatorTable[index]) -#define getCodeToDataDelta() codeToDataDelta -#define getIsObjectReference() 2 -#define halt() warning("halt") -#define haltmsg(msg) warning("halt: " msg) -#define interpretOffset() missOffset -#define maxCogCodeSize() (16*1024*1024) -#define maybeBreakGeneratingFromto(address,end) 0 -#define maybeBreakGeneratingInstructionWithIndex(i) 0 -#define maybeHaltIfDebugPC() 0 -#define methodLabel() methodLabel -#define methodZoneBase() methodZoneBase -#define minCallAddress() minValidCallAddress -#define minCogMethodAddress() methodZoneBase -#define noCheckEntryOffset() cmNoCheckEntryOffset -#define noContextSwitchBlockEntryOffset() blockNoContextSwitchOffset -#define notYetImplemented() warning("not yet implemented") -#define null 0 -#define printNum(n) printf("%" PRIdSQINT, (sqInt) (n)) -#define printOnTrace() (traceFlags & 1) -#define print(aString) printf("%s", aString) -#define recordBlockTrace() (traceFlags & 4) -#define recordEventTrace() (traceFlags & 16) -#define recordFastCCallPrimTrace() (traceFlags & 512) -#define recordOverflowTrace() (traceFlags & 32) -#define recordPrimTrace() (traceFlags & 8) -#define recordSendTrace() (traceFlags & 2) -#define reportError(n) warning("compilation error") -#define setHasMovableLiteral(b) (hasMovableLiteral = (b)) -#define setHasYoungReferent(b) (hasYoungReferent = (b)) -#define tryLockVMOwnerTo(value) ceTryLockVMOwner(value) -#define varBaseAddress() varBaseAddress -#define nextOpenPIC methodObject -#define nextOpenPICHack hack hack hack i.e. the getter macro does all the work -#define freeStart() mzFreeStart -#define limitZony() ((CogMethod *)mzFreeStart) -#define methodBytesFreedSinceLastCompaction() methodBytesFreedSinceLastCompaction -#define youngReferrers() youngReferrers -#define flushDCacheFromto(me,startAddress,endAddress) 0 -#define flushICacheFromto(me,startAddress,endAddress) cacheflush((char*) startAddress, endAddress - startAddress, ICACHE) -#define maybeConstant(sse) ((sse)->constant) -#define fullBlockEntryOffset() cbEntryOffset -#define fullBlockNoContextSwitchEntryOffset() cbNoSwitchEntryOffset -#define fixupAtIndex(index) (&fixups[index]) -#define simNativeStackAt(index) (simNativeStack + (index)) -#define simSelf() simStack -#define simStackAt(index) (simStack + (index)) -#define traceDescriptor(ign) 0 -#define traceFixupmerge(igu,ana) 0 -#define traceMerge(ign) 0 -#define traceSimStack() 0 -#define traceSpill(ign) 0 -#define allocatype(numElements, elementType) alloca((numElements)*sizeof(elementType)) -#define numElementsIn(anArray) (sizeof(anArray)/sizeof(anArray[0])) -#define oopisGreaterThanOrEqualTo(anOop,otherOop) ((usqInt)(anOop) >= (usqInt)(otherOop)) -#define oopisGreaterThanOrEqualToandLessThanOrEqualTo(anOop,baseOop,limitOop) ((usqInt)(anOop) >= (usqInt)(baseOop) && (usqInt)(anOop) <= (usqInt)(limitOop)) -#define oopisGreaterThanOrEqualToandLessThan(anOop,baseOop,limitOop) ((usqInt)(anOop) >= (usqInt)(baseOop) && (usqInt)(anOop) < (usqInt)(limitOop)) -#define oopisGreaterThan(anOop,otherOop) ((usqInt)(anOop) > (usqInt)(otherOop)) -#define oopisGreaterThanandLessThan(anOop,baseOop,limitOop) ((usqInt)(anOop) > (usqInt)(baseOop) && (usqInt)(anOop) < (usqInt)(limitOop)) -#define oopisLessThanOrEqualTo(anOop,otherOop) ((usqInt)(anOop) <= (usqInt)(otherOop)) -#define oopisLessThan(anOop,otherOop) ((usqInt)(anOop) < (usqInt)(otherOop)) - - - /* CogAbstractInstruction>>#addDependent: */ -static AbstractInstruction * NoDbgRegParms -addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *anInstruction) -{ - if (!(((self_in_addDependent->dependent)) == null)) { - (anInstruction->dependent = (self_in_addDependent->dependent)); - } - return ((self_in_addDependent->dependent) = anInstruction); -} - - -/* Answer an unused abstract register in the liveRegMask. - Subclasses with more registers can override to answer them. */ - - /* CogAbstractInstruction>>#availableFloatRegisterOrNoneFor: */ -static sqInt NoDbgRegParms -availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask) -{ - if (!(((liveRegsMask & (1U << DPFPReg0)) != 0))) { - return DPFPReg0; - } - if (!(((liveRegsMask & (1U << DPFPReg1)) != 0))) { - return DPFPReg1; - } - if (!(((liveRegsMask & (1U << DPFPReg2)) != 0))) { - return DPFPReg2; - } - if (!(((liveRegsMask & (1U << DPFPReg3)) != 0))) { - return DPFPReg3; - } - if (!(((liveRegsMask & (1U << DPFPReg4)) != 0))) { - return DPFPReg4; - } - if (!(((liveRegsMask & (1U << DPFPReg5)) != 0))) { - return DPFPReg5; - } - if (!(((liveRegsMask & (1U << DPFPReg6)) != 0))) { - return DPFPReg6; - } - if (!(((liveRegsMask & (1U << DPFPReg7)) != 0))) { - return DPFPReg7; - } - return NoReg; -} - - -/* Answer an unused abstract register in the liveRegMask. - Subclasses with more registers can override to answer them. - N.B. Do /not/ allocate TempReg. */ - - /* CogAbstractInstruction>>#availableRegisterOrNoneFor: */ -static sqInt NoDbgRegParms -availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask) -{ - if (!(((liveRegsMask & (1U << Arg1Reg)) != 0))) { - return Arg1Reg; - } - if (!(((liveRegsMask & (1U << Arg0Reg)) != 0))) { - return Arg0Reg; - } - if (!(((liveRegsMask & (1U << SendNumArgsReg)) != 0))) { - return SendNumArgsReg; - } - if (!(((liveRegsMask & (1U << ClassReg)) != 0))) { - return ClassReg; - } - if (!(((liveRegsMask & (1U << ReceiverResultReg)) != 0))) { - return ReceiverResultReg; - } - return NoReg; -} - - -/* For out-of-line literal support, clone a literal from a literal. */ - - /* CogAbstractInstruction>>#cloneLiteralFrom: */ -static void NoDbgRegParms -cloneLiteralFrom(AbstractInstruction * self_in_cloneLiteralFrom, AbstractInstruction *existingLiteral) -{ - assert((((existingLiteral->opcode)) == Literal) - && ((((self_in_cloneLiteralFrom->dependent)) == null) - && (((self_in_cloneLiteralFrom->address)) == null))); - (self_in_cloneLiteralFrom->opcode) = Literal; - (self_in_cloneLiteralFrom->annotation) = (existingLiteral->annotation); - ((self_in_cloneLiteralFrom->operands))[0] = (((existingLiteral->operands))[0]); - ((self_in_cloneLiteralFrom->operands))[1] = (((existingLiteral->operands))[1]); - ((self_in_cloneLiteralFrom->operands))[2] = (((existingLiteral->operands))[2]); -} - - -/* Load the stack pointer register with that of the C stack, effecting - a switch to the C stack. Used when machine code calls into the - CoInterpreter run-time (e.g. to invoke interpreter primitives). */ - - /* CogAbstractInstruction>>#genLoadCStackPointer */ -static sqInt NoDbgRegParms -genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer) -{ - AbstractInstruction *anInstruction; - - /* begin checkLiteral:forInstruction: */ - cStackPointerAddress(); - anInstruction = genoperandoperand(MoveAwR, cStackPointerAddress(), NativeSPReg); - return 0; -} - - -/* Load the frame and stack pointer registers with those of the C stack, - effecting a switch to the C stack. Used when machine code calls into - the CoInterpreter run-time (e.g. to invoke interpreter primitives). - N.B. CoInterpreter stack layout dictates that the stack pointer should be - loaded first. - The stack zone is allocated on the C stack before the interpreter runs and - hence before CStackPointer and CFramePointer are captured. So when running - in machine - code the native stack pointer and frame pointer appear to be on a colder - part of the - stack to CStackPointer and CFramePointer. When CStackPointerhas been set - and the frame pointer is still in machine code the current frame looks - like it has lots of - stack. If the frame pointer was set to CFramePointer before hand then it - would be beyond the stack pointer for that one instruction. */ - - /* CogAbstractInstruction>>#genLoadCStackPointers */ -static sqInt NoDbgRegParms -genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkLiteral:forInstruction: */ - cStackPointerAddress(); - anInstruction = genoperandoperand(MoveAwR, cStackPointerAddress(), NativeSPReg); - /* begin checkLiteral:forInstruction: */ - cFramePointerAddress(); - anInstruction1 = genoperandoperand(MoveAwR, cFramePointerAddress(), FPReg); - return 0; -} - - -/* Switch back to the Smalltalk stack. Assign SPReg first - because typically it is used immediately afterwards. */ - - /* CogAbstractInstruction>>#genLoadStackPointers */ -static sqInt NoDbgRegParms -genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkLiteral:forInstruction: */ - stackPointerAddress(); - anInstruction = genoperandoperand(MoveAwR, stackPointerAddress(), SPReg); - /* begin checkLiteral:forInstruction: */ - framePointerAddress(); - anInstruction1 = genoperandoperand(MoveAwR, framePointerAddress(), FPReg); - return 0; -} - - -/* Switch back to the Smalltalk stack where there may be a C return address - on top of stack below - the last primitive argument. Assign SPReg first because typically it is - used immediately afterwards. - */ - - /* CogAbstractInstruction>>#genLoadStackPointersForFastPrimCall: */ -static sqInt NoDbgRegParms -genLoadStackPointersForFastPrimCall(AbstractInstruction * self_in_genLoadStackPointersForFastPrimCall, sqInt spareReg) -{ - genLoadStackPointers(self_in_genLoadStackPointersForFastPrimCall); - return 0; -} - - -/* Save the frame and stack pointer registers to the framePointer - and stackPointer variables. Used to save the machine code frame - for use by the run-time when calling into the CoInterpreter run-time. */ - - /* CogAbstractInstruction>>#genSaveStackPointers */ -static sqInt NoDbgRegParms -genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkLiteral:forInstruction: */ - framePointerAddress(); - anInstruction = genoperandoperand(MoveRAw, FPReg, framePointerAddress()); - /* begin checkLiteral:forInstruction: */ - stackPointerAddress(); - anInstruction1 = genoperandoperand(MoveRAw, SPReg, stackPointerAddress()); - return 0; -} - - -/* Generic register swap code. Subclasses for processors that have a true - exchange operation will override to use it. */ - - /* CogAbstractInstruction>>#genSwapR:R:Scratch: */ -static AbstractInstruction * NoDbgRegParms -genSwapRRScratch(AbstractInstruction * self_in_genSwapRRScratch, sqInt regA, sqInt regB, sqInt regTmp) -{ - AbstractInstruction *first; - - first = genoperandoperand(MoveRR, regA, regTmp); - genoperandoperand(MoveRR, regB, regA); - genoperandoperand(MoveRR, TempReg, regB); - return first; -} - - /* CogAbstractInstruction>>#genWriteCResultIntoReg: */ -static void NoDbgRegParms -genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister) -{ - if ((abstractRegister != NoReg) - && (abstractRegister != ABIResultReg)) { - genoperandoperand(MoveRR, ABIResultReg, abstractRegister); - } -} - - -/* For out-of-line literal support, initialize a sharable literal. */ - - /* CogAbstractInstruction>>#initializeSharableLiteral: */ -static void NoDbgRegParms -initializeSharableLiteral(AbstractInstruction * self_in_initializeSharableLiteral, sqInt literal) -{ - (self_in_initializeSharableLiteral->opcode) = Literal; - - /* separate := nil for Slang */ - (self_in_initializeSharableLiteral->annotation) = null; - (self_in_initializeSharableLiteral->address) = null; - (self_in_initializeSharableLiteral->dependent) = null; - ((self_in_initializeSharableLiteral->operands))[0] = literal; - ((self_in_initializeSharableLiteral->operands))[1] = (1 + (((sqInt)((usqInt)(BytesPerOop) << 1)))); - ((self_in_initializeSharableLiteral->operands))[2] = -1; -} - - -/* For out-of-line literal support, initialize an unsharable literal. */ - - /* CogAbstractInstruction>>#initializeUniqueLiteral: */ -static void NoDbgRegParms -initializeUniqueLiteral(AbstractInstruction * self_in_initializeUniqueLiteral, sqInt literal) -{ - (self_in_initializeUniqueLiteral->opcode) = Literal; - - /* separate := nil for Slang */ - (self_in_initializeUniqueLiteral->annotation) = null; - (self_in_initializeUniqueLiteral->address) = null; - (self_in_initializeUniqueLiteral->dependent) = null; - ((self_in_initializeUniqueLiteral->operands))[0] = literal; - ((self_in_initializeUniqueLiteral->operands))[1] = (0 + (((sqInt)((usqInt)(BytesPerOop) << 1)))); - ((self_in_initializeUniqueLiteral->operands))[2] = -1; -} - - -/* Set the target of a jump instruction. These all have the target in the - first operand. */ - - /* CogAbstractInstruction>>#jmpTarget: */ -static AbstractInstruction * NoDbgRegParms -jmpTarget(AbstractInstruction * self_in_jmpTarget, AbstractInstruction *anAbstractInstruction) -{ - ((self_in_jmpTarget->operands))[0] = (((usqInt)anAbstractInstruction)); - return anAbstractInstruction; -} - - /* CogAbstractInstruction>>#resolveJumpTarget */ -static void NoDbgRegParms -resolveJumpTarget(AbstractInstruction * self_in_resolveJumpTarget) -{ - BytecodeFixup *fixup; - - assert(isJump(self_in_resolveJumpTarget)); - fixup = ((BytecodeFixup *) (((self_in_resolveJumpTarget->operands))[0])); - if (addressIsInFixups(fixup)) { - assert(addressIsInInstructions((fixup->targetInstruction))); - jmpTarget(self_in_resolveJumpTarget, (fixup->targetInstruction)); - } -} - - -/* Rewrite a CallFull instruction to call a different target. This variant is - used to rewrite cached primitive calls. - Answer the extent of the code change which is used to compute the range of - the icache to flush. - This defaults to rewriteCallAt:target:; processors that differentiate - between Call and CallFull will override. */ - - /* CogAbstractInstruction>>#rewriteCallFullAt:target: */ -static sqInt NoDbgRegParms -rewriteCallFullAttarget(AbstractInstruction * self_in_rewriteCallFullAttarget, sqInt callSiteReturnAddress, sqInt callTargetAddress) -{ - return rewriteCallAttarget(self_in_rewriteCallFullAttarget, callSiteReturnAddress, callTargetAddress); -} - - -/* Rewrite a JumpFull instruction to jump to a different target. This variant - is used to rewrite cached primitive calls. - Answer the extent of the code change which is used to compute the range of - the icache to flush. - This defaults to rewriteJumpLongAt:target:; processors that differentiate - between Jump and JumpFull will override. */ - - /* CogAbstractInstruction>>#rewriteJumpFullAt:target: */ -static sqInt NoDbgRegParms -rewriteJumpFullAttarget(AbstractInstruction * self_in_rewriteJumpFullAttarget, sqInt callSiteReturnAddress, sqInt callTargetAddress) -{ - return rewriteJumpLongAttarget(self_in_rewriteJumpFullAttarget, callSiteReturnAddress, callTargetAddress); -} - - /* CogBlockMethod>>#cmHomeMethod */ -static CogMethod * NoDbgRegParms -cmHomeMethod(CogBlockMethod * self_in_cmHomeMethod) -{ - return ((CogMethod *) ((((usqInt)self_in_cmHomeMethod)) - ((self_in_cmHomeMethod->homeOffset)))); -} - - /* CogBytecodeDescriptor>>#isBranch */ -static sqInt NoDbgRegParms -isBranch(BytecodeDescriptor * self_in_isBranch) -{ - return (((self_in_isBranch->spanFunction)) != null) - && (!((self_in_isBranch->isBlockCreation))); -} - - -/* destReg := (signed)srcReg >> quickConstant */ - - /* Cogit>>#ArithmeticShiftRightCq:R:R: */ -static AbstractInstruction * NoDbgRegParms -gArithmeticShiftRightCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) -{ - AbstractInstruction * first; - - return genoperandoperandoperand(ArithmeticShiftRightCqRR, quickConstant, srcReg, destReg); - first = genoperandoperand(MoveRR, srcReg, destReg); - genoperandoperand(ArithmeticShiftRightCqR, quickConstant, destReg); - return first; -} - - /* Cogit>>#abortOffset */ -sqInt -abortOffset(void) -{ - return missOffset; -} - - /* Cogit>>#addCleanBlockStarts */ -static void -addCleanBlockStarts(void) -{ - sqInt i; - sqInt iLimiT; - sqInt lit; - sqInt startPCOrNil; - - for (i = 1, iLimiT = (literalCountOf(methodObj)); i <= iLimiT; i += 1) { - lit = fetchPointerofObject(i, methodObj); - startPCOrNil = startPCOrNilOfLiteralin(lit, methodObj); - if (!(startPCOrNil == null)) { - maxLitIndex = ((maxLitIndex < i) ? i : maxLitIndex); - addBlockStartAtnumArgsnumCopiedspan(startPCOrNil - 1, argumentCountOfClosure(lit), copiedValueCountOfClosure(lit), spanForCleanBlockStartingAt(startPCOrNil - 1)); - } - } -} - - -/* Perform an integrity/leak check using the heapMap. - Set a bit at each cog method's header. */ - - /* Cogit>>#addCogMethodsToHeapMap */ -void -addCogMethodsToHeapMap(void) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - heapMapAtWordPut(cogMethod, 1); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* Cogit>>#addressIsInCurrentCompilation: */ -static sqInt NoDbgRegParms -addressIsInCurrentCompilation(sqInt address) -{ - return ((((usqInt)address)) >= ((methodLabel->address))) - && ((((usqInt)address)) < ((((youngReferrers()) < (((methodLabel->address)) + MaxMethodSize)) ? (youngReferrers()) : (((methodLabel->address)) + MaxMethodSize)))); -} - - /* Cogit>>#addressIsInFixups: */ -static sqInt NoDbgRegParms -addressIsInFixups(BytecodeFixup *address) -{ - return (BytecodeFixup *)address >= fixups && (BytecodeFixup *)address < (fixups + numAbstractOpcodes); -} - - -/* calculate the end of the n'th case statement - which is complicated - because we have case 1 right at the top of our CPIC and then build up from - the last one. Yes I know this sounds strange, but trust me - I'm an - Engineer, we do things backwards all the emit - */ - - /* Cogit>>#addressOfEndOfCase:inCPIC: */ -static sqInt NoDbgRegParms -addressOfEndOfCaseinCPIC(sqInt n, CogMethod *cPIC) -{ - assert((n >= 1) - && (n <= MaxCPICCases)); - return (n == 1 - ? (((sqInt)cPIC)) + firstCPICCaseOffset - : ((((sqInt)cPIC)) + firstCPICCaseOffset) + (((MaxCPICCases + 1) - n) * cPICCaseSize)); -} - - -/* Align methodZoneBase to that for the start of a method. */ - - /* Cogit>>#alignMethodZoneBase */ -static void -alignMethodZoneBase(void) -{ - usqInt oldBase; - - oldBase = methodZoneBase; - methodZoneBase = roundUpToMethodAlignment(backEnd(), methodZoneBase); - stopsFromto(backEnd, oldBase, methodZoneBase - 1); -} - - /* Cogit>>#alignUptoRoutineBoundary: */ -static sqInt NoDbgRegParms -alignUptoRoutineBoundary(sqInt anAddress) -{ - return (((anAddress + 7) | 7) - 7); -} - - -/* Check that all methods have valid selectors, and that all linked sends are - to valid targets and have valid cache tags - */ - - /* Cogit>>#allMachineCodeObjectReferencesValid */ -static sqInt -allMachineCodeObjectReferencesValid(void) -{ - CogMethod *cogMethod; - sqInt ok; - - ok = 1; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - if (!(asserta(checkValidOopReference((cogMethod->selector))))) { - ok = 0; - } - if (!(asserta((cogMethodDoesntLookKosher(cogMethod)) == 0))) { - ok = 0; - } - } - if ((((cogMethod->cmType)) == CMMethod) - || (((cogMethod->cmType)) == CMOpenPIC)) { - if (!(asserta((mapForperformUntilarg(cogMethod, checkIfValidOopRefAndTargetpccogMethod, cogMethod)) == 0))) { - ok = 0; - } - } - if (((cogMethod->cmType)) == CMClosedPIC) { - if (!(asserta(noTargetsFreeInClosedPIC(cogMethod)))) { - ok = 0; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return ok; -} - - /* Cogit>>#allMethodsHaveCorrectHeader */ -static sqInt -allMethodsHaveCorrectHeader(void) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - if (!(((cogMethod->objectHeader)) == (nullHeaderForMachineCodeMethod()))) { - return 0; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return 1; -} - - /* Cogit>>#annotateAbsolutePCRef: */ -static AbstractInstruction * NoDbgRegParms -annotateAbsolutePCRef(AbstractInstruction *abstractInstruction) -{ - (abstractInstruction->annotation = IsAbsPCReference); - return abstractInstruction; -} - - /* Cogit>>#annotateBytecode: */ -static AbstractInstruction * NoDbgRegParms -annotateBytecode(AbstractInstruction *abstractInstruction) -{ - (abstractInstruction->annotation = HasBytecodePC); - return abstractInstruction; -} - - /* Cogit>>#annotate:objRef: */ -static AbstractInstruction * NoDbgRegParms -annotateobjRef(AbstractInstruction *abstractInstruction, sqInt anOop) -{ - if (shouldAnnotateObjectReference(anOop)) { - setHasMovableLiteral(1); - if (isYoungObject(anOop)) { - setHasYoungReferent(1); - } - (abstractInstruction->annotation = IsObjectReference); - } - return abstractInstruction; -} - - /* Cogit>>#assertSaneJumpTarget: */ -static void NoDbgRegParms -assertSaneJumpTarget(AbstractInstruction *jumpTarget) -{ - assert((closedPICSize == null) - || ((openPICSize == null) - || ((addressIsInInstructions(jumpTarget)) - || ((((((usqInt)jumpTarget)) >= codeBase) && ((((usqInt)jumpTarget)) <= ((((sqInt)(limitZony()))) + (((closedPICSize < openPICSize) ? openPICSize : closedPICSize))))))))); -} - - -/* {self firstInvalidDualZoneAddress. self firstInvalidDualZoneAddress + - codeToDataDelta } - */ -/* {self firstInvalidDualZoneAddress hex. (self firstInvalidDualZoneAddress + - codeToDataDelta) hex } - */ -/* {(objectMemory longAt: self firstInvalidDualZoneAddress) hex. - (objectMemory longAt: self firstInvalidDualZoneAddress + codeToDataDelta) - hex } - */ -/* self armDisassembleDualZoneAnomalies */ -/* self armPrintDualZoneAnomalies */ - - /* Cogit>>#assertValidDualZone */ -static void -assertValidDualZone(void) -{ -} - - -/* Answer an unused abstract register in the registerMask, or NoReg if none. */ - - /* Cogit>>#availableRegisterOrNoneIn: */ -static sqInt NoDbgRegParms -availableRegisterOrNoneIn(sqInt liveRegsMask) -{ - sqInt reg; - - if (liveRegsMask != 0) { - for (reg = 0; reg <= 0x1F; reg += 1) { - if (((liveRegsMask & (1U << reg)) != 0)) { - return reg; - } - } - } - return NoReg; -} - - -/* Evaluate binaryFunction with the block start mcpc and supplied arg for - each entry in the block dispatch. If the function answers non-zero answer - the value - it answered. Used to update back-references to the home method in - compaction. */ - - /* Cogit>>#blockDispatchTargetsFor:perform:arg: */ -static sqInt NoDbgRegParms -blockDispatchTargetsForperformarg(CogMethod *cogMethod, usqInt (*binaryFunction)(sqInt mcpc, sqInt arg), sqInt arg) -{ - sqInt blockEntry; - usqInt end; - sqInt pc; - sqInt result; - usqInt targetpc; - - if (((cogMethod->blockEntryOffset)) == 0) { - return null; - } - blockEntry = ((cogMethod->blockEntryOffset)) + (((sqInt)cogMethod)); - pc = blockEntry; - end = (mapEndFor(cogMethod)) - 1; - while (pc < end) { - if (isJumpAt(backEnd, pc)) { - targetpc = jumpTargetPCAt(backEnd, pc); - if (targetpc < blockEntry) { - result = binaryFunction(targetpc, arg); - if (result != 0) { - return result; - } - } - } - pc += 4 /* instructionSizeAt: */; - } - return 0; -} - - -/* Answer the zero-relative bytecode pc matching the machine code pc argument - in cogMethod, given the start of the bytecodes for cogMethod's block or - method object. */ - - /* Cogit>>#bytecodePCFor:startBcpc:in: */ -sqInt -bytecodePCForstartBcpcin(sqInt mcpc, sqInt startbcpc, CogBlockMethod *cogMethod) -{ - sqInt aMethodObj; - sqInt annotation; - sqInt bcpc; - sqInt bsOffset; - sqInt byte; - BytecodeDescriptor *descriptor; - sqInt distance; - sqInt endbcpc; - CogMethod *homeMethod; - sqInt isBackwardBranch; - sqInt isInBlock; - sqInt latestContinuation; - usqInt map; - sqInt mapByte; - usqInt mcpc1; - sqInt nExts; - sqInt nextBcpc; - sqInt result; - sqInt targetPC; - - latestContinuation = 0; - /* begin mapFor:bcpc:performUntil:arg: */ - assert(((cogMethod->stackCheckOffset)) > 0); - - /* The stack check maps to the start of the first bytecode, - the first bytecode being effectively after frame build. */ - mcpc1 = (((usqInt)cogMethod)) + ((cogMethod->stackCheckOffset)); - result = findIsBackwardBranchMcpcBcpcMatchingMcpc(null, (0 + (((int)((usqInt)(HasBytecodePC) << 1)))), (((char *) mcpc1)), startbcpc, (((void *)mcpc))); - if (result != 0) { - return result; - } - - /* In both CMMethod and CMBlock cases find the start of the map and - skip forward to the bytecode pc map entry for the stack check. */ - bcpc = startbcpc; - if (((cogMethod->cmType)) == CMMethod) { - /* begin cmIsFullBlock */ - isInBlock = 0; - homeMethod = ((CogMethod *) cogMethod); - assert(startbcpc == (startPCOfMethodHeader((homeMethod->methodHeader)))); - map = ((((usqInt)homeMethod)) + ((homeMethod->blockSize))) - 1; - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert((annotation == IsAbsPCReference) - || ((annotation == IsObjectReference) - || ((annotation == IsRelativeCall) - || (annotation == IsDisplacementX2N)))); - latestContinuation = startbcpc; - aMethodObj = (homeMethod->methodObject); - endbcpc = (numBytesOf(aMethodObj)) - 1; - /* begin bytecodeSetOffsetForHeader: */ - (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader) - ? 0x100 - : 0) -# else - 0 -# endif - ; - bcpc += deltaToSkipPrimAndErrorStoreInheader(aMethodObj, (homeMethod->methodHeader)); - } - else { - isInBlock = 1; - assert(bcpc == ((cogMethod->startpc))); - homeMethod = cmHomeMethod(cogMethod); - map = findMapLocationForMcpcinMethod((((usqInt)cogMethod)) + (sizeof(CogBlockMethod)), homeMethod); - assert(map != 0); - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert(((((usqInt)(annotation)) >> AnnotationShift) == HasBytecodePC) - || ((((usqInt)(annotation)) >> AnnotationShift) == IsDisplacementX2N)); - while (((annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift)) != HasBytecodePC) { - map -= 1; - } - - /* skip fiducial; i.e. the map entry for the pc immediately following the method header. */ - map -= 1; - aMethodObj = (homeMethod->methodObject); - bcpc = startbcpc - ( -#if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet((homeMethod->methodHeader)) - ? AltBlockCreationBytecodeSize - : BlockCreationBytecodeSize) -#else // MULTIPLEBYTECODESETS - BlockCreationBytecodeSize -#endif - ); - /* begin bytecodeSetOffsetForHeader: */ - (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader1) - ? 0x100 - : 0) -# else - 0 -# endif - ; - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - endbcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, -1, aMethodObj)) - : 0)); - bcpc = startbcpc; - } - nExts = 0; - while ((((usqInt)((byteAt(map)))) >> AnnotationShift) != HasBytecodePC) { - map -= 1; - } - map -= 1; - while (((mapByte = byteAt(map))) != MapEnd) { - - /* defensive; we exit on bcpc */ - if (mapByte >= FirstAnnotation) { - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - mcpc1 += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if (annotation >= HasBytecodePC) { - if ((annotation == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - while (1) { - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - if (isInBlock) { - if (bcpc >= endbcpc) { - return 0; - } - } - else { - if (((descriptor->isReturn)) - && (bcpc >= latestContinuation)) { - return 0; - } - if ((isBranch(descriptor)) - || ((descriptor->isBlockCreation))) { - /* begin latestContinuationPCFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj); - targetPC = (bcpc + ((descriptor->numBytes))) + (((distance < 0) ? 0 : distance)); - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - /* latestContinuation = */ latestContinuation; - } - nextBcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) - : 0)); - if (((descriptor->isMapped)) - || (isInBlock - && ((descriptor->isMappedInBlock)))) break; - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - isBackwardBranch = (isBranch(descriptor)) - && ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) < 0)); - result = findIsBackwardBranchMcpcBcpcMatchingMcpc(descriptor, ((isBackwardBranch - ? (((sqInt)((usqInt)(annotation) << 1))) + 1 - : ((sqInt)((usqInt)(annotation) << 1)))), (((char *) mcpc1)), ((isBackwardBranch - ? bcpc - (2 * nExts) - : bcpc)), (((void *)mcpc))); - if (result != 0) { - return result; - } - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - } - else { - assert(((((usqInt)(mapByte)) >> AnnotationShift) == IsDisplacementX2N) - || ((((usqInt)(mapByte)) >> AnnotationShift) == IsAnnotationExtension)); - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc1 += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - return 0; -} - - -/* Big assumption here that calls and jumps look the same as regards their - displacement. This works on at least x86, ARM and x86_64. */ - - /* Cogit>>#CallRT: */ -static AbstractInstruction * NoDbgRegParms -CallRT(sqInt callTarget) -{ - AbstractInstruction *abstractInstruction; - - /* begin annotateCall: */ - abstractInstruction = genoperand(Call, callTarget); - (abstractInstruction->annotation = IsRelativeCall); - return abstractInstruction; -} - - /* Cogit>>#Call: */ -static AbstractInstruction * NoDbgRegParms -gCall(sqInt callTarget) -{ - return genoperand(Call, callTarget); -} - - -/* This is a static version of ceCallCogCodePopReceiverReg - for break-pointing when debugging in C. */ -/* This exists only for break-pointing. */ - - /* Cogit>>#callCogCodePopReceiver */ -void -callCogCodePopReceiver(void) -{ - realCECallCogCodePopReceiverReg(); - error("what??"); -} - - -/* This is a static version of ceCallCogCodePopReceiverAndClassRegs - for break-pointing when debugging in C. */ -/* This exists only for break-pointing. */ - - /* Cogit>>#callCogCodePopReceiverAndClassRegs */ -void -callCogCodePopReceiverAndClassRegs(void) -{ - realCECallCogCodePopReceiverAndClassRegs(); -} - - -/* Code entry closed PIC miss. A send has fallen - through a closed (finite) polymorphic inline cache. - Either extend it or patch the send site to an open PIC. - The stack looks like: - receiver - args - sp=> sender return address */ - - /* Cogit>>#ceCPICMiss:receiver: */ -static sqInt NoDbgRegParms -ceCPICMissreceiver(CogMethod *cPIC, sqInt receiver) -{ - sqInt cacheTag; - sqInt errorSelectorOrNil; - sqInt methodOrSelectorIndex; - sqInt newTargetMethodOrNil; - sqInt outerReturn; - sqInt result; - sqInt selector; - - outerReturn = stackTop(); - assert(!(((inlineCacheTagAt(backEnd, outerReturn)) == (picAbortDiscriminatorValue())))); - if (((cPIC->cPICNumCases)) < MaxCPICCases) { - /* begin lookup:for:methodAndErrorSelectorInto: */ - selector = (cPIC->selector); - methodOrSelectorIndex = lookupOrdinaryreceiver(selector, receiver); - if ((((usqInt)methodOrSelectorIndex)) > (maxLookupNoMNUErrorCode())) { - if (!(isOopCompiledMethod(methodOrSelectorIndex))) { - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = SelectorCannotInterpret; - goto l1; - } - if ((!(methodHasCogMethod(methodOrSelectorIndex))) - && (methodShouldBeCogged(methodOrSelectorIndex))) { - - /* We assume cog:selector: will *not* reclaim the method zone */ - cogselector(methodOrSelectorIndex, selector); - } - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = null; - goto l1; - } - if (methodOrSelectorIndex == SelectorDoesNotUnderstand) { - methodOrSelectorIndex = lookupMNUreceiver(splObj(SelectorDoesNotUnderstand), receiver); - if ((((usqInt)methodOrSelectorIndex)) > (maxLookupNoMNUErrorCode())) { - assert(isOopCompiledMethod(methodOrSelectorIndex)); - if ((!(methodHasCogMethod(methodOrSelectorIndex))) - && (methodShouldBeCogged(methodOrSelectorIndex))) { - - /* We assume cog:selector: will *not* reclaim the method zone */ - cogselector(methodOrSelectorIndex, splObj(SelectorDoesNotUnderstand)); - } - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = SelectorDoesNotUnderstand; - goto l1; - } - newTargetMethodOrNil = null; - errorSelectorOrNil = SelectorDoesNotUnderstand; - goto l1; - } - newTargetMethodOrNil = null; - errorSelectorOrNil = methodOrSelectorIndex; - l1: /* end lookup:for:methodAndErrorSelectorInto: */; - } - else { - newTargetMethodOrNil = (errorSelectorOrNil = null); - } - assert(outerReturn == (stackTop())); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - cacheTag = inlineCacheTagForInstance(receiver); - if ((((cPIC->cPICNumCases)) >= MaxCPICCases) - || (((errorSelectorOrNil != null) - && (errorSelectorOrNil != SelectorDoesNotUnderstand)) - || ((inlineCacheTagIsYoung(cacheTag)) - || ((newTargetMethodOrNil == null) - || (isYoung(newTargetMethodOrNil)))))) { - result = patchToOpenPICFornumArgsreceiver((cPIC->selector), (cPIC->cmNumArgs), receiver); - assert(!result); - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - return ceSendFromInLineCacheMiss(cPIC); - } - cogExtendPICCaseNMethodtagisMNUCase(cPIC, newTargetMethodOrNil, cacheTag, errorSelectorOrNil == SelectorDoesNotUnderstand); - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - executeCogPICfromLinkedSendWithReceiverandCacheTag(cPIC, receiver, inlineCacheTagAt(backEnd, outerReturn)); - return null; -} - - /* Cogit>>#ceFree: */ -void -ceFree(void *pointer) -{ - free(pointer); -} - - /* Cogit>>#ceMalloc: */ -static void* NoDbgRegParms -ceMalloc(size_t size) -{ - return malloc(size); -} - - -/* An in-line cache check in a method has failed. The failing entry check has - jumped to the ceMethodAbort abort call at the start of the method which - has called this routine. - If possible allocate a closed PIC for the current and existing classes. - The stack looks like: - receiver - args - sender return address - sp=> ceMethodAbort call return address - So we can find the method that did the failing entry check at - ceMethodAbort call return address - missOffset - and we can find the send site from the outer return address. */ - - /* Cogit>>#ceSICMiss: */ -static sqInt NoDbgRegParms -ceSICMiss(sqInt receiver) -{ - sqInt cacheTag; - usqInt entryPoint; - sqInt errorSelectorOrNil; - sqInt extent; - usqInt innerReturn; - sqInt methodOrSelectorIndex; - sqInt newTargetMethodOrNil; - usqInt outerReturn; - CogMethod *pic; - sqInt result; - sqInt selector; - CogMethod *targetMethod; - - - /* Whether we can relink to a PIC or not we need to pop off the inner return and identify the target method. */ - innerReturn = ((usqInt)(popStack())); - targetMethod = ((CogMethod *) (innerReturn - missOffset)); - outerReturn = ((usqInt)(stackTop())); - assert(((outerReturn >= methodZoneBase) && (outerReturn <= (freeStart())))); - entryPoint = callTargetFromReturnAddress(backEnd, outerReturn); - assert(((targetMethod->selector)) != (nilObject())); - assert(((((sqInt)targetMethod)) + cmEntryOffset) == entryPoint); - /* begin lookup:for:methodAndErrorSelectorInto: */ - selector = (targetMethod->selector); - methodOrSelectorIndex = lookupOrdinaryreceiver(selector, receiver); - if ((((usqInt)methodOrSelectorIndex)) > (maxLookupNoMNUErrorCode())) { - if (!(isOopCompiledMethod(methodOrSelectorIndex))) { - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = SelectorCannotInterpret; - goto l1; - } - if ((!(methodHasCogMethod(methodOrSelectorIndex))) - && (methodShouldBeCogged(methodOrSelectorIndex))) { - - /* We assume cog:selector: will *not* reclaim the method zone */ - cogselector(methodOrSelectorIndex, selector); - } - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = null; - goto l1; - } - if (methodOrSelectorIndex == SelectorDoesNotUnderstand) { - methodOrSelectorIndex = lookupMNUreceiver(splObj(SelectorDoesNotUnderstand), receiver); - if ((((usqInt)methodOrSelectorIndex)) > (maxLookupNoMNUErrorCode())) { - assert(isOopCompiledMethod(methodOrSelectorIndex)); - if ((!(methodHasCogMethod(methodOrSelectorIndex))) - && (methodShouldBeCogged(methodOrSelectorIndex))) { - - /* We assume cog:selector: will *not* reclaim the method zone */ - cogselector(methodOrSelectorIndex, splObj(SelectorDoesNotUnderstand)); - } - newTargetMethodOrNil = methodOrSelectorIndex; - errorSelectorOrNil = SelectorDoesNotUnderstand; - goto l1; - } - newTargetMethodOrNil = null; - errorSelectorOrNil = SelectorDoesNotUnderstand; - goto l1; - } - newTargetMethodOrNil = null; - errorSelectorOrNil = methodOrSelectorIndex; - l1: /* end lookup:for:methodAndErrorSelectorInto: */; - assert(outerReturn == (stackTop())); - cacheTag = inlineCacheTagForInstance(receiver); - if (((errorSelectorOrNil != null) - && (errorSelectorOrNil != SelectorDoesNotUnderstand)) - || ((inlineCacheTagIsYoung(cacheTag)) - || (((inlineCacheTagAt(backEnd, outerReturn)) == 0 /* picAbortDiscriminatorValue */) - || ((newTargetMethodOrNil == null) - || (isYoung(newTargetMethodOrNil)))))) { - result = patchToOpenPICFornumArgsreceiver((targetMethod->selector), (targetMethod->cmNumArgs), receiver); - assert(!result); - return ceSendFromInLineCacheMiss(targetMethod); - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - pic = openPICWithSelector((targetMethod->selector)); - if ((pic == null) - || (!1)) { - - /* otherwise attempt to create a closed PIC for the two cases. */ - pic = cogPICSelectornumArgsCase0MethodCase1MethodtagisMNUCase((targetMethod->selector), (targetMethod->cmNumArgs), targetMethod, newTargetMethodOrNil, cacheTag, errorSelectorOrNil == SelectorDoesNotUnderstand); - if ((((((sqInt)pic)) >= MaxNegativeErrorCode) && ((((sqInt)pic)) <= -1))) { - - /* For some reason the PIC couldn't be generated, most likely a lack of code memory. - Continue as if this is an unlinked send. */ - if ((((sqInt)pic)) == InsufficientCodeSpace) { - callForCogCompiledCodeCompaction(); - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - return ceSendFromInLineCacheMiss(targetMethod); - } - } - extent = (((pic->cmType)) == CMOpenPIC - ? rewriteInlineCacheAttagtarget(backEnd, outerReturn, inlineCacheValueForSelectorin(backEnd, (targetMethod->selector), mframeHomeMethodExport()), (((sqInt)pic)) + cmEntryOffset) - : rewriteCallAttarget(backEnd, outerReturn, (((sqInt)pic)) + cmEntryOffset)); - /* begin assertValidDualZoneFrom:to: */ - (((usqInt)pic)) + closedPICSize; -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, (((usqInt)pic)) + cmNoCheckEntryOffset, codeToDataDelta); -# endif - flushICacheFromto(backEnd, ((usqInt)pic), (((usqInt)pic)) + closedPICSize); - flushICacheFromto(backEnd, (((usqInt)outerReturn)) - extent, ((usqInt)outerReturn)); - executeCogPICfromLinkedSendWithReceiverandCacheTag(pic, receiver, inlineCacheTagAt(backEnd, outerReturn)); - return null; -} - - -/* Check for a valid object reference, if any, at a map entry. Answer a code - unique to each error for debugging. */ - - /* Cogit>>#checkIfValidOopRefAndTarget:pc:cogMethod: */ -static sqInt NoDbgRegParms -checkIfValidOopRefAndTargetpccogMethod(sqInt annotation, char *mcpc, CogMethod *cogMethod) -{ - usqInt cacheTag1; - sqInt entryPoint; - usqInt entryPoint1; - usqInt literal; - sqInt offset1; - sqInt *sendTable1; - sqInt tagCouldBeObj; - CogMethod *targetMethod1; - - if (annotation == IsObjectReference) { - literal = literalBeforeFollowingAddress(backEnd, ((usqInt)mcpc)); - if (!(asserta(checkValidOopReference(literal)))) { - return 1; - } - if ((couldBeObject(literal)) - && (isReallyYoungObject(literal))) { - if (!(asserta(((((CogMethod *) cogMethod))->cmRefersToYoung)))) { - return 2; - } - } - } - if (annotation >= IsSendCall) { - if (!(asserta((((((CogMethod *) cogMethod))->cmType)) == CMMethod))) { - return 3; - } - /* begin entryCacheTagAndCouldBeObjectAt:annotation:into: */ - cacheTag1 = inlineCacheTagAt(backEnd, ((sqInt)mcpc)); - - /* in-line cache tags are the selectors of sends if sends are unlinked, - the selectors of super sends (entry offset = cmNoCheckEntryOffset), - the selectors of open PIC sends (entry offset = cmEntryOffset, target is an Open PIC) - or in-line cache tags (classes, class indices, immediate bit patterns, etc). - Note that selectors can be immediate so there is no guarantee that they - are markable/remappable objects. */ - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - tagCouldBeObj = 1; - entryPoint = entryPoint1; - if (tagCouldBeObj) { - if (couldBeObject(cacheTag1)) { - if (!(asserta(checkValidOopReference(cacheTag1)))) { - return 4; - } - } - else { - if (!(asserta(validInlineCacheTag(cacheTag1)))) { - return 5; - } - } - if ((couldBeObject(cacheTag1)) - && (isReallyYoungObject(cacheTag1))) { - if (!(asserta(((((CogMethod *) cogMethod))->cmRefersToYoung)))) { - return 6; - } - } - } - else { - if (!(asserta(validInlineCacheTag(cacheTag1)))) { - return 9; - } - } - if (entryPoint > methodZoneBase) { - - /* It's a linked send; find which kind. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (!(asserta((((targetMethod1->cmType)) == CMMethod) - || ((((targetMethod1->cmType)) == CMClosedPIC) - || (((targetMethod1->cmType)) == CMOpenPIC))))) { - return 10; - } - } - } - return 0; -} - - -/* Check for a valid object reference, if any, at a map entry. Answer a code - unique to each error for debugging. */ - - /* Cogit>>#checkIfValidOopRef:pc:cogMethod: */ -static sqInt NoDbgRegParms -checkIfValidOopRefpccogMethod(sqInt annotation, char *mcpc, CogMethod *cogMethod) -{ - usqInt entryPoint; - usqInt literal; - usqInt offset; - sqInt offset1; - usqInt selectorOrCacheTag; - sqInt *sendTable; - - if (annotation == IsObjectReference) { - literal = literalBeforeFollowingAddress(backEnd, ((usqInt)mcpc)); - if (!(checkValidOopReference(literal))) { - print("object ref leak in CM "); - printHex(((sqInt)cogMethod)); - print(" @ "); - printHex(((sqInt)mcpc)); - cr(); - return 1; - } - } - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint <= methodZoneBase) { - offset = entryPoint; - } - else { - /* begin offsetAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable = ordinarySendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable = superSendTrampolines; - } - offset = offset1; - } - selectorOrCacheTag = inlineCacheTagAt(backEnd, ((sqInt)mcpc)); - if ((entryPoint > methodZoneBase) - && ((offset != cmNoCheckEntryOffset) - && ((((((CogMethod *) (entryPoint - offset)))->cmType)) != CMOpenPIC))) { - - /* linked non-super send, cacheTag is a cacheTag */ - if (!(validInlineCacheTag(selectorOrCacheTag))) { - print("cache tag leak in CM "); - printHex(((sqInt)cogMethod)); - print(" @ "); - printHex(((sqInt)mcpc)); - cr(); - return 1; - } - } - else { - - /* unlinked send or super send; cacheTag is a selector unless 64-bit, in which case it is an index. */ - if (!(checkValidOopReference(selectorOrCacheTag))) { - print("selector leak in CM "); - printHex(((sqInt)cogMethod)); - print(" @ "); - printHex(((sqInt)mcpc)); - cr(); - return 1; - } - } - } - return 0; -} - - -/* Answer if all references to objects in machine-code are valid. */ - - /* Cogit>>#checkIntegrityOfObjectReferencesInCode: */ -sqInt -checkIntegrityOfObjectReferencesInCode(sqInt gcModes) -{ - CogMethod *cogMethod; - sqInt count; - sqInt ok; - - cogMethod = ((CogMethod *) methodZoneBase); - ok = 1; - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - if ((cogMethod->cmRefersToYoung)) { - if (((count = occurrencesInYoungReferrers(cogMethod))) != 1) { - print("young referrer CM "); - printHex(((sqInt)cogMethod)); - if (count == 0) { - print(" is not in youngReferrers"); - cr(); - } - else { - print(" is in youngReferrers "); - printNum(count); - print(" times!"); - cr(); - } - ok = 0; - } - } - if (!(checkValidOopReference((cogMethod->selector)))) { - print("object leak in CM "); - printHex(((sqInt)cogMethod)); - print(" selector"); - cr(); - ok = 0; - } - if (((cogMethod->cmType)) == CMMethod) { - assert(((cogMethod->objectHeader)) == (nullHeaderForMachineCodeMethod())); - if (!(checkValidObjectReference((cogMethod->methodObject)))) { - print("object leak in CM "); - printHex(((sqInt)cogMethod)); - print(" methodObject"); - cr(); - ok = 0; - } - if (!(isOopCompiledMethod((cogMethod->methodObject)))) { - print("non-method in CM "); - printHex(((sqInt)cogMethod)); - print(" methodObject"); - cr(); - ok = 0; - } - if ((mapForperformUntilarg(cogMethod, checkIfValidOopRefpccogMethod, cogMethod)) != 0) { - ok = 0; - } - if (((gcModes & GCModeNewSpace) != 0)) { - if (((isYoungObject((cogMethod->methodObject))) - || (isYoung((cogMethod->selector)))) - && (!((cogMethod->cmRefersToYoung)))) { - print("CM "); - printHex(((sqInt)cogMethod)); - print(" refers to young but not marked as such"); - cr(); - ok = 0; - } - } - } - else { - if (((cogMethod->cmType)) == CMClosedPIC) { - if (!(checkValidObjectReferencesInClosedPIC(cogMethod))) { - ok = 0; - } - } - else { - if (((cogMethod->cmType)) == CMOpenPIC) { - if ((mapForperformUntilarg(cogMethod, checkIfValidOopRefpccogMethod, cogMethod)) != 0) { - ok = 0; - } - } - } - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return ok; -} - - /* Cogit>>#checkMaybeObjRefInClosedPIC: */ -static sqInt NoDbgRegParms -checkMaybeObjRefInClosedPIC(sqInt maybeObject) -{ - if (maybeObject == 0) { - return 1; - } - if (!(couldBeObject(maybeObject))) { - return 1; - } - return checkValidObjectReference(maybeObject); -} - - /* Cogit>>#checkValidObjectReferencesInClosedPIC: */ -static sqInt NoDbgRegParms -checkValidObjectReferencesInClosedPIC(CogMethod *cPIC) -{ - sqInt i; - sqInt ok; - sqInt pc; - - ok = 1; - - /* first we check the obj ref at the beginning of the CPIC */ - pc = (((sqInt)cPIC)) + firstCPICCaseOffset; - if (!(checkMaybeObjRefInClosedPIC(literalBeforeFollowingAddress(backEnd, pc - (jumpLongByteSize(backEnd)))))) { - print("object leak in CPIC "); - printHex(((sqInt)cPIC)); - print(" @ "); - printHex(pc - (jumpLongByteSize(backEnd))); - cr(); - ok = 0; - } - - /* For each case we check any object reference at the end address - sizeof(conditional instruction) and then increment the end address by case size */ - pc = addressOfEndOfCaseinCPIC((cPIC->cPICNumCases), cPIC); - for (i = 2; i <= ((cPIC->cPICNumCases)); i += 1) { - if (!(checkMaybeObjRefInClosedPIC(literalBeforeFollowingAddress(backEnd, pc - 16 /* jumpLongConditionalByteSize */)))) { - print("object leak in CPIC "); - printHex(((sqInt)cPIC)); - print(" @ "); - printHex((pc - 16 /* jumpLongConditionalByteSize */) - 8 /* loadLiteralByteSize */); - cr(); - ok = 0; - } - if (!(checkMaybeObjRefInClosedPIC(literalBeforeFollowingAddress(backEnd, (pc - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */)))) { - print("object leak in CPIC "); - printHex(((sqInt)cPIC)); - print(" @ "); - printHex(pc - 16 /* jumpLongConditionalByteSize */); - cr(); - ok = 0; - } - pc += cPICCaseSize; - } - return ok; -} - - -/* i.e. this should never be called, so keep it out of the main path. */ - - /* Cogit>>#cleanUpFailingCogCodeConstituents: */ -static sqInt NoDbgRegParms NeverInline -cleanUpFailingCogCodeConstituents(CogMethod *cogMethodArg) -{ - CogMethod *cogMethod; - - cogMethod = cogMethodArg; - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMClosedPIC) { - (cogMethod->methodObject = 0); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - popRemappableOop(); - return null; -} - - -/* Answer if the ClosedPIC refers to any unmarked objects or freed/freeable - target methods, - applying markAndTraceOrFreeCogMethod:firstVisit: to those targets to - determine if freed/freeable. - */ - - /* Cogit>>#closedPICRefersToUnmarkedObject: */ -static sqInt NoDbgRegParms -closedPICRefersToUnmarkedObject(CogMethod *cPIC) -{ - sqInt i; - usqInt object; - sqInt pc; - - if (!((isImmediate((cPIC->selector))) - || (isMarked((cPIC->selector))))) { - return 1; - } - pc = addressOfEndOfCaseinCPIC(1, cPIC); - if (couldBeObject((object = literalBeforeFollowingAddress(backEnd, pc - (jumpLongByteSize(backEnd)))))) { - if (!(isMarked(object))) { - return 1; - } - } - if (markAndTraceOrFreePICTargetin(jumpLongTargetBeforeFollowingAddress(backEnd, pc), cPIC)) { - return 1; - } - for (i = 2; i <= ((cPIC->cPICNumCases)); i += 1) { - pc = addressOfEndOfCaseinCPIC(i, cPIC); - if (couldBeObject((object = literalBeforeFollowingAddress(backEnd, pc - 16 /* jumpLongConditionalByteSize */)))) { - if (!(isMarked(object))) { - return 1; - } - } - if (couldBeObject((object = literalBeforeFollowingAddress(backEnd, (pc - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */)))) { - if (!(isMarked(object))) { - return 1; - } - } - if (markAndTraceOrFreePICTargetin(jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc), cPIC)) { - return 1; - } - } - return 0; -} - - /* Cogit>>#codeEntryFor: */ -char * -codeEntryFor(char *address) -{ - sqInt i; - - for (i = 0; i <= (trampolineTableIndex - 3); i += 2) { - if (((address >= (trampolineAddresses[i + 1])) && (address <= ((trampolineAddresses[i + 3]) - 1)))) { - return trampolineAddresses[i + 1]; - } - } - return null; -} - - /* Cogit>>#codeEntryNameFor: */ -char * -codeEntryNameFor(char *address) -{ - sqInt i; - - for (i = 0; i <= (trampolineTableIndex - 3); i += 2) { - if (((address >= (trampolineAddresses[i + 1])) && (address <= ((trampolineAddresses[i + 3]) - 1)))) { - return trampolineAddresses[i]; - } - } - return null; -} - - /* Cogit>>#cogCodeBase */ -sqInt -cogCodeBase(void) -{ - return codeBase; -} - - -/* Answer the contents of the code zone as an array of pair-wise element, - address in ascending address order. - Answer a string for a runtime routine or abstract label (beginning, end, - etc), a CompiledMethod for a CMMethod, - or a selector (presumably a Symbol) for a PIC. - If withDetails is true - - answer machine-code to bytecode pc mapping information for methods - - answer class, target pair information for closed PIC - N.B. Since the class tag for the first case of a closed PIC is stored at - the send site, it must be collected - by scanning methods (see - collectCogConstituentFor:Annotation:Mcpc:Bcpc:Method:). Since closed PICs - are never shared they always come after the method that references them, - so we don't need an extra pass - to collect the first case class tags, which are (temporarily) assigned to - each closed PIC's methodObject field. - But we do need to reset the methodObject fields to zero. This is done in - createPICData:, unless memory - runs out, in which case it is done by cleanUpFailingCogCodeConstituents:. */ - - /* Cogit>>#cogCodeConstituents: */ -sqInt -cogCodeConstituents(sqInt withDetails) -{ - CogMethod *cogMethod; - sqInt constituents; - sqInt count; - sqInt i; - sqInt label; - sqInt profileData; - sqInt value; - - - /* + 3 for start, freeStart and end */ - count = (trampolineTableIndex / 2) + 3; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - count += 1; - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - constituents = instantiateClassindexableSize(classArray(), count * 2); - if (!constituents) { - return constituents; - } - pushRemappableOop(constituents); - if ((((label = stringForCString("CogCode"))) == null) - || (((value = positive32BitIntegerFor(codeBase))) == null)) { - popRemappableOop(); - return null; - } - storePointerUncheckedofObjectwithValue(0, topRemappableOop(), label); - storePointerUncheckedofObjectwithValue(1, topRemappableOop(), value); - for (i = 0; i < trampolineTableIndex; i += 2) { - if ((((label = stringForCString(trampolineAddresses[i]))) == null) - || (((value = positive32BitIntegerFor(((usqInt)(trampolineAddresses[i + 1]))))) == null)) { - popRemappableOop(); - return null; - } - storePointerUncheckedofObjectwithValue(2 + i, topRemappableOop(), label); - storePointerUncheckedofObjectwithValue(3 + i, topRemappableOop(), value); - } - count = trampolineTableIndex + 2; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - profileData = (((cogMethod->cmType)) == CMMethod - ? (cogMethod->methodObject) - : (withDetails - && (((cogMethod->cmType)) == CMClosedPIC) - ? createCPICData(cogMethod) - : (cogMethod->selector))); - if (!profileData) { - return cleanUpFailingCogCodeConstituents(cogMethod); - } - storePointerUncheckedofObjectwithValue(count, topRemappableOop(), profileData); - if (withDetails) { - value = collectCogMethodConstituent(cogMethod); - } - else { - value = positive32BitIntegerFor(((usqInt)cogMethod)); - } - if (!value) { - return cleanUpFailingCogCodeConstituents(cogMethod); - } - storePointerUncheckedofObjectwithValue(count + 1, topRemappableOop(), value); - count += 2; - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if ((((label = stringForCString("CCFree"))) == null) - || (((value = positive32BitIntegerFor(mzFreeStart))) == null)) { - popRemappableOop(); - return null; - } - storePointerUncheckedofObjectwithValue(count, topRemappableOop(), label); - storePointerUncheckedofObjectwithValue(count + 1, topRemappableOop(), value); - if ((((label = stringForCString("CCEnd"))) == null) - || (((value = positive32BitIntegerFor(limitAddress))) == null)) { - popRemappableOop(); - return null; - } - storePointerUncheckedofObjectwithValue(count + 2, topRemappableOop(), label); - storePointerUncheckedofObjectwithValue(count + 3, topRemappableOop(), value); - constituents = popRemappableOop(); - beRootIfOld(constituents); - return constituents; -} - - -/* Extend the cPIC with the supplied case. If caseNMethod is cogged dispatch - direct to - its unchecked entry-point. If caseNMethod is not cogged, jump to the fast - interpreter dispatch, and if isMNUCase then dispatch to fast MNU - invocation and mark the cPIC as - having the MNU case for cache flushing. */ - - /* Cogit>>#cogExtendPIC:CaseNMethod:tag:isMNUCase: */ -static void NoDbgRegParms -cogExtendPICCaseNMethodtagisMNUCase(CogMethod *cPIC, sqInt caseNMethod, sqInt caseNTag, sqInt isMNUCase) -{ - sqInt address; - sqInt operand; - CogBlockMethod * self_in_cpicHasMNUCase; - sqInt target; - - compilationBreakpointclassTagisMNUCase((cPIC->selector), caseNTag, isMNUCase); - assert(!(inlineCacheTagIsYoung(caseNTag))); - assert((caseNMethod != null) - && (!(isYoung(caseNMethod)))); - if ((!isMNUCase) - && (methodHasCogMethod(caseNMethod))) { - - /* this isn't an MNU and we have an already cogged method to jump to */ - operand = 0; - target = (((sqInt)(cogMethodOf(caseNMethod)))) + cmNoCheckEntryOffset; - } - else { - operand = caseNMethod; - if (isMNUCase) { - - /* this is an MNU so tag the CPIC header and setup a jump to the MNUAbort */ - /* begin cpicHasMNUCase: */ - self_in_cpicHasMNUCase = ((CogBlockMethod *) (((CogMethod *) ((((usqInt)cPIC)) + codeToDataDelta)))); - (self_in_cpicHasMNUCase->cpicHasMNUCaseOrCMIsFullBlock) = 1; - target = (((sqInt)cPIC)) + (sizeof(CogMethod)); - } - else { - - /* setup a jump to the interpretAborth so we can cog the target method */ - target = (((sqInt)cPIC)) + (picInterpretAbortOffset()); - } - } - address = addressOfEndOfCaseinCPIC(((cPIC->cPICNumCases)) + 1, cPIC); - rewriteCPICCaseAttagobjReftarget(address, caseNTag, operand, target); - /* begin rewriteCPIC:caseJumpTo: */ - rewriteCPICJumpAttarget(backEnd, (((((sqInt)cPIC)) + firstCPICCaseOffset) - (jumpLongByteSize(backEnd))) - 8 /* loadLiteralByteSize */, address - cPICCaseSize); - ((((CogMethod *) ((((usqInt)cPIC)) + codeToDataDelta)))->cPICNumCases = ((cPIC->cPICNumCases)) + 1); - flushICacheFromto(backEnd, ((usqInt)cPIC), (((usqInt)cPIC)) + closedPICSize); - /* begin assertValidDualZoneFrom:to: */ - (((usqInt)cPIC)) + closedPICSize; -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, (((usqInt)cPIC)) + cmNoCheckEntryOffset, codeToDataDelta); -# endif -} - - /* Cogit>>#cogitPostGCAction: */ -void -cogitPostGCAction(sqInt gcMode) -{ - if ((gcMode == GCModeFull) - && (1)) { - voidYoungReferrersPostTenureAll(); - } -# if SPURVM - if (gcMode == GCModeBecome) { - followForwardedLiteralsInOpenPICList(); - } -# endif - assert(allMethodsHaveCorrectHeader()); - assert(((!(gcMode & (GCModeFull + GCModeNewSpace)))) - || (kosherYoungReferrers())); - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - -/* Check that the header fields onf a non-free method are consistent with - the type. Answer 0 if it is ok, otherwise answer a code for the error. */ - - /* Cogit>>#cogMethodDoesntLookKosher: */ -sqInt -cogMethodDoesntLookKosher(CogMethod *cogMethod) -{ - if (((((cogMethod->blockSize)) & (BytesPerWord - 1)) != 0) - || ((((cogMethod->blockSize)) < (sizeof(CogMethod))) - || (((cogMethod->blockSize)) >= 0x8000))) { - return 1; - } - if (((cogMethod->cmType)) == CMFree) { - return 2; - } - if (((cogMethod->cmType)) == CMMethod) { - if (!((((cogMethod->methodHeader)) & 1))) { - return 11; - } - if (!(couldBeObject((cogMethod->methodObject)))) { - return 12; - } - if ((((cogMethod->stackCheckOffset)) > 0) - && (((cogMethod->stackCheckOffset)) < cmNoCheckEntryOffset)) { - return 13; - } - return 0; - } - if (((cogMethod->cmType)) == CMOpenPIC) { - if (((cogMethod->blockSize)) != openPICSize) { - return 21; - } - if (((cogMethod->methodHeader)) != 0) { - return 22; - } - if (((cogMethod->objectHeader)) >= 0) { - if (!((((cogMethod->methodObject)) == 0) - || (compactionInProgress - || (((cogMethod->methodObject)) == (((usqInt)(methodFor(((void *)((cogMethod->methodObject))))))))))) { - return 23; - } - } - if (((cogMethod->stackCheckOffset)) != 0) { - return 24; - } - return 0; - } - if (((cogMethod->cmType)) == CMClosedPIC) { - if (((cogMethod->blockSize)) != closedPICSize) { - return 0x1F; - } - if (!(((((cogMethod->cPICNumCases)) >= 1) && (((cogMethod->cPICNumCases)) <= MaxCPICCases)))) { - return 32; - } - if (((cogMethod->methodHeader)) != 0) { - return 33; - } - if (((cogMethod->methodObject)) != 0) { - return 34; - } - return 0; - } - return 9; -} - - -/* Attempt to create a one-case PIC for an MNU. - The tag for the case is at the send site and so doesn't need to be - generated. - */ - - /* Cogit>>#cogMNUPICSelector:receiver:methodOperand:numArgs: */ -CogMethod * -cogMNUPICSelectorreceivermethodOperandnumArgs(sqInt selector, sqInt rcvr, sqInt methodOperand, sqInt numArgs) -{ - CogMethod * actualPIC; - usqInt startAddress; - CogMethod * writablePIC; - - if ((isYoung(selector)) - || ((inlineCacheTagForInstance(rcvr)) == 0 /* picAbortDiscriminatorValue */)) { - return 0; - } - compilationBreakpointclassTagisMNUCase(selector, fetchClassTagOf(rcvr), 1); - assert(endCPICCase0 != null); - startAddress = allocate(closedPICSize); - if (startAddress == 0) { - callForCogCompiledCodeCompaction(); - return 0; - } - maybeBreakGeneratingFromto(startAddress, startAddress + closedPICSize); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - - /* memcpy the prototype across to our allocated space; because anything else would be silly */ - writablePIC = ((CogMethod *) ((((usqInt)startAddress)) + codeToDataDelta)); - codeMemcpy(writablePIC, cPICPrototype, closedPICSize); - /* begin fillInCPICHeader:numArgs:numCases:hasMNUCase:selector: */ - assert(!(isYoung(selector))); - (writablePIC->cmType = CMClosedPIC); - (writablePIC->objectHeader = 0); - (writablePIC->blockSize = closedPICSize); - (writablePIC->methodObject = 0); - (writablePIC->methodHeader = 0); - (writablePIC->selector = selector); - (writablePIC->cmNumArgs = numArgs); - (writablePIC->cmHasMovableLiteral = 0); - (writablePIC->cmRefersToYoung = 0); - (writablePIC->cmUsageCount = initialClosedPICUsageCount()); - /* begin cpicHasMNUCase: */ - ((((CogBlockMethod *) writablePIC))->cpicHasMNUCaseOrCMIsFullBlock) = 1; - (writablePIC->cPICNumCases = 1); - (writablePIC->blockEntryOffset = 0); - assert(((writablePIC->cmType)) == CMClosedPIC); - assert(((writablePIC->selector)) == selector); - assert(((writablePIC->cmNumArgs)) == numArgs); - assert(((writablePIC->cPICNumCases)) == 1); - assert(closedPICSize == (roundUpLength(closedPICSize))); - /* begin maybeEnableSingleStep */ - configureMNUCPICmethodOperandnumArgsdelta((actualPIC = ((CogMethod *) startAddress)), methodOperand, numArgs, startAddress - (((usqInt)cPICPrototype))); - flushICacheFromto(backEnd, startAddress, startAddress + closedPICSize); - assert((callTargetFromReturnAddress(backEnd, startAddress + missOffset)) == (picAbortTrampolineFor(numArgs))); - /* begin assertValidDualZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, startAddress + cmNoCheckEntryOffset, codeToDataDelta); -# endif - return actualPIC; -} - - -/* Create an Open PIC. Temporarily create a direct call of - ceSendFromOpenPIC:. Should become a probe of the first-level method lookup - cache followed by a - call of ceSendFromOpenPIC: if the probe fails. */ - - /* Cogit>>#cogOpenPICSelector:numArgs: */ -static CogMethod * NoDbgRegParms -cogOpenPICSelectornumArgs(sqInt selector, sqInt numArgs) -{ - sqInt codeSize; - sqInt end; - sqInt fixupSize; - sqInt mapSize; - sqInt opcodeSize; - CogMethod *pic; - usqInt startAddress; - - compilationBreakpointisMNUCase(selector, 0); - startAddress = allocate(openPICSize); - if (startAddress == 0) { - return ((CogMethod *) InsufficientCodeSpace); - } - (methodLabel->address = startAddress); - (methodLabel->dependent = null); - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 100; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - compileOpenPICnumArgs(selector, numArgs); - computeMaximumSizes(); - concretizeAt(methodLabel, startAddress); - codeSize = generateInstructionsAt(startAddress + (sizeof(CogMethod))); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - mapSize = generateMapAtstart((startAddress + openPICSize) - 1, startAddress + cmNoCheckEntryOffset); - assert((((entry->address)) - startAddress) == cmEntryOffset); - assert(((roundUpLength((sizeof(CogMethod)) + codeSize)) + (roundUpLength(mapSize))) <= openPICSize); - end = outputInstructionsAt(startAddress + (sizeof(CogMethod))); - /* begin fillInOPICHeader:numArgs:selector: */ - pic = ((CogMethod *) ((((usqInt)startAddress)) + codeToDataDelta)); - (pic->cmType = CMOpenPIC); - (pic->objectHeader = 0); - (pic->blockSize = openPICSize); - addToOpenPICList(pic); - (pic->methodHeader = 0); - (pic->selector = selector); - (pic->cmNumArgs = numArgs); - (pic->cmHasMovableLiteral = isNonImmediate(selector)); - if ((pic->cmRefersToYoung = isYoung(selector))) { - addToYoungReferrers(pic); - } - (pic->cmUsageCount = initialOpenPICUsageCount()); - /* begin cpicHasMNUCase: */ - ((((CogBlockMethod *) pic))->cpicHasMNUCaseOrCMIsFullBlock) = 0; - (pic->cPICNumCases = 0); - (pic->blockEntryOffset = 0); - flushICacheFromto(backEnd, (((usqInt)pic)) - codeToDataDelta, ((((usqInt)pic)) - codeToDataDelta) + openPICSize); - assert(((pic->cmType)) == CMOpenPIC); - assert(((pic->selector)) == selector); - assert(((pic->cmNumArgs)) == numArgs); - assert((callTargetFromReturnAddress(backEnd, ((((sqInt)pic)) - codeToDataDelta) + missOffset)) == (picAbortTrampolineFor(numArgs))); - assert(openPICSize == (roundUpLength(openPICSize))); - /* begin assertValidDualZoneFrom:to: */ - ((((usqInt)pic)) - codeToDataDelta) + openPICSize; -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, ((((usqInt)pic)) - codeToDataDelta) + cmNoCheckEntryOffset, codeToDataDelta); -# endif - /* begin maybeEnableSingleStep */ - return ((CogMethod *) startAddress); -} - - -/* Attempt to create a two-case PIC for case0CogMethod and - case1Method,case1Tag. The tag for case0CogMethod is at the send site and - so doesn't need to be generated. - case1Method may be any of - - a Cog method; link to its unchecked entry-point - - a CompiledMethod; link to ceInterpretMethodFromPIC: - - a CompiledMethod; link to ceMNUFromPICMNUMethod:receiver: */ - - /* Cogit>>#cogPICSelector:numArgs:Case0Method:Case1Method:tag:isMNUCase: */ -static CogMethod * NoDbgRegParms -cogPICSelectornumArgsCase0MethodCase1MethodtagisMNUCase(sqInt selector, sqInt numArgs, CogMethod *case0CogMethod, sqInt case1MethodOrNil, sqInt case1Tag, sqInt isMNUCase) -{ - CogMethod * actualPIC; - usqInt startAddress; - CogMethod * writablePIC; - - if (isYoung(selector)) { - return ((CogMethod *) YoungSelectorInPIC); - } - compilationBreakpointclassTagisMNUCase(selector, case1Tag, isMNUCase); - startAddress = allocate(closedPICSize); - if (startAddress == 0) { - return ((CogMethod *) InsufficientCodeSpace); - } - maybeBreakGeneratingFromto(startAddress, startAddress + closedPICSize); - - /* memcpy the prototype across to our allocated space; because anything else would be silly */ - writablePIC = ((CogMethod *) ((((usqInt)startAddress)) + codeToDataDelta)); - codeMemcpy(writablePIC, cPICPrototype, closedPICSize); - /* begin fillInCPICHeader:numArgs:numCases:hasMNUCase:selector: */ - assert(!(isYoung(selector))); - (writablePIC->cmType = CMClosedPIC); - (writablePIC->objectHeader = 0); - (writablePIC->blockSize = closedPICSize); - (writablePIC->methodObject = 0); - (writablePIC->methodHeader = 0); - (writablePIC->selector = selector); - (writablePIC->cmNumArgs = numArgs); - (writablePIC->cmHasMovableLiteral = 0); - (writablePIC->cmRefersToYoung = 0); - (writablePIC->cmUsageCount = initialClosedPICUsageCount()); - /* begin cpicHasMNUCase: */ - ((((CogBlockMethod *) writablePIC))->cpicHasMNUCaseOrCMIsFullBlock) = isMNUCase; - (writablePIC->cPICNumCases = 2); - (writablePIC->blockEntryOffset = 0); - assert(((writablePIC->cmType)) == CMClosedPIC); - assert(((writablePIC->selector)) == selector); - assert(((writablePIC->cmNumArgs)) == numArgs); - assert(((writablePIC->cPICNumCases)) == 2); - assert(closedPICSize == (roundUpLength(closedPICSize))); - /* begin maybeEnableSingleStep */ - configureCPICCase0Case1MethodtagisMNUCasenumArgsdelta((actualPIC = ((CogMethod *) startAddress)), case0CogMethod, case1MethodOrNil, case1Tag, isMNUCase, numArgs, startAddress - (((usqInt)cPICPrototype))); - assert((callTargetFromReturnAddress(backEnd, startAddress + missOffset)) == (picAbortTrampolineFor(numArgs))); - return actualPIC; -} - - -/* Attempt to produce a machine code method for the bytecode method - object aMethodObj. N.B. If there is no code memory available do *NOT* - attempt to reclaim the method zone. Certain clients (e.g. ceSICMiss:) - depend on the zone remaining constant across method generation. */ - - /* Cogit>>#cog:selector: */ -CogMethod * -cogselector(sqInt aMethodObj, sqInt aSelectorOop) -{ - CogMethod *cogMethod; - sqInt selector; - - - /* inline exclude:selector: */ - assert(!((methodHasCogMethod(aMethodObj)))); - assert(!((isOopCompiledMethod(ultimateLiteralOf(aMethodObj))))); - - /* coInterpreter stringOf: selector */ - selector = (aSelectorOop == (nilObject()) - ? maybeSelectorOfMethod(aMethodObj) - : aSelectorOop); - if (!(selector == null)) { - compilationBreakpointisMNUCase(selector, 0); - } - if (aMethodObj == breakMethod) { - haltmsg("Compilation of breakMethod"); - } - if (methodUsesAlternateBytecodeSet(aMethodObj)) { - if ((numElementsIn(generatorTable)) <= 0x100) { - return null; - } - bytecodeSetOffset = 0x100; - } - else { - bytecodeSetOffset = 0; - } - methodObj = aMethodObj; - methodHeader = methodHeaderOf(aMethodObj); - receiverTags = receiverTagBitsForMethod(methodObj); - cogMethod = compileCogMethod(aSelectorOop); - if ((((((sqInt)cogMethod)) >= MaxNegativeErrorCode) && ((((sqInt)cogMethod)) <= -1))) { - if ((((sqInt)cogMethod)) == InsufficientCodeSpace) { - callForCogCompiledCodeCompaction(); - } - return null; - } - return cogMethod; -} - - /* Cogit>>#collectCogConstituentFor:Annotation:Mcpc:Bcpc:Method: */ -static sqInt NoDbgRegParms -collectCogConstituentForAnnotationMcpcBcpcMethod(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *cogMethodArg) -{ - sqInt address; - sqInt annotation; - usqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - - if (!descriptor) { - return 0; - } - if (!((descriptor->isMapped))) { - return 0; - } - address = positive32BitIntegerFor(((usqInt)mcpc)); - if (!address) { - return PrimErrNoMemory; - } - storePointerUncheckedofObjectwithValue(cogConstituentIndex, topRemappableOop(), address); - storePointerUncheckedofObjectwithValue(cogConstituentIndex + 1, topRemappableOop(), (((usqInt)bcpc << 1) | 1)); - - /* Collect any first case classTags for closed PICs. */ - cogConstituentIndex += 2; - if (((!(isBackwardBranchAndAnnotation & 1))) - && (((((usqInt)(isBackwardBranchAndAnnotation)) >> 1) >= IsSendCall) - || (0))) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* send is linked */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - annotation = ((usqInt)(isBackwardBranchAndAnnotation)) >> 1; - /* begin offsetAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (((targetMethod1->cmType)) == CMClosedPIC) { - (targetMethod1->methodObject = classForInlineCacheTag(inlineCacheTagAt(backEnd, mcpc))); - } - } - } - return 0; -} - - -/* Answer a description of the mapping between machine code pointers and - bytecode pointers for the Cog Method. - First value is the address of the cog method. - Following values are pairs of machine code pc and bytecode pc */ - - /* Cogit>>#collectCogMethodConstituent: */ -static sqInt NoDbgRegParms -collectCogMethodConstituent(CogMethod *cogMethod) -{ - sqInt address; - sqInt aMethodObj; - sqInt annotation; - sqInt bcpc; - sqInt bsOffset; - sqInt byte; - sqInt cm; - CogBlockMethod *cogBlockMethod; - sqInt data; - BytecodeDescriptor *descriptor; - sqInt distance; - sqInt endbcpc; - sqInt errCode; - CogMethod *homeMethod; - sqInt isBackwardBranch; - sqInt isInBlock; - sqInt latestContinuation; - usqInt map; - sqInt mapByte; - usqInt mcpc; - sqInt nExts; - sqInt nextBcpc; - sqInt nSlots; - sqInt result; - sqInt startbcpc; - sqInt targetPC; - - latestContinuation = 0; - if (!(((cogMethod->cmType)) == CMMethod)) { - return positive32BitIntegerFor(((usqInt)cogMethod)); - } - cogBlockMethod = ((CogBlockMethod *) cogMethod); - if (((cogBlockMethod->stackCheckOffset)) == 0) { - - /* isFrameless ? */ - return positive32BitIntegerFor(((usqInt)cogMethod)); - } - cm = (cogMethod->methodObject); - - /* +1 for first address */ - nSlots = ((((byteSizeOf(cm)) - (startPCOfMethod(cm))) * 2) + (minSlotsForShortening())) + 1; - data = instantiateClassindexableSize(splObj(ClassArray), nSlots); - if (!data) { - return null; - } - pushRemappableOop(data); - address = positive32BitIntegerFor(((usqInt)cogMethod)); - if (!address) { - popRemappableOop(); - return null; - } - storePointerUncheckedofObjectwithValue(0, topRemappableOop(), address); - cogConstituentIndex = 1; - /* begin mapFor:bcpc:performUntil:arg: */ - startbcpc = startPCOfMethod((cogMethod->methodObject)); - assert(((cogBlockMethod->stackCheckOffset)) > 0); - - /* The stack check maps to the start of the first bytecode, - the first bytecode being effectively after frame build. */ - mcpc = (((usqInt)cogBlockMethod)) + ((cogBlockMethod->stackCheckOffset)); - result = collectCogConstituentForAnnotationMcpcBcpcMethod(null, (0 + (((int)((usqInt)(HasBytecodePC) << 1)))), (((char *) mcpc)), startbcpc, (((void *)cogMethod))); - if (result != 0) { - errCode = result; - goto l7; - } - - /* In both CMMethod and CMBlock cases find the start of the map and - skip forward to the bytecode pc map entry for the stack check. */ - bcpc = startbcpc; - if (((cogBlockMethod->cmType)) == CMMethod) { - /* begin cmIsFullBlock */ - isInBlock = 0; - homeMethod = ((CogMethod *) cogBlockMethod); - assert(startbcpc == (startPCOfMethodHeader((homeMethod->methodHeader)))); - map = ((((usqInt)homeMethod)) + ((homeMethod->blockSize))) - 1; - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert((annotation == IsAbsPCReference) - || ((annotation == IsObjectReference) - || ((annotation == IsRelativeCall) - || (annotation == IsDisplacementX2N)))); - latestContinuation = startbcpc; - aMethodObj = (homeMethod->methodObject); - endbcpc = (numBytesOf(aMethodObj)) - 1; - /* begin bytecodeSetOffsetForHeader: */ - (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader) - ? 0x100 - : 0) -# else - 0 -# endif - ; - bcpc += deltaToSkipPrimAndErrorStoreInheader(aMethodObj, (homeMethod->methodHeader)); - } - else { - isInBlock = 1; - assert(bcpc == ((cogBlockMethod->startpc))); - homeMethod = cmHomeMethod(cogBlockMethod); - map = findMapLocationForMcpcinMethod((((usqInt)cogBlockMethod)) + (sizeof(CogBlockMethod)), homeMethod); - assert(map != 0); - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert(((((usqInt)(annotation)) >> AnnotationShift) == HasBytecodePC) - || ((((usqInt)(annotation)) >> AnnotationShift) == IsDisplacementX2N)); - while (((annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift)) != HasBytecodePC) { - map -= 1; - } - - /* skip fiducial; i.e. the map entry for the pc immediately following the method header. */ - map -= 1; - aMethodObj = (homeMethod->methodObject); - bcpc = startbcpc - ( -#if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet((homeMethod->methodHeader)) - ? AltBlockCreationBytecodeSize - : BlockCreationBytecodeSize) -#else // MULTIPLEBYTECODESETS - BlockCreationBytecodeSize -#endif - ); - /* begin bytecodeSetOffsetForHeader: */ - (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader1) - ? 0x100 - : 0) -# else - 0 -# endif - ; - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - endbcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, -1, aMethodObj)) - : 0)); - bcpc = startbcpc; - } - nExts = 0; - while ((((usqInt)((byteAt(map)))) >> AnnotationShift) != HasBytecodePC) { - map -= 1; - } - map -= 1; - while (((mapByte = byteAt(map))) != MapEnd) { - - /* defensive; we exit on bcpc */ - if (mapByte >= FirstAnnotation) { - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if (annotation >= HasBytecodePC) { - if ((annotation == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - while (1) { - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - if (isInBlock) { - if (bcpc >= endbcpc) { - errCode = 0; - goto l7; - } - } - else { - if (((descriptor->isReturn)) - && (bcpc >= latestContinuation)) { - errCode = 0; - goto l7; - } - if ((isBranch(descriptor)) - || ((descriptor->isBlockCreation))) { - /* begin latestContinuationPCFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj); - targetPC = (bcpc + ((descriptor->numBytes))) + (((distance < 0) ? 0 : distance)); - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - /* latestContinuation = */ latestContinuation; - } - nextBcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) - : 0)); - if (((descriptor->isMapped)) - || (isInBlock - && ((descriptor->isMappedInBlock)))) break; - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - isBackwardBranch = (isBranch(descriptor)) - && ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) < 0)); - result = collectCogConstituentForAnnotationMcpcBcpcMethod(descriptor, ((isBackwardBranch - ? (((sqInt)((usqInt)(annotation) << 1))) + 1 - : ((sqInt)((usqInt)(annotation) << 1)))), (((char *) mcpc)), ((isBackwardBranch - ? bcpc - (2 * nExts) - : bcpc)), (((void *)cogMethod))); - if (result != 0) { - errCode = result; - goto l7; - } - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - } - else { - assert(((((usqInt)(mapByte)) >> AnnotationShift) == IsDisplacementX2N) - || ((((usqInt)(mapByte)) >> AnnotationShift) == IsAnnotationExtension)); - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - errCode = 0; - l7: /* end mapFor:bcpc:performUntil:arg: */; - if (errCode != 0) { - popRemappableOop(); - return null; - } - if (cogConstituentIndex < nSlots) { - shortentoIndexableSize(topRemappableOop(), cogConstituentIndex); - } - return popRemappableOop(); -} - - /* Cogit>>#compactCogCompiledCode */ -void -compactCogCompiledCode(void) -{ - assertValidDualZone(); - assert(noCogMethodsMaximallyMarked()); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - markActiveMethodsAndReferents(); - freeOlderMethodsForCompaction(); - compactPICsWithFreedTargets(); - planCompaction(); - updateStackZoneReferencesToCompiledCodePreCompaction(); - relocateMethodsPreCompaction(); - assertValidDualZone(); - compactCompiledCode(); - stopsFromto(backEnd, freeStart(), (youngReferrers()) - 1); - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), ((usqInt)(youngReferrers()))); - assert(allMethodsHaveCorrectHeader()); - assert(kosherYoungReferrers()); - assertValidDualZone(); -} - - /* Cogit>>#compactPICsWithFreedTargets */ -static void -compactPICsWithFreedTargets(void) -{ - CogMethod *cogMethod; - sqInt count; - - cogMethod = ((CogMethod *) methodZoneBase); - count = 0; - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) == CMClosedPIC) - && (cPICCompactAndIsNowEmpty(cogMethod))) { - ((((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)))->cmType = CMFree); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - count += 1; - } - assert(count == (numMethods())); -} - - -/* The start of a CogMethod has a call to a run-time abort routine that - either handles an in-line cache failure or a stack overflow. The routine - selects the - path depending on ReceiverResultReg; if zero it takes the stack overflow - path; if nonzero the in-line cache miss path. Neither of these paths - returns. The abort routine must be called; In the callee the method is - located by - adding the relevant offset to the return address of the call. - - N.B. This code must match that in compilePICAbort: so that the offset of - the return address of the call is the same in methods and closed PICs. */ - - /* Cogit>>#compileAbort */ -static AbstractInstruction * -compileAbort(void) -{ - AbstractInstruction *anInstruction; - sqInt callTarget; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 0, ReceiverResultReg); - stackOverflowCall = anInstruction; - - /* If there is a link register it must be saved (pushed onto the stack) before it - is smashed by the abort call, and hence needs to be manually handled here */ - sendMiss = genoperand(PushR, LinkReg); - /* begin Call: */ - callTarget = methodAbortTrampolineFor(methodOrBlockNumArgs); - return genoperand(Call, callTarget); -} - - /* Cogit>>#compileBlockDispatchFrom:to: */ -static sqInt NoDbgRegParms -compileBlockDispatchFromto(sqInt lowBlockStartIndex, sqInt highBlockStartIndex) -{ - AbstractInstruction *anInstruction; - BlockStart *blockStart; - sqInt halfWay; - AbstractInstruction *jmp; - - if (lowBlockStartIndex == highBlockStartIndex) { - blockStart = blockStartAt(lowBlockStartIndex); - genoperand(Jump, ((sqInt)((blockStart->entryLabel)))); - return null; - } - halfWay = (highBlockStartIndex + lowBlockStartIndex) / 2; - assert(((halfWay >= lowBlockStartIndex) && (halfWay <= highBlockStartIndex))); - - /* N.B. FLAGS := TempReg - startpc */ - blockStart = blockStartAt(halfWay); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)(((blockStart->startpc)) + 1) << 1) | 1); - anInstruction = genoperandoperand(CmpCqR, (((usqInt)(((blockStart->startpc)) + 1) << 1) | 1), TempReg); - if (lowBlockStartIndex == halfWay) { - genConditionalBranchoperand(JumpLessOrEqual, ((sqInt)((blockStart->entryLabel)))); - compileBlockDispatchFromto(halfWay + 1, highBlockStartIndex); - return null; - } - if ((halfWay + 1) == highBlockStartIndex) { - blockStart = blockStartAt(highBlockStartIndex); - genConditionalBranchoperand(JumpGreater, ((sqInt)((blockStart->entryLabel)))); - return compileBlockDispatchFromto(lowBlockStartIndex, halfWay); - } - jmp = genConditionalBranchoperand(JumpGreater, ((sqInt)0)); - compileBlockDispatchFromto(lowBlockStartIndex, halfWay); - if (halfWay == highBlockStartIndex) { - blockStart = blockStartAt(highBlockStartIndex); - jmpTarget(jmp, (blockStart->entryLabel)); - } - else { - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileBlockDispatchFromto(halfWay + 1, highBlockStartIndex); - } - return 0; -} - - -/* Compile a block's entry. This looks like a dummy CogBlockMethod header - (for frame parsing) - followed by either a frame build, if a frame is required, or nothing. The - CogMethodHeader's objectHeader field is a back pointer to the method, but - this can't be filled in until code generation. */ - - /* Cogit>>#compileBlockEntry: */ -static void NoDbgRegParms -compileBlockEntry(BlockStart *blockStart) -{ - AbstractInstruction *abstractInstruction; - sqInt alignment; - - /* begin AlignmentNops: */ - alignment = blockAlignment(); - genoperand(AlignmentNops, alignment); - (blockStart->fakeHeader = genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - switch (sizeof(CogBlockMethod)) { - case 8: - genoperand(Fill32, 0); - genoperand(Fill32, 0); - break; - case 12: - genoperand(Fill32, 0); - genoperand(Fill32, 0); - genoperand(Fill32, 0); - break; - case 16: - genoperand(Fill32, 0); - genoperand(Fill32, 0); - genoperand(Fill32, 0); - genoperand(Fill32, 0); - break; - default: - error("Case not found and no otherwise clause"); - } - (blockStart->entryLabel = genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (needsFrame) { - compileBlockFrameBuild(blockStart); - if (recordBlockTrace()) { - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceTraceBlockActivationTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - } - } - else { - compileBlockFramelessEntry(blockStart); - } -} - - -/* Generate a call to aRoutine with up to 4 arguments. If resultRegOrNone is - not NoReg assign the C result to resultRegOrNone. If saveRegs, save all - registers. Hack: a negative arg value indicates an abstract register, a - non-negative value - indicates a constant. */ - - /* Cogit>>#compileCallFor:numArgs:arg:arg:arg:arg:resultReg:regsToSave: */ -static void NoDbgRegParms -compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt resultRegOrNone, sqInt regMask) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - const int cStackAlignment = STACK_ALIGN_BYTES; - sqInt delta; - sqInt numRegsPushed; - usqInt regMaskCopy; - sqInt regsToSave; - sqInt wordsPushedModAlignment; - - regsToSave = (resultRegOrNone == NoReg - ? regMask - : ((regMask | (1U << resultRegOrNone)) - (1U << resultRegOrNone))); - if (cStackAlignment > BytesPerWord) { - /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ - regMaskCopy = ((usqInt)regsToSave); - numRegsPushed = 0; - while (regMaskCopy != 0) { - numRegsPushed += regMaskCopy & 1; - regMaskCopy = ((regMaskCopy) >> 1); - } - if ((numRegsPushed == 0) - && ((numIntRegArgs(((AbstractInstruction *) backEnd))) >= numArgs)) { - goto l1; - } - wordsPushedModAlignment = (numRegsPushed + ((((numArgs - (numIntRegArgs(((AbstractInstruction *) backEnd)))) < 0) ? 0 : (numArgs - (numIntRegArgs(((AbstractInstruction *) backEnd))))))) % (cStackAlignment / BytesPerWord); - if (wordsPushedModAlignment != 0) { - delta = (cStackAlignment / BytesPerWord) - wordsPushedModAlignment; - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, delta * BytesPerWord, SPReg); - } - l1: /* end genAlignCStackSavingRegisters:numArgs:wordAlignment: */; - } - genSaveRegs(backEnd, regsToSave); - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - if (numArgs == 0) { - goto l13; - } - if (regOrConst0 < NoReg) { - /* begin MoveCq:R: */ - anInstruction4 = genoperandoperand(MoveCqR, -2 - regOrConst0, A0); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, regOrConst0, A0); - } - if (numArgs == 1) { - goto l13; - } - if (regOrConst1 < NoReg) { - /* begin MoveCq:R: */ - anInstruction11 = genoperandoperand(MoveCqR, -2 - regOrConst1, A1); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, regOrConst1, A1); - } - if (numArgs == 2) { - goto l13; - } - if (regOrConst2 < NoReg) { - /* begin MoveCq:R: */ - anInstruction21 = genoperandoperand(MoveCqR, -2 - regOrConst2, A2); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, regOrConst2, A2); - } - if (numArgs == 3) { - goto l13; - } - if (regOrConst3 < NoReg) { - /* begin MoveCq:R: */ - anInstruction3 = genoperandoperand(MoveCqR, -2 - regOrConst3, A3); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, regOrConst3, A3); - } - l13: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin checkLiteral:forInstruction: */ - anInstruction2 = genoperand(CallFull, ((usqInt)aRoutine)); - genWriteCResultIntoReg(backEnd, resultRegOrNone); - assert(numArgs <= 4); - genRestoreRegs(backEnd, regsToSave); -} - - -/* Compile the cache tag computation and the first comparison. Answer the - address of that comparison. */ - - /* Cogit>>#compileCPICEntry */ -static AbstractInstruction * -compileCPICEntry(void) -{ - entry = genGetInlineCacheClassTagFromintoforEntry(ReceiverResultReg, TempReg, 1); - /* begin CmpR:R: */ - assert(!((ClassReg == SPReg))); - genoperandoperand(CmpRR, ClassReg, TempReg); - return genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -} - - -/* The entry code to a method checks that the class of the current receiver - matches that in the inline cache. Other non-obvious elements are that its - alignment must be - different from the alignment of the noCheckEntry so that the method map - machinery can distinguish normal and super sends (super sends bind to the - noCheckEntry). */ - - /* Cogit>>#compileEntry */ -static void -compileEntry(void) -{ - AbstractInstruction *anInstruction1; - AbstractInstruction * inst; - - entry = genGetInlineCacheClassTagFromintoforEntry(ReceiverResultReg, TempReg, 1); - /* begin CmpR:R: */ - assert(!((ClassReg == SPReg))); - genoperandoperand(CmpRR, ClassReg, TempReg); - genConditionalBranchoperand(JumpNonZero, ((sqInt)sendMiss)); - noCheckEntry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - if (((traceFlags & 0x100) == 0x100)) { - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - /* begin checkLiteral:forInstruction: */ - anInstruction1 = genoperand(CallFull, ceTraceLinkedSendTrampoline); - /* begin PopR: */ - genoperand(PopR, LinkReg); - } -} - - -/* Compile the top-level method body. */ - - /* Cogit>>#compileMethodBody */ -static sqInt -compileMethodBody(void) -{ - if (endPC < initialPC) { - return 0; - } - return compileAbstractInstructionsFromthrough(initialPC + (deltaToSkipPrimAndErrorStoreInheader(methodObj, methodHeader)), endPC); -} - - -/* The start of a PIC has a call to a run-time abort routine that either - handles a dispatch to an - interpreted method or a dispatch of an MNU case. The routine selects the - path by testing - ClassReg, which holds the inline cache tag; if equal to the - picAbortDiscriminatorValue (zero) - it takes the MNU path; if nonzero the dispatch to interpreter path. - Neither of these paths - returns. The abort routine must be called; In the callee the PIC is - located by adding the - relevant offset to the return address of the call. - - N.B. This code must match that in compileAbort so that the offset of the - return address of - the call is the same in methods and closed PICs. */ - - /* Cogit>>#compilePICAbort: */ -static sqInt NoDbgRegParms -compilePICAbort(sqInt numArgs) -{ - AbstractInstruction *anInstruction; - sqInt callTarget; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 0 /* picAbortDiscriminatorValue */, ClassReg); - picMNUAbort = anInstruction; - - /* If there is a link register it must be saved (pushed onto the stack) before it - is smashed by the abort call, and hence needs to be manually handled here */ - picInterpretAbort = genoperand(PushR, LinkReg); - /* begin Call: */ - callTarget = picAbortTrampolineFor(numArgs); - genoperand(Call, callTarget); - return 0; -} - - -/* Compile the compare of stackLimit against the stack pointer, jumping to - the stackOverflowCall if - the stack pointer is below the limit. Answer a bytecode annotated label - that follows the sequence. - - The stack check functions both as a genuine stack limit check to prevent - calls overflowing stack pages, - and as an event/context-switch break out. To cause an event check - (including a check for a required - context switch), stackLimit is set to the highest possible value, and - hence all stack limit checks will - fail. A path in the stack overflow abort then arranges to call event - checking if it has been requested. - - Certain block activations (e.g. valueNoContextSwitch:) must not context - switch, and in that - case, SendNumArgs is set to zero to communicate to the stack overflow - abort that it should - not perform event/context-switch (yet). */ - - /* Cogit>>#compileStackOverflowCheck: */ -static AbstractInstruction * NoDbgRegParms -compileStackOverflowCheck(sqInt canContextSwitch) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction * jumpSkip; - AbstractInstruction * label; - - /* begin checkLiteral:forInstruction: */ - stackLimitAddress(); - anInstruction1 = genoperandoperand(MoveAwR, stackLimitAddress(), TempReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, SPReg); - if (canContextSwitch) { - genConditionalBranchoperand(JumpBelow, ((sqInt)stackOverflowCall)); - label = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - else { - jumpSkip = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 0, SendNumArgsReg); - genoperand(Jump, ((sqInt)stackOverflowCall)); - jmpTarget(jumpSkip, (label = genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - } - /* begin annotateBytecode: */ - (label->annotation = HasBytecodePC); - return label; -} - - -/* Generate a trampoline with up to four arguments. Generate either a call or - a jump to aRoutine - as requested by callJumpBar. If generating a call and resultRegOrNone is - not NoReg pass the C - result back in resultRegOrNone. - Hack: a negative value indicates an abstract register, a non-negative - value indicates a constant. */ - - /* Cogit>>#compileTrampolineFor:numArgs:arg:arg:arg:arg:regsToSave:pushLinkReg:resultReg: */ -static void NoDbgRegParms -compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone) -{ - genSmalltalkToCStackSwitch(pushLinkReg); - compileCallFornumArgsargargargargresultRegregsToSave(aRoutine, numArgs, regOrConst0, regOrConst1, regOrConst2, regOrConst3, resultRegOrNone, regMask); - genLoadStackPointers(backEnd); - genTrampolineReturn(pushLinkReg); -} - - -/* Generate the entry code for a method to determine cmEntryOffset and - cmNoCheckEntryOffset. We - need cmNoCheckEntryOffset up front to be able to generate the map starting - from cmNoCheckEntryOffset */ -/* stack allocate the various collections so that they - are effectively garbage collected on return. */ - - /* Cogit>>#computeEntryOffsets */ -static void -computeEntryOffsets(void) -{ - sqInt fixupSize; - sqInt opcodeSize; - AbstractInstruction *sendMissCall; - - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 24; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - methodOrBlockNumArgs = 0; - sendMissCall = compileAbort(); - compileEntry(); - computeMaximumSizes(); - generateInstructionsAt(methodZoneBase + (sizeof(CogMethod))); - cmEntryOffset = ((entry->address)) - methodZoneBase; - cmNoCheckEntryOffset = ((noCheckEntry->address)) - methodZoneBase; - missOffset = (((sendMissCall->address)) + ((sendMissCall->machineCodeSize))) - methodZoneBase; - entryPointMask = BytesPerWord - 1; - while ((cmEntryOffset & entryPointMask) == (cmNoCheckEntryOffset & entryPointMask)) { - entryPointMask = (entryPointMask + entryPointMask) + 1; - } - if (entryPointMask >= (roundUpToMethodAlignment(backEnd(), 1))) { - error("cannot differentiate checked and unchecked entry-points with current cog method alignment"); - } - checkedEntryAlignment = cmEntryOffset & entryPointMask; - uncheckedEntryAlignment = cmNoCheckEntryOffset & entryPointMask; - assert(checkedEntryAlignment != uncheckedEntryAlignment); -} - - -/* Generate the entry code for a method to determine cmEntryOffset and - cmNoCheckEntryOffset. We - need cmNoCheckEntryOffset up front to be able to generate the map starting - from cmNoCheckEntryOffset */ -/* stack allocate the various collections so that they - are effectively garbage collected on return. */ - - /* Cogit>>#computeFullBlockEntryOffsets */ -static void -computeFullBlockEntryOffsets(void) -{ - } - - -/* While we order variables in the CoInterpreter in order of dynamic - frequency, and hence - expect that stackPointer will be output first, C optimizers and linkers - may get their own - ideas and ``improve upon'' this ordering. So we cannot depend on - stackPointer being - at the lowest address of the variables we want to access through - VarBaseReg. Here we - choose the minimum amongst a set to try to choose a varBaseAddress that is - just less - than but iwht in range of all variables we want to access through it. */ - - /* Cogit>>#computeGoodVarBaseAddress */ -static usqInt -computeGoodVarBaseAddress(void) -{ - usqInt minAddress; - - - /* stackLimit is e.g. lowest using the clang toolchain on MacOS X */ - minAddress = stackLimitAddress(); - if ((stackPointerAddress()) < minAddress) { - minAddress = stackPointerAddress(); - } - if ((framePointerAddress()) < minAddress) { - minAddress = framePointerAddress(); - } - if ((instructionPointerAddress()) < minAddress) { - minAddress = instructionPointerAddress(); - } - if ((argumentCountAddress()) < minAddress) { - minAddress = argumentCountAddress(); - } - if ((primFailCodeAddress()) < minAddress) { - minAddress = primFailCodeAddress(); - } - return minAddress; -} - - -/* This pass assigns maximum sizes to all abstract instructions and - eliminates jump fixups. - It hence assigns the maximum address an instruction will occur at which - allows the next - pass to conservatively size jumps. */ - - /* Cogit>>#computeMaximumSizes */ -static void -computeMaximumSizes(void) -{ - AbstractInstruction *abstractInstruction; - sqInt i; - sqInt relativeAddress; - - relativeAddress = 0; - for (i = 0; i < opcodeIndex; i += 1) { - maybeBreakGeneratingInstructionWithIndex(i); - abstractInstruction = abstractInstructionAt(i); - (abstractInstruction->address = relativeAddress); - (abstractInstruction->maxSize = computeMaximumSize(abstractInstruction)); - relativeAddress += (abstractInstruction->maxSize); - } -} - - -/* Configure a copy of the prototype CPIC for a two-case PIC for - case0CogMethod and - case1Method - case1Tag. - The tag for case0CogMethod is at the send site and so doesn't need to be - generated. case1Method may be any of - - a Cog method; jump to its unchecked entry-point - - a CompiledMethod; jump to the ceInterpretFromPIC trampoline - - nil; call ceMNUFromPIC - addDelta is the address change from the prototype to the new CPIC - location, needed - because the loading of the CPIC label at the end may use a literal instead - of a pc relative load. */ -/* self disassembleFrom: cPIC asInteger + (self sizeof: CogMethod) to: cPIC - asInteger + closedPICSize - */ - - /* Cogit>>#configureCPIC:Case0:Case1Method:tag:isMNUCase:numArgs:delta: */ -static sqInt NoDbgRegParms -configureCPICCase0Case1MethodtagisMNUCasenumArgsdelta(CogMethod *cPIC, CogMethod *case0CogMethod, sqInt case1Method, sqInt case1Tag, sqInt isMNUCase, sqInt numArgs, sqInt addrDelta) -{ - sqInt caseEndAddress; - int operand; - sqInt targetEntry; - - assert(case1Method != null); - rewriteCallAttarget(backEnd, (((sqInt)cPIC)) + missOffset, picAbortTrampolineFor(numArgs)); - assert(!(inlineCacheTagIsYoung(case1Tag))); - if ((!isMNUCase) - && (methodHasCogMethod(case1Method))) { - operand = 0; - targetEntry = (((sqInt)(cogMethodOf(case1Method)))) + cmNoCheckEntryOffset; - } - else { - - /* We do not scavenge PICs, hence we cannot cache the MNU method if it is in new space. */ - operand = ((case1Method == null) - || (isYoungObject(case1Method)) - ? 0 - : case1Method); - targetEntry = (case1Method == null - ? (((sqInt)cPIC)) + (sizeof(CogMethod)) - : (((sqInt)cPIC)) + (picInterpretAbortOffset())); - } - rewriteJumpLongAttarget(backEnd, (((sqInt)cPIC)) + firstCPICCaseOffset, (((sqInt)case0CogMethod)) + cmNoCheckEntryOffset); - - /* update the cpic case */ - caseEndAddress = addressOfEndOfCaseinCPIC(2, cPIC); - rewriteCPICCaseAttagobjReftarget(caseEndAddress, case1Tag, operand, ((sqInt)((isMNUCase - ? (((sqInt)cPIC)) + (sizeof(CogMethod)) - : targetEntry)))); - relocateMethodReferenceBeforeAddressby(backEnd, ((((sqInt)cPIC)) + cPICEndOfCodeOffset) - (jumpLongByteSize(backEnd)), addrDelta); - rewriteJumpLongAttarget(backEnd, (((sqInt)cPIC)) + cPICEndOfCodeOffset, cPICMissTrampolineFor(numArgs)); - return 0; -} - - -/* Configure a copy of the prototype CPIC for a one-case MNU CPIC that calls - ceMNUFromPIC for - case0Tag The tag for case0 is at the send site and so doesn't need to be - generated. addDelta is the address change from the prototype to the new - CPIC location, needed - because the loading of the CPIC label at the end may be a literal instead - of a pc-relative load. */ -/* adjust the jump at missOffset, the ceAbortXArgs */ - - /* Cogit>>#configureMNUCPIC:methodOperand:numArgs:delta: */ -static sqInt NoDbgRegParms -configureMNUCPICmethodOperandnumArgsdelta(CogMethod *cPIC, sqInt methodOperand, sqInt numArgs, sqInt addrDelta) -{ - int operand; - sqInt target; - - rewriteCallAttarget(backEnd, (((sqInt)cPIC)) + missOffset, picAbortTrampolineFor(numArgs)); - - /* set the jump to the case0 method */ - operand = ((methodOperand == null) - || (isYoungObject(methodOperand)) - ? 0 - : methodOperand); - rewriteJumpLongAttarget(backEnd, (((sqInt)cPIC)) + firstCPICCaseOffset, (((sqInt)cPIC)) + (sizeof(CogMethod))); - storeLiteralbeforeFollowingAddress(backEnd, operand, ((((sqInt)cPIC)) + firstCPICCaseOffset) - (jumpLongByteSize(backEnd))); - rewriteJumpLongAttarget(backEnd, (((sqInt)cPIC)) + cPICEndOfCodeOffset, cPICMissTrampolineFor(numArgs)); - relocateMethodReferenceBeforeAddressby(backEnd, ((((sqInt)cPIC)) + cPICEndOfCodeOffset) - (jumpLongByteSize(backEnd)), addrDelta); - /* begin rewriteCPIC:caseJumpTo: */ - target = addressOfEndOfCaseinCPIC(2, cPIC); - rewriteCPICJumpAttarget(backEnd, (((((sqInt)cPIC)) + firstCPICCaseOffset) - (jumpLongByteSize(backEnd))) - 8 /* loadLiteralByteSize */, target); - return 0; -} - - -/* Scan the CPIC for target methods that have been freed and eliminate them. - Since the first entry cannot be eliminated, answer that the PIC should be - freed if the first entry is to a free target. Answer if the PIC is now - empty or should be freed. */ - - /* Cogit>>#cPICCompactAndIsNowEmpty: */ -static sqInt NoDbgRegParms -cPICCompactAndIsNowEmpty(CogMethod *cPIC) -{ - usqInt entryPoint; - sqInt followingAddress; - sqInt i; - sqInt methods[MaxCPICCases]; - sqInt pc; - int tags[MaxCPICCases]; - CogMethod *targetMethod; - sqInt targets[MaxCPICCases]; - sqInt used; - sqInt valid; - - used = 0; - for (i = 1; i <= ((cPIC->cPICNumCases)); i += 1) { - pc = addressOfEndOfCaseinCPIC(i, cPIC); - entryPoint = (i == 1 - ? jumpLongTargetBeforeFollowingAddress(backEnd, pc) - : jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc)); - - /* Collect all target triples except for triples whose entry-point is a freed method */ - valid = 1; - if (!(((((usqInt)cPIC)) <= (((usqInt)entryPoint))) - && (((((usqInt)cPIC)) + ((cPIC->blockSize))) >= (((usqInt)entryPoint))))) { - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - assert((((targetMethod->cmType)) == CMMethod) - || (((targetMethod->cmType)) == CMFree)); - if (((targetMethod->cmType)) == CMFree) { - if (i == 1) { - return 1; - } - valid = 0; - } - } - if (valid) { - tags[used] = ((i > 1 - ? (/* begin literal32BeforeFollowingAddress: */ - (followingAddress = pc - 16 /* jumpLongConditionalByteSize */), - literalBeforeFollowingAddress(((AbstractInstruction *) backEnd), followingAddress)) - : 0)); - targets[used] = entryPoint; - methods[used] = (literalBeforeFollowingAddress(backEnd, pc - ((i == 1 - ? jumpLongByteSize(backEnd) - : 24)))); - used += 1; - } - } - if (used == ((cPIC->cPICNumCases))) { - return 0; - } - if (used == 0) { - return 1; - } - ((((CogMethod *) ((((usqInt)cPIC)) + codeToDataDelta)))->cPICNumCases = used); - if (used == 1) { - pc = addressOfEndOfCaseinCPIC(2, cPIC); - /* begin rewriteCPIC:caseJumpTo: */ - rewriteCPICJumpAttarget(backEnd, (((((sqInt)cPIC)) + firstCPICCaseOffset) - (jumpLongByteSize(backEnd))) - 8 /* loadLiteralByteSize */, pc); - return 0; - } - for (i = 1; i < used; i += 1) { - pc = addressOfEndOfCaseinCPIC(i + 1, cPIC); - rewriteCPICCaseAttagobjReftarget(pc, tags[i], methods[i], targets[i]); - } - /* begin rewriteCPIC:caseJumpTo: */ - rewriteCPICJumpAttarget(backEnd, (((((sqInt)cPIC)) + firstCPICCaseOffset) - (jumpLongByteSize(backEnd))) - 8 /* loadLiteralByteSize */, pc - cPICCaseSize); - return 0; -} - - -/* scan the CPIC for target methods that have been freed. */ - - /* Cogit>>#cPICHasFreedTargets: */ -static sqInt NoDbgRegParms -cPICHasFreedTargets(CogMethod *cPIC) -{ - usqInt entryPoint; - sqInt i; - sqInt pc; - CogMethod *targetMethod; - - for (i = 1; i <= ((cPIC->cPICNumCases)); i += 1) { - pc = addressOfEndOfCaseinCPIC(i, cPIC); - - /* Find target from jump. Ignore jumps to the interpret and MNU calls within this PIC */ - entryPoint = (i == 1 - ? jumpLongTargetBeforeFollowingAddress(backEnd, pc) - : jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc)); - if (!(((((usqInt)cPIC)) <= (((usqInt)entryPoint))) - && (((((usqInt)cPIC)) + ((cPIC->blockSize))) >= (((usqInt)entryPoint))))) { - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - assert((((targetMethod->cmType)) == CMMethod) - || (((targetMethod->cmType)) == CMFree)); - if (((targetMethod->cmType)) == CMFree) { - return 1; - } - } - } - return 0; -} - - -/* Whimsey; we want 16rCA5E10 + cPICPrototypeCaseOffset to be somewhere in - the middle of the zone. - */ - - /* Cogit>>#cPICPrototypeCaseOffset */ -static usqInt -cPICPrototypeCaseOffset(void) -{ - return ((methodZoneBase + (youngReferrers())) / 2) - 13262352; -} - - -/* Are any of the jumps from this CPIC to targetMethod? */ - - /* Cogit>>#cPIC:HasTarget: */ -static sqInt NoDbgRegParms -cPICHasTarget(CogMethod *cPIC, CogMethod *targetMethod) -{ - sqInt i; - sqInt pc; - sqInt target; - - target = (((usqInt)targetMethod)) + cmNoCheckEntryOffset; - - /* Since this is a fast test doing simple compares we don't need to care that some - cases have nonsense addresses in there. Just zip on through. */ - /* First jump is unconditional; subsequent ones are conditional */ - pc = (((sqInt)cPIC)) + firstCPICCaseOffset; - if (target == (jumpLongTargetBeforeFollowingAddress(backEnd, pc))) { - return 1; - } - for (i = 2; i <= MaxCPICCases; i += 1) { - pc += cPICCaseSize; - if (target == (jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc))) { - return 1; - } - } - return 0; -} - - -/* Answer an Array of the PIC's selector, followed by class and - targetMethod/doesNotUnderstand: for each entry in the PIC. - */ - - /* Cogit>>#createCPICData: */ -static sqInt NoDbgRegParms -createCPICData(CogMethod *cPIC) -{ - sqInt class; - usqInt entryPoint; - sqInt i; - sqInt pc; - sqInt picData; - sqInt target; - CogMethod *targetMethod; - - assert((((cPIC->methodObject)) == 0) - || (addressCouldBeOop((cPIC->methodObject)))); - picData = instantiateClassindexableSize(classArray(), (((cPIC->cPICNumCases)) * 2) + 1); - if (!picData) { - return picData; - } - storePointerUncheckedofObjectwithValue(0, picData, (cPIC->selector)); - for (i = 1; i <= ((cPIC->cPICNumCases)); i += 1) { - pc = addressOfEndOfCaseinCPIC(i, cPIC); - if (i == 1) { - - /* first case may have been collected and stored here by collectCogConstituentFor:Annotation:Mcpc:Bcpc:Method: */ - class = (cPIC->methodObject); - if (class == 0) { - class = nilObject(); - } - entryPoint = jumpLongTargetBeforeFollowingAddress(backEnd, pc); - } - else { - class = classForInlineCacheTag(literalBeforeFollowingAddress(backEnd, pc - 16 /* jumpLongConditionalByteSize */)); - entryPoint = jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc); - } - if (((((usqInt)cPIC)) <= (((usqInt)entryPoint))) - && (((((usqInt)cPIC)) + ((cPIC->blockSize))) >= (((usqInt)entryPoint)))) { - target = splObj(SelectorDoesNotUnderstand); - } - else { - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - assert(((targetMethod->cmType)) == CMMethod); - target = (targetMethod->methodObject); - } - storePointerUncheckedofObjectwithValue((i * 2) - 1, picData, class); - storePointerUncheckedofObjectwithValue(i * 2, picData, target); - } - beRootIfOld(picData); - (cPIC->methodObject = 0); - return picData; -} - - -/* Division is a little weird on some processors. Defer to the backEnd - to allow it to generate any special code it may need to. */ - - /* Cogit>>#DivR:R:Quo:Rem: */ -static AbstractInstruction * NoDbgRegParms -gDivRRQuoRem(sqInt rDivisor, sqInt rDividend, sqInt rQuotient, sqInt rRemainder) -{ - genDivRRQuoRem(backEnd, rDivisor, rDividend, rQuotient, rRemainder); - return abstractInstructionAt(opcodeIndex - 1); -} - - -/* Return the default number of bytes to allocate for native code at startup. - The actual value can be set via vmParameterAt: and/or a preference in the - ini file. */ - - /* Cogit>>#defaultCogCodeSize */ -sqInt -defaultCogCodeSize(void) -{ - return 0x180000; -} - - -/* Answer the number of bytecodes to skip to get to the first bytecode - past the primitive call and any store of the error code. */ - - /* Cogit>>#deltaToSkipPrimAndErrorStoreIn:header: */ -static sqInt NoDbgRegParms -deltaToSkipPrimAndErrorStoreInheader(sqInt aMethodObj, sqInt aMethodHeader) -{ - return (((primitiveIndexOfMethodheader(aMethodObj, aMethodHeader)) > 0) - && ((longStoreBytecodeForHeader(aMethodHeader)) == (fetchByteofObject((startPCOfMethod(aMethodObj)) + (sizeOfCallPrimitiveBytecode(aMethodHeader)), aMethodObj))) - ? (sizeOfCallPrimitiveBytecode(aMethodHeader)) + (sizeOfLongStoreTempBytecode(aMethodHeader)) - : 0); -} - - /* Cogit>>#endPCOf: */ -static sqInt NoDbgRegParms -endPCOf(sqInt aMethod) -{ - sqInt bsOffset; - sqInt byte; - BytecodeDescriptor *descriptor; - sqInt distance; - sqInt end; - sqInt latestContinuation; - sqInt nExts; - sqInt pc; - sqInt prim; - sqInt targetPC; - - pc = (latestContinuation = startPCOfMethod(aMethod)); - if (((prim = primitiveIndexOf(aMethod))) > 0) { - if (isQuickPrimitiveIndex(prim)) { - return pc - 1; - } - } - /* begin bytecodeSetOffsetFor: */ - bsOffset = -# if MULTIPLEBYTECODESETS - (methodUsesAlternateBytecodeSet(aMethod) - ? 0x100 - : 0) -# else - (assert(!((methodUsesAlternateBytecodeSet(aMethod)))), - 0) -# endif - ; - nExts = 0; - end = numBytesOf(aMethod); - while (pc <= end) { - byte = fetchByteofObject(pc, aMethod); - descriptor = generatorAt(byte + bsOffset); - if (((descriptor->isReturn)) - && (pc >= latestContinuation)) { - end = pc; - } - if ((isBranch(descriptor)) - || ((descriptor->isBlockCreation))) { - distance = ((descriptor->spanFunction))(descriptor, pc, nExts, aMethod); - targetPC = (pc + ((descriptor->numBytes))) + distance; - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - if ((descriptor->isBlockCreation)) { - pc += distance; - } - } - else { - /* latestContinuation = */ latestContinuation; - } - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - pc += (descriptor->numBytes); - } - return end; -} - - -/* This is a static version of ceEnterCogCodePopReceiverReg - for break-pointing when debugging in C. */ -/* This exists only for break-pointing. */ - - /* Cogit>>#enterCogCodePopReceiver */ -void -enterCogCodePopReceiver(void) -{ - realCEEnterCogCodePopReceiverReg(); - error("what??"); -} - - -/* Answer if the entryPoint's tag is expected to be a selector reference, as - opposed to a class tag. - */ - - /* Cogit>>#entryPointTagIsSelector: */ -static sqInt NoDbgRegParms -entryPointTagIsSelector(sqInt entryPoint) -{ - return (entryPoint < methodZoneBase) - || (((entryPoint & entryPointMask) == uncheckedEntryAlignment) - || (((entryPoint & entryPointMask) == checkedEntryAlignment) - && ((((((CogMethod *) (entryPoint - cmEntryOffset)))->cmType)) == CMOpenPIC))); -} - - -/* Use asserts to check if the ClosedPICPrototype is as expected from - compileClosedPICPrototype, and can be updated as required via - rewriteCPICCaseAt:tag:objRef:target:. If all asserts pass, answer - 0, otherwise answer a bit mask identifying all the errors. */ -/* self disassembleFrom: methodZoneBase + (self sizeof: CogMethod) to: - methodZoneBase + closedPICSize - */ - - /* Cogit>>#expectedClosedPICPrototype: */ -static sqInt NoDbgRegParms -expectedClosedPICPrototype(CogMethod *cPIC) -{ - usqInt classTag; - sqInt classTagPC; - usqInt entryPoint; - sqInt errors; - sqInt i; - sqInt methodObjPC; - usqInt object; - sqInt pc; - - errors = 0; - - /* First jump is unconditional; subsequent ones are conditional */ - pc = (((usqInt)cPIC)) + firstCPICCaseOffset; - object = literalBeforeFollowingAddress(backEnd, pc - (jumpLongByteSize(backEnd))); - if (!(asserta(object == (firstPrototypeMethodOop())))) { - errors = 1; - } - entryPoint = jumpLongTargetBeforeFollowingAddress(backEnd, pc); - if (!(asserta(entryPoint == ((cPICPrototypeCaseOffset()) + 13262352)))) { - errors += 2; - } - for (i = 1; i < MaxCPICCases; i += 1) { - - /* verify information in case is as expected. */ - pc += cPICCaseSize; - methodObjPC = (pc - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */; - object = literalBeforeFollowingAddress(backEnd, methodObjPC); - if (!(asserta(object == ((subsequentPrototypeMethodOop()) + i)))) { - errors = errors | 4; - } - classTagPC = pc - 16 /* jumpLongConditionalByteSize */; - /* begin literal32BeforeFollowingAddress: */ - classTag = literalBeforeFollowingAddress(((AbstractInstruction *) backEnd), classTagPC); - if (!(asserta(classTag == (3133021973U + i)))) { - errors = errors | 8; - } - entryPoint = jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc); - if (!(asserta(entryPoint == (((cPICPrototypeCaseOffset()) + 13262352) + (i * 16))))) { - errors = errors | 16; - } - rewriteCPICCaseAttagobjReftarget(pc, classTag ^ 0x5A5A5A5A, object ^ 0xA5A5A5A5U, entryPoint ^ 0x55AA50); - object = literalBeforeFollowingAddress(backEnd, methodObjPC); - if (!(asserta(object == (((subsequentPrototypeMethodOop()) + i) ^ 0xA5A5A5A5U)))) { - errors = errors | 32; - } - /* begin literal32BeforeFollowingAddress: */ - classTag = literalBeforeFollowingAddress(((AbstractInstruction *) backEnd), classTagPC); - if (!(asserta(classTag == ((3133021973U + i) ^ 0x5A5A5A5A)))) { - errors = errors | 64; - } - entryPoint = jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc); - if (!(asserta(entryPoint == ((((cPICPrototypeCaseOffset()) + 13262352) + (i * 16)) ^ 0x55AA50)))) { - errors = errors | 128; - } - rewriteCPICCaseAttagobjReftarget(pc, classTag ^ 0x5A5A5A5A, object ^ 0xA5A5A5A5U, entryPoint ^ 0x55AA50); - } - entryPoint = jumpLongTargetBeforeFollowingAddress(backEnd, (((usqInt)cPIC)) + cPICEndOfCodeOffset); - if (!(asserta(entryPoint == (cPICMissTrampolineFor(0))))) { - errors += 0x100; - } - return errors; -} - - -/* Fill in the block headers now we know the exact layout of the code. */ - - /* Cogit>>#fillInBlockHeadersAt: */ -static sqInt NoDbgRegParms -fillInBlockHeadersAt(sqInt startAddress) -{ - sqInt aCogMethodOrInteger; - CogBlockMethod *blockHeader; - BlockStart *blockStart; - sqInt i; - - if (!(needsFrame - && (blockCount > 0))) { - return null; - } - if (blockNoContextSwitchOffset == null) { - blockNoContextSwitchOffset = ((blockEntryLabel->address)) - ((blockEntryNoContextSwitch->address)); - } - else { - assert(blockNoContextSwitchOffset == (((blockEntryLabel->address)) - ((blockEntryNoContextSwitch->address)))); - } - for (i = 0; i < blockCount; i += 1) { - blockStart = blockStartAt(i); - /* begin writableBlockMethodFor: */ - aCogMethodOrInteger = (((blockStart->fakeHeader))->address); - blockHeader = ((CogBlockMethod *) ((((usqInt)aCogMethodOrInteger)) + codeToDataDelta)); - (blockHeader->homeOffset = ((((blockStart->fakeHeader))->address)) - startAddress); - (blockHeader->startpc = (blockStart->startpc)); - (blockHeader->cmType = CMBlock); - (blockHeader->cmNumArgs = (blockStart->numArgs)); - (blockHeader->cbUsesInstVars = (blockStart->hasInstVarRef)); - (blockHeader->stackCheckOffset = (((blockStart->stackCheckLabel)) == null - ? 0 - : ((((blockStart->stackCheckLabel))->address)) - ((((blockStart->fakeHeader))->address)))); - } - return 0; -} - - -/* Fill in the header for theCogMehtod method. This may be located at the - writable mapping. */ - - /* Cogit>>#fillInMethodHeader:size:selector: */ -static void NoDbgRegParms -fillInMethodHeadersizeselector(CogMethod *method, sqInt size, sqInt selector) -{ - sqInt actualMethodLocation; - CogMethod *originalMethod; - sqInt rawHeader; - - actualMethodLocation = (((usqInt)method)) - codeToDataDelta; - (method->cmType = CMMethod); - (method->objectHeader = nullHeaderForMachineCodeMethod()); - (method->blockSize = size); - (method->methodObject = methodObj); - - /* If the method has already been cogged (e.g. Newspeak accessors) then - leave the original method attached to its cog method, but get the right header. */ - rawHeader = rawHeaderOf(methodObj); - if (isCogMethodReference(rawHeader)) { - originalMethod = ((CogMethod *) rawHeader); - assert(((originalMethod->blockSize)) == size); - assert(methodHeader == ((originalMethod->methodHeader))); - } - else { - rawHeaderOfput(methodObj, actualMethodLocation); - } - (method->methodHeader = methodHeader); - (method->selector = selector); - (method->cmNumArgs = argumentCountOfMethodHeader(methodHeader)); - (method->cmHasMovableLiteral = hasMovableLiteral); - if ((method->cmRefersToYoung = hasYoungReferent)) { - addToYoungReferrers(method); - } - (method->cmUsageCount = initialMethodUsageCount()); - /* begin cpicHasMNUCase: */ - ((((CogBlockMethod *) method))->cpicHasMNUCaseOrCMIsFullBlock) = 0; - (method->cmUsesPenultimateLit = maxLitIndex >= ((literalCountOfMethodHeader(methodHeader)) - 2)); - (method->blockEntryOffset = (blockEntryLabel != null - ? ((blockEntryLabel->address)) - actualMethodLocation - : 0)); - if (needsFrame) { - if (!((((stackCheckLabel->address)) - actualMethodLocation) <= MaxStackCheckOffset)) { - error("too much code for stack check offset"); - } - } - (method->stackCheckOffset = (needsFrame - ? ((stackCheckLabel->address)) - actualMethodLocation - : 0)); - assert((callTargetFromReturnAddress(backEnd, actualMethodLocation + missOffset)) == (methodAbortTrampolineFor((method->cmNumArgs)))); - assert(size == (roundUpLength(size))); - /* begin assertValidDualZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, actualMethodLocation + cmNoCheckEntryOffset, codeToDataDelta); -# endif - /* begin maybeEnableSingleStep */ -} - - /* Cogit>>#findBackwardBranch:IsBackwardBranch:Mcpc:Bcpc:MatchingBcpc: */ -static sqInt NoDbgRegParms -findBackwardBranchIsBackwardBranchMcpcBcpcMatchingBcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *targetBcpc) -{ - return ((((isBackwardBranchAndAnnotation & 1) != 0)) - && ((((sqInt)targetBcpc)) == bcpc) - ? ((sqInt)mcpc) - : 0); -} - - /* Cogit>>#findBlockMethodWithEntry:startBcpc: */ -static usqInt NoDbgRegParms -findBlockMethodWithEntrystartBcpc(sqInt blockEntryMcpc, sqInt startBcpc) -{ - CogBlockMethod *cogBlockMethod; - - cogBlockMethod = ((CogBlockMethod *) (blockEntryMcpc - (sizeof(CogBlockMethod)))); - if (((cogBlockMethod->startpc)) == startBcpc) { - return ((usqInt)cogBlockMethod); - } - return 0; -} - - /* Cogit>>#findMapLocationForMcpc:inMethod: */ -static usqInt NoDbgRegParms -findMapLocationForMcpcinMethod(usqInt targetMcpc, CogMethod *cogMethod) -{ - sqInt annotation; - usqInt map; - sqInt mapByte; - sqInt mcpc; - - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - if (mcpc == targetMcpc) { - return map; - } - while (((mapByte = byteAt(map))) != MapEnd) { - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - if (annotation != IsAnnotationExtension) { - mcpc += 4 /* codeGranularity */ * ((annotation == IsDisplacementX2N - ? ((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift)) - : mapByte & DisplacementMask)); - } - if (mcpc >= targetMcpc) { - assert(mcpc == targetMcpc); - if (annotation == IsDisplacementX2N) { - map -= 1; - mapByte = byteAt(map); - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - assert(annotation > IsAnnotationExtension); - } - return map; - } - map -= 1; - } - return 0; -} - - -/* Find the CMMethod or CMBlock that has zero-relative startbcpc as its first - bytecode pc. - As this is for cannot resume processing and/or conversion to machine-code - on backward - branch, it doesn't have to be fast. Enumerate block returns and map to - bytecode pcs. */ - - /* Cogit>>#findMethodForStartBcpc:inHomeMethod: */ -CogBlockMethod * -findMethodForStartBcpcinHomeMethod(sqInt startbcpc, CogMethod *cogMethod) -{ - assert(((cogMethod->cmType)) == CMMethod); - if (startbcpc == (startPCOfMethodHeader((cogMethod->methodHeader)))) { - return ((CogBlockMethod *) cogMethod); - } - assert(((cogMethod->blockEntryOffset)) != 0); - return ((CogBlockMethod *) (blockDispatchTargetsForperformarg(cogMethod, findBlockMethodWithEntrystartBcpc, startbcpc))); -} - - -/* Machine code addresses map to the following bytecode for all bytecodes - except backward branches, where they map to the backward branch itself. - This is so that loops continue, rather than terminate prematurely. */ - - /* Cogit>>#find:IsBackwardBranch:Mcpc:Bcpc:MatchingMcpc: */ -static sqInt NoDbgRegParms -findIsBackwardBranchMcpcBcpcMatchingMcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *targetMcpc) -{ - return (targetMcpc == mcpc - ? ((descriptor == null) - || (((isBackwardBranchAndAnnotation & 1) != 0)) - ? bcpc - : bcpc + ((descriptor->numBytes))) - : 0); -} - - /* Cogit>>#firstMappedPCFor: */ -static sqInt NoDbgRegParms -firstMappedPCFor(CogMethod *cogMethod) -{ - return (((usqInt)cogMethod)) + cmNoCheckEntryOffset; -} - - -/* Answer a fake value for the first method oop in the PIC prototype. - Since we use MoveUniqueCw:R: it must not be confused with a - method-relative address. */ - - /* Cogit>>#firstPrototypeMethodOop */ -static sqInt -firstPrototypeMethodOop(void) -{ - return (addressIsInCurrentCompilation(99282957) - ? 212332557 - : 99282957); -} - - /* Cogit>>#fixupAt: */ -static BytecodeFixup * NoDbgRegParms -fixupAt(sqInt fixupPC) -{ - return fixupAtIndex(fixupPC - initialPC); -} - - /* Cogit>>#freeCogMethod: */ -void -freeCogMethod(CogMethod *cogMethod) -{ - freeMethod(cogMethod); - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - -/* Call ceSendMustBeBooleanTo: via the relevant trampoline. */ - - /* Cogit>>#genCallMustBeBooleanFor: */ -static AbstractInstruction * NoDbgRegParms -genCallMustBeBooleanFor(sqInt boolean) -{ - AbstractInstruction *abstractInstruction; - sqInt callTarget; - - /* begin CallRT: */ - callTarget = (boolean == (falseObject()) - ? ceSendMustBeBooleanAddFalseTrampoline - : ceSendMustBeBooleanAddTrueTrampoline); - /* begin annotateCall: */ - abstractInstruction = genoperand(Call, callTarget); - (abstractInstruction->annotation = IsRelativeCall); - return abstractInstruction; -} - - /* Cogit>>#genConditionalBranch:operand: */ -static AbstractInstruction * NoDbgRegParms -genConditionalBranchoperand(sqInt opcode, sqInt operandOne) -{ - return noteFollowingConditionalBranch(previousInstruction(), genoperand(opcode, operandOne)); -} - - -/* An enilopmart (the reverse of a trampoline) is a piece of code that makes - the system-call-like transition from the C runtime into generated machine - code. The desired arguments and entry-point are pushed on a stackPage's - stack. The enilopmart pops off the values to be loaded into registers and - then executes a return instruction to pop off the entry-point and jump to - it. - BEFORE AFTER (stacks grow down) - whatever stackPointer -> whatever - target address => reg1 = reg1val, etc - reg1val pc = target address - reg2val - stackPointer -> reg3val */ - - /* Cogit>>#genEnilopmartFor:and:and:forCall:called: */ -static void (*genEnilopmartForandandforCallcalled(sqInt regArg1, sqInt regArg2OrNone, sqInt regArg3OrNone, sqInt forCall, char *trampolineName))(void) - -{ - AbstractInstruction *anInstruction; - sqInt endAddress; - usqInt enilopmart; - sqInt quickConstant; - sqInt size; - - zeroOpcodeIndex(); - /* begin MoveCq:R: */ - quickConstant = varBaseAddress(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - genLoadStackPointers(backEnd); - if (regArg3OrNone != NoReg) { - genoperand(PopR, regArg3OrNone); - } - if (regArg2OrNone != NoReg) { - genoperand(PopR, regArg2OrNone); - } - genoperand(PopR, regArg1); - genEnilopmartReturn(forCall); - computeMaximumSizes(); - size = generateInstructionsAt(methodZoneBase); - endAddress = outputInstructionsAt(methodZoneBase); - assert((methodZoneBase + size) == endAddress); - enilopmart = methodZoneBase; - methodZoneBase = alignUptoRoutineBoundary(endAddress); - stopsFromto(backEnd, endAddress, methodZoneBase - 1); - recordGeneratedRunTimeaddress(trampolineName, enilopmart); - return ((void (*)(void)) enilopmart); -} - - -/* An enilopmart (the reverse of a trampoline) is a piece of code that makes - the system-call-like transition from the C runtime into generated machine - code. At the point the enilopmart enters machine code via a return - instruction, any argument registers have been loaded with their values and - the stack, if - for call, looks like - ret pc - stackPointer -> target address - - and if not for call, looks like - whatever - stackPointer -> target address - - If forCall and running on a CISC, ret pc must be left on the stack. If - forCall and - running on a RISC, ret pc must be popped into LinkReg. In either case, - target address must be removed from the stack and jumped/returned to. */ - - /* Cogit>>#genEnilopmartReturn: */ -static void NoDbgRegParms -genEnilopmartReturn(sqInt forCall) -{ - if (forCall) { - genoperand(PopR, RISCTempReg); - genoperand(PopR, LinkReg); - genoperand(JumpR, RISCTempReg); - } - else { - genoperand(PopR, RISCTempReg); - genoperand(JumpR, RISCTempReg); - } -} - - -/* Generate the routine that writes the current values of the C frame and - stack pointers into - variables. These are used to establish the C stack in trampolines back - into the C run-time. - This routine assumes the system's frame pointer is the same as that used - in generated code. */ - - /* Cogit>>#generateCaptureCStackPointers: */ -static void NoDbgRegParms NeverInline -generateCaptureCStackPointers(sqInt captureFramePointer) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - sqInt callerSavedReg; - sqInt fixupSize; - sqInt offset; - sqInt opcodeSize; - sqInt pushedVarBaseReg; - sqInt quickConstant; - usqInt startAddress; - - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 32; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - - /* Must happen first; value may be used in accessing any of the following addresses */ - startAddress = methodZoneBase; - callerSavedReg = 0; - pushedVarBaseReg = 0; - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { - - /* VarBaseReg is not caller-saved; must save and restore it, either by using an available caller-saved reg or push/pop. */ - - /* TempReg used below */ - callerSavedReg = availableRegisterOrNoneIn(((ABICallerSavedRegisterMask | (1U << TempReg)) - (1U << TempReg))); - if (callerSavedReg == NoReg) { - gNativePushR(VarBaseReg); - pushedVarBaseReg = 1; - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, VarBaseReg, callerSavedReg); - } - } - /* begin MoveCq:R: */ - quickConstant = varBaseAddress(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - if (captureFramePointer) { - /* begin checkLiteral:forInstruction: */ - cFramePointerAddress(); - anInstruction1 = genoperandoperand(MoveRAw, FPReg, cFramePointerAddress()); - } - if (pushedVarBaseReg) { - /* begin LoadEffectiveAddressMw:r:R: */ - offset = (pushedVarBaseReg - ? 0 /* leafCallStackPointerDelta */ + BytesPerWord - : 0 /* leafCallStackPointerDelta */); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(LoadEffectiveAddressMwrR, offset, NativeSPReg, TempReg); - /* begin checkLiteral:forInstruction: */ - cStackPointerAddress(); - anInstruction3 = genoperandoperand(MoveRAw, TempReg, cStackPointerAddress()); - } - else { - /* begin checkLiteral:forInstruction: */ - cStackPointerAddress(); - anInstruction4 = genoperandoperand(MoveRAw, NativeSPReg, cStackPointerAddress()); - } - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { - if (pushedVarBaseReg) { - gNativePopR(VarBaseReg); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, callerSavedReg, VarBaseReg); - } - } - gNativeRetN(0); - outputInstructionsForGeneratedRuntimeAt(startAddress); - flushICacheFromto(backEnd, ((usqInt)startAddress), ((usqInt)methodZoneBase)); - recordGeneratedRunTimeaddress("ceCaptureCStackPointers", startAddress); - ceCaptureCStackPointers = ((void (*)(void)) startAddress); -} - - -/* Generate the prototype ClosedPIC to determine how much space a full closed - PIC takes. - When we first allocate a closed PIC it only has one or two cases and we - want to grow it. - So we have to determine how big a full one is before hand. */ -/* stack allocate the various collections so that they - are effectively garbage collected on return. */ - - /* Cogit>>#generateClosedPICPrototype */ -static void -generateClosedPICPrototype(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - CogMethod * cPIC; - AbstractInstruction * cPICEndOfCodeLabel; - sqInt endAddress; - AbstractInstruction * endCPICCase1; - sqInt fixupSize; - sqInt h; - AbstractInstruction *jumpNext; - sqInt jumpTarget; - sqInt jumpTarget1; - sqInt jumpTarget2; - sqInt numArgs; - sqInt opcode; - sqInt opcodeSize; - sqInt wordConstant; - sqInt wordConstant1; - - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = MaxCPICCases * 9; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - (methodLabel->address = methodZoneBase); - (methodLabel->dependent = null); - /* begin compileClosedPICPrototype */ - compilePICAbort((numArgs = 0)); - - /* At the end of the entry code we need to jump to the first case code, which is actually the last chunk. - On each entension we must update this jump to move back one case. */ - jumpNext = compileCPICEntry(); - /* begin MoveUniqueCw:R: */ - wordConstant1 = firstPrototypeMethodOop(); - /* begin uniqueLiteral:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCwR, wordConstant1, SendNumArgsReg); - /* begin JumpLong: */ - jumpTarget1 = (((methodZoneBase + (youngReferrers())) / 2) - 13262352) + 13262352; - genoperand(JumpLong, jumpTarget1); - endCPICCase0 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - for (h = 1; h < MaxCPICCases; h += 1) { - if (h == (MaxCPICCases - 1)) { - jmpTarget(jumpNext, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - /* begin MoveUniqueCw:R: */ - wordConstant = (subsequentPrototypeMethodOop()) + h; - /* begin uniqueLiteral:forInstruction: */ - anInstruction = genoperandoperand(MoveCwR, wordConstant, SendNumArgsReg); - /* begin gen:literal32:operand: */ - opcode = CmpCwR; - /* begin checkLiteral32:forInstruction: */ - anInstruction1 = genoperandoperand(opcode, 3133021973U + h, TempReg); - /* begin JumpLongZero: */ - jumpTarget = ((((methodZoneBase + (youngReferrers())) / 2) - 13262352) + 13262352) + (h * 16); - genConditionalBranchoperand(JumpLongZero, ((sqInt)jumpTarget)); - if (h == 1) { - endCPICCase1 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - } - /* begin checkLiteral:forInstruction: */ - (methodLabel->address); - anInstruction3 = genoperandoperand(MoveCwR, (methodLabel->address), ClassReg); - /* begin JumpLong: */ - jumpTarget2 = cPICMissTrampolineFor(numArgs); - genoperand(JumpLong, jumpTarget2); - cPICEndOfCodeLabel = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - computeMaximumSizes(); - cPIC = ((CogMethod *) methodZoneBase); - closedPICSize = (sizeof(CogMethod)) + (generateInstructionsAt(methodZoneBase + (sizeof(CogMethod)))); - endAddress = outputInstructionsAt(methodZoneBase + (sizeof(CogMethod))); - assert((methodZoneBase + closedPICSize) == endAddress); - firstCPICCaseOffset = ((endCPICCase0->address)) - methodZoneBase; - cPICEndOfCodeOffset = ((cPICEndOfCodeLabel->address)) - methodZoneBase; - cPICCaseSize = ((endCPICCase1->address)) - ((endCPICCase0->address)); - cPICEndSize = closedPICSize - (((MaxCPICCases - 1) * cPICCaseSize) + firstCPICCaseOffset); - closedPICSize = roundUpToMethodAlignment(backEnd(), closedPICSize); - assert(((picInterpretAbort->address)) == (((methodLabel->address)) + (picInterpretAbortOffset()))); - assert((expectedClosedPICPrototype(cPIC)) == 0); - storeLiteralbeforeFollowingAddress(backEnd, 0, ((endCPICCase0->address)) - (jumpLongByteSize(backEnd))); - methodZoneBase = alignUptoRoutineBoundary(endAddress); - cPICPrototype = cPIC; -} - - -/* We handle jump sizing simply. First we make a pass that asks each - instruction to compute its maximum size. Then we make a pass that - sizes jumps based on the maxmimum sizes. Then we make a pass - that fixes up jumps. When fixing up a jump the jump is not allowed to - choose a smaller offset but must stick to the size set in the second pass. */ - - /* Cogit>>#generateCogMethod: */ -static CogMethod * NoDbgRegParms -generateCogMethod(sqInt selector) -{ - sqInt codeSize; - usqIntptr_t headerSize; - sqInt mapSize; - sqInt result; - usqInt startAddress; - sqInt totalSize; - - headerSize = sizeof(CogMethod); - (methodLabel->address = freeStart()); - computeMaximumSizes(); - concretizeAt(methodLabel, freeStart()); - codeSize = generateInstructionsAt(((methodLabel->address)) + headerSize); - mapSize = generateMapAtstart(null, ((methodLabel->address)) + cmNoCheckEntryOffset); - totalSize = roundUpToMethodAlignment(backEnd(), (headerSize + codeSize) + mapSize); - if (totalSize > MaxMethodSize) { - return ((CogMethod *) MethodTooBig); - } - startAddress = allocate(totalSize); - if (startAddress == 0) { - return ((CogMethod *) InsufficientCodeSpace); - } - assert((startAddress + cmEntryOffset) == ((entry->address))); - assert((startAddress + cmNoCheckEntryOffset) == ((noCheckEntry->address))); - result = outputInstructionsAt(startAddress + headerSize); - assert(((startAddress + headerSize) + codeSize) == result); - padIfPossibleWithStopsFromto(backEnd, result, ((startAddress + totalSize) - mapSize) - 1); - generateMapAtstart((startAddress + totalSize) - 1, startAddress + cmNoCheckEntryOffset); - fillInBlockHeadersAt(startAddress); - fillInMethodHeadersizeselector(((CogMethod *) ((((usqInt)startAddress)) + codeToDataDelta)), totalSize, selector); - flushICacheFromto(backEnd, startAddress, startAddress + totalSize); - return ((CogMethod *) startAddress); -} - - -/* Generate the method map at addressrNull (or compute it if addressOrNull is - null). Answer the length of the map in byes. Each entry in the map is in - two parts. In the - least signficant bits are a displacement of how far from the start or - previous entry, - unless it is an IsAnnotationExtension byte, in which case those bits are - the extension. - In the most signficant bits are the type of annotation at the point - reached. A null - byte ends the map. */ - - /* Cogit>>#generateMapAt:start: */ -static sqInt NoDbgRegParms -generateMapAtstart(usqInt addressOrNull, usqInt startAddress) -{ - unsigned char annotation; - sqInt delta; - sqInt i; - AbstractInstruction *instruction; - sqInt length; - usqInt location; - sqInt mapEntry; - sqInt maxDelta; - usqInt mcpc; - - length = 0; - location = startAddress; - for (i = 0; i < opcodeIndex; i += 1) { - instruction = abstractInstructionAt(i); - annotation = (instruction->annotation); - if (!(annotation == null)) { - /* begin mapEntryAddress */ - mcpc = ((instruction->address)) + ((instruction->machineCodeSize)); - while (((delta = (mcpc - location) / 4 /* codeGranularity */)) > DisplacementMask) { - maxDelta = (((((delta < MaxX2NDisplacement) ? delta : MaxX2NDisplacement)) | DisplacementMask) - DisplacementMask); - assert((((usqInt)(maxDelta)) >> AnnotationShift) <= DisplacementMask); - if (!(addressOrNull == null)) { - /* begin addToMap:instruction:byte:at:for: */ - codeByteAtput(addressOrNull - length, (((usqInt)(maxDelta)) >> AnnotationShift) + DisplacementX2N); - } - location += maxDelta * 4 /* codeGranularity */; - length += 1; - } - if (!(addressOrNull == null)) { - mapEntry = delta + (((sqInt)((usqInt)((((annotation < IsSendCall) ? annotation : IsSendCall))) << AnnotationShift))); - /* begin addToMap:instruction:byte:at:for: */ - codeByteAtput(addressOrNull - length, mapEntry); - } - location += delta * 4 /* codeGranularity */; - length += 1; - if (annotation > IsSendCall) { - - /* Add the necessary IsAnnotationExtension */ - if (!(addressOrNull == null)) { - mapEntry = (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift))) + (annotation - IsSendCall); - /* begin addToMap:instruction:byte:at:for: */ - codeByteAtput(addressOrNull - length, mapEntry); - } - length += 1; - } - } - } - if (!(addressOrNull == null)) { - /* begin addToMap:instruction:byte:at:for: */ - codeByteAtput(addressOrNull - length, MapEnd); - } - return length + 1; -} - - -/* Generate the prototype OpenPIC to determine how much space an open PIC - takes. - */ -/* stack allocate the various collections so that they - are effectively garbage collected on return. */ - - /* Cogit>>#generateOpenPICPrototype */ -static void -generateOpenPICPrototype(void) -{ - sqInt codeSize; - sqInt fixupSize; - sqInt mapSize; - sqInt opcodeSize; - - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 100; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - (methodLabel->address = methodZoneBase); - (methodLabel->dependent = null); - compileOpenPICnumArgs(specialSelector(0), 1 /* numRegArgs */); - computeMaximumSizes(); - concretizeAt(methodLabel, methodZoneBase); - codeSize = generateInstructionsAt(methodZoneBase + (sizeof(CogMethod))); - mapSize = generateMapAtstart(null, methodZoneBase + cmNoCheckEntryOffset); - openPICSize = (roundUpLength((sizeof(CogMethod)) + codeSize)) + (roundUpToMethodAlignment(backEnd(), mapSize)); -} - - -/* Generate the run-time entries at the base of the native code zone and - update the base. - */ - - /* Cogit>>#generateRunTimeTrampolines */ -static void -generateRunTimeTrampolines(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction2; - - ceSendMustBeBooleanAddFalseTrampoline = genMustBeBooleanTrampolineForcalled(falseObject(), "ceSendMustBeBooleanAddFalseTrampoline"); - ceSendMustBeBooleanAddTrueTrampoline = genMustBeBooleanTrampolineForcalled(trueObject(), "ceSendMustBeBooleanAddTrueTrampoline"); - /* begin genNonLocalReturnTrampoline */ - zeroOpcodeIndex(); - /* begin checkLiteral:forInstruction: */ - instructionPointerAddress(); - anInstruction2 = genoperandoperand(MoveRAw, LinkReg, instructionPointerAddress()); - ceNonLocalReturnTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNonLocalReturn, "ceNonLocalReturnTrampoline", 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 0, NoReg, 1); - /* begin genCheckForInterruptsTrampoline */ - zeroOpcodeIndex(); - /* begin checkLiteral:forInstruction: */ - instructionPointerAddress(); - anInstruction = genoperandoperand(MoveRAw, LinkReg, instructionPointerAddress()); - ceCheckForInterruptTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceCheckForInterrupt, "ceCheckForInterruptTrampoline", 0, null, null, null, null, 0 /* emptyRegisterMask */, 0, NoReg, 1); - ceFetchContextInstVarTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceContextinstVar, "ceFetchContextInstVarTrampoline", 2, ReceiverResultReg, SendNumArgsReg, null, null, 0 /* emptyRegisterMask */, 1, SendNumArgsReg, 0); - ceStoreContextInstVarTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceContextinstVarvalue, "ceStoreContextInstVarTrampoline", 3, ReceiverResultReg, SendNumArgsReg, ClassReg, null, 0 /* emptyRegisterMask */, 1, ReceiverResultReg, 0); - - /* ceInvokeInterpreter is an optimization and a work-around. Historically we used setjmp/longjmp to reenter the - interpreter at the current C stack base. The C stack base is set at start-up and on each callback enter and - callback return. The interpreter must be invoked whenever a non-machine-code method must be run. That might - be when invoking an interpreter method from one of the send linking routines (ceSend:...), or on continuing from - an evaluation primitive such as primitiveExecuteMethod. The problem here is that such primitives could have - been invoked by the interpreter or by machine code. So some form of non-local jump is required. But at least as - early as MSVC Community 2017, the Microshaft longjmp performs stack unwinding which gets hoplessly confused - (bless its little heart) by any stack switch between machine code and C stack, and raises a spurious - Stack cookie instrumentation code detected a stack-based buffer overrun - error from the bowels of gs_report.c _GSHandlerCheck. - Since the CoInterpreter maintains the base of the C stack in CFramePointer & CStackPointer, it is straight-forward - for us to simply call interpret after doing the switch to the C stack, avoiding the stack unwind issue altogether. */ - ceCannotResumeTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceCannotResume, "ceCannotResumeTrampoline", 0, null, null, null, null, 0 /* emptyRegisterMask */, 1, NoReg, 0); - - /* These two are unusual; they are reached by return instructions. */ - ceInvokeInterpret = genInvokeInterpretTrampoline(); - ceReturnToInterpreterTrampoline = genReturnToInterpreterTrampoline(); - ceBaseFrameReturnTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceBaseFrameReturn, "ceBaseFrameReturnTrampoline", 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 0, NoReg, 0); - } - - -/* Generate a routine ceCaptureCStackPointers that will capture the C stack - pointer, and, if it is in use, the C frame pointer. These are used in - trampolines to call - run-time routines in the interpreter from machine-code. */ - - /* Cogit>>#generateStackPointerCapture */ -static void -generateStackPointerCapture(void) -{ - usqInt oldMethodZoneBase; - sqInt oldTrampolineTableIndex; - - - /* For the benefit of the following assert, assume the minimum at first. */ - cFramePointerInUse = 0; - assertCStackWellAligned(); - oldMethodZoneBase = methodZoneBase; - oldTrampolineTableIndex = trampolineTableIndex; - generateCaptureCStackPointers(1); - ceCaptureCStackPointers(); - if (!((cFramePointerInUse = checkIfCFramePointerInUse()))) { - methodZoneBase = oldMethodZoneBase; - trampolineTableIndex = oldTrampolineTableIndex; - generateCaptureCStackPointers(0); - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - assertCStackWellAligned(); -} - - -/* Generate the run-time entries and exits at the base of the native code - zone and update the base. - Read the class-side method trampolines for documentation on the various - trampolines - */ - - /* Cogit>>#generateTrampolines */ -static void -generateTrampolines(void) -{ - sqInt fixupSize; - usqInt methodZoneStart; - sqInt opcodeSize; - - methodZoneStart = methodZoneBase; - (methodLabel->address = methodZoneStart); - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 80; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - setHasYoungReferent(0); - generateSendTrampolines(); - generateMissAbortTrampolines(); - generateObjectRepresentationTrampolines(); - generateRunTimeTrampolines(); - generateEnilopmarts(); - generateTracingTrampolines(); - recordGeneratedRunTimeaddress("methodZoneBase", methodZoneBase); -} - - /* Cogit>>#generatorForPC: */ -static BytecodeDescriptor * NoDbgRegParms -generatorForPC(sqInt pc) -{ - return generatorAt(bytecodeSetOffset + (fetchByteofObject(pc, methodObj))); -} - - -/* Generate a pair of routines that answer the frame pointer, and the stack - pointer immediately - after a leaf call, used for checking stack pointer alignment, frame - pointer usage, etc. N.B. - these are exported to the CoInterpreter et al via Cogit - class>>mustBeGlobal:. - */ - - /* Cogit>>#genGetLeafCallStackPointers */ -static void -genGetLeafCallStackPointers(void) -{ - sqInt fixupSize; - sqInt opcodeSize; - usqInt startAddress; - - /* begin allocateOpcodes:bytecodes: */ - numAbstractOpcodes = 4; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - startAddress = methodZoneBase; - genoperandoperand(MoveRR, FPReg, ABIResultReg); - genoperand(RetN, 0); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress("ceGetFP", startAddress); - ceGetFP = ((usqIntptr_t (*)(void)) startAddress); - startAddress = methodZoneBase; - zeroOpcodeIndex(); - genoperandoperand(MoveRR, NativeSPReg, ABIResultReg); - genoperand(RetN, 0); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress("ceGetSP", startAddress); - ceGetSP = ((usqIntptr_t (*)(void)) startAddress); -} - - -/* Generate the abort for a PIC. This abort performs either a call of - ceInterpretMethodFromPIC:receiver: to handle invoking an uncogged target - or a call of ceMNUFromPICMNUMethod:receiver: to handle an MNU dispatch - in a closed PIC. It distinguishes the two by testing ClassReg. If the - register is zero then this is an MNU. - - This poses a problem in 32-bit Spur, where zero is the cache tag for - immediate characters (tag pattern 2r10) because SmallIntegers have tag - patterns 2r11 - and 2r01, so anding with 1 reduces these to 0 & 1. We solve the ambiguity - by patching send sites with a 0 cache tag to open PICs instead of closed - PICs. */ - - /* Cogit>>#genInnerPICAbortTrampoline: */ -static usqInt NoDbgRegParms -genInnerPICAbortTrampoline(char *name) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *jumpMNUCase; - - /* begin CmpCq:R: */ - anInstruction = genoperandoperand(CmpCqR, 0 /* picAbortDiscriminatorValue */, ClassReg); - jumpMNUCase = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(ceInterpretMethodFromPICreceiver, 2, SendNumArgsReg, ReceiverResultReg, null, null, 0 /* emptyRegisterMask */, 0, NoReg); - jmpTarget(jumpMNUCase, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceMNUFromPICMNUMethodreceiver, name, 2, SendNumArgsReg, ReceiverResultReg, null, null, 0 /* emptyRegisterMask */, 0, NoReg, 1); -} - - -/* Switch to the C stack (do *not* save the Smalltalk stack pointers; - this is the caller's responsibility), and invoke interpret PDQ. */ - - /* Cogit>>#genInvokeInterpretTrampoline */ -static void (*genInvokeInterpretTrampoline(void))(void) - -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - sqInt quickConstant; - usqInt startAddress; - - startAddress = methodZoneBase; - zeroOpcodeIndex(); - /* begin MoveCq:R: */ - quickConstant = varBaseAddress(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - if (cFramePointerInUse) { - genLoadCStackPointers(backEnd); - } - else { - genLoadCStackPointer(backEnd); - } - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l16; - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction5 = genoperandoperand(MoveCqR, -2 - null, A0); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A0); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction11 = genoperandoperand(MoveCqR, -2 - null, A1); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A1); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction21 = genoperandoperand(MoveCqR, -2 - null, A2); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A2); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction31 = genoperandoperand(MoveCqR, -2 - null, A3); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A3); - } - l16: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin checkLiteral:forInstruction: */ - cReturnAddressAddress(); - anInstruction1 = genoperandoperand(MoveAwR, cReturnAddressAddress(), LinkReg); - /* begin checkLiteral:forInstruction: */ - ((sqInt)(((usqInt)interpret))); - anInstruction4 = genoperand(JumpFull, ((sqInt)(((usqInt)interpret)))); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress("ceInvokeInterpret", startAddress); - return ((void (*)(void)) startAddress); -} - - -/* The in-line cache for a send is implemented as a constant load into - ClassReg. We always use a 32-bit load, even in 64-bits. - - In the initial (unlinked) state the in-line cache is notionally loaded - with the selector. - But since in 64-bits an arbitrary selector oop won't fit in a 32-bit - constant load, we - instead load the cache with the selector's index, either into the literal - frame of the - current method, or into the special selector array. Negative values are - 1-relative indices into the special selector array. - - When a send is linked, the load of the selector, or selector index, is - overwritten with a - load of the receiver's class, or class tag. Hence, the 64-bit VM is - currently constrained - to use class indices as cache tags. If out-of-line literals are used, - distinct caches /must - not/ share acche locations, for if they do, send cacheing will be confused - by the sharing. - Hence we use the MoveUniqueC32:R: instruction that will not share literal - locations. */ - - /* Cogit>>#genLoadInlineCacheWithSelector: */ -static void NoDbgRegParms -genLoadInlineCacheWithSelector(sqInt selectorIndex) -{ - AbstractInstruction *anInstruction; - sqInt cacheValue; - sqInt opcode; - sqInt selector; - - assert((selectorIndex < 0 - ? (((-selectorIndex) >= 1) && ((-selectorIndex) <= (numSpecialSelectors()))) - : ((selectorIndex >= 0) && (selectorIndex <= ((literalCountOf(methodObj)) - 1))))); - selector = (selectorIndex < 0 - ? specialSelector(-1 - selectorIndex) - : getLiteral(selectorIndex)); - assert(addressCouldBeOop(selector)); - if (isNonImmediate(selector)) { - setHasMovableLiteral(1); - } - if (isYoung(selector)) { - setHasYoungReferent(1); - } - cacheValue = selector; - /* begin gen:uniqueLiteral32:operand: */ - opcode = MoveCwR; - /* begin uniqueLiteral32:forInstruction: */ - anInstruction = genoperandoperand(opcode, cacheValue, ClassReg); -} - - /* Cogit>>#genReturnToInterpreterTrampoline */ -static usqInt -genReturnToInterpreterTrampoline(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - usqInt startAddress; - - startAddress = methodZoneBase; - zeroOpcodeIndex(); - genoperand(PushR, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperandoperand(MoveMwrR, FoxIFSavedIP, FPReg, TempReg); - /* begin checkLiteral:forInstruction: */ - instructionPointerAddress(); - anInstruction5 = genoperandoperand(MoveRAw, TempReg, instructionPointerAddress()); - genSmalltalkToCStackSwitch(0); - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l17; - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction6 = genoperandoperand(MoveCqR, -2 - null, A0); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A0); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction11 = genoperandoperand(MoveCqR, -2 - null, A1); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A1); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction21 = genoperandoperand(MoveCqR, -2 - null, A2); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A2); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction31 = genoperandoperand(MoveCqR, -2 - null, A3); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A3); - } - l17: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin checkLiteral:forInstruction: */ - cReturnAddressAddress(); - anInstruction = genoperandoperand(MoveAwR, cReturnAddressAddress(), LinkReg); - /* begin checkLiteral:forInstruction: */ - ((sqInt)(((usqInt)interpret))); - anInstruction3 = genoperand(JumpFull, ((sqInt)(((usqInt)interpret)))); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress("ceReturnToInterpreterTrampoline", startAddress); - return startAddress; -} - - -/* If the client requires, then on an ARM-like RISC processor, the return - address needs to - be pushed to the stack so that the interpreter sees the same stack layout - as on CISC. - */ - - /* Cogit>>#genSmalltalkToCStackSwitch: */ -static sqInt NoDbgRegParms -genSmalltalkToCStackSwitch(sqInt pushLinkReg) -{ - if (pushLinkReg) { - genoperand(PushR, LinkReg); - } - genSaveStackPointers(backEnd); - if (cFramePointerInUse) { - genLoadCStackPointers(backEnd); - } - else { - genLoadCStackPointer(backEnd); - } - return 0; -} - - -/* Generate a trampoline with up to four arguments. Generate either a call or - a jump to aRoutineOrNil - as requested by callJumpBar. If generating a call and resultRegOrNone is - not NoReg pass the C result - back in resultRegOrNone. - Hack: a negative value indicates an abstract register, a non-negative - value indicates a constant. */ - - /* Cogit>>#genTrampolineFor:called:numArgs:arg:arg:arg:arg:regsToSave:pushLinkReg:resultReg:appendOpcodes: */ -static usqInt NoDbgRegParms -genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(void *aRoutine, char *trampolineName, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone, sqInt appendBoolean) -{ - usqInt startAddress; - - startAddress = methodZoneBase; - if (!appendBoolean) { - zeroOpcodeIndex(); - } - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(aRoutine, numArgs, regOrConst0, regOrConst1, regOrConst2, regOrConst3, regMask, pushLinkReg, resultRegOrNone); - outputInstructionsForGeneratedRuntimeAt(startAddress); - recordGeneratedRunTimeaddress(trampolineName, startAddress); - recordRunTimeObjectReferences(); - /* begin assertValidDualZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - assertCoherentCodeAtdelta(backEnd, codeBase + cmNoCheckEntryOffset, codeToDataDelta); -# endif - return startAddress; -} - - -/* To return from a trampoline call we have to take the return address off - the stack, - iof it has been saved */ - - /* Cogit>>#genTrampolineReturn: */ -static void NoDbgRegParms -genTrampolineReturn(sqInt lnkRegWasPushed) -{ - if (lnkRegWasPushed - && (1)) { - genoperand(PopR, LinkReg); - genoperand(RetN, 0); - } - else { - genoperand(RetN, 0); - } -} - - -/* */ - - /* Cogit>>#gen: */ -static AbstractInstruction * NoDbgRegParms -gen(sqInt opcode) -{ - AbstractInstruction *abstractInstruction; - - assert(opcodeIndex < numAbstractOpcodes); - abstractInstruction = abstractInstructionAt(opcodeIndex); - opcodeIndex += 1; - (abstractInstruction->opcode = opcode); - return abstractInstruction; -} - - -/* */ -/* */ - - /* Cogit>>#gen:operand: */ -static AbstractInstruction * NoDbgRegParms -genoperand(sqInt opcode, sqInt operand) -{ - AbstractInstruction *abstractInstruction; - - assert(opcodeIndex < numAbstractOpcodes); - abstractInstruction = abstractInstructionAt(opcodeIndex); - opcodeIndex += 1; - (abstractInstruction->opcode = opcode); - ((abstractInstruction->operands))[0] = operand; - return abstractInstruction; -} - - -/* */ -/* */ -/* */ - - /* Cogit>>#gen:operand:operand: */ -static AbstractInstruction * NoDbgRegParms -genoperandoperand(sqInt opcode, sqInt operandOne, sqInt operandTwo) -{ - AbstractInstruction *abstractInstruction; - - assert(opcodeIndex < numAbstractOpcodes); - abstractInstruction = abstractInstructionAt(opcodeIndex); - opcodeIndex += 1; - (abstractInstruction->opcode = opcode); - ((abstractInstruction->operands))[0] = operandOne; - ((abstractInstruction->operands))[1] = operandTwo; - return abstractInstruction; -} - - -/* */ -/* */ -/* */ -/* */ - - /* Cogit>>#gen:operand:operand:operand: */ -static AbstractInstruction * NoDbgRegParms -genoperandoperandoperand(sqInt opcode, sqInt operandOne, sqInt operandTwo, sqInt operandThree) -{ - AbstractInstruction *abstractInstruction; - - assert(opcodeIndex < numAbstractOpcodes); - abstractInstruction = abstractInstructionAt(opcodeIndex); - opcodeIndex += 1; - (abstractInstruction->opcode = opcode); - ((abstractInstruction->operands))[0] = operandOne; - ((abstractInstruction->operands))[1] = operandTwo; - ((abstractInstruction->operands))[2] = operandThree; - return abstractInstruction; -} - - /* Cogit>>#getLiteral: */ -static sqInt NoDbgRegParms -getLiteral(sqInt litIndex) -{ - if (maxLitIndex < litIndex) { - maxLitIndex = litIndex; - } - return literalofMethod(litIndex, methodObj); -} - - /* Cogit>>#incrementUsageOfTargetIfLinkedSend:mcpc:ignored: */ -static sqInt NoDbgRegParms -incrementUsageOfTargetIfLinkedSendmcpcignored(sqInt annotation, char *mcpc, sqInt superfluity) -{ - sqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - - if (annotation >= IsSendCall) { - assert(annotation != IsNSSendCall); - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (((targetMethod1->cmUsageCount)) < (CMMaxUsageCount / 2)) { - ((((CogMethod *) ((((usqInt)targetMethod1)) + codeToDataDelta)))->cmUsageCount = ((targetMethod1->cmUsageCount)) + 1); - } - } - } - return 0; -} - - -/* Answer a usage count that reflects likely long-term usage. */ - - /* Cogit>>#initialClosedPICUsageCount */ -static sqInt -initialClosedPICUsageCount(void) -{ - return CMMaxUsageCount / 2; -} - - /* Cogit>>#initializeBackend */ -static void -initializeBackend(void) -{ - (methodLabel->machineCodeSize = 0); - (methodLabel->opcode = Label); - ((methodLabel->operands))[0] = 0; - ((methodLabel->operands))[1] = 0; - assert((!((registerMaskFor(VarBaseReg)) & CallerSavedRegisterMask))); - varBaseAddress = computeGoodVarBaseAddress(); - assert((stackLimitAddress()) >= varBaseAddress); - assert((cStackPointerAddress()) >= varBaseAddress); - assert((cFramePointerAddress()) >= varBaseAddress); - assert((cReturnAddressAddress()) >= varBaseAddress); - assert((nextProfileTickAddress()) >= varBaseAddress); - } - - /* Cogit>>#initializeCodeZoneFrom:upTo: */ -void -initializeCodeZoneFromupTo(sqInt startAddress, sqInt endAddress) -{ - sqInt fixupSize; - sqInt numberOfAbstractOpcodes; - sqInt opcodeSize; - usqInt startAddress1; - - initializeBackend(); - sqMakeMemoryExecutableFromToCodeToDataDelta(startAddress, endAddress, -# if DUAL_MAPPED_CODE_ZONE - (&codeToDataDelta) -# else - null -# endif - ); - stopsFromto(backEnd, startAddress, endAddress - 1); - codeBase = (methodZoneBase = startAddress); - minValidCallAddress = (((((codeBase < (interpretAddress())) ? codeBase : (interpretAddress()))) < (primitiveFailAddress())) ? (((codeBase < (interpretAddress())) ? codeBase : (interpretAddress()))) : (primitiveFailAddress())); - /* begin manageFrom:to: */ - mzFreeStart = (baseAddress = methodZoneBase); - youngReferrers = (limitAddress = endAddress); - openPICList = null; - methodBytesFreedSinceLastCompaction = 0; - methodCount = 0; - assertValidDualZone(); - /* begin maybeGenerateCacheFlush */ - /* begin generateVMOwnerLockFunctions */ -# if COGMTVM - /* begin allocateOpcodes:bytecodes: */ - numberOfAbstractOpcodes = numLowLevelLockOpcodes(backEnd); - numAbstractOpcodes = numberOfAbstractOpcodes; - opcodeSize = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupSize = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - abstractOpcodes = alloca(opcodeSize + fixupSize); - bzero(abstractOpcodes, opcodeSize + fixupSize); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeSize)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - zeroOpcodeIndex(); - startAddress1 = methodZoneBase; - generateLowLevelTryLock(backEnd, vmOwnerAddress()); - outputInstructionsForGeneratedRuntimeAt(startAddress1); - recordGeneratedRunTimeaddress("ceTryLockVMOwner", startAddress1); - ceTryLockVMOwner = ((usqIntptr_t (*)(usqIntptr_t)) startAddress1); -# endif // COGMTVM - genGetLeafCallStackPointers(); - generateStackPointerCapture(); - generateTrampolines(); - computeEntryOffsets(); - computeFullBlockEntryOffsets(); - generateClosedPICPrototype(); - alignMethodZoneBase(); - flushICacheFromto(backEnd, startAddress, ((usqInt)methodZoneBase)); - /* begin maybeFlushWritableZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - if (codeToDataDelta > 0) { - flushDCacheFromto(backEnd, startAddress, ((usqInt)methodZoneBase)); - } -# endif - /* begin manageFrom:to: */ - mzFreeStart = (baseAddress = methodZoneBase); - youngReferrers = (limitAddress = endAddress); - openPICList = null; - methodBytesFreedSinceLastCompaction = 0; - methodCount = 0; - generateOpenPICPrototype(); -} - - -/* Answer a usage count that reflects likely long-term usage. - Answer 1 for non-primitives or quick primitives (inst var accessors), - 2 for methods with interpreter primitives, and 3 for compiled primitives. */ - - /* Cogit>>#initialMethodUsageCount */ -static sqInt -initialMethodUsageCount(void) -{ - if ((primitiveIndex == 1) - || (isQuickPrimitiveIndex(primitiveIndex))) { - return 1; - } - if (!(primitiveGeneratorOrNil())) { - return 2; - } - return 3; -} - - -/* Answer a usage count that reflects likely long-term usage. */ - - /* Cogit>>#initialOpenPICUsageCount */ -static sqInt -initialOpenPICUsageCount(void) -{ - return CMMaxUsageCount - 1; -} - - /* Cogit>>#inverseBranchFor: */ -static sqInt NoDbgRegParms -inverseBranchFor(sqInt opcode) -{ - switch (opcode) { - case JumpLongZero: - return JumpLongNonZero; - - case JumpLongNonZero: - return JumpLongZero; - - case JumpZero: - return JumpNonZero; - - case JumpNonZero: - return JumpZero; - - case JumpNegative: - return JumpNonNegative; - - case JumpNonNegative: - return JumpNegative; - - case JumpOverflow: - return JumpNoOverflow; - - case JumpNoOverflow: - return JumpOverflow; - - case JumpCarry: - return JumpNoCarry; - - case JumpNoCarry: - return JumpCarry; - - case JumpLess: - return JumpGreaterOrEqual; - - case JumpGreaterOrEqual: - return JumpLess; - - case JumpGreater: - return JumpLessOrEqual; - - case JumpLessOrEqual: - return JumpGreater; - - case JumpBelow: - return JumpAboveOrEqual; - - case JumpAboveOrEqual: - return JumpBelow; - - case JumpAbove: - return JumpBelowOrEqual; - - case JumpBelowOrEqual: - return JumpAbove; - - default: - error("Case not found and no otherwise clause"); - } - error("invalid opcode for inverse"); - return 0; -} - - -/* See Cogit class>>initializeAnnotationConstants */ - - /* Cogit>>#isPCMappedAnnotation: */ -static sqInt NoDbgRegParms -isPCMappedAnnotation(sqInt annotation) -{ - return annotation >= HasBytecodePC; -} - - /* Cogit>>#isPCWithinMethodZone: */ -sqInt -isPCWithinMethodZone(void *address) -{ - return (((((usqInt)address)) >= methodZoneBase) && ((((usqInt)address)) <= (freeStart()))); -} - - -/* Answer if the instruction preceding retpc is a call instruction. */ - - /* Cogit>>#isSendReturnPC: */ -sqInt -isSendReturnPC(sqInt retpc) -{ - usqInt target; - - if (!(isCallPrecedingReturnPC(backEnd, retpc))) { - return 0; - } - target = callTargetFromReturnAddress(backEnd, retpc); - return (((target >= firstSend) && (target <= lastSend))) - || (((target >= methodZoneBase) && (target <= (freeStart())))); -} - - -/* Floating-point jumps are a little weird on some processors. Defer to - the backEnd to allow it to generate any special code it may need to. */ - - /* Cogit>>#JumpFPEqual: */ -static AbstractInstruction * NoDbgRegParms -gJumpFPEqual(void *jumpTarget) -{ - /* begin genJumpFPEqual: */ - return genoperand(JumpFPEqual, ((sqInt)jumpTarget)); -} - - -/* Floating-point jumps are a little weird on some processors. Defer to - the backEnd to allow it to generate any special code it may need to. */ - - /* Cogit>>#JumpFPGreaterOrEqual: */ -static AbstractInstruction * NoDbgRegParms -gJumpFPGreaterOrEqual(void *jumpTarget) -{ - /* begin genJumpFPGreaterOrEqual: */ - return genoperand(JumpFPGreaterOrEqual, ((sqInt)jumpTarget)); -} - - -/* Floating-point jumps are a little weird on some processors. Defer to - the backEnd to allow it to generate any special code it may need to. */ - - /* Cogit>>#JumpFPGreater: */ -static AbstractInstruction * NoDbgRegParms -gJumpFPGreater(void *jumpTarget) -{ - /* begin genJumpFPGreater: */ - return genoperand(JumpFPGreater, ((sqInt)jumpTarget)); -} - - -/* Floating-point jumps are a little weird on some processors. Defer to - the backEnd to allow it to generate any special code it may need to. */ - - /* Cogit>>#JumpFPNotEqual: */ -static AbstractInstruction * NoDbgRegParms -gJumpFPNotEqual(void *jumpTarget) -{ - /* begin genJumpFPNotEqual: */ - return genoperand(JumpFPNotEqual, ((sqInt)jumpTarget)); -} - - -/* destReg := srcReg << quickConstant */ - - /* Cogit>>#LogicalShiftLeftCq:R:R: */ -static AbstractInstruction * NoDbgRegParms -gLogicalShiftLeftCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) -{ - AbstractInstruction * first; - - return genoperandoperandoperand(LogicalShiftLeftCqRR, quickConstant, srcReg, destReg); - first = genoperandoperand(MoveRR, srcReg, destReg); - genoperandoperand(LogicalShiftLeftCqR, quickConstant, destReg); - return first; -} - - /* Cogit>>#lastOpcode */ -static AbstractInstruction * -lastOpcode(void) -{ - assert(opcodeIndex > 0); - return abstractInstructionAt(opcodeIndex - 1); -} - - /* Cogit>>#linkSendAt:in:to:offset:receiver: */ -void -linkSendAtintooffsetreceiver(sqInt callSiteReturnAddress, CogMethod *sendingMethod, CogMethod *targetMethod, sqInt theEntryOffset, sqInt receiver) -{ - sqInt extent; - sqInt inlineCacheTag; - - assert((theEntryOffset == cmEntryOffset) - || (theEntryOffset == cmNoCheckEntryOffset)); - assert(((callSiteReturnAddress >= methodZoneBase) && (callSiteReturnAddress <= (freeStart())))); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - if (theEntryOffset == cmNoCheckEntryOffset) { - - /* no need to change selector cache tag */ - extent = rewriteCallAttarget(backEnd, callSiteReturnAddress, (((sqInt)targetMethod)) + cmNoCheckEntryOffset); - } - else { - inlineCacheTag = inlineCacheTagForInstance(receiver); - if (inlineCacheTagIsYoung(inlineCacheTag)) { - ensureInYoungReferrers(sendingMethod); - } - extent = rewriteInlineCacheAttagtarget(backEnd, callSiteReturnAddress, inlineCacheTag, (((sqInt)targetMethod)) + theEntryOffset); - } - flushICacheFromto(backEnd, (((usqInt)callSiteReturnAddress)) - extent, ((usqInt)callSiteReturnAddress)); -} - - /* Cogit>>#loadBytesAndGetDescriptor */ -static BytecodeDescriptor * -loadBytesAndGetDescriptor(void) -{ - BytecodeDescriptor *descriptor; - - byte0 = (fetchByteofObject(bytecodePC, methodObj)) + bytecodeSetOffset; - descriptor = generatorAt(byte0); - loadSubsequentBytesForDescriptorat(descriptor, bytecodePC); - return descriptor; -} - - /* Cogit>>#loadSubsequentBytesForDescriptor:at: */ -static void NoDbgRegParms -loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc) -{ - if (((descriptor->numBytes)) > 1) { - byte1 = fetchByteofObject(pc + 1, methodObj); - if (((descriptor->numBytes)) > 2) { - byte2 = fetchByteofObject(pc + 2, methodObj); - if (((descriptor->numBytes)) > 3) { - byte3 = fetchByteofObject(pc + 3, methodObj); - if (((descriptor->numBytes)) > 4) { - notYetImplemented(); - } - } - } - } -} - - /* Cogit>>#MoveCw:R: */ -static AbstractInstruction * NoDbgRegParms -gMoveCwR(sqInt wordConstant, sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkLiteral:forInstruction: */ - anInstruction = genoperandoperand(MoveCwR, wordConstant, reg); - return anInstruction; -} - - /* Cogit>>#MoveMw:r:R: */ -static AbstractInstruction * NoDbgRegParms -gMoveMwrR(sqInt offset, sqInt baseReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, baseReg, destReg); - return anInstruction; -} - - -/* Answer the address of the null byte at the end of the method map. */ - - /* Cogit>>#mapEndFor: */ -static usqInt NoDbgRegParms -mapEndFor(CogMethod *cogMethod) -{ - usqInt end; - - end = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while ((byteAt(end)) != MapEnd) { - end -= 1; - assert(end > (firstMappedPCFor(cogMethod))); - } - return end; -} - - -/* Unlinking/GC/Disassembly support */ -/* most of the time arg is a CogMethod... */ - - /* Cogit>>#mapFor:performUntil:arg: */ -static sqInt NoDbgRegParms -mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg) -{ - sqInt annotation; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - - /* begin firstMappedPCFor: */ - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = functionSymbol(annotation, (((char *) mcpc)), arg); - if (result != 0) { - return result; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - return 0; -} - - -/* Remap all object references in the closed PIC. Answer if any references - are young. - Set codeModified if any modifications are made. */ - - /* Cogit>>#mapObjectReferencesInClosedPIC: */ -static sqInt NoDbgRegParms -mapObjectReferencesInClosedPIC(CogMethod *cPIC) -{ - sqInt i; - sqInt pc; - sqInt refersToYoung; - - - /* first we check the potential method oop load at the beginning of the CPIC */ - pc = addressOfEndOfCaseinCPIC(1, cPIC); - - /* We find the end address of the cPICNumCases'th case and can then just step forward by the case size thereafter */ - refersToYoung = remapMaybeObjRefInClosedPICAt(pc - (jumpLongByteSize(backEnd))); - - /* Next we check the potential class ref in the compare instruction, and the potential method oop load for each case. */ - pc = addressOfEndOfCaseinCPIC((cPIC->cPICNumCases), cPIC); - for (i = 2; i <= ((cPIC->cPICNumCases)); i += 1) { - if (remapMaybeObjRefInClosedPICAt(pc - 16 /* jumpLongConditionalByteSize */)) { - refersToYoung = 1; - } - if (remapMaybeObjRefInClosedPICAt((pc - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */)) { - refersToYoung = 1; - } - pc += cPICCaseSize; - } - return refersToYoung; -} - - -/* Update all references to objects in the generated runtime. */ - - /* Cogit>>#mapObjectReferencesInGeneratedRuntime */ -static void -mapObjectReferencesInGeneratedRuntime(void) -{ - sqInt i; - usqInt literal; - sqInt mappedLiteral; - usqInt mcpc; - - for (i = 0; i < runtimeObjectRefIndex; i += 1) { - mcpc = objectReferencesInRuntime[i]; - literal = literalBeforeFollowingAddress(backEnd, mcpc); - mappedLiteral = remapObject(literal); - if (mappedLiteral != literal) { - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - storeLiteralbeforeFollowingAddress(backEnd, mappedLiteral, mcpc); - } - } -} - - -/* Update all references to objects in machine code for a become. - Unlike incrementalGC or fullGC a method that does not refer to young may - refer to young as a result of the become operation. Unlike incrementalGC - or fullGC the reference from a Cog method to its methodObject *must not* - change since the two are two halves of the same object. */ - - /* Cogit>>#mapObjectReferencesInMachineCodeForBecome */ -static void -mapObjectReferencesInMachineCodeForBecome(void) -{ - sqInt annotation; - CogMethod * cogMethod; - sqInt freedPIC; - sqInt hasYoungObj; - sqInt hasYoungObjPtr; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt remappedMethod; - sqInt result; - CogMethod * writableCogMethod; - - hasYoungObj = 0; - hasYoungObjPtr = ((sqInt)((&hasYoungObj))); - codeModified = (freedPIC = 0); - mapObjectReferencesInGeneratedRuntime(); - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - assert(!hasYoungObj); - if (((cogMethod->cmType)) != CMFree) { - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - writableCogMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - (writableCogMethod->selector = remapOop((cogMethod->selector))); - if (((cogMethod->cmType)) == CMClosedPIC) { - if ((isYoung((cogMethod->selector))) - || (mapObjectReferencesInClosedPIC(cogMethod))) { - freedPIC = 1; - freeMethod(cogMethod); - } - } - else { - if (isYoung((cogMethod->selector))) { - hasYoungObj = 1; - } - if (((cogMethod->cmType)) == CMMethod) { - assert(((cogMethod->objectHeader)) == (nullHeaderForMachineCodeMethod())); - remappedMethod = remapOop((cogMethod->methodObject)); - if (remappedMethod != ((cogMethod->methodObject))) { - if (methodHasCogMethod(remappedMethod)) { - error("attempt to become two cogged methods"); - } - if (!(withoutForwardingOnandwithsendToCogit((cogMethod->methodObject), remappedMethod, (cogMethod->cmUsesPenultimateLit), methodhasSameCodeAscheckPenultimate))) { - error("attempt to become cogged method into different method"); - } - if ((rawHeaderOf((cogMethod->methodObject))) == (((sqInt)cogMethod))) { - rawHeaderOfput((cogMethod->methodObject), (cogMethod->methodHeader)); - (writableCogMethod->methodHeader = rawHeaderOf(remappedMethod)); - (writableCogMethod->methodObject = remappedMethod); - rawHeaderOfput(remappedMethod, ((sqInt)cogMethod)); - } - else { - assert((noAssertMethodClassAssociationOf((cogMethod->methodObject))) == (nilObject())); - (writableCogMethod->methodHeader = rawHeaderOf(remappedMethod)); - (writableCogMethod->methodObject = remappedMethod); - } - } - if (isYoung((cogMethod->methodObject))) { - hasYoungObj = 1; - } - } - /* begin mapFor:performUntil:arg: */ - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = remapIfObjectRefpchasYoung(annotation, (((char *) mcpc)), (((CogMethod *) hasYoungObjPtr))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - if (hasYoungObj) { - ensureInYoungReferrers(cogMethod); - hasYoungObj = 0; - } - else { - (cogMethod->cmRefersToYoung = 0); - } - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - pruneYoungReferrers(); - if (freedPIC) { - unlinkSendsToFree(); - } - if (codeModified) { - - /* After updating oops in inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)codeBase), freeStart()); - } -} - - -/* Update all references to objects in machine code for a full gc. Since - the current (New)ObjectMemory GC makes everything old in a full GC - a method not referring to young will not refer to young afterwards */ - - /* Cogit>>#mapObjectReferencesInMachineCodeForFullGC */ -static void -mapObjectReferencesInMachineCodeForFullGC(void) -{ - sqInt annotation; - CogMethod * cogMethod; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - CogMethod * writableCogMethod; - - codeModified = 0; - mapObjectReferencesInGeneratedRuntime(); - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - writableCogMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - (writableCogMethod->selector = remapOop((cogMethod->selector))); - if (((cogMethod->cmType)) == CMClosedPIC) { - assert(!((cogMethod->cmRefersToYoung))); - mapObjectReferencesInClosedPIC(cogMethod); - } - else { - if (((cogMethod->cmType)) == CMMethod) { - assert(((cogMethod->objectHeader)) == (nullHeaderForMachineCodeMethod())); - (writableCogMethod->methodObject = remapOop((cogMethod->methodObject))); - } - /* begin mapFor:performUntil:arg: */ - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = remapIfObjectRefpchasYoung(annotation, (((char *) mcpc)), 0); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - if (((cogMethod->cmRefersToYoung)) - && (1)) { - (writableCogMethod->cmRefersToYoung = 0); - } - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - pruneYoungReferrers(); - if (codeModified) { - - /* After updating oops in inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)codeBase), freeStart()); - } -} - - -/* Update all references to objects in machine code for either a Spur - scavenging gc - or a Squeak V3 incremental GC. Avoid scanning all code by using the - youngReferrers list. In a young gc a method referring to young may no - longer refer to young, but a - method not referring to young cannot and will not refer to young - afterwards. */ - - /* Cogit>>#mapObjectReferencesInMachineCodeForYoungGC */ -static void -mapObjectReferencesInMachineCodeForYoungGC(void) -{ - sqInt annotation; - CogMethod * cogMethod; - sqInt hasYoungObj; - sqInt hasYoungObjPtr; - usqInt map; - sqInt mapByte; - sqInt mcpc; - usqInt pointer; - sqInt result; - CogMethod * writableCogMethod; - sqInt zoneIsWritable; - - codeModified = (zoneIsWritable = (hasYoungObj = 0)); - hasYoungObjPtr = ((sqInt)((&hasYoungObj))); - pointer = youngReferrers(); - while (pointer < limitAddress) { - assert(!hasYoungObj); - cogMethod = ((CogMethod *) (longAt(pointer))); - if (((cogMethod->cmType)) == CMFree) { - assert(!((cogMethod->cmRefersToYoung))); - } - else { - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - if ((cogMethod->cmRefersToYoung)) { - assert((((cogMethod->cmType)) == CMMethod) - || (((cogMethod->cmType)) == CMOpenPIC)); - if (!zoneIsWritable) { - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - zoneIsWritable = 1; - } - writableCogMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - (writableCogMethod->selector = remapOop((cogMethod->selector))); - if (isYoung((cogMethod->selector))) { - hasYoungObj = 1; - } - if (((cogMethod->cmType)) == CMMethod) { - assert(((cogMethod->objectHeader)) == (nullHeaderForMachineCodeMethod())); - (writableCogMethod->methodObject = remapOop((cogMethod->methodObject))); - if (isYoung((cogMethod->methodObject))) { - hasYoungObj = 1; - } - } - /* begin mapFor:performUntil:arg: */ - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = remapIfObjectRefpchasYoung(annotation, (((char *) mcpc)), (((void *)hasYoungObjPtr))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - if (hasYoungObj) { - hasYoungObj = 0; - } - else { - (writableCogMethod->cmRefersToYoung = 0); - } - } - } - pointer += BytesPerWord; - } - pruneYoungReferrers(); - if (codeModified) { - - /* After updating oops in inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } -} - - -/* Update all references to objects in machine code. */ - - /* Cogit>>#mapObjectReferencesInMachineCode: */ -void -mapObjectReferencesInMachineCode(sqInt gcMode) -{ - switch (gcMode) { - case GCModeNewSpace: - - /* N.B. do *not* ensureWritableCodeZone for every scavenge. */ - mapObjectReferencesInMachineCodeForYoungGC(); - break; - case GCModeFull: - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - mapObjectReferencesInMachineCodeForFullGC(); - break; - case GCModeBecome: - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - mapObjectReferencesInMachineCodeForBecome(); - break; - default: - error("Case not found and no otherwise clause"); - } - if (!(asserta((freeStart()) <= (youngReferrers())))) { - error("youngReferrers list overflowed"); - } -} - - -/* Free any methods that refer to unmarked objects, unlinking sends to freed - methods. - */ - - /* Cogit>>#markAndTraceMachineCodeForNewSpaceGC */ -static void -markAndTraceMachineCodeForNewSpaceGC(void) -{ - sqInt annotation; - CogMethod *cogMethod; - usqInt map; - sqInt mapByte; - sqInt mcpc; - usqInt pointer; - sqInt result; - - if (leakCheckNewSpaceGC()) { - asserta(allMachineCodeObjectReferencesValid()); - } - codeModified = 0; - pointer = youngReferrers(); - while (pointer < limitAddress) { - cogMethod = ((CogMethod *) (longAt(pointer))); - if ((cogMethod->cmRefersToYoung)) { - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - assert((((cogMethod->cmType)) == CMMethod) - || (((cogMethod->cmType)) == CMOpenPIC)); - if (isYoung((cogMethod->selector))) { - markAndTrace((cogMethod->selector)); - } - if (((cogMethod->cmType)) == CMMethod) { - if (isYoung((cogMethod->methodObject))) { - markAndTrace((cogMethod->methodObject)); - } - /* begin markYoungObjectsIn: */ - assert((((cogMethod->cmType)) == CMMethod) - || (((cogMethod->cmType)) == CMOpenPIC)); - if (isYoung((cogMethod->selector))) { - markAndTrace((cogMethod->selector)); - } - if ((((cogMethod->cmType)) == CMMethod) - && (isYoung((cogMethod->methodObject)))) { - markAndTrace((cogMethod->methodObject)); - } - /* begin mapFor:performUntil:arg: */ - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = markYoungObjectspcmethod(annotation, (((char *) mcpc)), cogMethod); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - } - pointer += BytesPerWord; - } - if (leakCheckNewSpaceGC()) { - asserta(allMachineCodeObjectReferencesValid()); - } - if (codeModified) { - - /* After updating oops in inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } -} - - -/* Mark and trace any object references in the generated run-time. */ - - /* Cogit>>#markAndTraceObjectReferencesInGeneratedRuntime */ -static void -markAndTraceObjectReferencesInGeneratedRuntime(void) -{ - sqInt i; - usqInt literal; - usqInt mcpc; - - for (i = 0; i < runtimeObjectRefIndex; i += 1) { - mcpc = objectReferencesInRuntime[i]; - literal = literalBeforeFollowingAddress(backEnd, mcpc); - /* begin markAndTraceLiteral:in:atpc: */ - markAndTraceLiteral(literal); - } -} - - /* Cogit>>#markAndTraceObjectsOrFreeMachineCode: */ -void -markAndTraceObjectsOrFreeMachineCode(sqInt inFullGC) -{ - if (inFullGC) { - markAndTraceOrFreeMachineCodeForFullGC(); - } - else { - markAndTraceMachineCodeForNewSpaceGC(); - } -} - - -/* Mark and trace objects in the argument and free if it is appropriate. - Answer if the method has been freed. firstVisit is a hint used to avoid - scanning methods we've already seen. False positives are fine. - For a CMMethod this - frees if the bytecode method isnt marked, - marks and traces object literals and selectors, - unlinks sends to targets that should be freed. - For a CMClosedPIC this - frees if it refers to anything that should be freed or isn't marked. - For a CMOpenPIC this - frees if the selector isn't marked. */ -/* this recurses at most one level down */ - - /* Cogit>>#markAndTraceOrFreeCogMethod:firstVisit: */ -static sqInt NoDbgRegParms -markAndTraceOrFreeCogMethodfirstVisit(CogMethod *cogMethod, sqInt firstVisit) -{ - sqInt annotation; - sqInt literal; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - - if (((cogMethod->cmType)) == CMFree) { - return 1; - } - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - if (((cogMethod->cmType)) == CMMethod) { - if (!(isMarked((cogMethod->methodObject)))) { - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - freeMethod(cogMethod); - return 1; - } - if (firstVisit) { - /* begin markLiteralsAndUnlinkUnmarkedSendsIn: */ - assert(((cogMethod->cmType)) == CMMethod); - assert(isMarked((cogMethod->methodObject))); - /* begin markAndTraceLiteral:in:at: */ - literal = (cogMethod->selector); - (&((cogMethod->selector))); - markAndTraceLiteral(literal); - /* begin maybeMarkIRCsIn: */ - /* begin mapFor:performUntil:arg: */ - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = markLiteralsAndUnlinkIfUnmarkedSendpcmethod(annotation, (((char *) mcpc)), cogMethod); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - return 0; - } - if (((cogMethod->cmType)) == CMClosedPIC) { - if (!(closedPICRefersToUnmarkedObject(cogMethod))) { - return 0; - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - freeMethod(cogMethod); - return 1; - } - if (((cogMethod->cmType)) == CMOpenPIC) { - if (isMarked((cogMethod->selector))) { - return 0; - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - freeMethod(cogMethod); - return 1; - } - assert((((cogMethod->cmType)) == CMMethod) - || ((((cogMethod->cmType)) == CMClosedPIC) - || (((cogMethod->cmType)) == CMOpenPIC))); - return 0; -} - - -/* Free any methods that refer to unmarked objects, unlinking sends to freed - methods. - */ - - /* Cogit>>#markAndTraceOrFreeMachineCodeForFullGC */ -static void -markAndTraceOrFreeMachineCodeForFullGC(void) -{ - CogMethod *cogMethod; - - if (leakCheckFullGC()) { - asserta(allMachineCodeObjectReferencesValid()); - } - codeModified = 0; - markAndTraceObjectReferencesInGeneratedRuntime(); - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - markAndTraceOrFreeCogMethodfirstVisit(cogMethod, 1); - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (leakCheckFullGC()) { - asserta(allMachineCodeObjectReferencesValid()); - } - if (codeModified) { - - /* After updating oops in inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } -} - - -/* If entryPoint is that of some method, then mark and trace objects in it - and free if it is appropriate. - Answer if the method has been freed. */ - - /* Cogit>>#markAndTraceOrFreePICTarget:in: */ -static sqInt NoDbgRegParms -markAndTraceOrFreePICTargetin(sqInt entryPoint, CogMethod *cPIC) -{ - CogMethod *targetMethod; - - assert((entryPoint > methodZoneBase) - && (entryPoint < (freeStart()))); - if (((((usqInt)cPIC)) <= (((usqInt)entryPoint))) - && (((((usqInt)cPIC)) + ((cPIC->blockSize))) >= (((usqInt)entryPoint)))) { - return 0; - } - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - assert((((targetMethod->cmType)) == CMMethod) - || (((targetMethod->cmType)) == CMFree)); - return markAndTraceOrFreeCogMethodfirstVisit(targetMethod, (((usqInt)targetMethod)) > (((usqInt)cPIC))); -} - - -/* Mark and trace literals. Unlink sends that have unmarked cache tags or - targets. - */ - - /* Cogit>>#markLiteralsAndUnlinkIfUnmarkedSend:pc:method: */ -static sqInt NoDbgRegParms -markLiteralsAndUnlinkIfUnmarkedSendpcmethod(sqInt annotation, char *mcpc, sqInt cogMethod) -{ - usqInt cacheTag1; - sqInt cacheTagMarked; - usqInt entryPoint1; - usqInt literal; - sqInt literal1; - sqInt offset1; - sqInt *sendTable1; - sqInt tagCouldBeObj1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - literal = 0; - if (annotation == IsObjectReference) { - literal = literalBeforeFollowingAddress(backEnd, ((usqInt)mcpc)); - markAndTraceLiteral(literal); - codeModified = 1; - l1: ; - } - if (annotation >= IsSendCall) { - /* begin entryCacheTagAndCouldBeObjectAt:annotation:into: */ - cacheTag1 = inlineCacheTagAt(backEnd, ((sqInt)mcpc)); - - /* in-line cache tags are the selectors of sends if sends are unlinked, - the selectors of super sends (entry offset = cmNoCheckEntryOffset), - the selectors of open PIC sends (entry offset = cmEntryOffset, target is an Open PIC) - or in-line cache tags (classes, class indices, immediate bit patterns, etc). - Note that selectors can be immediate so there is no guarantee that they - are markable/remappable objects. */ - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - tagCouldBeObj1 = 1; - cacheTagMarked = tagCouldBeObj1 - && (cacheTagIsMarked(cacheTag1)); - if (entryPoint1 > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - targetMethod1 = ((CogMethod *) (entryPoint1 - offset1)); - if ((!cacheTagMarked) - || (markAndTraceOrFreeCogMethodfirstVisit(targetMethod1, (((usqInt)targetMethod1)) > (((usqInt)mcpc))))) { - - /* Either the cacheTag is unmarked (e.g. new class) or the target - has been freed (because it is unmarked), so unlink the send. */ - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - /* begin markAndTraceLiteral:in:at: */ - literal1 = (targetMethod1->selector); - (&((targetMethod1->selector))); - markAndTraceLiteral(literal1); - } - } - else { - - /* cacheTag is selector */ - markAndTraceLiteral(cacheTag1); - codeModified = 1; - l3: ; - } - } - return 0; -} - - /* Cogit>>#markMethodAndReferents: */ -void -markMethodAndReferents(CogBlockMethod *aCogMethod) -{ - sqInt annotation; - CogMethod * cogMethod; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - CogMethod * writableMethod; - - assert((((aCogMethod->cmType)) == CMMethod) - || (((aCogMethod->cmType)) == CMBlock)); - cogMethod = (((aCogMethod->cmType)) == CMMethod - ? ((CogMethod *) aCogMethod) - : cmHomeMethod(aCogMethod)); - writableMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - (writableMethod->cmUsageCount = CMMaxUsageCount); - /* begin mapFor:performUntil:arg: */ - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = incrementUsageOfTargetIfLinkedSendmcpcignored(annotation, (((char *) mcpc)), 0); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; -} - - -/* Mark and trace young literals. */ - - /* Cogit>>#markYoungObjects:pc:method: */ -static sqInt NoDbgRegParms -markYoungObjectspcmethod(sqInt annotation, char *mcpc, sqInt cogMethod) -{ - usqInt cacheTag1; - usqInt entryPoint1; - usqInt literal; - sqInt tagCouldBeObj1; - - if (annotation == IsObjectReference) { - literal = literalBeforeFollowingAddress(backEnd, ((usqInt)mcpc)); - markAndTraceLiteralIfYoung(literal); - } - if (annotation >= IsSendCall) { - /* begin entryCacheTagAndCouldBeObjectAt:annotation:into: */ - cacheTag1 = inlineCacheTagAt(backEnd, ((sqInt)mcpc)); - - /* in-line cache tags are the selectors of sends if sends are unlinked, - the selectors of super sends (entry offset = cmNoCheckEntryOffset), - the selectors of open PIC sends (entry offset = cmEntryOffset, target is an Open PIC) - or in-line cache tags (classes, class indices, immediate bit patterns, etc). - Note that selectors can be immediate so there is no guarantee that they - are markable/remappable objects. */ - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - tagCouldBeObj1 = 1; - if (tagCouldBeObj1) { - markAndTraceLiteralIfYoung(cacheTag1); - } - } - return 0; -} - - /* Cogit>>#maxCogMethodAddress */ -usqInt -maxCogMethodAddress(void) -{ - return ((usqInt)(limitZony())); -} - - -/* If this is the Newspeak VM and the objectRepresentation supports pinning - then allocate space for the implicit receiver caches on the heap. */ - - /* Cogit>>#maybeAllocAndInitIRCs */ -static sqInt -maybeAllocAndInitIRCs(void) -{ - return 1; -} - - -/* Check that the header fields are consistent with the type. - Answer 0 if it is ok, otherwise answer a code for the error. */ - - /* Cogit>>#maybeFreeCogMethodDoesntLookKosher: */ -static sqInt NoDbgRegParms -maybeFreeCogMethodDoesntLookKosher(CogMethod *cogMethod) -{ - sqInt result; - - result = cogMethodDoesntLookKosher(cogMethod); - return (result == 2 - ? 0 - : result); -} - - /* Cogit>>#mclassIsSmallInteger */ -static sqInt -mclassIsSmallInteger(void) -{ - return (receiverTags & 1); -} - - -/* Answer the absolute machine code pc matching the zero-relative - bytecode pc of a backward branch in cogMethod, given the start - of the bytecodes for cogMethod's block or method object. */ - - /* Cogit>>#mcPCForBackwardBranch:startBcpc:in: */ -usqInt -mcPCForBackwardBranchstartBcpcin(sqInt bcpc, sqInt startbcpc, CogBlockMethod *cogMethod) -{ - sqInt aMethodObj; - sqInt annotation; - sqInt bcpc1; - sqInt bsOffset; - sqInt byte; - BytecodeDescriptor *descriptor; - sqInt distance; - sqInt endbcpc; - CogMethod *homeMethod; - sqInt isBackwardBranch; - sqInt isInBlock; - sqInt latestContinuation; - usqInt map; - sqInt mapByte; - usqInt mcpc; - sqInt nExts; - sqInt nextBcpc; - sqInt result; - sqInt targetPC; - - latestContinuation = 0; - /* begin mapFor:bcpc:performUntil:arg: */ - assert(((cogMethod->stackCheckOffset)) > 0); - - /* The stack check maps to the start of the first bytecode, - the first bytecode being effectively after frame build. */ - mcpc = (((usqInt)cogMethod)) + ((cogMethod->stackCheckOffset)); - result = (((((0 + (((int)((usqInt)(HasBytecodePC) << 1)))) & 1) != 0)) - && ((((sqInt)(((void *)bcpc)))) == startbcpc) - ? ((sqInt)(((char *) mcpc))) - : 0); - if (result != 0) { - return result; - } - - /* In both CMMethod and CMBlock cases find the start of the map and - skip forward to the bytecode pc map entry for the stack check. */ - bcpc1 = startbcpc; - if (((cogMethod->cmType)) == CMMethod) { - /* begin cmIsFullBlock */ - isInBlock = 0; - homeMethod = ((CogMethod *) cogMethod); - assert(startbcpc == (startPCOfMethodHeader((homeMethod->methodHeader)))); - map = ((((usqInt)homeMethod)) + ((homeMethod->blockSize))) - 1; - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert((annotation == IsAbsPCReference) - || ((annotation == IsObjectReference) - || ((annotation == IsRelativeCall) - || (annotation == IsDisplacementX2N)))); - latestContinuation = startbcpc; - aMethodObj = (homeMethod->methodObject); - endbcpc = (numBytesOf(aMethodObj)) - 1; - /* begin bytecodeSetOffsetForHeader: */ - (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader) - ? 0x100 - : 0) -# else - 0 -# endif - ; - bcpc1 += deltaToSkipPrimAndErrorStoreInheader(aMethodObj, (homeMethod->methodHeader)); - } - else { - isInBlock = 1; - assert(bcpc1 == ((cogMethod->startpc))); - homeMethod = cmHomeMethod(cogMethod); - map = findMapLocationForMcpcinMethod((((usqInt)cogMethod)) + (sizeof(CogBlockMethod)), homeMethod); - assert(map != 0); - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert(((((usqInt)(annotation)) >> AnnotationShift) == HasBytecodePC) - || ((((usqInt)(annotation)) >> AnnotationShift) == IsDisplacementX2N)); - while (((annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift)) != HasBytecodePC) { - map -= 1; - } - - /* skip fiducial; i.e. the map entry for the pc immediately following the method header. */ - map -= 1; - aMethodObj = (homeMethod->methodObject); - bcpc1 = startbcpc - ( -#if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet((homeMethod->methodHeader)) - ? AltBlockCreationBytecodeSize - : BlockCreationBytecodeSize) -#else // MULTIPLEBYTECODESETS - BlockCreationBytecodeSize -#endif - ); - /* begin bytecodeSetOffsetForHeader: */ - (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader1) - ? 0x100 - : 0) -# else - 0 -# endif - ; - byte = (fetchByteofObject(bcpc1, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - endbcpc = (bcpc1 + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc1, -1, aMethodObj)) - : 0)); - bcpc1 = startbcpc; - } - nExts = 0; - while ((((usqInt)((byteAt(map)))) >> AnnotationShift) != HasBytecodePC) { - map -= 1; - } - map -= 1; - while (((mapByte = byteAt(map))) != MapEnd) { - - /* defensive; we exit on bcpc */ - if (mapByte >= FirstAnnotation) { - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if (annotation >= HasBytecodePC) { - if ((annotation == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - while (1) { - byte = (fetchByteofObject(bcpc1, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - if (isInBlock) { - if (bcpc1 >= endbcpc) { - return 0; - } - } - else { - if (((descriptor->isReturn)) - && (bcpc1 >= latestContinuation)) { - return 0; - } - if ((isBranch(descriptor)) - || ((descriptor->isBlockCreation))) { - /* begin latestContinuationPCFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, bcpc1, nExts, aMethodObj); - targetPC = (bcpc1 + ((descriptor->numBytes))) + (((distance < 0) ? 0 : distance)); - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - /* latestContinuation = */ latestContinuation; - } - nextBcpc = (bcpc1 + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc1, nExts, aMethodObj)) - : 0)); - if (((descriptor->isMapped)) - || (isInBlock - && ((descriptor->isMappedInBlock)))) break; - bcpc1 = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - isBackwardBranch = (isBranch(descriptor)) - && ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, bcpc1, nExts, aMethodObj)) < 0)); - result = findBackwardBranchIsBackwardBranchMcpcBcpcMatchingBcpc(descriptor, ((isBackwardBranch - ? (((sqInt)((usqInt)(annotation) << 1))) + 1 - : ((sqInt)((usqInt)(annotation) << 1)))), (((char *) mcpc)), ((isBackwardBranch - ? bcpc1 - (2 * nExts) - : bcpc1)), (((void *)bcpc))); - if (result != 0) { - return result; - } - bcpc1 = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - } - else { - assert(((((usqInt)(mapByte)) >> AnnotationShift) == IsDisplacementX2N) - || ((((usqInt)(mapByte)) >> AnnotationShift) == IsAnnotationExtension)); - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - return 0; -} - - -/* For the purposes of become: see if the two methods are similar, i.e. can - be safely becommed. - This is pretty strict. All literals and bytecodes must be identical. Only - trailer bytes and header - flags can differ. */ - - /* Cogit>>#method:hasSameCodeAs:checkPenultimate: */ -static sqInt NoDbgRegParms -methodhasSameCodeAscheckPenultimate(sqInt methodA, sqInt methodB, sqInt comparePenultimateLiteral) -{ - sqInt bi; - sqInt endPCA; - sqInt headerA; - sqInt headerB; - sqInt li; - sqInt numLitsA; - - headerA = methodHeaderOf(methodA); - headerB = methodHeaderOf(methodB); - numLitsA = literalCountOfMethodHeader(headerA); - endPCA = endPCOf(methodA); - if (((argumentCountOfMethodHeader(headerA)) != (argumentCountOfMethodHeader(headerB))) - || (((temporaryCountOfMethodHeader(headerA)) != (temporaryCountOfMethodHeader(headerB))) - || (((primitiveIndexOfMethodheader(methodA, headerA)) != (primitiveIndexOfMethodheader(methodB, headerB))) - || ((numLitsA != (literalCountOfMethodHeader(headerB))) - || (endPCA > (numBytesOf(methodB))))))) { - return 0; - } - for (li = 1; li < numLitsA; li += 1) { - if ((fetchPointerofObject(li, methodA)) != (fetchPointerofObject(li, methodB))) { - if ((li < (numLitsA - 1)) - || (comparePenultimateLiteral)) { - return 0; - } - } - } - for (bi = (startPCOfMethod(methodA)); bi <= endPCA; bi += 1) { - if ((fetchByteofObject(bi, methodA)) != (fetchByteofObject(bi, methodB))) { - return 0; - } - } - return 1; -} - - /* Cogit>>#mnuOffset */ -sqInt -mnuOffset(void) -{ - return missOffset; -} - - /* Cogit>>#NativePopR: */ -static AbstractInstruction * NoDbgRegParms -gNativePopR(sqInt reg) -{ - return genoperand(PopR, reg); -} - - /* Cogit>>#NativePushR: */ -static AbstractInstruction * NoDbgRegParms -gNativePushR(sqInt reg) -{ - return genoperand(PushR, reg); -} - - /* Cogit>>#NativeRetN: */ -static AbstractInstruction * NoDbgRegParms -gNativeRetN(sqInt offset) -{ - return genoperand(RetN, offset); -} - - /* Cogit>>#needsFrameIfImmutability: */ -static sqInt NoDbgRegParms -needsFrameIfImmutability(sqInt stackDelta) -{ - return IMMUTABILITY; -} - - /* Cogit>>#needsFrameIfInBlock: */ -static sqInt NoDbgRegParms -needsFrameIfInBlock(sqInt stackDelta) -{ - return inBlock > 0; -} - - /* Cogit>>#needsFrameNever: */ -static sqInt NoDbgRegParms -needsFrameNever(sqInt stackDelta) -{ - return 0; -} - - /* Cogit>>#noAssertMethodClassAssociationOf: */ -static sqInt NoDbgRegParms -noAssertMethodClassAssociationOf(sqInt methodPointer) -{ - return literalofMethod((literalCountOfMethodHeader(noAssertHeaderOf(methodPointer))) - 1, methodPointer); -} - - -/* Check that no method is maximally marked. A maximal mark is an indication - the method has been scanned to increase the usage count of its referent - methods. */ - - /* Cogit>>#noCogMethodsMaximallyMarked */ -static sqInt -noCogMethodsMaximallyMarked(void) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) != CMFree) - && (((cogMethod->cmUsageCount)) == CMMaxUsageCount)) { - return 0; - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return 1; -} - - -/* Answer if all targets in the PIC are in-use methods. */ - - /* Cogit>>#noTargetsFreeInClosedPIC: */ -static sqInt NoDbgRegParms -noTargetsFreeInClosedPIC(CogMethod *cPIC) -{ - return !(cPICHasFreedTargets(cPIC)); -} - - /* Cogit>>#OrCq:R:R: */ -static AbstractInstruction * NoDbgRegParms -gOrCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction * first; - - /* begin gen:quickConstant:operand:operand: */ - anInstruction = genoperandoperandoperand(OrCqRR, quickConstant, srcReg, destReg); - return anInstruction; - if (srcReg == destReg) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(OrCqR, quickConstant, destReg); - return anInstruction1; - } - first = genoperandoperand(MoveRR, srcReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(OrCqR, quickConstant, destReg); - return first; -} - - -/* Store the generated machine code, answering the last address */ - - /* Cogit>>#outputInstructionsAt: */ -static sqInt NoDbgRegParms -outputInstructionsAt(sqInt startAddress) -{ - sqInt absoluteAddress; - AbstractInstruction * abstractInstruction; - sqInt i; - sqInt j; - - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - absoluteAddress = startAddress; - for (i = 0; i < opcodeIndex; i += 1) { - maybeBreakGeneratingInstructionWithIndex(i); - abstractInstruction = abstractInstructionAt(i); - assert(((abstractInstruction->address)) == absoluteAddress); - /* begin outputMachineCodeAt: */ - for (j = 0; j < ((abstractInstruction->machineCodeSize)); j += 4) { - longAtput(absoluteAddress + j, ((abstractInstruction->machineCode))[j / 4]); - } - absoluteAddress += (abstractInstruction->machineCodeSize); - } - return absoluteAddress; -} - - -/* Output instructions generated for one of the generated run-time routines, - a trampoline, etc - */ - - /* Cogit>>#outputInstructionsForGeneratedRuntimeAt: */ -static sqInt NoDbgRegParms -outputInstructionsForGeneratedRuntimeAt(sqInt startAddress) -{ - sqInt endAddress; - sqInt size; - - computeMaximumSizes(); - (methodLabel->address = startAddress); - size = generateInstructionsAt(startAddress); - endAddress = outputInstructionsAt(startAddress); - assert((startAddress + size) == endAddress); - methodZoneBase = alignUptoRoutineBoundary(endAddress); - stopsFromto(backEnd, endAddress, methodZoneBase - 1); - return startAddress; -} - - /* Cogit>>#PushCw: */ -static AbstractInstruction * NoDbgRegParms -gPushCw(sqInt wordConstant) -{ - AbstractInstruction *anInstruction; - - /* begin checkLiteral:forInstruction: */ - anInstruction = genoperand(PushCw, wordConstant); - return anInstruction; -} - - -/* Code entry closed PIC full or miss to an instance of a young class or to a - young target method. - Attempt to patch the send site to an open PIC. Answer if the attempt - succeeded; in fact it will - only return if the attempt failed. - The stack looks like: - receiver - args - sp=> sender return address */ - - /* Cogit>>#patchToOpenPICFor:numArgs:receiver: */ -sqInt -patchToOpenPICFornumArgsreceiver(sqInt selector, sqInt numArgs, sqInt receiver) -{ - sqInt extent; - CogMethod *oPIC; - sqInt outerReturn; - - - /* See if an Open PIC is already available. */ - outerReturn = stackTop(); - oPIC = openPICWithSelector(selector); - if (!oPIC) { - - /* otherwise attempt to create an Open PIC. */ - oPIC = cogOpenPICSelectornumArgs(selector, numArgs); - if ((((((sqInt)oPIC)) >= MaxNegativeErrorCode) && ((((sqInt)oPIC)) <= -1))) { - - /* For some reason the PIC couldn't be generated, most likely a lack of code memory. */ - if ((((sqInt)oPIC)) == InsufficientCodeSpace) { - callForCogCompiledCodeCompaction(); - } - return 0; - } - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - extent = rewriteInlineCacheAttagtarget(backEnd, outerReturn, inlineCacheValueForSelectorin(backEnd, selector, mframeHomeMethodExport()), (((sqInt)oPIC)) + cmEntryOffset); - flushICacheFromto(backEnd, (((usqInt)outerReturn)) - extent, ((usqInt)outerReturn)); - flushICacheFromto(backEnd, ((usqInt)oPIC), (((usqInt)oPIC)) + openPICSize); - executeCogMethodfromLinkedSendWithReceiver(oPIC, receiver); - return 1; -} - - -/* This value is used to decide between MNU processing - or interpretation in the closed PIC aborts. */ - - /* Cogit>>#picAbortDiscriminatorValue */ -static sqInt -picAbortDiscriminatorValue(void) -{ - return 0; -} - - -/* Answer the start of the abort sequence for invoking the interpreter in a - closed PIC. - */ - - /* Cogit>>#picInterpretAbortOffset */ -static sqInt -picInterpretAbortOffset(void) -{ - return (interpretOffset()) - (8 /* pushLinkRegisterByteSize */ + (callInstructionByteSize(backEnd))); -} - - /* Cogit>>#previousInstruction */ -static AbstractInstruction * -previousInstruction(void) -{ - assert(opcodeIndex > 0); - return abstractInstructionAt(opcodeIndex - 1); -} - - /* Cogit>>#printCogMethodFor: */ -void -printCogMethodFor(void *address) -{ - CogMethod * cogMethod; - - cogMethod = methodFor(address); - if (cogMethod == null) { - if ((codeEntryFor(address)) == null) { - print("not a method"); - cr(); - } - else { - print("trampoline "); - print(codeEntryNameFor(address)); - cr(); - } - } - else { - printCogMethod(cogMethod); - } -} - - /* Cogit>>#printTrampolineTable */ -void -printTrampolineTable(void) -{ - sqInt i; - - for (i = 0; i < trampolineTableIndex; i += 2) { - printHex(((sqInt)(trampolineAddresses[i + 1]))); - print(": "); - print(((char *) (trampolineAddresses[i]))); - cr(); - } -} - - /* Cogit>>#processorHasDivQuoRemAndMClassIsSmallInteger */ -static sqInt -processorHasDivQuoRemAndMClassIsSmallInteger(void) -{ - return mclassIsSmallInteger(); -} - - /* Cogit>>#processorHasMultiplyAndMClassIsSmallInteger */ -static sqInt -processorHasMultiplyAndMClassIsSmallInteger(void) -{ - return 0; -} - - /* Cogit>>#recordGeneratedRunTime:address: */ -static void NoDbgRegParms -recordGeneratedRunTimeaddress(char *aString, sqInt address) -{ - assert((trampolineTableIndex + 2) <= (NumTrampolines * 2)); - trampolineAddresses[trampolineTableIndex] = aString; - trampolineAddresses[trampolineTableIndex + 1] = (((char *) address)); - - /* self printTrampolineTable */ - trampolineTableIndex += 2; -} - - -/* This one for C support code. */ - - /* Cogit>>#recordPrimTraceFunc */ -sqInt -recordPrimTraceFunc(void) -{ - return recordPrimTrace(); -} - - /* Cogit>>#recordRunTimeObjectReferences */ -static void -recordRunTimeObjectReferences(void) -{ - sqInt i; - AbstractInstruction *instruction; - - for (i = 0; i < opcodeIndex; i += 1) { - instruction = abstractInstructionAt(i); - if (((instruction->annotation)) == IsObjectReference) { - assert(runtimeObjectRefIndex < NumObjRefsInRuntime); - assert(!hasYoungReferent); - if (hasYoungReferent) { - error("attempt to generate run-time routine containing young object reference. Cannot initialize Cogit run-time."); - } - objectReferencesInRuntime[runtimeObjectRefIndex] = (((usqInt)(((instruction->address)) + ((instruction->machineCodeSize))))); - runtimeObjectRefIndex += 1; - } - } -} - - /* Cogit>>#registerMaskFor: */ -static sqInt NoDbgRegParms -registerMaskFor(sqInt reg) -{ - return 1U << reg; -} - - /* Cogit>>#registerMaskFor:and:and: */ -static sqInt NoDbgRegParms -registerMaskForandand(sqInt reg1, sqInt reg2, sqInt reg3) -{ - return ((1U << reg1) | (1U << reg2)) | (1U << reg3); -} - - /* Cogit>>#relocateCallsAndSelfReferencesInMethod: */ -static void NoDbgRegParms -relocateCallsAndSelfReferencesInMethod(CogMethod *cogMethod) -{ - sqInt annotation; - sqInt callDelta; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt refDelta; - sqInt result; - - refDelta = (cogMethod->objectHeader); - callDelta = 0; - assert((((cogMethod->cmType)) == CMMethod) - || (((cogMethod->cmType)) == CMOpenPIC)); - assert((callTargetFromReturnAddress(backEnd, (((sqInt)cogMethod)) + missOffset)) == ((((cogMethod->cmType)) == CMMethod - ? methodAbortTrampolineFor((cogMethod->cmNumArgs)) - : picAbortTrampolineFor((cogMethod->cmNumArgs))))); - relocateCallBeforeReturnPCby(backEnd, (((sqInt)cogMethod)) + missOffset, -callDelta); - /* begin mapFor:performUntil:arg: */ - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = relocateIfCallOrMethodReferencemcpcdelta(annotation, (((char *) mcpc)), (((void *)refDelta))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; -} - - /* Cogit>>#relocateCallsInClosedPIC: */ -static void NoDbgRegParms -relocateCallsInClosedPIC(CogMethod *cPIC) -{ - sqInt callDelta; - sqInt entryPoint; - sqInt i; - sqInt pc; - sqInt refDelta; - CogMethod *targetMethod; - - refDelta = (cPIC->objectHeader); - callDelta = 0; - assert((callTargetFromReturnAddress(backEnd, (((sqInt)cPIC)) + missOffset)) == (picAbortTrampolineFor((cPIC->cmNumArgs)))); - relocateCallBeforeReturnPCby(backEnd, (((sqInt)cPIC)) + missOffset, -callDelta); - pc = (((sqInt)cPIC)) + firstCPICCaseOffset; - for (i = 1; i <= ((cPIC->cPICNumCases)); i += 1) { - pc = addressOfEndOfCaseinCPIC(i, cPIC); - entryPoint = (i == 1 - ? jumpLongTargetBeforeFollowingAddress(backEnd, pc) - : jumpLongConditionalTargetBeforeFollowingAddress(backEnd, pc)); - if (((((usqInt)cPIC)) <= (((usqInt)entryPoint))) - && (((((usqInt)cPIC)) + ((cPIC->blockSize))) >= (((usqInt)entryPoint)))) { - - /* Interpret/MNU */ - if (i == 1) { - relocateJumpLongBeforeFollowingAddressby(backEnd, pc, refDelta); - } - else { - relocateJumpLongConditionalBeforeFollowingAddressby(backEnd, pc, refDelta); - } - } - else { - targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); - assert(((targetMethod->cmType)) == CMMethod); - if (i == 1) { - relocateJumpLongBeforeFollowingAddressby(backEnd, pc, -(callDelta - ((targetMethod->objectHeader)))); - } - else { - relocateJumpLongConditionalBeforeFollowingAddressby(backEnd, pc, -(callDelta - ((targetMethod->objectHeader)))); - } - } - } - assert(((cPIC->cPICNumCases)) > 0); - relocateMethodReferenceBeforeAddressby(backEnd, (addressOfEndOfCaseinCPIC(2, cPIC)) + 8 /* loadLiteralByteSize */, refDelta); - relocateJumpLongBeforeFollowingAddressby(backEnd, (((sqInt)cPIC)) + cPICEndOfCodeOffset, -callDelta); -} - - -/* To placate the C static type system... */ - - /* Cogit>>#relocateIfCallOrMethodReference:mcpc:delta: */ -static sqInt NoDbgRegParms -relocateIfCallOrMethodReferencemcpcdelta(sqInt annotation, char *mcpc, CogMethod *refDeltaArg) -{ - sqInt callDelta; - sqInt entryPoint; - sqInt offset1; - sqInt refDelta; - sqInt *sendTable1; - CogMethod *targetMethod; - sqInt unlinkedRoutine; - - refDelta = ((sqInt) refDeltaArg); - callDelta = 0; - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint <= methodZoneBase) { - - /* send is not linked; just relocate */ - relocateCallBeforeReturnPCby(backEnd, ((sqInt)mcpc), -callDelta); - return 0; - } - /* begin offsetAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - targetMethod = ((CogMethod *) (entryPoint - offset1)); - if (((targetMethod->cmType)) != CMFree) { - - /* send target not freed; just relocate. */ - relocateCallBeforeReturnPCby(backEnd, ((sqInt)mcpc), -(callDelta - ((targetMethod->objectHeader)))); - return 0; - } - unlinkedRoutine = sendTable1[((((targetMethod->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod->cmNumArgs)) : (NumSendTrampolines - 1))]; - unlinkedRoutine -= callDelta; - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod->selector), enumeratingCogMethod), unlinkedRoutine); - return 0; - } - if (annotation == IsRelativeCall) { - relocateCallBeforeReturnPCby(backEnd, ((sqInt)mcpc), -callDelta); - return 0; - } - if (annotation == IsAbsPCReference) { - relocateMethodReferenceBeforeAddressby(backEnd, ((sqInt)mcpc), refDelta); - } - return 0; -} - - -/* to placate the C static type system... */ - - /* Cogit>>#remapIfObjectRef:pc:hasYoung: */ -static sqInt NoDbgRegParms -remapIfObjectRefpchasYoung(sqInt annotation, char *mcpc, CogMethod *hasYoungPtr) -{ - usqInt cacheTag1; - usqInt entryPoint1; - usqInt literal; - sqInt mappedCacheTag; - sqInt mappedLiteral; - sqInt offset1; - sqInt *sendTable1; - sqInt tagCouldBeObj1; - CogMethod *targetMethod1; - - if (annotation == IsObjectReference) { - literal = literalBeforeFollowingAddress(backEnd, ((usqInt)mcpc)); - if (couldBeObject(literal)) { - mappedLiteral = remapObject(literal); - if (literal != mappedLiteral) { - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - storeLiteralbeforeFollowingAddress(backEnd, mappedLiteral, ((usqInt)mcpc)); - } - if ((hasYoungPtr != 0) - && (isYoung(mappedLiteral))) { - (*((sqInt *) hasYoungPtr) = 1); - } - } - } - if (annotation >= IsSendCall) { - /* begin entryCacheTagAndCouldBeObjectAt:annotation:into: */ - cacheTag1 = inlineCacheTagAt(backEnd, ((sqInt)mcpc)); - - /* in-line cache tags are the selectors of sends if sends are unlinked, - the selectors of super sends (entry offset = cmNoCheckEntryOffset), - the selectors of open PIC sends (entry offset = cmEntryOffset, target is an Open PIC) - or in-line cache tags (classes, class indices, immediate bit patterns, etc). - Note that selectors can be immediate so there is no guarantee that they - are markable/remappable objects. */ - entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - tagCouldBeObj1 = 1; - if (tagCouldBeObj1 - && (couldBeObject(cacheTag1))) { - mappedCacheTag = remapObject(cacheTag1); - if (cacheTag1 != mappedCacheTag) { - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheTagat(backEnd, mappedCacheTag, ((usqInt)mcpc)); - } - if ((hasYoungPtr != 0) - && (isYoung(mappedCacheTag))) { - (*((sqInt *) hasYoungPtr) = 1); - } - } - if (hasYoungPtr != 0) { - - /* Since the unlinking routines may rewrite the cacheTag to the send's selector, and - since they don't have the cogMethod to hand and can't add it to youngReferrers, - the method must remain in youngReferrers if the targetMethod's selector is young. */ - if (entryPoint1 > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - targetMethod1 = ((CogMethod *) (entryPoint1 - offset1)); - if (isYoung((targetMethod1->selector))) { - (*((sqInt *) hasYoungPtr) = 1); - } - } - } - } - return 0; -} - - -/* Remap a potential object reference from a closed PIC. - This may be an object reference, an inline cache tag or null. - Answer if the updated literal is young. - mcpc is the address of the next instruction following either - the load of the method literal or the compare of the class tag. */ - - /* Cogit>>#remapMaybeObjRefInClosedPICAt: */ -static sqInt NoDbgRegParms -remapMaybeObjRefInClosedPICAt(sqInt mcpc) -{ - usqInt object; - sqInt subject; - - object = literalBeforeFollowingAddress(backEnd, mcpc); - if (!(couldBeObject(object))) { - return 0; - } - subject = remapOop(object); - if (object != subject) { - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - storeLiteralbeforeFollowingAddress(backEnd, subject, mcpc); - } - return isYoungObject(subject); -} - - -/* Rewrite the three values involved in a CPIC case. Used by the initialize & - extend CPICs. - c.f. expectedClosedPICPrototype: */ -/* write the obj ref/operand via the second ldr */ - - /* Cogit>>#rewriteCPICCaseAt:tag:objRef:target: */ -static void NoDbgRegParms -rewriteCPICCaseAttagobjReftarget(sqInt followingAddress, sqInt newTag, sqInt newObjRef, sqInt newTarget) -{ - sqInt classTagPC; - sqInt methodObjPC; - - methodObjPC = (followingAddress - 16 /* jumpLongConditionalByteSize */) - 8 /* cmpC32RTempByteSize */; - storeLiteralbeforeFollowingAddress(backEnd, newObjRef, methodObjPC); - - /* rewite the tag via the first ldr */ - classTagPC = followingAddress - 16 /* jumpLongConditionalByteSize */; - /* begin storeLiteral32:beforeFollowingAddress: */ - storeLiteralbeforeFollowingAddress(((AbstractInstruction *) backEnd), newTag, classTagPC); - rewriteConditionalJumpLongAttarget(backEnd, followingAddress, newTarget); -} - - -/* Answer the number of clean blocks found in the literal frame */ - - /* Cogit>>#scanForCleanBlocks */ -static sqInt -scanForCleanBlocks(void) -{ - sqInt i; - sqInt iLimiT; - sqInt lit; - sqInt numCleanBlocks; - sqInt startPCOrNil; - - numCleanBlocks = 0; - for (i = 1, iLimiT = (literalCountOf(methodObj)); i <= iLimiT; i += 1) { - lit = fetchPointerofObject(i, methodObj); - startPCOrNil = startPCOrNilOfLiteralin(lit, methodObj); - if (!(startPCOrNil == null)) { - numCleanBlocks += 1; - } - } - return numCleanBlocks; -} - - /* Cogit>>#setBreakMethod: */ -void -setBreakMethod(sqInt anObj) -{ - breakMethod = anObj; -} - - -/* If a method is compiled to machine code via a block entry it won't have a - selector. A subsequent send can find the method and hence fill in the - selector. - */ -/* self disassembleMethod: cogMethod */ - - /* Cogit>>#setSelectorOf:to: */ -void -setSelectorOfto(CogMethod *cogMethod, sqInt aSelectorOop) -{ - compilationBreakpointisMNUCase(aSelectorOop, 0); - assert(((cogMethod->cmType)) == CMMethod); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - ((((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)))->selector = aSelectorOop); - if (isYoung(aSelectorOop)) { - ensureInYoungReferrers(cogMethod); - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - /* Cogit>>#spanForCleanBlockStartingAt: */ -static sqInt NoDbgRegParms -spanForCleanBlockStartingAt(sqInt startPC) -{ - BytecodeDescriptor *descriptor; - sqInt end; - sqInt pc; - - pc = startPC; - end = numBytesOf(methodObj); - while (pc <= end) { - /* begin generatorForPC: */ - descriptor = generatorAt(bytecodeSetOffset + (fetchByteofObject(pc, methodObj))); - pc += (descriptor->numBytes); - if ((descriptor->isReturn)) { - return pc - startPC; - } - } - error("couldn't locate end of clean block"); - return 0; -} - - /* Cogit>>#stackCheckOffsetOfBlockAt:isMcpc: */ -static usqInt NoDbgRegParms -stackCheckOffsetOfBlockAtisMcpc(sqInt blockEntryMcpc, sqInt mcpc) -{ - CogBlockMethod *cogBlockMethod; - - cogBlockMethod = ((CogBlockMethod *) (blockEntryMcpc - (sizeof(CogBlockMethod)))); - if (((((sqInt)cogBlockMethod)) + ((cogBlockMethod->stackCheckOffset))) == mcpc) { - return ((usqInt)cogBlockMethod); - } - return 0; -} - - -/* Answer a fake value for the method oop in other than the first case in the - PIC prototype. - Since we use MoveUniqueCw:R: it must not be confused with a - method-relative address. - */ - - /* Cogit>>#subsequentPrototypeMethodOop */ -static sqInt -subsequentPrototypeMethodOop(void) -{ - return (addressIsInCurrentCompilation(0xBADA550) - ? 0xDEADEAD - : 0xBADA550); -} - - /* Cogit>>#traceLinkedSendOffset */ -sqInt -traceLinkedSendOffset(void) -{ - return (cmNoCheckEntryOffset + (callFullInstructionByteSize(backEnd))) + (8 /* pushLinkRegisterByteSize */); -} - - -/* Encode true and false and 0 to N such that they can't be confused for - register numbers (including NoReg) - and can be tested for by isTrampolineArgConstant: and decoded by - trampolineArgValue: - */ - - /* Cogit>>#trampolineArgConstant: */ -static sqInt NoDbgRegParms -trampolineArgConstant(sqInt booleanOrInteger) -{ - assert(booleanOrInteger >= 0); - return -2 - booleanOrInteger; -} - - /* Cogit>>#trampolineName:numArgs: */ -static char * NoDbgRegParms -trampolineNamenumArgs(char *routinePrefix, sqInt numArgs) -{ - char *theString; - - /* begin trampolineName:numArgs:limit: */ - theString = malloc((strlen(routinePrefix)) + 6); - sprintf(theString, "%s%cArgs", routinePrefix, (numArgs <= (NumSendTrampolines - 2) - ? '0' + numArgs - : 'N')); - return theString; -} - - /* Cogit>>#trampolineName:numRegArgs: */ -static char * NoDbgRegParms -trampolineNamenumRegArgs(char *routinePrefix, sqInt numArgs) -{ - sqInt argsLimit; - char *theString; - - /* begin trampolineName:numArgs:limit: */ - argsLimit = 1 /* numRegArgs */; - theString = malloc((strlen(routinePrefix)) + 6); - sprintf(theString, "%s%cArgs", routinePrefix, (numArgs <= argsLimit - ? '0' + numArgs - : 'N')); - return theString; -} - - /* Cogit>>#unknownBytecode */ -static sqInt -unknownBytecode(void) -{ - return EncounteredUnknownBytecode; -} - - -/* Unlink all sends in cog methods. */ - - /* Cogit>>#unlinkAllSends */ -void -unlinkAllSends(void) -{ - sqInt annotation; - CogMethod *cogMethod; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - - if (!methodZoneBase) { - return; - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - cogMethod = ((CogMethod *) methodZoneBase); - voidOpenPICList(); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - /* begin mapFor:performUntil:arg: */ - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfLinkedSendpcignored(annotation, (((char *) mcpc)), 0); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - else { - if (((cogMethod->cmType)) != CMFree) { - freeMethod(cogMethod); - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); -} - - -/* To placate the C static type system... */ - - /* Cogit>>#unlinkIfFreeOrLinkedSend:pc:of: */ -static sqInt NoDbgRegParms -unlinkIfFreeOrLinkedSendpcof(sqInt annotation, char *mcpc, CogMethod *theSelector) -{ - sqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if ((((targetMethod1->cmType)) == CMFree) - || (((targetMethod1->selector)) == (((sqInt) theSelector)))) { - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - } - return 0; -} - - /* Cogit>>#unlinkIfLinkedSendToFree:pc:ignored: */ -static sqInt NoDbgRegParms -unlinkIfLinkedSendToFreepcignored(sqInt annotation, char *mcpc, sqInt superfluity) -{ - sqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (((targetMethod1->cmType)) == CMFree) { - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - } - return 0; -} - - -/* To placate the C static type system... */ - - /* Cogit>>#unlinkIfLinkedSend:pc:if: */ -static sqInt NoDbgRegParms -unlinkIfLinkedSendpcif(sqInt annotation, char *mcpc, CogMethod *criterionArg) -{ - sqInt (*criterion)(CogMethod *); - sqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - criterion = ((void *)criterionArg); - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if (criterion(targetMethod1)) { - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - } - return 0; -} - - /* Cogit>>#unlinkIfLinkedSend:pc:ignored: */ -static sqInt NoDbgRegParms -unlinkIfLinkedSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity) -{ - usqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - return 0; -} - - /* Cogit>>#unlinkIfLinkedSend:pc:to: */ -static sqInt NoDbgRegParms -unlinkIfLinkedSendpcto(sqInt annotation, char *mcpc, sqInt theCogMethod) -{ - sqInt entryPoint; - sqInt offset1; - sqInt *sendTable1; - CogMethod *targetMethod1; - sqInt unlinkedRoutine; - - if (annotation >= IsSendCall) { - entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); - if (entryPoint > methodZoneBase) { - - /* It's a linked send. */ - /* begin targetMethodAndSendTableFor:annotation:into: */ - if (annotation == IsSendCall) { - offset1 = cmEntryOffset; - sendTable1 = ordinarySendTrampolines; - } - else { - assert(annotation == IsSuperSend); - offset1 = cmNoCheckEntryOffset; - sendTable1 = superSendTrampolines; - } - targetMethod1 = ((CogMethod *) (entryPoint - offset1)); - if ((((sqInt)targetMethod1)) == theCogMethod) { - /* begin unlinkSendAt:targetMethod:sendTable: */ - unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; - /* begin setCodeModified */ -# if DUAL_MAPPED_CODE_ZONE - codeModified = 1; -# else - codeModified = 1; -# endif - rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), inlineCacheValueForSelectorin(backEnd, (targetMethod1->selector), enumeratingCogMethod), unlinkedRoutine); - } - } - } - return 0; -} - - -/* Unlink all sends in cog methods. Free all Closed PICs with the selector, - or with an MNU case if isMNUSelector. First check if any method actually - has the selector; if not there can't be any linked send to it. This - routine (including descendents) is performance critical. It contributes - perhaps 30% of entire execution time in Compiler recompileAll. */ - - /* Cogit>>#unlinkSendsOf:isMNUSelector: */ -void -unlinkSendsOfisMNUSelector(sqInt selector, sqInt isMNUSelector) -{ - sqInt annotation; - CogMethod *cogMethod; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt mustScanAndUnlink; - sqInt result; - - if (!methodZoneBase) { - return; - } - cogMethod = ((CogMethod *) methodZoneBase); - mustScanAndUnlink = 0; - if (isMNUSelector) { - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) != CMFree) { - if ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock)) { - assert(((cogMethod->cmType)) == CMClosedPIC); - freeMethod(cogMethod); - mustScanAndUnlink = 1; - } - else { - if (((cogMethod->selector)) == selector) { - mustScanAndUnlink = 1; - if (((cogMethod->cmType)) == CMClosedPIC) { - freeMethod(cogMethod); - } - } - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - } - else { - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) != CMFree) - && (((cogMethod->selector)) == selector)) { - mustScanAndUnlink = 1; - if (((cogMethod->cmType)) == CMClosedPIC) { - freeMethod(cogMethod); - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - } - if (!mustScanAndUnlink) { - return; - } - codeModified = 0; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - /* begin mapFor:performUntil:arg: */ - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfFreeOrLinkedSendpcof(annotation, (((char *) mcpc)), (((CogMethod *) selector))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (codeModified) { - - /* After possibly updating inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - -/* Unlink all sends in cog methods to free methods and/or pics. */ - - /* Cogit>>#unlinkSendsToFree */ -void -unlinkSendsToFree(void) -{ - sqInt annotation; - CogMethod *cogMethod; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - - if (!methodZoneBase) { - return; - } - codeModified = 0; - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - /* begin mapFor:performUntil:arg: */ - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfLinkedSendToFreepcignored(annotation, (((char *) mcpc)), 0); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - else { - if (((cogMethod->cmType)) == CMClosedPIC) { - assert(noTargetsFreeInClosedPIC(cogMethod)); - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (codeModified) { - - /* After possibly updating inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } -} - - -/* Unlink all sends in cog methods to methods with a machine code - primitive, and free machine code primitive methods if freeIfTrue. - To avoid having to scan PICs, free any and all PICs */ - - /* Cogit>>#unlinkSendsToMethodsSuchThat:AndFreeIf: */ -void -unlinkSendsToMethodsSuchThatAndFreeIf(sqInt (*criterion)(CogMethod *), sqInt freeIfTrue) -{ - sqInt annotation; - CogMethod *cogMethod; - sqInt freedSomething; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - - if (!methodZoneBase) { - return; - } - codeModified = (freedSomething = 0); - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - if (freeIfTrue - && (criterion(cogMethod))) { - freeMethod(cogMethod); - freedSomething = 1; - } - else { - /* begin mapFor:performUntil:arg: */ - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfLinkedSendpcif(annotation, (((char *) mcpc)), (((CogMethod *) criterion))); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - } - else { - if (((cogMethod->cmType)) == CMClosedPIC) { - freeMethod(cogMethod); - freedSomething = 1; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (freedSomething) { - unlinkSendsToFree(); - } - else { - if (codeModified) { - - /* After possibly updating inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } - } -} - - -/* Unlink all sends in cog methods to a particular target method. - If targetMethodObject isn't actually a method (perhaps being - used via invokeAsMethod) then there's nothing to do. */ - - /* Cogit>>#unlinkSendsTo:andFreeIf: */ -void -unlinkSendsToandFreeIf(sqInt targetMethodObject, sqInt freeIfTrue) -{ - sqInt annotation; - CogMethod *cogMethod; - sqInt freedPIC; - usqInt map; - sqInt mapByte; - sqInt mcpc; - sqInt result; - CogMethod *targetMethod; - - if (!((isOopCompiledMethod(targetMethodObject)) - && (methodHasCogMethod(targetMethodObject)))) { - return; - } - targetMethod = cogMethodOf(targetMethodObject); - if (!methodZoneBase) { - return; - } - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - codeModified = (freedPIC = 0); - cogMethod = ((CogMethod *) methodZoneBase); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - /* begin mapFor:performUntil:arg: */ - mcpc = (((usqInt)cogMethod)) + cmNoCheckEntryOffset; - map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; - while (((mapByte = byteAt(map))) != MapEnd) { - if (mapByte >= FirstAnnotation) { - - /* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */ - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if ((((annotation = ((usqInt)(mapByte)) >> AnnotationShift)) == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - result = unlinkIfLinkedSendpcto(annotation, (((char *) mcpc)), targetMethod); - if (result != 0) { - goto l2; - } - } - else { - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - l2: /* end mapFor:performUntil:arg: */; - } - else { - if ((((cogMethod->cmType)) == CMClosedPIC) - && (cPICHasTarget(cogMethod, targetMethod))) { - freeMethod(cogMethod); - freedPIC = 1; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - if (freeIfTrue) { - freeMethod(targetMethod); - } - if (freedPIC) { - unlinkSendsToFree(); - } - else { - if (codeModified) { - - /* After possibly updating inline caches we need to flush the icache. */ - flushICacheFromto(backEnd, ((usqInt)methodZoneBase), freeStart()); - } - } - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - /* Cogit>>#voidCogCompiledCode */ -void -voidCogCompiledCode(void) -{ - CogMethod *cogMethod; - - /* begin clearCogCompiledCode */ - cogMethod = ((CogMethod *) baseAddress); - while ((((usqInt)cogMethod)) < mzFreeStart) { - if (((cogMethod->cmType)) == CMMethod) { - freeMethod(cogMethod); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - /* begin manageFrom:to: */ - mzFreeStart = (/* baseAddress = */ baseAddress); - youngReferrers = (/* limitAddress = */ limitAddress); - openPICList = null; - methodBytesFreedSinceLastCompaction = 0; - methodCount = 0; - /* begin ensureExecutableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif -} - - -/* Access for the object representations when they need to prepend code to - trampolines. - */ -/* Eliminate stale dependent info. */ - - /* Cogit>>#zeroOpcodeIndex */ -static void -zeroOpcodeIndex(void) -{ - sqInt i; - - for (i = 0; i < opcodeIndex; i += 1) { - ((abstractOpcodes[i]).dependent = null); - } - zeroOpcodeIndexForNewOpcodes(); -} - - -/* Access for the object representations when they need to prepend code to - trampolines. - */ - - /* Cogit>>#zeroOpcodeIndexForNewOpcodes */ -static void -zeroOpcodeIndexForNewOpcodes(void) -{ - opcodeIndex = 0; -} - - /* CogMethod>>#counters */ -static sqInt NoDbgRegParms -counters(CogMethod * self_in_counters) -{ - return 0; -} - - /* CogMethodZone>>#addToOpenPICList: */ -static void NoDbgRegParms -addToOpenPICList(CogMethod *anOpenPIC) -{ - assert(((anOpenPIC->cmType)) == CMOpenPIC); - assert((openPICList == null) - || (((openPICList->cmType)) == CMOpenPIC)); - assertValidDualZoneWriteAddress(anOpenPIC); - (anOpenPIC->nextOpenPIC = ((usqInt)openPICList)); - openPICList = ((CogMethod *) ((((usqInt)anOpenPIC)) - (getCodeToDataDelta()))); -} - - /* CogMethodZone>>#addToYoungReferrers: */ -static void NoDbgRegParms -addToYoungReferrers(CogMethod *cogMethod) -{ - assertValidDualZoneWriteAddress(cogMethod); - assert((occurrencesInYoungReferrers(cogMethod)) == 0); - assert((cogMethod->cmRefersToYoung)); - assert((youngReferrers <= limitAddress) - && (youngReferrers >= (limitAddress - (methodCount * BytesPerWord)))); - if (!(asserta((limitAddress - (methodCount * BytesPerWord)) >= mzFreeStart))) { - error("no room on youngReferrers list"); - } - youngReferrers -= BytesPerWord; - codeLongAtput(youngReferrers, (((usqInt)cogMethod)) - (getCodeToDataDelta())); -} - - /* CogMethodZone>>#allocate: */ -static usqInt NoDbgRegParms -allocate(sqInt numBytes) -{ - usqInt allocation; - sqInt roundedBytes; - - roundedBytes = (numBytes + 7) & -8; - if ((mzFreeStart + roundedBytes) >= (limitAddress - (methodCount * BytesPerWord))) { - return 0; - } - allocation = mzFreeStart; - mzFreeStart += roundedBytes; - methodCount += 1; - return allocation; -} - - -/* Answer the method containing mcpc for the purposes of code zone - compaction, where mcpc is actually the value of instructionPointer at the - time of a compaction. */ - - /* CogMethodZone>>#cogMethodContaining: */ -CogMethod * -cogMethodContaining(usqInt mcpc) -{ - CogMethod * cogMethod; - CogMethod * prevMethod; - - if (mcpc > limitAddress) { - return null; - } - if (mcpc < baseAddress) { - /* begin assertMcpcIsPrimReturn: */ - assert((mcpc == cePrimReturnEnterCogCode) - || (mcpc == cePrimReturnEnterCogCodeProfiling)); - return null; - } - assert(mcpc < (freeStart())); - cogMethod = ((CogMethod *) baseAddress); - while ((((usqInt)cogMethod)) < mcpc) { - prevMethod = cogMethod; - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - assert((prevMethod != null) - && ((mcpc == ((((usqInt)prevMethod)) + ((prevMethod->stackCheckOffset)))) - || ((mcpcisAtStackCheckOfBlockMethodIn(mcpc, prevMethod)) - || (((primitiveIndexOfMethodheader((prevMethod->methodObject), (prevMethod->methodHeader))) > 0) - || ((isCallPrecedingReturnPC(backEnd(), mcpc)) - && ((callTargetFromReturnAddress(backEnd(), mcpc)) == (ceCheckForInterruptTrampoline()))))))); - return prevMethod; -} - - /* CogMethodZone>>#compactCompiledCode */ -static void -compactCompiledCode(void) -{ - unsigned short bytes; - CogMethod *dest; - sqInt objectHeaderValue; - CogMethod *source; - CogMethod * writableVersion; - - compactionInProgress = 1; - methodCount = 0; - objectHeaderValue = nullHeaderForMachineCodeMethod(); - source = ((CogMethod *) baseAddress); - voidOpenPICList(); - voidUnpairedMethodList(); - while ((source < (limitZony())) - && (((source->cmType)) != CMFree)) { - assert((cogMethodDoesntLookKosher(source)) == 0); - /* begin writableMethodFor: */ - writableVersion = ((CogMethod *) ((((usqInt)source)) + codeToDataDelta)); - (writableVersion->objectHeader = objectHeaderValue); - if (((source->cmUsageCount)) > 0) { - (writableVersion->cmUsageCount = ((source->cmUsageCount)) / 2); - } - /* begin maybeLinkOnUnpairedMethodList: */ - /* begin clearSavedPICUsageCount: */ - if (((source->cmType)) == CMOpenPIC) { - addToOpenPICList(writableVersion); - } - methodCount += 1; - source = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)source)) + ((source->blockSize))))); - } - if (source >= (limitZony())) { - haltmsg("no free methods; cannot compact."); - return; - } - dest = source; - while (source < (limitZony())) { - assert((maybeFreeCogMethodDoesntLookKosher(source)) == 0); - bytes = (source->blockSize); - if (((source->cmType)) != CMFree) { - methodCount += 1; - codeMemmove(dest, source, bytes); - /* begin maybeFlushWritableZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - if (codeToDataDelta > 0) { - flushDCacheFromto(backEnd, ((usqInt)dest), (((usqInt)dest)) + bytes); - } -# endif - ((writableVersion = ((CogMethod *) ((((usqInt)dest)) + codeToDataDelta)))->objectHeader = objectHeaderValue); - if (((dest->cmType)) == CMMethod) { - - /* For non-Newspeak there should be a one-to-one mapping between bytecoded and - cog methods. For Newspeak not necessarily, but only for anonymous accessors. */ - /* Only update the original method's header if it is referring to this CogMethod. */ - if ((((sqInt)(rawHeaderOf((dest->methodObject))))) == (((sqInt)source))) { - rawHeaderOfput((dest->methodObject), ((sqInt)dest)); - } - else { - assert((noAssertMethodClassAssociationOf((dest->methodObject))) == (nilObject())); - /* begin linkOnUnpairedMethodList: */ - } - } - else { - /* begin clearSavedPICUsageCount: */ - if (((dest->cmType)) == CMOpenPIC) { - addToOpenPICList(writableVersion); - } - } - if (((dest->cmUsageCount)) > 0) { - (writableVersion->cmUsageCount = ((dest->cmUsageCount)) / 2); - } - /* begin maybeFlushWritableZoneFrom:to: */ -# if DUAL_MAPPED_CODE_ZONE - if (codeToDataDelta > 0) { - flushDCacheFromto(backEnd, ((usqInt)dest), ((usqInt)(dest + 1))); - } -# endif - dest = ((CogMethod *) ((((usqInt)dest)) + bytes)); - } - source = ((CogMethod *) ((((usqInt)source)) + bytes)); - } - mzFreeStart = ((usqInt)dest); - methodBytesFreedSinceLastCompaction = 0; - compactionInProgress = 0; -} - - /* CogMethodZone>>#ensureInYoungReferrers: */ -static void NoDbgRegParms -ensureInYoungReferrers(CogMethod *cogMethod) -{ - CogMethod * writableMethod; - - assertValidDualZoneReadAddress(cogMethod); - if (!((cogMethod->cmRefersToYoung))) { - assert((occurrencesInYoungReferrers(cogMethod)) == 0); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - ((writableMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)))->cmRefersToYoung = 1); - addToYoungReferrers(writableMethod); - } -} - - /* CogMethodZone>>#freeMethod: */ -static void NoDbgRegParms -freeMethod(CogMethod *cogMethod) -{ - CogMethod * writableMethod; - - assert(((cogMethod->cmType)) != CMFree); - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - if (((cogMethod->cmType)) == CMMethod) { - - /* For non-Newspeak there should be a one-to-one mapping between bytecoded and - cog methods. For Newspeak not necessarily, but only for anonymous accessors. */ - /* Only reset the original method's header if it is referring to this CogMethod. */ - if ((((sqInt)(rawHeaderOf((cogMethod->methodObject))))) == (((sqInt)cogMethod))) { - rawHeaderOfput((cogMethod->methodObject), (cogMethod->methodHeader)); - } - else { - assert((noAssertMethodClassAssociationOf((cogMethod->methodObject))) == (nilObject())); - } - } - if (((cogMethod->cmType)) == CMOpenPIC) { - removeFromOpenPICList(cogMethod); - } - /* begin writableMethodFor: */ - writableMethod = ((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)); - (writableMethod->cmRefersToYoung = 0); - (writableMethod->cmType = CMFree); - methodBytesFreedSinceLastCompaction += (cogMethod->blockSize); -} - - -/* Free methods, preferring older methods for compaction, up to some - fraction, currently a quarter. - */ - - /* CogMethodZone>>#freeOlderMethodsForCompaction */ -static void -freeOlderMethodsForCompaction(void) -{ - sqInt amountToFree; - CogMethod *cogMethod; - sqInt freeableUsage; - sqInt freedSoFar; - sqInt initialFreeSpace; - sqInt zoneSize; - - zoneSize = limitAddress - baseAddress; - initialFreeSpace = (limitAddress - mzFreeStart) + methodBytesFreedSinceLastCompaction; - freedSoFar = initialFreeSpace; - - /* 4 needs to be e.g. a start-up parameter */ - amountToFree = zoneSize / 4; - freeableUsage = 0; - do { - cogMethod = ((CogMethod *) baseAddress); - while (((((usqInt)cogMethod)) < mzFreeStart) - && (freedSoFar < amountToFree)) { - if ((((cogMethod->cmType)) != CMFree) - && (((cogMethod->cmUsageCount)) <= freeableUsage)) { - freeMethod(cogMethod); - freedSoFar += (cogMethod->blockSize); - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - } while((freedSoFar < amountToFree) - && (((freeableUsage += 1)) < CMMaxUsageCount)); -} - - -/* Answer that all entries in youngReferrers are in-use and have the - cmRefersToYoung flag set. - Used to check that the youngreferrers pruning routines work correctly. */ - - /* CogMethodZone>>#kosherYoungReferrers */ -sqInt -kosherYoungReferrers(void) -{ - CogMethod * cogMethod; - usqInt pointer; - CogMethod * prevMethod; - - if ((youngReferrers > limitAddress) - || (youngReferrers < mzFreeStart)) { - return 0; - } - pointer = youngReferrers; - while (pointer < limitAddress) { - cogMethod = ((CogMethod *) (longAt(pointer))); - if (((cogMethod->cmType)) != CMFree) { - if (!((cogMethod->cmRefersToYoung))) { - return 0; - } - if ((occurrencesInYoungReferrers(cogMethod)) != 1) { - return 0; - } - } - pointer += BytesPerWord; - } - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - prevMethod = cogMethod; - if (((cogMethod->cmType)) != CMFree) { - if ((occurrencesInYoungReferrers(cogMethod)) != (((cogMethod->cmRefersToYoung) - ? 1 - : 0))) { - return 0; - } - } - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - if (cogMethod == prevMethod) { - return 0; - } - } - return 1; -} - - -/* For assert checking... */ - - /* CogMethodZone>>#mcpc:isAtStackCheckOfBlockMethodIn: */ -static sqInt NoDbgRegParms -mcpcisAtStackCheckOfBlockMethodIn(sqInt mcpc, CogMethod *cogMethod) -{ - if (((cogMethod->blockEntryOffset)) == 0) { - return 0; - } - return (blockDispatchTargetsForperformarg(cogMethod, stackCheckOffsetOfBlockAtisMcpc, mcpc)) != 0; -} - - /* CogMethodZone>>#methodFor: */ -CogMethod * -methodFor(void *address) -{ - CogMethod * cogMethod; - CogMethod * nextMethod; - - cogMethod = ((CogMethod *) baseAddress); - while ((cogMethod < (limitZony())) - && ((((usqInt)cogMethod)) <= (((usqInt)address)))) { - /* begin methodAfter: */ - nextMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - if (nextMethod == cogMethod) { - return null; - } - if (((((usqInt)address)) >= (((usqInt)cogMethod))) - && ((((usqInt)address)) < (((usqInt)nextMethod)))) { - return cogMethod; - } - cogMethod = nextMethod; - } - return null; -} - - /* CogMethodZone>>#methodsCompiledToMachineCodeInto: */ -sqInt -methodsCompiledToMachineCodeInto(sqInt arrayObj) -{ - CogMethod *cogMethod; - sqInt methodIndex; - - methodIndex = 0; - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == CMMethod) { - storePointerUncheckedofObjectwithValue(methodIndex, arrayObj, (cogMethod->methodObject)); - methodIndex += 1; - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return methodIndex; -} - - /* CogMethodZone>>#numMethods */ -sqInt -numMethods(void) -{ - return methodCount; -} - - /* CogMethodZone>>#numMethodsOfType: */ -sqInt -numMethodsOfType(sqInt cogMethodType) -{ - CogMethod *cogMethod; - sqInt n; - - n = 0; - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == cogMethodType) { - n += 1; - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - return n; -} - - /* CogMethodZone>>#occurrencesInYoungReferrers: */ -static sqInt NoDbgRegParms -occurrencesInYoungReferrers(CogMethod *cogMethod) -{ - sqInt count; - usqInt pointer; - - assert(youngReferrers <= limitAddress); - count = 0; - pointer = youngReferrers; - while (pointer < limitAddress) { - if ((((sqInt)cogMethod)) == (longAt(pointer))) { - count += 1; - } - pointer += BytesPerWord; - } - return count; -} - - /* CogMethodZone>>#openPICWithSelector: */ -static CogMethod * NoDbgRegParms -openPICWithSelector(sqInt aSelector) -{ - CogMethod *openPIC; - - openPIC = openPICList; - do { - if ((openPIC == null) - || (((openPIC->selector)) == aSelector)) { - return openPIC; - } - openPIC = ((CogMethod *) ((openPIC->nextOpenPIC))); - } while(1); - return 0; -} - - -/* Some methods have been freed. Compute how much each survivor needs to - move during the ensuing compaction and record it in the objectHeader - field. - For Sista, where we want PICs to last so they can be observed, we need to - keep PICs unless - they are definitely unused. So we need to identify unused PICs. So in - planCompact, zero the - usage counts of all PICs, saving the actual usage count in - blockEntryOffset. Then in - relocateMethodsPreCompaction (actually in - relocateIfCallOrMethodReference:mcpc:delta:) restore the usage counts of - used PICs. Finally in compactCompiledCode, clear the blockEntryOffset - of the unused PICs; they will then have a zero count and be reclaimed in - the next code compaction. */ - - /* CogMethodZone>>#planCompaction */ -static void -planCompaction(void) -{ - CogMethod *cogMethod; - sqInt delta; - - delta = 0; - cogMethod = ((CogMethod *) baseAddress); - while ((((usqInt)cogMethod)) < mzFreeStart) { - if (((cogMethod->cmType)) == CMFree) { - delta -= (cogMethod->blockSize); - } - else { - assert((cogMethodDoesntLookKosher(cogMethod)) == 0); - ((((CogMethod *) ((((usqInt)cogMethod)) + codeToDataDelta)))->objectHeader = delta); - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* CogMethodZone>>#printCogMethods */ -void -printCogMethods(void) -{ - CogMethod *cogMethod; - sqInt nc; - sqInt nf; - sqInt nm; - sqInt no; - sqInt nu; - - /* begin printCogMethodsSummarizing: */ - nm = (nc = (no = (nf = (nu = 0)))); - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - printCogMethod(cogMethod); - switch ((cogMethod->cmType)) { - case CMFree: - nf += 1; - break; - case CMMethod: - nm += 1; - break; - case CMClosedPIC: - nc += 1; - break; - case CMOpenPIC: - no += 1; - break; - default: - nu += 1; - - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - print("CMMethod "); - printNum(nm); - print(" CMClosedPIC "); - printNum(nc); - print(" CMOpenPIC "); - printNum(no); - print(" CMFree "); - printNum(nf); - if (nu > 0) { - print(" UNKNOWN "); - printNum(nu); - } - print(" total "); - printNum((((nm + nc) + no) + nf) + nu); - cr(); -} - - /* CogMethodZone>>#printCogMethodsOfType: */ -void -printCogMethodsOfType(sqInt cmType) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if (((cogMethod->cmType)) == cmType) { - printCogMethod(cogMethod); - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* CogMethodZone>>#printCogMethodsWithMethod: */ -void -printCogMethodsWithMethod(sqInt methodOop) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) != CMFree) - && (((cogMethod->methodObject)) == methodOop)) { - printCogMethod(cogMethod); - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* CogMethodZone>>#printCogMethodsWithPrimitive: */ -void -printCogMethodsWithPrimitive(sqInt primIdx) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) == CMMethod) - && (primIdx == (primitiveIndexOfMethodheader((cogMethod->methodObject), (cogMethod->methodHeader))))) { - printCogMethod(cogMethod); - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* CogMethodZone>>#printCogMethodsWithSelector: */ -void -printCogMethodsWithSelector(sqInt selectorOop) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) baseAddress); - while (cogMethod < (limitZony())) { - if ((((cogMethod->cmType)) != CMFree) - && (((cogMethod->selector)) == selectorOop)) { - printCogMethod(cogMethod); - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } -} - - /* CogMethodZone>>#printCogYoungReferrers */ -void -printCogYoungReferrers(void) -{ - CogMethod *cogMethod; - usqInt pointer; - - pointer = youngReferrers; - while (pointer < limitAddress) { - cogMethod = ((CogMethod *) (longAt(pointer))); - if (!((cogMethod->cmRefersToYoung))) { - print("*"); - } - if (((cogMethod->cmType)) == CMFree) { - print("!"); - } - if (!(((cogMethod->cmRefersToYoung)) - && (((cogMethod->cmType)) != CMFree))) { - print(" "); - } - printCogMethod(cogMethod); - pointer += BytesPerWord; - } -} - - /* CogMethodZone>>#printOpenPICList */ -sqInt -printOpenPICList(void) -{ - sqInt n; - CogMethod *openPIC; - - /* begin printOpenPICListSummarizing: */ - n = 0; - openPIC = openPICList; - while (!(openPIC == null)) { - n += 1; - printCogMethod(openPIC); - openPIC = ((CogMethod *) ((openPIC->nextOpenPIC))); - } - return n; -} - - /* CogMethodZone>>#pruneYoungReferrers */ -sqInt -pruneYoungReferrers(void) -{ - usqInt dest; - usqInt next; - usqInt source; - - assert(youngReferrers <= limitAddress); - if (youngReferrers == limitAddress) { - return null; - } - dest = limitAddress; - while (1) { - next = dest - BytesPerWord; - if (!((next >= youngReferrers) - && (((((CogMethod *) (longAt(next))))->cmRefersToYoung)))) break; - dest = next; - } - assert(dest >= youngReferrers); - source = dest - BytesPerWord; - while (source >= youngReferrers) { - if (((((CogMethod *) (longAt(source))))->cmRefersToYoung)) { - assert(source < (dest - BytesPerWord)); - if (!(next == null)) { - - /* convenient first-time flag */ - next = null; - /* begin ensureWritableCodeZone */ -# if !DUAL_MAPPED_CODE_ZONE - -# endif - } - codeLongAtput((dest -= BytesPerWord), longAt(source)); - } - source -= BytesPerWord; - } - youngReferrers = dest; - assert(kosherYoungReferrers()); - return 0; -} - - /* CogMethodZone>>#relocateAndPruneYoungReferrers */ -static sqInt -relocateAndPruneYoungReferrers(void) -{ - CogMethod *cogMethod; - usqInt dest; - usqInt next; - usqInt source; - - assert(youngReferrers <= limitAddress); - if (youngReferrers == limitAddress) { - return null; - } - dest = limitAddress; - while (1) { - next = dest - BytesPerWord; - if (!((next >= youngReferrers) - && (((((cogMethod = ((CogMethod *) (longAt(next))))->cmType)) != CMFree) - && ((cogMethod->cmRefersToYoung))))) break; - if (((cogMethod->objectHeader)) != 0) { - codeLongAtput(next, (((sqInt)cogMethod)) + ((cogMethod->objectHeader))); - } - dest = next; - } - assert(dest >= youngReferrers); - source = dest - BytesPerWord; - while (source >= youngReferrers) { - cogMethod = ((CogMethod *) (longAt(source))); - if ((((cogMethod->cmType)) != CMFree) - && ((cogMethod->cmRefersToYoung))) { - assert(source < (dest - BytesPerWord)); - if (((cogMethod->objectHeader)) != 0) { - cogMethod = ((CogMethod *) ((((sqInt)cogMethod)) + (((sqInt)((cogMethod->objectHeader)))))); - } - codeLongAtput((dest -= BytesPerWord), ((sqInt)cogMethod)); - } - source -= BytesPerWord; - } - youngReferrers = dest; - return 0; -} - - -/* All surviving methods have had the amount they are going to relocate by - stored in their objectHeader fields. Relocate all relative calls so that - after the compaction of both the method containing each call and the call - target the calls invoke the same target. */ - - /* CogMethodZone>>#relocateMethodsPreCompaction */ -static sqInt -relocateMethodsPreCompaction(void) -{ - CogMethod *cogMethod; - - cogMethod = ((CogMethod *) baseAddress); - while ((((usqInt)cogMethod)) < mzFreeStart) { - if (((cogMethod->cmType)) != CMFree) { - if (((cogMethod->cmType)) == CMClosedPIC) { - relocateCallsInClosedPIC(cogMethod); - } - else { - relocateCallsAndSelfReferencesInMethod(cogMethod); - } - } - /* begin methodAfter: */ - cogMethod = ((CogMethod *) (roundUpToMethodAlignment(backEnd(), (((sqInt)cogMethod)) + ((cogMethod->blockSize))))); - } - relocateAndPruneYoungReferrers(); - return 1; -} - - /* CogMethodZone>>#removeFromOpenPICList: */ -static sqInt NoDbgRegParms -removeFromOpenPICList(CogMethod *anOpenPIC) -{ - CogMethod *prevPIC; - - assert(((anOpenPIC->cmType)) == CMOpenPIC); - if (!openPICList) { - return null; - } - assert((((openPICList->cmType)) == CMOpenPIC) - && ((((openPICList->nextOpenPIC)) == null) - || ((((((CogMethod *) ((openPICList->nextOpenPIC))))->cmType)) == CMOpenPIC))); - if (anOpenPIC == openPICList) { - - /* N.B. Use self rather than coInterpreter to avoid attempting to cast nil. - Conversion to CogMethod done in the nextOpenPIC accessor. */ - openPICList = ((CogMethod *) ((anOpenPIC->nextOpenPIC))); - return null; - } - prevPIC = openPICList; - do { - assert((prevPIC != null) - && (((prevPIC->cmType)) == CMOpenPIC)); - if (((prevPIC->nextOpenPIC)) == (((usqInt)anOpenPIC))) { - ((((CogMethod *) ((((usqInt)prevPIC)) + codeToDataDelta)))->nextOpenPIC = (anOpenPIC->nextOpenPIC)); - return null; - } - prevPIC = ((CogMethod *) ((prevPIC->nextOpenPIC))); - } while(1); - return 0; -} - - -/* Determine the default alignment for the start of a CogMethod, which in - turn determines the size of the mask used to distinguish the checked and - unchecked entry-points, used to distinguish normal and super sends on - method unlinking. - This is passed onto the backEnd to allow processors with coarse - instructions (ARM) to increase the alignment if required. */ - - /* CogMethodZone>>#roundUpLength: */ -static sqInt NoDbgRegParms -roundUpLength(sqInt numBytes) -{ - return roundUpToMethodAlignment(backEnd(), numBytes); -} - - /* CogMethodZone>>#voidOpenPICList */ -static void -voidOpenPICList(void) -{ - openPICList = null; -} - - /* CogMethodZone>>#voidUnpairedMethodList */ -static void -voidUnpairedMethodList(void) -{ - } - - /* CogMethodZone>>#voidYoungReferrersPostTenureAll */ -static void -voidYoungReferrersPostTenureAll(void) -{ - CogMethod *cogMethod; - usqInt pointer; - - assert(youngReferrers <= limitAddress); - pointer = youngReferrers; - while (pointer < limitAddress) { - cogMethod = ((CogMethod *) (longAt(pointer))); - if (((cogMethod->cmType)) != CMFree) { - (cogMethod->cmRefersToYoung = 0); - } - pointer += BytesPerWord; - } - youngReferrers = limitAddress; -} - - -/* useful for VM debugging; use export: so it will be accessible on win32 */ - - /* CogMethodZone>>#whereIsMaybeCodeThing: */ -EXPORT(char *) -whereIsMaybeCodeThing(sqInt anOop) -{ - if (oopisGreaterThanOrEqualToandLessThan(anOop, codeBase, limitAddress)) { - if (oopisLessThan(anOop, minCogMethodAddress())) { - return " is in generated runtime"; - } - if (oopisLessThan(anOop, mzFreeStart)) { - return " is in generated methods"; - } - if (oopisLessThan(anOop, youngReferrers)) { - return " is in code zone"; - } - return " is in young referrers"; - } - return null; -} - - /* CogMIPSELCompiler>>#addiuR:R:C: */ -static sqInt NoDbgRegParms -addiuRRC(AbstractInstruction * self_in_addiuRRC, sqInt destReg, sqInt srcReg, sqInt imm) -{ - return itypersrtsignedImmediate(self_in_addiuRRC, ADDIU, srcReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#adduR:R:R: */ -static sqInt NoDbgRegParms -adduRRR(AbstractInstruction * self_in_adduRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_adduRRR, SPECIAL, leftReg, rightReg, destReg, 0, ADDU); -} - - /* CogMIPSELCompiler>>#andiR:R:C: */ -static sqInt NoDbgRegParms -andiRRC(AbstractInstruction * self_in_andiRRC, sqInt destReg, sqInt srcReg, sqInt imm) -{ - return itypersrteitherImmediate(self_in_andiRRC, ANDI, srcReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#andR:R:R: */ -static sqInt NoDbgRegParms -andRRR(AbstractInstruction * self_in_andRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_andRRR, SPECIAL, leftReg, rightReg, destReg, 0, AND); -} - - /* CogMIPSELCompiler>>#beqR:R:offset: */ -static sqInt NoDbgRegParms -beqRRoffset(AbstractInstruction * self_in_beqRRoffset, sqInt leftReg, sqInt rightReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_beqRRoffset, BEQ, leftReg, rightReg, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#bgezR:offset: */ -static sqInt NoDbgRegParms -bgezRoffset(AbstractInstruction * self_in_bgezRoffset, sqInt cmpReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_bgezRoffset, REGIMM, cmpReg, BGEZ, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#bgtzR:offset: */ -static sqInt NoDbgRegParms -bgtzRoffset(AbstractInstruction * self_in_bgtzRoffset, sqInt cmpReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_bgtzRoffset, BGTZ, cmpReg, 0, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#blezR:offset: */ -static sqInt NoDbgRegParms -blezRoffset(AbstractInstruction * self_in_blezRoffset, sqInt cmpReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_blezRoffset, BLEZ, cmpReg, 0, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#bltzR:offset: */ -static sqInt NoDbgRegParms -bltzRoffset(AbstractInstruction * self_in_bltzRoffset, sqInt cmpReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_bltzRoffset, REGIMM, cmpReg, BLTZ, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#bneR:R:offset: */ -static sqInt NoDbgRegParms -bneRRoffset(AbstractInstruction * self_in_bneRRoffset, sqInt leftReg, sqInt rightReg, sqInt offset) -{ - assert((offset & 3) == 0); - assert(((offset >= -131072) && (offset <= 0x1FFFF))); - return itypersrtsignedImmediate(self_in_bneRRoffset, BNE, leftReg, rightReg, (offset) >> 2); -} - - /* CogMIPSELCompiler>>#callInstructionByteSize */ -static sqInt NoDbgRegParms -callInstructionByteSize(AbstractInstruction * self_in_callInstructionByteSize) -{ - flag("todo"); - return 16; -} - - -/* csra - 16: lui t9, high - csra - 12: ori t9, low - csra - 8: jalr t9 - csra - 4: nop (delay slot) */ - - /* CogMIPSELCompiler>>#callTargetFromReturnAddress: */ -static usqInt NoDbgRegParms -callTargetFromReturnAddress(AbstractInstruction * self_in_callTargetFromReturnAddress, sqInt callSiteReturnAddress) -{ - assert((opcodeAtAddress(self_in_callTargetFromReturnAddress, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_callTargetFromReturnAddress, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_callTargetFromReturnAddress, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_callTargetFromReturnAddress, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_callTargetFromReturnAddress))); - return literalAtAddress(self_in_callTargetFromReturnAddress, callSiteReturnAddress - 12); -} - - -/* NOTE: the right reg (rt) MUST equal dest reg (rd) or behavior is undefined */ - - /* CogMIPSELCompiler>>#clzR:R:R: */ -static sqInt NoDbgRegParms -clzRRR(AbstractInstruction * self_in_clzRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_clzRRR, SPECIAL, leftReg, rightReg, destReg, 0, 32); -} - - /* CogMIPSELCompiler>>#cmpC32RTempByteSize */ -static sqInt NoDbgRegParms -cmpC32RTempByteSize(AbstractInstruction * self_in_cmpC32RTempByteSize) -{ - return 8; -} - - -/* Each MIPS instruction has 4 bytes. Many abstract opcodes need more than - one instruction. Instructions that refer to constants and/or literals - depend on literals - being stored in-line or out-of-line. - - N.B. The ^N forms are to get around the bytecode compiler's long branch - limits which are exceeded when each case jumps around the otherwise. */ - - /* CogMIPSELCompiler>>#computeMaximumSize */ -static sqInt NoDbgRegParms -computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize) -{ - switch ((self_in_computeMaximumSize->opcode)) { - case BrEqualRR: - case BrNotEqualRR: - case JumpR: - case Jump: - case JumpZero: - case JumpNonZero: - case JumpNegative: - case JumpNonNegative: - case JumpOverflow: - case JumpNoOverflow: - case JumpCarry: - case JumpNoCarry: - case JumpLess: - case JumpGreaterOrEqual: - case JumpGreater: - case JumpLessOrEqual: - case JumpBelow: - case JumpAboveOrEqual: - case JumpAbove: - case JumpBelowOrEqual: - case JumpFPEqual: - case JumpFPNotEqual: - case JumpFPLess: - case JumpFPGreaterOrEqual: - case JumpFPGreater: - case JumpFPLessOrEqual: - case JumpFPOrdered: - case JumpFPUnordered: - case RetN: - case MoveCwR: - case MoveXbrRR: - case MoveRXbrR: - case PopR: - case PushR: - case ConvertRRd: - return 8; - - case BrUnsignedLessRR: - case BrUnsignedLessEqualRR: - case BrUnsignedGreaterRR: - case BrUnsignedGreaterEqualRR: - case BrSignedLessRR: - case BrSignedLessEqualRR: - case BrSignedGreaterRR: - case BrSignedGreaterEqualRR: - case XorCqR: - case AddCwR: - case AndCwR: - case OrCwR: - case SubCwR: - case XorCwR: - case MoveXwrRR: - case MoveRXwrR: - case PrefetchAw: - return 12; - - case BrLongEqualRR: - case BrLongNotEqualRR: - case PushCw: - case PushCq: - return 16; - - case MulRR: - case DivRR: - case MoveLowR: - case MoveHighR: - case Literal: - case Fill32: - case Nop: - case Stop: - case AddRR: - case AndRR: - case OrRR: - case XorRR: - case SubRR: - case NegateR: - case AddRRR: - case SubRRR: - case LogicalShiftLeftCqR: - case LogicalShiftRightCqR: - case ArithmeticShiftRightCqR: - case LogicalShiftLeftRR: - case LogicalShiftRightRR: - case ArithmeticShiftRightRR: - case AddRdRd: - case CmpRdRd: - case SubRdRd: - case MulRdRd: - case DivRdRd: - case SqrtRd: - case ClzRR: - case MoveRR: - case MoveRdRd: - case MoveRMwr: - case MoveMbrR: - case MoveRMbr: - case MoveM16rR: - case MoveRM16r: - return 4; - - case Label: - return 0; - - case AlignmentNops: - return (((self_in_computeMaximumSize->operands))[0]) - 4; - - case Call: - case CallFull: - case JumpFull: - case JumpLong: - case JumpLongZero: - case JumpLongNonZero: - return 16; - - case AddCqR: - case OrCqR: - case OrCqRR: - case SubCqR: - case TstCqR: - case LoadEffectiveAddressMwrR: - return (isShortOffset(self_in_computeMaximumSize, ((self_in_computeMaximumSize->operands))[0]) - ? 4 - : 12); - - case AndCqR: - case AndCqRR: - return ((((((self_in_computeMaximumSize->operands))[0]) >= 0) && ((((self_in_computeMaximumSize->operands))[0]) <= 0xFFFF)) - ? 4 - : 12); - - case CmpCqR: - case CmpCwR: - case AddCheckOverflowCqR: - case SubCheckOverflowCqR: - return 28; - - case CmpRR: - case AddCheckOverflowRR: - case SubCheckOverflowRR: - case MulCheckOverflowRR: - return 20; - - case MoveCqR: - return (isShortOffset(self_in_computeMaximumSize, ((self_in_computeMaximumSize->operands))[0]) - ? 4 - : 8); - - case MoveAwR: - case MoveAbR: - return (((((self_in_computeMaximumSize->operands))[0]) != null) - && ((((varBaseAddress()) - (0x8000)) < (((self_in_computeMaximumSize->operands))[0])) - && ((((self_in_computeMaximumSize->operands))[0]) < ((varBaseAddress()) + (0x8000)))) - ? 4 - : 12); - - case MoveRAw: - case MoveRAb: - return (((((self_in_computeMaximumSize->operands))[1]) != null) - && ((((varBaseAddress()) - (0x8000)) < (((self_in_computeMaximumSize->operands))[1])) - && ((((self_in_computeMaximumSize->operands))[1]) < ((varBaseAddress()) + (0x8000)))) - ? 4 - : 12); - - case MoveRdM64r: - case MoveM64rRd: - return 12; - - case MoveMwrR: - return (isShortOffset(self_in_computeMaximumSize, ((self_in_computeMaximumSize->operands))[0]) - ? 4 - : 16); - - default: - error("Case not found and no otherwise clause"); - } - return 0; -} - - /* CogMIPSELCompiler>>#concretizeAddCheckOverflowCqR */ -static sqInt NoDbgRegParms -concretizeAddCheckOverflowCqR(AbstractInstruction * self_in_concretizeAddCheckOverflowCqR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - sqInt aWord4; - sqInt aWord5; - sqInt aWord6; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeAddCheckOverflowCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAddCheckOverflowCqR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeAddCheckOverflowCqR, AT, high16BitsOf(self_in_concretizeAddCheckOverflowCqR, rightImm)); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeAddCheckOverflowCqR, AT, AT, low16BitsOf(self_in_concretizeAddCheckOverflowCqR, rightImm)); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = adduRRR(self_in_concretizeAddCheckOverflowCqR, OverflowTemp1, leftReg, ZR); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = adduRRR(self_in_concretizeAddCheckOverflowCqR, destReg, leftReg, AT); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[12 / 4] = aWord3; - /* begin machineCodeAt:put: */ - aWord4 = xorRRR(self_in_concretizeAddCheckOverflowCqR, OverflowTemp2, destReg, AT); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[16 / 4] = aWord4; - /* begin machineCodeAt:put: */ - aWord5 = xorRRR(self_in_concretizeAddCheckOverflowCqR, OverflowTemp1, destReg, OverflowTemp1); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[20 / 4] = aWord5; - /* begin machineCodeAt:put: */ - aWord6 = andRRR(self_in_concretizeAddCheckOverflowCqR, Overflow, OverflowTemp1, OverflowTemp2); - ((self_in_concretizeAddCheckOverflowCqR->machineCode))[24 / 4] = aWord6; - return 28; -} - - /* CogMIPSELCompiler>>#concretizeAddCheckOverflowRR */ -static sqInt NoDbgRegParms -concretizeAddCheckOverflowRR(AbstractInstruction * self_in_concretizeAddCheckOverflowRR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - sqInt aWord4; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeAddCheckOverflowRR->operands))[0]; - - /* Save original LHS */ - destReg = (leftReg = ((self_in_concretizeAddCheckOverflowRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeAddCheckOverflowRR, OverflowTemp1, leftReg, ZR); - ((self_in_concretizeAddCheckOverflowRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = adduRRR(self_in_concretizeAddCheckOverflowRR, destReg, leftReg, rightReg); - ((self_in_concretizeAddCheckOverflowRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = xorRRR(self_in_concretizeAddCheckOverflowRR, OverflowTemp2, destReg, rightReg); - ((self_in_concretizeAddCheckOverflowRR->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = xorRRR(self_in_concretizeAddCheckOverflowRR, OverflowTemp1, destReg, OverflowTemp1); - ((self_in_concretizeAddCheckOverflowRR->machineCode))[12 / 4] = aWord3; - /* begin machineCodeAt:put: */ - aWord4 = andRRR(self_in_concretizeAddCheckOverflowRR, Overflow, OverflowTemp1, OverflowTemp2); - ((self_in_concretizeAddCheckOverflowRR->machineCode))[16 / 4] = aWord4; - return 20; -} - - /* CogMIPSELCompiler>>#concretizeAddCqR */ -static sqInt NoDbgRegParms -concretizeAddCqR(AbstractInstruction * self_in_concretizeAddCqR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeAddCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAddCqR->operands))[1]); - if (!(isShortOffset(self_in_concretizeAddCqR, rightImm))) { - return concretizeAddCwR(self_in_concretizeAddCqR); - } - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizeAddCqR, destReg, leftReg, rightImm); - ((self_in_concretizeAddCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeAddCwR */ -static sqInt NoDbgRegParms -concretizeAddCwR(AbstractInstruction * self_in_concretizeAddCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeAddCwR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAddCwR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeAddCwR, AT, high16BitsOf(self_in_concretizeAddCwR, rightImm)); - ((self_in_concretizeAddCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeAddCwR, AT, AT, low16BitsOf(self_in_concretizeAddCwR, rightImm)); - ((self_in_concretizeAddCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = adduRRR(self_in_concretizeAddCwR, destReg, leftReg, AT); - ((self_in_concretizeAddCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeAddRRDest: */ -static sqInt NoDbgRegParms -concretizeAddRRDest(AbstractInstruction * self_in_concretizeAddRRDest, sqInt destReg) -{ - sqInt aWord; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeAddRRDest->operands))[0]; - leftReg = ((self_in_concretizeAddRRDest->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeAddRRDest, destReg, leftReg, rightReg); - ((self_in_concretizeAddRRDest->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeAlignmentNops */ -static usqInt NoDbgRegParms -concretizeAlignmentNops(AbstractInstruction * self_in_concretizeAlignmentNops) -{ - sqInt p; - - assert((((self_in_concretizeAlignmentNops->machineCodeSize)) % 4) == 0); - for (p = 0; p < ((self_in_concretizeAlignmentNops->machineCodeSize)); p += 4) { - /* begin machineCodeAt:put: */ - ((self_in_concretizeAlignmentNops->machineCode))[p / 4] = 0 /* nop */; - } - return (self_in_concretizeAlignmentNops->machineCodeSize); -} - - /* CogMIPSELCompiler>>#concretizeAndCqR */ -static sqInt NoDbgRegParms -concretizeAndCqR(AbstractInstruction * self_in_concretizeAndCqR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeAndCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAndCqR->operands))[1]); - if (!(isShortOffset(self_in_concretizeAndCqR, rightImm))) { - return concretizeAndCwR(self_in_concretizeAndCqR); - } - /* begin machineCodeAt:put: */ - aWord = andiRRC(self_in_concretizeAndCqR, destReg, leftReg, rightImm); - ((self_in_concretizeAndCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeAndCqRDest: */ -static sqInt NoDbgRegParms -concretizeAndCqRDest(AbstractInstruction * self_in_concretizeAndCqRDest, sqInt destReg) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt srcReg; - usqInt value; - - value = ((self_in_concretizeAndCqRDest->operands))[0]; - srcReg = ((self_in_concretizeAndCqRDest->operands))[1]; - if (((value >= 0) && (value <= 0xFFFF))) { - /* begin machineCodeAt:put: */ - aWord = andiRRC(self_in_concretizeAndCqRDest, destReg, srcReg, value); - ((self_in_concretizeAndCqRDest->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeAndCqRDest, AT, high16BitsOf(self_in_concretizeAndCqRDest, value)); - ((self_in_concretizeAndCqRDest->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeAndCqRDest, AT, AT, low16BitsOf(self_in_concretizeAndCqRDest, value)); - ((self_in_concretizeAndCqRDest->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = andRRR(self_in_concretizeAndCqRDest, destReg, srcReg, AT); - ((self_in_concretizeAndCqRDest->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeAndCwR */ -static sqInt NoDbgRegParms -concretizeAndCwR(AbstractInstruction * self_in_concretizeAndCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeAndCwR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAndCwR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeAndCwR, AT, high16BitsOf(self_in_concretizeAndCwR, rightImm)); - ((self_in_concretizeAndCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeAndCwR, AT, AT, low16BitsOf(self_in_concretizeAndCwR, rightImm)); - ((self_in_concretizeAndCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = andRRR(self_in_concretizeAndCwR, destReg, leftReg, AT); - ((self_in_concretizeAndCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeAndRR */ -static sqInt NoDbgRegParms -concretizeAndRR(AbstractInstruction * self_in_concretizeAndRR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeAndRR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeAndRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = andRRR(self_in_concretizeAndRR, destReg, leftReg, rightReg); - ((self_in_concretizeAndRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeArithmeticShiftRightCqR */ -static sqInt NoDbgRegParms -concretizeArithmeticShiftRightCqR(AbstractInstruction * self_in_concretizeArithmeticShiftRightCqR) -{ - sqInt aWord; - sqInt distance; - usqInt reg; - - distance = (((((self_in_concretizeArithmeticShiftRightCqR->operands))[0]) < 0x1F) ? (((self_in_concretizeArithmeticShiftRightCqR->operands))[0]) : 0x1F); - reg = ((self_in_concretizeArithmeticShiftRightCqR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = sraRRC(self_in_concretizeArithmeticShiftRightCqR, reg, reg, distance); - ((self_in_concretizeArithmeticShiftRightCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeArithmeticShiftRightRR */ -static sqInt NoDbgRegParms -concretizeArithmeticShiftRightRR(AbstractInstruction * self_in_concretizeArithmeticShiftRightRR) -{ - sqInt aWord; - usqInt destReg; - usqInt distReg; - - distReg = ((self_in_concretizeArithmeticShiftRightRR->operands))[0]; - destReg = ((self_in_concretizeArithmeticShiftRightRR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = sravRRR(self_in_concretizeArithmeticShiftRightRR, destReg, destReg, distReg); - ((self_in_concretizeArithmeticShiftRightRR->machineCode))[0 / 4] = aWord; - return 4; -} - - -/* Generate concrete machine code for the instruction at actualAddress, - setting machineCodeSize, and answer the following address. */ -/* Generate concrete machine code for the instruction at actualAddress, - setting machineCodeSize, and answer the following address. */ - - /* CogMIPSELCompiler>>#concretizeAt: */ -static sqInt NoDbgRegParms -concretizeAt(AbstractInstruction * self_in_concretizeAt, sqInt actualAddress) -{ - assert((actualAddress % 4) == 0); - (self_in_concretizeAt->address) = actualAddress; - (self_in_concretizeAt->machineCodeSize) = dispatchConcretize(self_in_concretizeAt); - assert((((self_in_concretizeAt->maxSize)) == null) - || (((self_in_concretizeAt->maxSize)) >= ((self_in_concretizeAt->machineCodeSize)))); - return actualAddress + ((self_in_concretizeAt->machineCodeSize)); -} - - /* CogMIPSELCompiler>>#concretizeBrEqualRR */ -static sqInt NoDbgRegParms -concretizeBrEqualRR(AbstractInstruction * self_in_concretizeBrEqualRR) -{ - sqInt aWord; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrEqualRR->address)) + 4))); - leftReg = ((self_in_concretizeBrEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrEqualRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = beqRRoffset(self_in_concretizeBrEqualRR, leftReg, rightReg, offset); - ((self_in_concretizeBrEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrEqualRR->machineCode))[4 / 4] = 0 /* nop */; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeBrLongEqualRR */ -static sqInt NoDbgRegParms -concretizeBrLongEqualRR(AbstractInstruction * self_in_concretizeBrLongEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - usqInt jumpTargetAddr; - AbstractInstruction *jumpTargetInstruction; - usqInt leftReg; - usqInt rightReg; - - /* begin longJumpTargetAddress */ - jumpTarget = ((AbstractInstruction *) (((self_in_concretizeBrLongEqualRR->operands))[0])); - if ((addressIsInInstructions(jumpTarget)) - || (jumpTarget == (methodLabel()))) { - jumpTarget = ((AbstractInstruction *) ((jumpTarget->address))); - } - assert(jumpTarget != 0); - jumpTargetInstruction = jumpTarget; - flag("todo"); - jumpTargetAddr = (((usqInt)jumpTargetInstruction)) & 0xFFFFFFF; - leftReg = ((self_in_concretizeBrLongEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrLongEqualRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = bneRRoffset(self_in_concretizeBrLongEqualRR, leftReg, rightReg, 12); - ((self_in_concretizeBrLongEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrLongEqualRR->machineCode))[4 / 4] = 0 /* nop */; - /* begin machineCodeAt:put: */ - aWord1 = jA(self_in_concretizeBrLongEqualRR, jumpTargetAddr); - ((self_in_concretizeBrLongEqualRR->machineCode))[8 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrLongEqualRR->machineCode))[12 / 4] = 0 /* nop */; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeBrLongNotEqualRR */ -static sqInt NoDbgRegParms -concretizeBrLongNotEqualRR(AbstractInstruction * self_in_concretizeBrLongNotEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - usqInt jumpTargetAddr; - AbstractInstruction *jumpTargetInstruction; - usqInt leftReg; - usqInt rightReg; - - /* begin longJumpTargetAddress */ - jumpTarget = ((AbstractInstruction *) (((self_in_concretizeBrLongNotEqualRR->operands))[0])); - if ((addressIsInInstructions(jumpTarget)) - || (jumpTarget == (methodLabel()))) { - jumpTarget = ((AbstractInstruction *) ((jumpTarget->address))); - } - assert(jumpTarget != 0); - jumpTargetInstruction = jumpTarget; - flag("todo"); - jumpTargetAddr = (((usqInt)jumpTargetInstruction)) & 0xFFFFFFF; - leftReg = ((self_in_concretizeBrLongNotEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrLongNotEqualRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = beqRRoffset(self_in_concretizeBrLongNotEqualRR, leftReg, rightReg, 12); - ((self_in_concretizeBrLongNotEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrLongNotEqualRR->machineCode))[4 / 4] = 0 /* nop */; - /* begin machineCodeAt:put: */ - aWord1 = jA(self_in_concretizeBrLongNotEqualRR, jumpTargetAddr); - ((self_in_concretizeBrLongNotEqualRR->machineCode))[8 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrLongNotEqualRR->machineCode))[12 / 4] = 0 /* nop */; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeBrNotEqualRR */ -static sqInt NoDbgRegParms -concretizeBrNotEqualRR(AbstractInstruction * self_in_concretizeBrNotEqualRR) -{ - sqInt aWord; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrNotEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrNotEqualRR->address)) + 4))); - leftReg = ((self_in_concretizeBrNotEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrNotEqualRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = bneRRoffset(self_in_concretizeBrNotEqualRR, leftReg, rightReg, offset); - ((self_in_concretizeBrNotEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrNotEqualRR->machineCode))[4 / 4] = 0 /* nop */; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeBrSignedGreaterEqualRR */ -static sqInt NoDbgRegParms -concretizeBrSignedGreaterEqualRR(AbstractInstruction * self_in_concretizeBrSignedGreaterEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrSignedGreaterEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrSignedGreaterEqualRR->address)) + 8))); - leftReg = ((self_in_concretizeBrSignedGreaterEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrSignedGreaterEqualRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltRRR(self_in_concretizeBrSignedGreaterEqualRR, BranchTemp, leftReg, rightReg); - ((self_in_concretizeBrSignedGreaterEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = beqRRoffset(self_in_concretizeBrSignedGreaterEqualRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrSignedGreaterEqualRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrSignedGreaterEqualRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrSignedGreaterRR */ -static sqInt NoDbgRegParms -concretizeBrSignedGreaterRR(AbstractInstruction * self_in_concretizeBrSignedGreaterRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrSignedGreaterRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrSignedGreaterRR->address)) + 8))); - leftReg = ((self_in_concretizeBrSignedGreaterRR->operands))[1]; - rightReg = ((self_in_concretizeBrSignedGreaterRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltRRR(self_in_concretizeBrSignedGreaterRR, BranchTemp, rightReg, leftReg); - ((self_in_concretizeBrSignedGreaterRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = bneRRoffset(self_in_concretizeBrSignedGreaterRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrSignedGreaterRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrSignedGreaterRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrSignedLessEqualRR */ -static sqInt NoDbgRegParms -concretizeBrSignedLessEqualRR(AbstractInstruction * self_in_concretizeBrSignedLessEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrSignedLessEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrSignedLessEqualRR->address)) + 8))); - leftReg = ((self_in_concretizeBrSignedLessEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrSignedLessEqualRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltRRR(self_in_concretizeBrSignedLessEqualRR, BranchTemp, rightReg, leftReg); - ((self_in_concretizeBrSignedLessEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = beqRRoffset(self_in_concretizeBrSignedLessEqualRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrSignedLessEqualRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrSignedLessEqualRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrSignedLessRR */ -static sqInt NoDbgRegParms -concretizeBrSignedLessRR(AbstractInstruction * self_in_concretizeBrSignedLessRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrSignedLessRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrSignedLessRR->address)) + 8))); - leftReg = ((self_in_concretizeBrSignedLessRR->operands))[1]; - rightReg = ((self_in_concretizeBrSignedLessRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltRRR(self_in_concretizeBrSignedLessRR, BranchTemp, leftReg, rightReg); - ((self_in_concretizeBrSignedLessRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = bneRRoffset(self_in_concretizeBrSignedLessRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrSignedLessRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrSignedLessRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrUnsignedGreaterEqualRR */ -static sqInt NoDbgRegParms -concretizeBrUnsignedGreaterEqualRR(AbstractInstruction * self_in_concretizeBrUnsignedGreaterEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrUnsignedGreaterEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrUnsignedGreaterEqualRR->address)) + 8))); - leftReg = ((self_in_concretizeBrUnsignedGreaterEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrUnsignedGreaterEqualRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltuRRR(self_in_concretizeBrUnsignedGreaterEqualRR, BranchTemp, leftReg, rightReg); - ((self_in_concretizeBrUnsignedGreaterEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = beqRRoffset(self_in_concretizeBrUnsignedGreaterEqualRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrUnsignedGreaterEqualRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrUnsignedGreaterEqualRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrUnsignedGreaterRR */ -static sqInt NoDbgRegParms -concretizeBrUnsignedGreaterRR(AbstractInstruction * self_in_concretizeBrUnsignedGreaterRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrUnsignedGreaterRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrUnsignedGreaterRR->address)) + 8))); - leftReg = ((self_in_concretizeBrUnsignedGreaterRR->operands))[1]; - rightReg = ((self_in_concretizeBrUnsignedGreaterRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltuRRR(self_in_concretizeBrUnsignedGreaterRR, BranchTemp, rightReg, leftReg); - ((self_in_concretizeBrUnsignedGreaterRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = bneRRoffset(self_in_concretizeBrUnsignedGreaterRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrUnsignedGreaterRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrUnsignedGreaterRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrUnsignedLessEqualRR */ -static sqInt NoDbgRegParms -concretizeBrUnsignedLessEqualRR(AbstractInstruction * self_in_concretizeBrUnsignedLessEqualRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrUnsignedLessEqualRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrUnsignedLessEqualRR->address)) + 8))); - leftReg = ((self_in_concretizeBrUnsignedLessEqualRR->operands))[1]; - rightReg = ((self_in_concretizeBrUnsignedLessEqualRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltuRRR(self_in_concretizeBrUnsignedLessEqualRR, BranchTemp, rightReg, leftReg); - ((self_in_concretizeBrUnsignedLessEqualRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = beqRRoffset(self_in_concretizeBrUnsignedLessEqualRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrUnsignedLessEqualRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrUnsignedLessEqualRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeBrUnsignedLessRR */ -static sqInt NoDbgRegParms -concretizeBrUnsignedLessRR(AbstractInstruction * self_in_concretizeBrUnsignedLessRR) -{ - sqInt aWord; - sqInt aWord1; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - usqInt leftReg; - sqInt offset; - usqInt rightReg; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeBrUnsignedLessRR->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeBrUnsignedLessRR->address)) + 8))); - leftReg = ((self_in_concretizeBrUnsignedLessRR->operands))[1]; - rightReg = ((self_in_concretizeBrUnsignedLessRR->operands))[2]; - assert(leftReg != BranchTemp); - assert(rightReg != BranchTemp); - /* begin machineCodeAt:put: */ - aWord = sltuRRR(self_in_concretizeBrUnsignedLessRR, BranchTemp, leftReg, rightReg); - ((self_in_concretizeBrUnsignedLessRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = bneRRoffset(self_in_concretizeBrUnsignedLessRR, BranchTemp, ZR, offset); - ((self_in_concretizeBrUnsignedLessRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - ((self_in_concretizeBrUnsignedLessRR->machineCode))[8 / 4] = 0 /* nop */; - return 12; -} - - -/* Call is used only for calls within code-space, See CallFull for general - anywhere in address space calling - */ -/* Relative branches in MIPS have a displacement of +/- 131kB (signed 18 - bits), which is too small to cover - the method zone. */ - - /* CogMIPSELCompiler>>#concretizeCall */ -static sqInt NoDbgRegParms -concretizeCall(AbstractInstruction * self_in_concretizeCall) -{ - return concretizeCallFull(self_in_concretizeCall); -} - - /* CogMIPSELCompiler>>#concretizeCallFull */ -static sqInt NoDbgRegParms -concretizeCallFull(AbstractInstruction * self_in_concretizeCallFull) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - AbstractInstruction *jumpTarget; - usqInt jumpTargetAddr; - AbstractInstruction *jumpTargetInstruction; - - /* begin longJumpTargetAddress */ - jumpTarget = ((AbstractInstruction *) (((self_in_concretizeCallFull->operands))[0])); - if ((addressIsInInstructions(jumpTarget)) - || (jumpTarget == (methodLabel()))) { - jumpTarget = ((AbstractInstruction *) ((jumpTarget->address))); - } - assert(jumpTarget != 0); - jumpTargetInstruction = jumpTarget; - jumpTargetAddr = ((usqInt)jumpTargetInstruction); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeCallFull, TargetReg, high16BitsOf(self_in_concretizeCallFull, jumpTargetAddr)); - ((self_in_concretizeCallFull->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeCallFull, TargetReg, TargetReg, low16BitsOf(self_in_concretizeCallFull, jumpTargetAddr)); - ((self_in_concretizeCallFull->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = jalR(self_in_concretizeCallFull, TargetReg); - ((self_in_concretizeCallFull->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - ((self_in_concretizeCallFull->machineCode))[12 / 4] = 0 /* nop */; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeClzRR */ -static sqInt NoDbgRegParms -concretizeClzRR(AbstractInstruction * self_in_concretizeClzRR) -{ - sqInt aWord; - usqInt destReg; - usqInt maskReg; - usqInt rightReg; - - maskReg = ((self_in_concretizeClzRR->operands))[0]; - destReg = (rightReg = ((self_in_concretizeClzRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = clzRRR(self_in_concretizeClzRR, destReg, maskReg, rightReg); - ((self_in_concretizeClzRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeCmpCqR */ -static sqInt NoDbgRegParms -concretizeCmpCqR(AbstractInstruction * self_in_concretizeCmpCqR) -{ - return concretizeCmpCwR(self_in_concretizeCmpCqR); -} - - /* CogMIPSELCompiler>>#concretizeCmpCwR */ -static sqInt NoDbgRegParms -concretizeCmpCwR(AbstractInstruction * self_in_concretizeCmpCwR) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeCmpRR */ -static sqInt NoDbgRegParms -concretizeCmpRR(AbstractInstruction * self_in_concretizeCmpRR) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeDivRR */ -static sqInt NoDbgRegParms -concretizeDivRR(AbstractInstruction * self_in_concretizeDivRR) -{ - sqInt aWord; - usqInt dividendReg; - usqInt divisorReg; - - dividendReg = ((self_in_concretizeDivRR->operands))[0]; - divisorReg = ((self_in_concretizeDivRR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = divRR(self_in_concretizeDivRR, dividendReg, divisorReg); - ((self_in_concretizeDivRR->machineCode))[0 / 4] = aWord; - return 4; -} - - -/* fill with operand 0 according to the processor's endianness. - You might think this is bogus and we should fill with stop instrurctions - instead, but this is used to leave room for a CMBlock header before the - code for a block; - the gaps get filled in by fillInBlockHeadersAt: after code has been - generated. */ - - /* CogMIPSELCompiler>>#concretizeFill32 */ -static sqInt NoDbgRegParms -concretizeFill32(AbstractInstruction * self_in_concretizeFill32) -{ - sqInt aWord; - - /* begin machineCodeAt:put: */ - aWord = ((self_in_concretizeFill32->operands))[0]; - ((self_in_concretizeFill32->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeJump */ -static sqInt NoDbgRegParms -concretizeJump(AbstractInstruction * self_in_concretizeJump) -{ - sqInt aWord; - AbstractInstruction *jumpTarget; - AbstractInstruction *jumpTarget1; - sqInt offset; - - /* begin computeJumpTargetOffsetPlus: */ - jumpTarget1 = ((AbstractInstruction *) (((self_in_concretizeJump->operands))[0])); - assertSaneJumpTarget(jumpTarget1); - if ((addressIsInInstructions(jumpTarget1)) - || (jumpTarget1 == (methodLabel()))) { - jumpTarget1 = ((AbstractInstruction *) ((jumpTarget1->address))); - } - assert(jumpTarget1 != 0); - jumpTarget = jumpTarget1; - offset = (((int) jumpTarget)) - (((int) (((self_in_concretizeJump->address)) + 4))); - flag("BranchRange"); - /* begin machineCodeAt:put: */ - aWord = beqRRoffset(self_in_concretizeJump, ZR, ZR, offset); - ((self_in_concretizeJump->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeJump->machineCode))[4 / 4] = 0 /* nop */; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeJumpFull */ -static sqInt NoDbgRegParms -concretizeJumpFull(AbstractInstruction * self_in_concretizeJumpFull) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - AbstractInstruction *jumpTarget; - usqInt jumpTargetAddr; - AbstractInstruction *jumpTargetInstruction; - - /* begin longJumpTargetAddress */ - jumpTarget = ((AbstractInstruction *) (((self_in_concretizeJumpFull->operands))[0])); - if ((addressIsInInstructions(jumpTarget)) - || (jumpTarget == (methodLabel()))) { - jumpTarget = ((AbstractInstruction *) ((jumpTarget->address))); - } - assert(jumpTarget != 0); - jumpTargetInstruction = jumpTarget; - jumpTargetAddr = ((usqInt)jumpTargetInstruction); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeJumpFull, TargetReg, high16BitsOf(self_in_concretizeJumpFull, jumpTargetAddr)); - ((self_in_concretizeJumpFull->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeJumpFull, TargetReg, TargetReg, low16BitsOf(self_in_concretizeJumpFull, jumpTargetAddr)); - ((self_in_concretizeJumpFull->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = jR(self_in_concretizeJumpFull, TargetReg); - ((self_in_concretizeJumpFull->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - ((self_in_concretizeJumpFull->machineCode))[12 / 4] = 0 /* nop */; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeJumpLong */ -static sqInt NoDbgRegParms -concretizeJumpLong(AbstractInstruction * self_in_concretizeJumpLong) -{ - return concretizeJumpFull(self_in_concretizeJumpLong); -} - - /* CogMIPSELCompiler>>#concretizeJumpLongNonZero */ -static sqInt NoDbgRegParms -concretizeJumpLongNonZero(AbstractInstruction * self_in_concretizeJumpLongNonZero) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpLongZero */ -static sqInt NoDbgRegParms -concretizeJumpLongZero(AbstractInstruction * self_in_concretizeJumpLongZero) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpNonZero */ -static sqInt NoDbgRegParms -concretizeJumpNonZero(AbstractInstruction * self_in_concretizeJumpNonZero) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpNoOverflow */ -static sqInt NoDbgRegParms -concretizeJumpNoOverflow(AbstractInstruction * self_in_concretizeJumpNoOverflow) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpOverflow */ -static sqInt NoDbgRegParms -concretizeJumpOverflow(AbstractInstruction * self_in_concretizeJumpOverflow) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpR */ -static sqInt NoDbgRegParms -concretizeJumpR(AbstractInstruction * self_in_concretizeJumpR) -{ - sqInt aWord; - usqInt reg; - - flag("OABI"); - reg = ((self_in_concretizeJumpR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = jR(self_in_concretizeJumpR, reg); - ((self_in_concretizeJumpR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - ((self_in_concretizeJumpR->machineCode))[4 / 4] = 0 /* nop */; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeJumpSignedGreaterEqual */ -static sqInt NoDbgRegParms -concretizeJumpSignedGreaterEqual(AbstractInstruction * self_in_concretizeJumpSignedGreaterEqual) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpSignedGreaterThan */ -static sqInt NoDbgRegParms -concretizeJumpSignedGreaterThan(AbstractInstruction * self_in_concretizeJumpSignedGreaterThan) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpSignedLessEqual */ -static sqInt NoDbgRegParms -concretizeJumpSignedLessEqual(AbstractInstruction * self_in_concretizeJumpSignedLessEqual) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpSignedLessThan */ -static sqInt NoDbgRegParms -concretizeJumpSignedLessThan(AbstractInstruction * self_in_concretizeJumpSignedLessThan) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpUnsignedGreaterEqual */ -static sqInt NoDbgRegParms -concretizeJumpUnsignedGreaterEqual(AbstractInstruction * self_in_concretizeJumpUnsignedGreaterEqual) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpUnsignedGreaterThan */ -static sqInt NoDbgRegParms -concretizeJumpUnsignedGreaterThan(AbstractInstruction * self_in_concretizeJumpUnsignedGreaterThan) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpUnsignedLessEqual */ -static sqInt NoDbgRegParms -concretizeJumpUnsignedLessEqual(AbstractInstruction * self_in_concretizeJumpUnsignedLessEqual) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpUnsignedLessThan */ -static sqInt NoDbgRegParms -concretizeJumpUnsignedLessThan(AbstractInstruction * self_in_concretizeJumpUnsignedLessThan) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeJumpZero */ -static sqInt NoDbgRegParms -concretizeJumpZero(AbstractInstruction * self_in_concretizeJumpZero) -{ - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeLoadEffectiveAddressMwrR */ -static sqInt NoDbgRegParms -concretizeLoadEffectiveAddressMwrR(AbstractInstruction * self_in_concretizeLoadEffectiveAddressMwrR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt baseReg; - usqInt destReg; - sqInt offset; - - offset = ((self_in_concretizeLoadEffectiveAddressMwrR->operands))[0]; - baseReg = ((self_in_concretizeLoadEffectiveAddressMwrR->operands))[1]; - destReg = ((self_in_concretizeLoadEffectiveAddressMwrR->operands))[2]; - if (isShortOffset(self_in_concretizeLoadEffectiveAddressMwrR, offset)) { - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizeLoadEffectiveAddressMwrR, destReg, baseReg, offset); - ((self_in_concretizeLoadEffectiveAddressMwrR->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeLoadEffectiveAddressMwrR, AT, high16BitsOf(self_in_concretizeLoadEffectiveAddressMwrR, offset)); - ((self_in_concretizeLoadEffectiveAddressMwrR->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeLoadEffectiveAddressMwrR, AT, AT, low16BitsOf(self_in_concretizeLoadEffectiveAddressMwrR, offset)); - ((self_in_concretizeLoadEffectiveAddressMwrR->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = adduRRR(self_in_concretizeLoadEffectiveAddressMwrR, destReg, baseReg, AT); - ((self_in_concretizeLoadEffectiveAddressMwrR->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeLogicalShiftLeftCqR */ -static sqInt NoDbgRegParms -concretizeLogicalShiftLeftCqR(AbstractInstruction * self_in_concretizeLogicalShiftLeftCqR) -{ - sqInt aWord; - sqInt distance; - usqInt reg; - - distance = (((((self_in_concretizeLogicalShiftLeftCqR->operands))[0]) < 0x1F) ? (((self_in_concretizeLogicalShiftLeftCqR->operands))[0]) : 0x1F); - reg = ((self_in_concretizeLogicalShiftLeftCqR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = sllRRC(self_in_concretizeLogicalShiftLeftCqR, reg, reg, distance); - ((self_in_concretizeLogicalShiftLeftCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeLogicalShiftLeftRR */ -static sqInt NoDbgRegParms -concretizeLogicalShiftLeftRR(AbstractInstruction * self_in_concretizeLogicalShiftLeftRR) -{ - sqInt aWord; - usqInt destReg; - usqInt distReg; - - distReg = ((self_in_concretizeLogicalShiftLeftRR->operands))[0]; - destReg = ((self_in_concretizeLogicalShiftLeftRR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = sllvRRR(self_in_concretizeLogicalShiftLeftRR, destReg, destReg, distReg); - ((self_in_concretizeLogicalShiftLeftRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeLogicalShiftRightCqR */ -static sqInt NoDbgRegParms -concretizeLogicalShiftRightCqR(AbstractInstruction * self_in_concretizeLogicalShiftRightCqR) -{ - sqInt aWord; - sqInt distance; - usqInt reg; - - distance = (((((self_in_concretizeLogicalShiftRightCqR->operands))[0]) < 0x1F) ? (((self_in_concretizeLogicalShiftRightCqR->operands))[0]) : 0x1F); - reg = ((self_in_concretizeLogicalShiftRightCqR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = srlRRC(self_in_concretizeLogicalShiftRightCqR, reg, reg, distance); - ((self_in_concretizeLogicalShiftRightCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeLogicalShiftRightRR */ -static sqInt NoDbgRegParms -concretizeLogicalShiftRightRR(AbstractInstruction * self_in_concretizeLogicalShiftRightRR) -{ - sqInt aWord; - usqInt destReg; - usqInt distReg; - - distReg = ((self_in_concretizeLogicalShiftRightRR->operands))[0]; - destReg = ((self_in_concretizeLogicalShiftRightRR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = srlvRRR(self_in_concretizeLogicalShiftRightRR, destReg, destReg, distReg); - ((self_in_concretizeLogicalShiftRightRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveAbR */ -static sqInt NoDbgRegParms -concretizeMoveAbR(AbstractInstruction * self_in_concretizeMoveAbR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt destReg; - usqInt srcAddr; - - srcAddr = ((self_in_concretizeMoveAbR->operands))[0]; - destReg = ((self_in_concretizeMoveAbR->operands))[1]; - if ((srcAddr != null) - && ((((varBaseAddress()) - (0x8000)) < srcAddr) - && (srcAddr < ((varBaseAddress()) + (0x8000))))) { - /* begin machineCodeAt:put: */ - aWord = lwRbaseoffset(self_in_concretizeMoveAbR, destReg, ConcreteVarBaseReg, srcAddr - (varBaseAddress())); - ((self_in_concretizeMoveAbR->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeMoveAbR, AT, high16BitsOf(self_in_concretizeMoveAbR, srcAddr)); - ((self_in_concretizeMoveAbR->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeMoveAbR, AT, AT, low16BitsOf(self_in_concretizeMoveAbR, srcAddr)); - ((self_in_concretizeMoveAbR->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = lbuRbaseoffset(self_in_concretizeMoveAbR, destReg, AT, 0); - ((self_in_concretizeMoveAbR->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMoveAwR */ -static sqInt NoDbgRegParms -concretizeMoveAwR(AbstractInstruction * self_in_concretizeMoveAwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt destReg; - usqInt srcAddr; - - srcAddr = ((self_in_concretizeMoveAwR->operands))[0]; - destReg = ((self_in_concretizeMoveAwR->operands))[1]; - if ((srcAddr != null) - && ((((varBaseAddress()) - (0x8000)) < srcAddr) - && (srcAddr < ((varBaseAddress()) + (0x8000))))) { - /* begin machineCodeAt:put: */ - aWord = lwRbaseoffset(self_in_concretizeMoveAwR, destReg, ConcreteVarBaseReg, srcAddr - (varBaseAddress())); - ((self_in_concretizeMoveAwR->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeMoveAwR, AT, high16BitsOf(self_in_concretizeMoveAwR, srcAddr)); - ((self_in_concretizeMoveAwR->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeMoveAwR, AT, AT, low16BitsOf(self_in_concretizeMoveAwR, srcAddr)); - ((self_in_concretizeMoveAwR->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = lwRbaseoffset(self_in_concretizeMoveAwR, destReg, AT, 0); - ((self_in_concretizeMoveAwR->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMoveCqR */ -static sqInt NoDbgRegParms -concretizeMoveCqR(AbstractInstruction * self_in_concretizeMoveCqR) -{ - sqInt aWord; - usqInt reg; - sqInt word; - - word = ((self_in_concretizeMoveCqR->operands))[0]; - reg = ((self_in_concretizeMoveCqR->operands))[1]; - if (!(isShortOffset(self_in_concretizeMoveCqR, word))) { - return concretizeMoveCwR(self_in_concretizeMoveCqR); - } - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizeMoveCqR, reg, ZR, word); - ((self_in_concretizeMoveCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveCwR */ -static sqInt NoDbgRegParms -concretizeMoveCwR(AbstractInstruction * self_in_concretizeMoveCwR) -{ - sqInt aWord; - sqInt aWord1; - usqInt reg; - sqInt word; - - word = ((self_in_concretizeMoveCwR->operands))[0]; - reg = ((self_in_concretizeMoveCwR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeMoveCwR, reg, high16BitsOf(self_in_concretizeMoveCwR, word)); - ((self_in_concretizeMoveCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeMoveCwR, reg, reg, low16BitsOf(self_in_concretizeMoveCwR, word)); - ((self_in_concretizeMoveCwR->machineCode))[4 / 4] = aWord1; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeMoveHighR */ -static sqInt NoDbgRegParms -concretizeMoveHighR(AbstractInstruction * self_in_concretizeMoveHighR) -{ - sqInt aWord; - usqInt destReg; - - destReg = ((self_in_concretizeMoveHighR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = mfhiR(self_in_concretizeMoveHighR, destReg); - ((self_in_concretizeMoveHighR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveLowR */ -static sqInt NoDbgRegParms -concretizeMoveLowR(AbstractInstruction * self_in_concretizeMoveLowR) -{ - sqInt aWord; - usqInt destReg; - - destReg = ((self_in_concretizeMoveLowR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = mfloR(self_in_concretizeMoveLowR, destReg); - ((self_in_concretizeMoveLowR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveM16rR */ -static sqInt NoDbgRegParms -concretizeMoveM16rR(AbstractInstruction * self_in_concretizeMoveM16rR) -{ - sqInt aWord; - usqInt destReg; - sqInt offset; - usqInt srcReg; - - offset = ((self_in_concretizeMoveM16rR->operands))[0]; - srcReg = ((self_in_concretizeMoveM16rR->operands))[1]; - destReg = ((self_in_concretizeMoveM16rR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = lhuRbaseoffset(self_in_concretizeMoveM16rR, destReg, srcReg, offset); - ((self_in_concretizeMoveM16rR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveMbrR */ -static sqInt NoDbgRegParms -concretizeMoveMbrR(AbstractInstruction * self_in_concretizeMoveMbrR) -{ - sqInt aWord; - usqInt destReg; - sqInt offset; - usqInt srcReg; - - offset = ((self_in_concretizeMoveMbrR->operands))[0]; - srcReg = ((self_in_concretizeMoveMbrR->operands))[1]; - destReg = ((self_in_concretizeMoveMbrR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = lbuRbaseoffset(self_in_concretizeMoveMbrR, destReg, srcReg, offset); - ((self_in_concretizeMoveMbrR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveMwrR */ -static sqInt NoDbgRegParms -concretizeMoveMwrR(AbstractInstruction * self_in_concretizeMoveMwrR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - sqInt aWord4; - usqInt baseReg; - usqInt destReg; - sqInt offset; - - offset = ((self_in_concretizeMoveMwrR->operands))[0]; - baseReg = ((self_in_concretizeMoveMwrR->operands))[1]; - destReg = ((self_in_concretizeMoveMwrR->operands))[2]; - if (isShortOffset(self_in_concretizeMoveMwrR, offset)) { - /* begin machineCodeAt:put: */ - aWord = lwRbaseoffset(self_in_concretizeMoveMwrR, destReg, baseReg, offset); - ((self_in_concretizeMoveMwrR->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeMoveMwrR, AT, high16BitsOf(self_in_concretizeMoveMwrR, offset)); - ((self_in_concretizeMoveMwrR->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeMoveMwrR, AT, AT, low16BitsOf(self_in_concretizeMoveMwrR, offset)); - ((self_in_concretizeMoveMwrR->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = adduRRR(self_in_concretizeMoveMwrR, AT, baseReg, AT); - ((self_in_concretizeMoveMwrR->machineCode))[8 / 4] = aWord3; - /* begin machineCodeAt:put: */ - aWord4 = lwRbaseoffset(self_in_concretizeMoveMwrR, destReg, AT, 0); - ((self_in_concretizeMoveMwrR->machineCode))[12 / 4] = aWord4; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeMoveRAb */ -static sqInt NoDbgRegParms -concretizeMoveRAb(AbstractInstruction * self_in_concretizeMoveRAb) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt destAddr; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRAb->operands))[0]; - destAddr = ((self_in_concretizeMoveRAb->operands))[1]; - if ((destAddr != null) - && ((((varBaseAddress()) - (0x8000)) < destAddr) - && (destAddr < ((varBaseAddress()) + (0x8000))))) { - /* begin machineCodeAt:put: */ - aWord = swRbaseoffset(self_in_concretizeMoveRAb, srcReg, ConcreteVarBaseReg, destAddr - (varBaseAddress())); - ((self_in_concretizeMoveRAb->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeMoveRAb, AT, high16BitsOf(self_in_concretizeMoveRAb, destAddr)); - ((self_in_concretizeMoveRAb->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeMoveRAb, AT, AT, low16BitsOf(self_in_concretizeMoveRAb, destAddr)); - ((self_in_concretizeMoveRAb->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = sbRbaseoffset(self_in_concretizeMoveRAb, srcReg, AT, 0); - ((self_in_concretizeMoveRAb->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMoveRAw */ -static sqInt NoDbgRegParms -concretizeMoveRAw(AbstractInstruction * self_in_concretizeMoveRAw) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt destAddr; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRAw->operands))[0]; - destAddr = ((self_in_concretizeMoveRAw->operands))[1]; - if ((destAddr != null) - && ((((varBaseAddress()) - (0x8000)) < destAddr) - && (destAddr < ((varBaseAddress()) + (0x8000))))) { - /* begin machineCodeAt:put: */ - aWord = swRbaseoffset(self_in_concretizeMoveRAw, srcReg, ConcreteVarBaseReg, destAddr - (varBaseAddress())); - ((self_in_concretizeMoveRAw->machineCode))[0 / 4] = aWord; - return 4; - } - /* begin machineCodeAt:put: */ - aWord1 = luiRC(self_in_concretizeMoveRAw, AT, high16BitsOf(self_in_concretizeMoveRAw, destAddr)); - ((self_in_concretizeMoveRAw->machineCode))[0 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = oriRRC(self_in_concretizeMoveRAw, AT, AT, low16BitsOf(self_in_concretizeMoveRAw, destAddr)); - ((self_in_concretizeMoveRAw->machineCode))[4 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = swRbaseoffset(self_in_concretizeMoveRAw, srcReg, AT, 0); - ((self_in_concretizeMoveRAw->machineCode))[8 / 4] = aWord3; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMoveRM16r */ -static sqInt NoDbgRegParms -concretizeMoveRM16r(AbstractInstruction * self_in_concretizeMoveRM16r) -{ - sqInt aWord; - usqInt destReg; - sqInt offset; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRM16r->operands))[0]; - offset = ((self_in_concretizeMoveRM16r->operands))[1]; - destReg = ((self_in_concretizeMoveRM16r->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = shRbaseoffset(self_in_concretizeMoveRM16r, srcReg, destReg, offset); - ((self_in_concretizeMoveRM16r->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveRMbr */ -static sqInt NoDbgRegParms -concretizeMoveRMbr(AbstractInstruction * self_in_concretizeMoveRMbr) -{ - sqInt aWord; - usqInt destReg; - sqInt offset; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRMbr->operands))[0]; - offset = ((self_in_concretizeMoveRMbr->operands))[1]; - destReg = ((self_in_concretizeMoveRMbr->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = sbRbaseoffset(self_in_concretizeMoveRMbr, srcReg, destReg, offset); - ((self_in_concretizeMoveRMbr->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveRMwr */ -static sqInt NoDbgRegParms -concretizeMoveRMwr(AbstractInstruction * self_in_concretizeMoveRMwr) -{ - sqInt aWord; - usqInt baseReg; - sqInt offset; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRMwr->operands))[0]; - offset = ((self_in_concretizeMoveRMwr->operands))[1]; - baseReg = ((self_in_concretizeMoveRMwr->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = swRbaseoffset(self_in_concretizeMoveRMwr, srcReg, baseReg, offset); - ((self_in_concretizeMoveRMwr->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveRR */ -static sqInt NoDbgRegParms -concretizeMoveRR(AbstractInstruction * self_in_concretizeMoveRR) -{ - sqInt aWord; - usqInt destReg; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRR->operands))[0]; - destReg = ((self_in_concretizeMoveRR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeMoveRR, destReg, srcReg, ZR); - ((self_in_concretizeMoveRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeMoveRXbrR */ -static sqInt NoDbgRegParms -concretizeMoveRXbrR(AbstractInstruction * self_in_concretizeMoveRXbrR) -{ - sqInt aWord; - sqInt aWord1; - usqInt baseReg; - usqInt indexReg; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRXbrR->operands))[0]; - indexReg = ((self_in_concretizeMoveRXbrR->operands))[1]; - baseReg = ((self_in_concretizeMoveRXbrR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeMoveRXbrR, AT, baseReg, indexReg); - ((self_in_concretizeMoveRXbrR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = sbRbaseoffset(self_in_concretizeMoveRXbrR, srcReg, AT, 0); - ((self_in_concretizeMoveRXbrR->machineCode))[4 / 4] = aWord1; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeMoveRXwrR */ -static sqInt NoDbgRegParms -concretizeMoveRXwrR(AbstractInstruction * self_in_concretizeMoveRXwrR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt baseReg; - usqInt indexReg; - usqInt srcReg; - - srcReg = ((self_in_concretizeMoveRXwrR->operands))[0]; - indexReg = ((self_in_concretizeMoveRXwrR->operands))[1]; - baseReg = ((self_in_concretizeMoveRXwrR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = sllRRC(self_in_concretizeMoveRXwrR, AT, indexReg, 2); - ((self_in_concretizeMoveRXwrR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = adduRRR(self_in_concretizeMoveRXwrR, AT, baseReg, AT); - ((self_in_concretizeMoveRXwrR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = swRbaseoffset(self_in_concretizeMoveRXwrR, srcReg, AT, 0); - ((self_in_concretizeMoveRXwrR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMoveXbrRR */ -static sqInt NoDbgRegParms -concretizeMoveXbrRR(AbstractInstruction * self_in_concretizeMoveXbrRR) -{ - sqInt aWord; - sqInt aWord1; - usqInt baseReg; - usqInt destReg; - usqInt indexReg; - - - /* index is number of *bytes* */ - indexReg = ((self_in_concretizeMoveXbrRR->operands))[0]; - baseReg = ((self_in_concretizeMoveXbrRR->operands))[1]; - destReg = ((self_in_concretizeMoveXbrRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeMoveXbrRR, AT, baseReg, indexReg); - ((self_in_concretizeMoveXbrRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = lbuRbaseoffset(self_in_concretizeMoveXbrRR, destReg, AT, 0); - ((self_in_concretizeMoveXbrRR->machineCode))[4 / 4] = aWord1; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeMoveXwrRR */ -static sqInt NoDbgRegParms -concretizeMoveXwrRR(AbstractInstruction * self_in_concretizeMoveXwrRR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt baseReg; - usqInt destReg; - usqInt indexReg; - - indexReg = ((self_in_concretizeMoveXwrRR->operands))[0]; - baseReg = ((self_in_concretizeMoveXwrRR->operands))[1]; - destReg = ((self_in_concretizeMoveXwrRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = sllRRC(self_in_concretizeMoveXwrRR, AT, indexReg, 2); - ((self_in_concretizeMoveXwrRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = adduRRR(self_in_concretizeMoveXwrRR, AT, baseReg, AT); - ((self_in_concretizeMoveXwrRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = lwRbaseoffset(self_in_concretizeMoveXwrRR, destReg, AT, 0); - ((self_in_concretizeMoveXwrRR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeMulCheckOverflowRR */ -static sqInt NoDbgRegParms -concretizeMulCheckOverflowRR(AbstractInstruction * self_in_concretizeMulCheckOverflowRR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeMulCheckOverflowRR->operands))[0]; - - /* Overflow occured if the sign bit of the low part is different from the high part. */ - destReg = (leftReg = ((self_in_concretizeMulCheckOverflowRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = multRR(self_in_concretizeMulCheckOverflowRR, leftReg, rightReg); - ((self_in_concretizeMulCheckOverflowRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = mfloR(self_in_concretizeMulCheckOverflowRR, destReg); - ((self_in_concretizeMulCheckOverflowRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = sraRRC(self_in_concretizeMulCheckOverflowRR, OverflowTemp1, destReg, 0x1F); - ((self_in_concretizeMulCheckOverflowRR->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = mfhiR(self_in_concretizeMulCheckOverflowRR, OverflowTemp2); - ((self_in_concretizeMulCheckOverflowRR->machineCode))[12 / 4] = aWord3; - return 16; -} - - /* CogMIPSELCompiler>>#concretizeNegateR */ -static sqInt NoDbgRegParms -concretizeNegateR(AbstractInstruction * self_in_concretizeNegateR) -{ - sqInt aWord; - usqInt reg; - - reg = ((self_in_concretizeNegateR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = subuRRR(self_in_concretizeNegateR, reg, ZR, reg); - ((self_in_concretizeNegateR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeNop */ -static sqInt NoDbgRegParms -concretizeNop(AbstractInstruction * self_in_concretizeNop) -{ - /* begin machineCodeAt:put: */ - ((self_in_concretizeNop->machineCode))[0 / 4] = 0 /* nop */; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeOrCqR */ -static sqInt NoDbgRegParms -concretizeOrCqR(AbstractInstruction * self_in_concretizeOrCqR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeOrCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeOrCqR->operands))[1]); - if (!(((rightImm >= 0) && (rightImm <= 0xFFFF)))) { - return concretizeOrCwR(self_in_concretizeOrCqR); - } - /* begin machineCodeAt:put: */ - aWord = oriRRC(self_in_concretizeOrCqR, destReg, leftReg, rightImm); - ((self_in_concretizeOrCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeOrCqRR */ -static sqInt NoDbgRegParms -concretizeOrCqRR(AbstractInstruction * self_in_concretizeOrCqRR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt dstReg; - usqInt srcReg; - usqInt value; - - value = ((self_in_concretizeOrCqRR->operands))[0]; - srcReg = ((self_in_concretizeOrCqRR->operands))[1]; - dstReg = ((self_in_concretizeOrCqRR->operands))[2]; - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeOrCqRR, AT, high16BitsOf(self_in_concretizeOrCqRR, value)); - ((self_in_concretizeOrCqRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeOrCqRR, AT, AT, low16BitsOf(self_in_concretizeOrCqRR, value)); - ((self_in_concretizeOrCqRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = orRRR(self_in_concretizeOrCqRR, dstReg, srcReg, AT); - ((self_in_concretizeOrCqRR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeOrCwR */ -static sqInt NoDbgRegParms -concretizeOrCwR(AbstractInstruction * self_in_concretizeOrCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeOrCwR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeOrCwR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeOrCwR, AT, high16BitsOf(self_in_concretizeOrCwR, rightImm)); - ((self_in_concretizeOrCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeOrCwR, AT, AT, low16BitsOf(self_in_concretizeOrCwR, rightImm)); - ((self_in_concretizeOrCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = orRRR(self_in_concretizeOrCwR, destReg, leftReg, AT); - ((self_in_concretizeOrCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeOrRR */ -static sqInt NoDbgRegParms -concretizeOrRR(AbstractInstruction * self_in_concretizeOrRR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeOrRR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeOrRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = orRRR(self_in_concretizeOrRR, destReg, leftReg, rightReg); - ((self_in_concretizeOrRR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizePopR */ -static sqInt NoDbgRegParms -concretizePopR(AbstractInstruction * self_in_concretizePopR) -{ - sqInt aWord; - sqInt aWord1; - usqInt destReg; - - destReg = ((self_in_concretizePopR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = lwRbaseoffset(self_in_concretizePopR, destReg, SP, 0); - ((self_in_concretizePopR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = addiuRRC(self_in_concretizePopR, SP, SP, 4); - ((self_in_concretizePopR->machineCode))[4 / 4] = aWord1; - return 8; -} - - /* CogMIPSELCompiler>>#concretizePrefetchAw */ -static sqInt NoDbgRegParms -concretizePrefetchAw(AbstractInstruction * self_in_concretizePrefetchAw) -{ - usqInt addressOperand; - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - - addressOperand = ((self_in_concretizePrefetchAw->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizePrefetchAw, AT, high16BitsOf(self_in_concretizePrefetchAw, addressOperand)); - ((self_in_concretizePrefetchAw->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizePrefetchAw, AT, AT, low16BitsOf(self_in_concretizePrefetchAw, addressOperand)); - ((self_in_concretizePrefetchAw->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = prefRoffsethint(self_in_concretizePrefetchAw, AT, 0, HintLoad); - ((self_in_concretizePrefetchAw->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizePushCq */ -static sqInt NoDbgRegParms -concretizePushCq(AbstractInstruction * self_in_concretizePushCq) -{ - return concretizePushCw(self_in_concretizePushCq); -} - - /* CogMIPSELCompiler>>#concretizePushCw */ -static sqInt NoDbgRegParms -concretizePushCw(AbstractInstruction * self_in_concretizePushCw) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - usqInt value; - - value = ((self_in_concretizePushCw->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizePushCw, AT, high16BitsOf(self_in_concretizePushCw, value)); - ((self_in_concretizePushCw->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizePushCw, AT, AT, low16BitsOf(self_in_concretizePushCw, value)); - ((self_in_concretizePushCw->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = addiuRRC(self_in_concretizePushCw, SP, SP, -4); - ((self_in_concretizePushCw->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = swRbaseoffset(self_in_concretizePushCw, AT, SP, 0); - ((self_in_concretizePushCw->machineCode))[12 / 4] = aWord3; - return 16; -} - - /* CogMIPSELCompiler>>#concretizePushR */ -static sqInt NoDbgRegParms -concretizePushR(AbstractInstruction * self_in_concretizePushR) -{ - sqInt aWord; - sqInt aWord1; - usqInt srcReg; - - srcReg = ((self_in_concretizePushR->operands))[0]; - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizePushR, SP, SP, -4); - ((self_in_concretizePushR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = swRbaseoffset(self_in_concretizePushR, srcReg, SP, 0); - ((self_in_concretizePushR->machineCode))[4 / 4] = aWord1; - return 8; -} - - /* CogMIPSELCompiler>>#concretizeRetN */ -static sqInt NoDbgRegParms -concretizeRetN(AbstractInstruction * self_in_concretizeRetN) -{ - sqInt aWord; - sqInt aWord1; - sqInt offset; - - offset = ((self_in_concretizeRetN->operands))[0]; - /* begin machineCodeAt:put: */ - aWord1 = jR(self_in_concretizeRetN, RA); - ((self_in_concretizeRetN->machineCode))[0 / 4] = aWord1; - if (offset == 0) { - /* begin machineCodeAt:put: */ - ((self_in_concretizeRetN->machineCode))[4 / 4] = 0 /* nop */; - } - else { - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizeRetN, SP, SP, offset); - ((self_in_concretizeRetN->machineCode))[4 / 4] = aWord; - } - return 8; -} - - /* CogMIPSELCompiler>>#concretizeStop */ -static sqInt NoDbgRegParms -concretizeStop(AbstractInstruction * self_in_concretizeStop) -{ - sqInt aWord; - - /* begin machineCodeAt:put: */ - aWord = stop(self_in_concretizeStop); - ((self_in_concretizeStop->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeSubCheckOverflowCqR */ -static sqInt NoDbgRegParms -concretizeSubCheckOverflowCqR(AbstractInstruction * self_in_concretizeSubCheckOverflowCqR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - sqInt aWord4; - sqInt aWord5; - sqInt aWord6; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeSubCheckOverflowCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeSubCheckOverflowCqR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeSubCheckOverflowCqR, AT, high16BitsOf(self_in_concretizeSubCheckOverflowCqR, rightImm)); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeSubCheckOverflowCqR, AT, AT, low16BitsOf(self_in_concretizeSubCheckOverflowCqR, rightImm)); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = adduRRR(self_in_concretizeSubCheckOverflowCqR, OverflowTemp1, leftReg, ZR); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = subuRRR(self_in_concretizeSubCheckOverflowCqR, destReg, leftReg, AT); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[12 / 4] = aWord3; - /* begin machineCodeAt:put: */ - aWord4 = xorRRR(self_in_concretizeSubCheckOverflowCqR, OverflowTemp2, destReg, AT); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[16 / 4] = aWord4; - /* begin machineCodeAt:put: */ - aWord5 = xorRRR(self_in_concretizeSubCheckOverflowCqR, OverflowTemp1, destReg, OverflowTemp1); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[20 / 4] = aWord5; - /* begin machineCodeAt:put: */ - aWord6 = andRRR(self_in_concretizeSubCheckOverflowCqR, Overflow, OverflowTemp1, OverflowTemp2); - ((self_in_concretizeSubCheckOverflowCqR->machineCode))[24 / 4] = aWord6; - return 28; -} - - /* CogMIPSELCompiler>>#concretizeSubCheckOverflowRR */ -static sqInt NoDbgRegParms -concretizeSubCheckOverflowRR(AbstractInstruction * self_in_concretizeSubCheckOverflowRR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - sqInt aWord3; - sqInt aWord4; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeSubCheckOverflowRR->operands))[0]; - - /* Save original LHS */ - destReg = (leftReg = ((self_in_concretizeSubCheckOverflowRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = adduRRR(self_in_concretizeSubCheckOverflowRR, OverflowTemp1, leftReg, ZR); - ((self_in_concretizeSubCheckOverflowRR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = subuRRR(self_in_concretizeSubCheckOverflowRR, destReg, leftReg, rightReg); - ((self_in_concretizeSubCheckOverflowRR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = xorRRR(self_in_concretizeSubCheckOverflowRR, OverflowTemp2, destReg, rightReg); - ((self_in_concretizeSubCheckOverflowRR->machineCode))[8 / 4] = aWord2; - /* begin machineCodeAt:put: */ - aWord3 = xorRRR(self_in_concretizeSubCheckOverflowRR, OverflowTemp1, destReg, OverflowTemp1); - ((self_in_concretizeSubCheckOverflowRR->machineCode))[12 / 4] = aWord3; - /* begin machineCodeAt:put: */ - aWord4 = andRRR(self_in_concretizeSubCheckOverflowRR, Overflow, OverflowTemp1, OverflowTemp2); - ((self_in_concretizeSubCheckOverflowRR->machineCode))[16 / 4] = aWord4; - return 20; -} - - /* CogMIPSELCompiler>>#concretizeSubCqR */ -static sqInt NoDbgRegParms -concretizeSubCqR(AbstractInstruction * self_in_concretizeSubCqR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeSubCqR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeSubCqR->operands))[1]); - if (!(isShortOffset(self_in_concretizeSubCqR, -rightImm))) { - return concretizeSubCwR(self_in_concretizeSubCqR); - } - /* begin machineCodeAt:put: */ - aWord = addiuRRC(self_in_concretizeSubCqR, destReg, leftReg, -rightImm); - ((self_in_concretizeSubCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeSubCwR */ -static sqInt NoDbgRegParms -concretizeSubCwR(AbstractInstruction * self_in_concretizeSubCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeSubCwR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeSubCwR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeSubCwR, AT, high16BitsOf(self_in_concretizeSubCwR, rightImm)); - ((self_in_concretizeSubCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeSubCwR, AT, AT, low16BitsOf(self_in_concretizeSubCwR, rightImm)); - ((self_in_concretizeSubCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = subuRRR(self_in_concretizeSubCwR, destReg, leftReg, AT); - ((self_in_concretizeSubCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeSubRRDest: */ -static sqInt NoDbgRegParms -concretizeSubRRDest(AbstractInstruction * self_in_concretizeSubRRDest, sqInt destReg) -{ - sqInt aWord; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeSubRRDest->operands))[0]; - leftReg = ((self_in_concretizeSubRRDest->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = subuRRR(self_in_concretizeSubRRDest, destReg, leftReg, rightReg); - ((self_in_concretizeSubRRDest->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeTstCqR */ -static sqInt NoDbgRegParms -concretizeTstCqR(AbstractInstruction * self_in_concretizeTstCqR) -{ - sqInt aWord; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeTstCqR->operands))[0]; - leftReg = ((self_in_concretizeTstCqR->operands))[1]; - if (!(isShortOffset(self_in_concretizeTstCqR, rightImm))) { - return concretizeTstCwR(self_in_concretizeTstCqR); - } - /* begin machineCodeAt:put: */ - aWord = andiRRC(self_in_concretizeTstCqR, Cmp, leftReg, rightImm); - ((self_in_concretizeTstCqR->machineCode))[0 / 4] = aWord; - return 4; -} - - /* CogMIPSELCompiler>>#concretizeTstCwR */ -static sqInt NoDbgRegParms -concretizeTstCwR(AbstractInstruction * self_in_concretizeTstCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeTstCwR->operands))[0]; - leftReg = ((self_in_concretizeTstCwR->operands))[1]; - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeTstCwR, AT, high16BitsOf(self_in_concretizeTstCwR, rightImm)); - ((self_in_concretizeTstCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeTstCwR, AT, AT, low16BitsOf(self_in_concretizeTstCwR, rightImm)); - ((self_in_concretizeTstCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = andRRR(self_in_concretizeTstCwR, Cmp, leftReg, AT); - ((self_in_concretizeTstCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeUnimplemented */ -static sqInt NoDbgRegParms -concretizeUnimplemented(AbstractInstruction * self_in_concretizeUnimplemented) -{ - error("Unimplemented RTL instruction"); - return 0; -} - - /* CogMIPSELCompiler>>#concretizeXorCwR */ -static sqInt NoDbgRegParms -concretizeXorCwR(AbstractInstruction * self_in_concretizeXorCwR) -{ - sqInt aWord; - sqInt aWord1; - sqInt aWord2; - usqInt destReg; - usqInt leftReg; - usqInt rightImm; - - rightImm = ((self_in_concretizeXorCwR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeXorCwR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = luiRC(self_in_concretizeXorCwR, AT, high16BitsOf(self_in_concretizeXorCwR, rightImm)); - ((self_in_concretizeXorCwR->machineCode))[0 / 4] = aWord; - /* begin machineCodeAt:put: */ - aWord1 = oriRRC(self_in_concretizeXorCwR, AT, AT, low16BitsOf(self_in_concretizeXorCwR, rightImm)); - ((self_in_concretizeXorCwR->machineCode))[4 / 4] = aWord1; - /* begin machineCodeAt:put: */ - aWord2 = xorRRR(self_in_concretizeXorCwR, destReg, leftReg, AT); - ((self_in_concretizeXorCwR->machineCode))[8 / 4] = aWord2; - return 12; -} - - /* CogMIPSELCompiler>>#concretizeXorRR */ -static sqInt NoDbgRegParms -concretizeXorRR(AbstractInstruction * self_in_concretizeXorRR) -{ - sqInt aWord; - usqInt destReg; - usqInt leftReg; - usqInt rightReg; - - rightReg = ((self_in_concretizeXorRR->operands))[0]; - destReg = (leftReg = ((self_in_concretizeXorRR->operands))[1]); - /* begin machineCodeAt:put: */ - aWord = xorRRR(self_in_concretizeXorRR, destReg, leftReg, rightReg); - ((self_in_concretizeXorRR->machineCode))[0 / 4] = aWord; - return 4; -} - - -/* Attempt to generate concrete machine code for the instruction at address. - This is the inner dispatch of concretizeAt: actualAddress which exists - only to get around the branch size limits in the SqueakV3 (blue book - derived) bytecode set. */ - - /* CogMIPSELCompiler>>#dispatchConcretize */ -static sqInt NoDbgRegParms -dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) -{ - AbstractInstruction *dependentChain; - - switch ((self_in_dispatchConcretize->opcode)) { - case BrEqualRR: - return concretizeBrEqualRR(self_in_dispatchConcretize); - - case BrNotEqualRR: - return concretizeBrNotEqualRR(self_in_dispatchConcretize); - - case BrUnsignedLessRR: - return concretizeBrUnsignedLessRR(self_in_dispatchConcretize); - - case BrUnsignedLessEqualRR: - return concretizeBrUnsignedLessEqualRR(self_in_dispatchConcretize); - - case BrUnsignedGreaterRR: - return concretizeBrUnsignedGreaterRR(self_in_dispatchConcretize); - - case BrUnsignedGreaterEqualRR: - return concretizeBrUnsignedGreaterEqualRR(self_in_dispatchConcretize); - - case BrSignedLessRR: - return concretizeBrSignedLessRR(self_in_dispatchConcretize); - - case BrSignedLessEqualRR: - return concretizeBrSignedLessEqualRR(self_in_dispatchConcretize); - - case BrSignedGreaterRR: - return concretizeBrSignedGreaterRR(self_in_dispatchConcretize); - - case BrSignedGreaterEqualRR: - return concretizeBrSignedGreaterEqualRR(self_in_dispatchConcretize); - - case BrLongEqualRR: - return concretizeBrLongEqualRR(self_in_dispatchConcretize); - - case BrLongNotEqualRR: - return concretizeBrLongNotEqualRR(self_in_dispatchConcretize); - - case MulRR: - case JumpNegative: - case JumpNonNegative: - case JumpCarry: - case JumpNoCarry: - case JumpFPEqual: - case JumpFPNotEqual: - case JumpFPLess: - case JumpFPGreaterOrEqual: - case JumpFPGreater: - case JumpFPLessOrEqual: - case JumpFPOrdered: - case JumpFPUnordered: - case XorCqR: - case AddRdRd: - case CmpRdRd: - case DivRdRd: - case MulRdRd: - case SubRdRd: - case SqrtRd: - case MoveRMbr: - case MoveM64rRd: - case MoveRdM64r: - case ConvertRRd: - return concretizeUnimplemented(self_in_dispatchConcretize); - - case DivRR: - return concretizeDivRR(self_in_dispatchConcretize); - - case MoveLowR: - return concretizeMoveLowR(self_in_dispatchConcretize); - - case MoveHighR: - return concretizeMoveHighR(self_in_dispatchConcretize); - - case Label: - /* begin concretizeLabel */ - dependentChain = (self_in_dispatchConcretize->dependent); - while (!(dependentChain == null)) { - /* begin updateLabel: */ - assert((((dependentChain->opcode)) == MoveCwR) - || (((dependentChain->opcode)) == PushCw)); - ((dependentChain->operands))[0] = (((self_in_dispatchConcretize->address)) + (((self_in_dispatchConcretize->operands))[1])); - dependentChain = (dependentChain->dependent); - } - return 0; - - case AlignmentNops: - return concretizeAlignmentNops(self_in_dispatchConcretize); - - case Fill32: - return concretizeFill32(self_in_dispatchConcretize); - - case Nop: - return concretizeNop(self_in_dispatchConcretize); - - case Call: - return concretizeCall(self_in_dispatchConcretize); - - case CallFull: - return concretizeCallFull(self_in_dispatchConcretize); - - case JumpR: - return concretizeJumpR(self_in_dispatchConcretize); - - case JumpFull: - return concretizeJumpFull(self_in_dispatchConcretize); - - case JumpLong: - return concretizeJumpLong(self_in_dispatchConcretize); - - case JumpLongZero: - return concretizeJumpLongZero(self_in_dispatchConcretize); - - case JumpLongNonZero: - return concretizeJumpLongNonZero(self_in_dispatchConcretize); - - case Jump: - return concretizeJump(self_in_dispatchConcretize); - - case JumpZero: - return concretizeJumpZero(self_in_dispatchConcretize); - - case JumpNonZero: - return concretizeJumpNonZero(self_in_dispatchConcretize); - - case JumpOverflow: - return concretizeJumpOverflow(self_in_dispatchConcretize); - - case JumpNoOverflow: - return concretizeJumpNoOverflow(self_in_dispatchConcretize); - - case JumpLess: - return concretizeJumpSignedLessThan(self_in_dispatchConcretize); - - case JumpGreaterOrEqual: - return concretizeJumpSignedGreaterEqual(self_in_dispatchConcretize); - - case JumpGreater: - return concretizeJumpSignedGreaterThan(self_in_dispatchConcretize); - - case JumpLessOrEqual: - return concretizeJumpSignedLessEqual(self_in_dispatchConcretize); - - case JumpBelow: - return concretizeJumpUnsignedLessThan(self_in_dispatchConcretize); - - case JumpAboveOrEqual: - return concretizeJumpUnsignedGreaterEqual(self_in_dispatchConcretize); - - case JumpAbove: - return concretizeJumpUnsignedGreaterThan(self_in_dispatchConcretize); - - case JumpBelowOrEqual: - return concretizeJumpUnsignedLessEqual(self_in_dispatchConcretize); - - case RetN: - return concretizeRetN(self_in_dispatchConcretize); - - case Stop: - return concretizeStop(self_in_dispatchConcretize); - - case AddCqR: - return concretizeAddCqR(self_in_dispatchConcretize); - - case AndCqR: - return concretizeAndCqRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]); - - case AndCqRR: - return concretizeAndCqRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[2]); - - case OrCqRR: - return concretizeOrCqRR(self_in_dispatchConcretize); - - case CmpCqR: - return concretizeCmpCqR(self_in_dispatchConcretize); - - case OrCqR: - return concretizeOrCqR(self_in_dispatchConcretize); - - case SubCqR: - return concretizeSubCqR(self_in_dispatchConcretize); - - case TstCqR: - return concretizeTstCqR(self_in_dispatchConcretize); - - case AddCwR: - return concretizeAddCwR(self_in_dispatchConcretize); - - case AndCwR: - return concretizeAndCwR(self_in_dispatchConcretize); - - case CmpCwR: - return concretizeCmpCwR(self_in_dispatchConcretize); - - case OrCwR: - return concretizeOrCwR(self_in_dispatchConcretize); - - case SubCwR: - return concretizeSubCwR(self_in_dispatchConcretize); - - case XorCwR: - return concretizeXorCwR(self_in_dispatchConcretize); - - case AddRR: - return concretizeAddRRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]); - - case AndRR: - return concretizeAndRR(self_in_dispatchConcretize); - - case CmpRR: - return concretizeCmpRR(self_in_dispatchConcretize); - - case OrRR: - return concretizeOrRR(self_in_dispatchConcretize); - - case SubRR: - return concretizeSubRRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]); - - case XorRR: - return concretizeXorRR(self_in_dispatchConcretize); - - case AddRRR: - return concretizeAddRRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[2]); - - case SubRRR: - return concretizeSubRRDest(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[2]); - - case NegateR: - return concretizeNegateR(self_in_dispatchConcretize); - - case LoadEffectiveAddressMwrR: - return concretizeLoadEffectiveAddressMwrR(self_in_dispatchConcretize); - - case ArithmeticShiftRightCqR: - return concretizeArithmeticShiftRightCqR(self_in_dispatchConcretize); - - case LogicalShiftRightCqR: - return concretizeLogicalShiftRightCqR(self_in_dispatchConcretize); - - case LogicalShiftLeftCqR: - return concretizeLogicalShiftLeftCqR(self_in_dispatchConcretize); - - case ArithmeticShiftRightRR: - return concretizeArithmeticShiftRightRR(self_in_dispatchConcretize); - - case LogicalShiftLeftRR: - return concretizeLogicalShiftLeftRR(self_in_dispatchConcretize); - - case LogicalShiftRightRR: - return concretizeLogicalShiftRightRR(self_in_dispatchConcretize); - - case ClzRR: - return concretizeClzRR(self_in_dispatchConcretize); - - case MoveCqR: - return concretizeMoveCqR(self_in_dispatchConcretize); - - case MoveCwR: - return concretizeMoveCwR(self_in_dispatchConcretize); - - case MoveRR: - return concretizeMoveRR(self_in_dispatchConcretize); - - case MoveAwR: - return concretizeMoveAwR(self_in_dispatchConcretize); - - case MoveRAw: - return concretizeMoveRAw(self_in_dispatchConcretize); - - case MoveAbR: - return concretizeMoveAbR(self_in_dispatchConcretize); - - case MoveRAb: - return concretizeMoveRAb(self_in_dispatchConcretize); - - case MoveMbrR: - return concretizeMoveMbrR(self_in_dispatchConcretize); - - case MoveM16rR: - return concretizeMoveM16rR(self_in_dispatchConcretize); - - case MoveRM16r: - return concretizeMoveRM16r(self_in_dispatchConcretize); - - case MoveMwrR: - return concretizeMoveMwrR(self_in_dispatchConcretize); - - case MoveXbrRR: - return concretizeMoveXbrRR(self_in_dispatchConcretize); - - case MoveRXbrR: - return concretizeMoveRXbrR(self_in_dispatchConcretize); - - case MoveXwrRR: - return concretizeMoveXwrRR(self_in_dispatchConcretize); - - case MoveRXwrR: - return concretizeMoveRXwrR(self_in_dispatchConcretize); - - case MoveRMwr: - return concretizeMoveRMwr(self_in_dispatchConcretize); - - case PopR: - return concretizePopR(self_in_dispatchConcretize); - - case PushR: - return concretizePushR(self_in_dispatchConcretize); - - case PushCq: - return concretizePushCq(self_in_dispatchConcretize); - - case PushCw: - return concretizePushCw(self_in_dispatchConcretize); - - case PrefetchAw: - return concretizePrefetchAw(self_in_dispatchConcretize); - - case AddCheckOverflowCqR: - return concretizeAddCheckOverflowCqR(self_in_dispatchConcretize); - - case AddCheckOverflowRR: - return concretizeAddCheckOverflowRR(self_in_dispatchConcretize); - - case SubCheckOverflowCqR: - return concretizeSubCheckOverflowCqR(self_in_dispatchConcretize); - - case SubCheckOverflowRR: - return concretizeSubCheckOverflowRR(self_in_dispatchConcretize); - - case MulCheckOverflowRR: - return concretizeMulCheckOverflowRR(self_in_dispatchConcretize); - - default: - error("Case not found and no otherwise clause"); - } - return 0; -} - - /* CogMIPSELCompiler>>#divR:R: */ -static sqInt NoDbgRegParms -divRR(AbstractInstruction * self_in_divRR, sqInt dividendReg, sqInt divisorReg) -{ - flag("todo"); - return rtypersrtrdsafunct(self_in_divRR, SPECIAL, dividendReg, divisorReg, 0, 0, DIV); -} - - -/* Answer if CallFull and/or JumpFull are relative and hence need relocating - on method - compation. If so, they are annotated with IsRelativeCall in methods and - relocated in - relocateIfCallOrMethodReference:mcpc:delta: */ - - /* CogMIPSELCompiler>>#fullCallsAreRelative */ -static sqInt NoDbgRegParms -fullCallsAreRelative(AbstractInstruction * self_in_fullCallsAreRelative) -{ - return 0; -} - - /* CogMIPSELCompiler>>#functionAtAddress: */ -static sqInt NoDbgRegParms -functionAtAddress(AbstractInstruction * self_in_functionAtAddress, sqInt mcpc) -{ - return (longAt(mcpc)) & 0x3F; -} - - /* CogMIPSELCompiler>>#genDivR:R:Quo:Rem: */ -static sqInt NoDbgRegParms -genDivRRQuoRem(AbstractInstruction * self_in_genDivRRQuoRem, sqInt abstractRegDivisor, sqInt abstractRegDividend, sqInt abstractRegQuotient, sqInt abstractRegRemainder) -{ - genoperandoperand(DivRR, abstractRegDividend, abstractRegDivisor); - genoperand(MoveLowR, abstractRegQuotient); - genoperand(MoveHighR, abstractRegRemainder); - return 0; -} - - /* CogMIPSELCompiler>>#genMulR:R: */ -static AbstractInstruction * NoDbgRegParms -genMulRR(AbstractInstruction * self_in_genMulRR, sqInt regSource, sqInt regDest) -{ - return genoperandoperand(MulRR, regSource, regDest); -} - - -/* Ensure that the register args are pushed before the outer and - inner retpcs at an entry miss for arity <= self numRegArgs. The - outer retpc is that of a call at a send site. The inner is the call - from a method or PIC abort/miss to the trampoline. */ -/* Putting the receiver and args above the return address means the - CoInterpreter has a single machine-code frame format which saves - us a lot of work. */ -/* Iff there are register args convert - sp -> outerRetpc (send site retpc) - linkReg = innerRetpc (PIC abort/miss retpc) - to - base -> receiver - (arg0) - (arg1) - sp -> outerRetpc (send site retpc) - sp -> linkReg/innerRetpc (PIC abort/miss retpc) */ - - /* CogMIPSELCompiler>>#genPushRegisterArgsForAbortMissNumArgs: */ -static void NoDbgRegParms -genPushRegisterArgsForAbortMissNumArgs(AbstractInstruction * self_in_genPushRegisterArgsForAbortMissNumArgs, sqInt numArgs) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - flag("inefficient"); - if (numArgs <= 1 /* numRegArgs */) { - assert((numRegArgs()) <= 2); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, SPReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveRMwr, ReceiverResultReg, 0, SPReg); - if (numArgs > 0) { - /* begin PushR: */ - genoperand(PushR, Arg0Reg); - if (numArgs > 1) { - /* begin PushR: */ - genoperand(PushR, Arg1Reg); - } - } - /* begin PushR: */ - genoperand(PushR, TempReg); - } - /* begin PushR: */ - genoperand(PushR, LinkReg); -} - - -/* Ensure that the register args are pushed before the retpc for arity <= - self numRegArgs. - */ -/* This is easy on a RISC like ARM because the return address is in the link - register. Putting - the receiver and args above the return address means the CoInterpreter has - a single - machine-code frame format which saves us a lot of work - NOTA BENE: we do NOT push the return address here, which means it must be - dealt with later. */ - - /* CogMIPSELCompiler>>#genPushRegisterArgsForNumArgs:scratchReg: */ -static void NoDbgRegParms -genPushRegisterArgsForNumArgsscratchReg(AbstractInstruction * self_in_genPushRegisterArgsForNumArgsscratchReg, sqInt numArgs, sqInt ignored) -{ - flag("inefficient"); - if (numArgs <= 1 /* numRegArgs */) { - assert((numRegArgs()) <= 2); - /* begin PushR: */ - genoperand(PushR, ReceiverResultReg); - if (numArgs > 0) { - /* begin PushR: */ - genoperand(PushR, Arg0Reg); - if (numArgs > 1) { - /* begin PushR: */ - genoperand(PushR, Arg1Reg); - } - } - } -} - - -/* This is a no-op on MIPS since the ABI passes up to 4 args in registers and - trampolines currently observe that limit. - */ - - /* CogMIPSELCompiler>>#genRemoveNArgsFromStack: */ -static sqInt NoDbgRegParms -genRemoveNArgsFromStack(AbstractInstruction * self_in_genRemoveNArgsFromStack, sqInt n) -{ - assert(n <= 4); - return 0; -} - - -/* Restore the registers in regMask as saved by genSaveRegs:. - We don't need to do anything because all of the abstract registers are - allocated to C preserved registers. But for the future... */ - - /* CogMIPSELCompiler>>#genRestoreRegs: */ -static sqInt NoDbgRegParms -genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask) -{ - sqInt reg; - - assert(regMask == 0); - assert(!((((regMask & (registerMaskForandand(SP, FP, RA))) != 0)))); - for (reg = R0; reg <= R28; reg += 1) { - if (((regMask & (1U << reg)) != 0)) { - /* begin PopR: */ - genoperand(PopR, reg); - } - } - return 0; -} - - -/* Save the registers in regMask for a call into the C run-time from a - trampoline. We don't need to do anything because all of the abstract - registers are - allocated to C preserved registers. But for the future... */ - - /* CogMIPSELCompiler>>#genSaveRegs: */ -static sqInt NoDbgRegParms -genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask) -{ - sqInt reg; - - assert(regMask == 0); - assert(!((((regMask & (registerMaskForandand(SP, FP, RA))) != 0)))); - for (reg = R28; reg >= R0; reg += -1) { - if (((regMask & (1U << reg)) != 0)) { - /* begin PushR: */ - genoperand(PushR, reg); - } - } - return 0; -} - - /* CogMIPSELCompiler>>#genSubstituteReturnAddress: */ -static AbstractInstruction * NoDbgRegParms -genSubstituteReturnAddress(AbstractInstruction * self_in_genSubstituteReturnAddress, sqInt retpc) -{ - AbstractInstruction *anInstruction; - - /* begin checkLiteral:forInstruction: */ - anInstruction = genoperandoperand(MoveCwR, retpc, RA); - return anInstruction; -} - - -/* Answer if the processor has a dedicated callee-saved register to point to - the base of commonly-accessed variables. */ - - /* CogMIPSELCompiler>>#hasVarBaseRegister */ -static sqInt NoDbgRegParms -hasVarBaseRegister(AbstractInstruction * self_in_hasVarBaseRegister) -{ - return 1; -} - - /* CogMIPSELCompiler>>#high16BitsOf: */ -static usqInt NoDbgRegParms -high16BitsOf(AbstractInstruction * self_in_high16BitsOf, usqInt word) -{ - return (word) >> 16; -} - - -/* Answer the inline cache tag for the return address of a send. */ -/* MoveCwR ClassReg selectorIndex/expectedClass - Call: unlinked send stub/expectedTarget - Push ReceiverResult <-- callSiteReturnAddress */ -/* lui s3, selector/tagHigh - ori s3, s3, selector/tagLow - lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jalr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#inlineCacheTagAt: */ -static usqInt NoDbgRegParms -inlineCacheTagAt(AbstractInstruction * self_in_inlineCacheTagAt, usqInt callSiteReturnAddress) -{ - assert((opcodeAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 24)) == LUI); - assert((opcodeAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 20)) == ORI); - assert((opcodeAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_inlineCacheTagAt))); - return literalAtAddress(self_in_inlineCacheTagAt, callSiteReturnAddress - 20); -} - - -/* Answer the instruction size at pc. */ - - /* CogMIPSELCompiler>>#instructionSizeAt: */ -static sqInt NoDbgRegParms -instructionSizeAt(AbstractInstruction * self_in_instructionSizeAt, sqInt pc) -{ - return 4; -} - - -/* Assuming mcpc is a send return pc answer if the instruction before it is a - call (not a CallFull). - */ -/* cogit disassembleFrom: mcpc - 8 to: mcpc. */ - - /* CogMIPSELCompiler>>#isCallPrecedingReturnPC: */ -static sqInt NoDbgRegParms -isCallPrecedingReturnPC(AbstractInstruction * self_in_isCallPrecedingReturnPC, sqInt mcpc) -{ - if ((opcodeAtAddress(self_in_isCallPrecedingReturnPC, mcpc - 8)) == JAL) { - return 1; - } - if (((opcodeAtAddress(self_in_isCallPrecedingReturnPC, mcpc - 8)) == SPECIAL) - && ((functionAtAddress(self_in_isCallPrecedingReturnPC, mcpc - 8)) == JALR)) { - return 1; - } - return 0; -} - - /* CogMIPSELCompiler>>#isJump */ -static sqInt NoDbgRegParms -isJump(AbstractInstruction * self_in_isJump) -{ - return (((((self_in_isJump->opcode)) >= FirstJump) && (((self_in_isJump->opcode)) <= LastJump))) - || (((((self_in_isJump->opcode)) >= BrEqualRR) && (((self_in_isJump->opcode)) <= BrLongNotEqualRR))); -} - - -/* cogit disassembleFrom: pc to: pc + 4. */ - - /* CogMIPSELCompiler>>#isJumpAt: */ -static sqInt NoDbgRegParms -isJumpAt(AbstractInstruction * self_in_isJumpAt, sqInt pc) -{ - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == J) { - return 1; - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == SPECIAL) { - if ((functionAtAddress(self_in_isJumpAt, pc)) == JR) { - return 1; - } - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == BEQ) { - return 1; - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == BNE) { - return 1; - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == BLEZ) { - return 1; - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == BGTZ) { - return 1; - } - if ((opcodeAtAddress(self_in_isJumpAt, pc)) == REGIMM) { - if ((rtAtAddress(self_in_isJumpAt, pc)) == BLTZ) { - return 1; - } - if ((rtAtAddress(self_in_isJumpAt, pc)) == BGEZ) { - return 1; - } - } - return 0; -} - - -/* Answer if the receiver is a pc-dependent instruction. */ - - /* CogMIPSELCompiler>>#isPCDependent */ -static sqInt NoDbgRegParms -isPCDependent(AbstractInstruction * self_in_isPCDependent) -{ - return (isJump(self_in_isPCDependent)) - || (((self_in_isPCDependent->opcode)) == AlignmentNops); -} - - /* CogMIPSELCompiler>>#isShortOffset: */ -static sqInt NoDbgRegParms -isShortOffset(AbstractInstruction * self_in_isShortOffset, sqInt offset) -{ - return ((offset >= -32768) && (offset <= 0x7FFF)); -} - - /* CogMIPSELCompiler>>#itype:rs:rt:eitherImmediate: */ -static sqInt NoDbgRegParms -itypersrteitherImmediate(AbstractInstruction * self_in_itypersrteitherImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate) -{ - assert(((op >= 0) && (op <= 0x3F))); - assert(((rs >= 0) && (rs <= 0x1F))); - assert(((rt >= 0) && (rt <= 0x1F))); - return (((((sqInt)((usqInt)(op) << 26))) | (((sqInt)((usqInt)(rs) << 21)))) | (((sqInt)((usqInt)(rt) << 16)))) | (immediate & 0xFFFF); -} - - /* CogMIPSELCompiler>>#itype:rs:rt:signedImmediate: */ -static sqInt NoDbgRegParms -itypersrtsignedImmediate(AbstractInstruction * self_in_itypersrtsignedImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate) -{ - assert(((op >= 0) && (op <= 0x3F))); - assert(((rs >= 0) && (rs <= 0x1F))); - assert(((rt >= 0) && (rt <= 0x1F))); - assert(isShortOffset(self_in_itypersrtsignedImmediate, immediate)); - return (((((sqInt)((usqInt)(op) << 26))) | (((sqInt)((usqInt)(rs) << 21)))) | (((sqInt)((usqInt)(rt) << 16)))) | (immediate & 0xFFFF); -} - - /* CogMIPSELCompiler>>#itype:rs:rt:unsignedImmediate: */ -static sqInt NoDbgRegParms -itypersrtunsignedImmediate(AbstractInstruction * self_in_itypersrtunsignedImmediate, sqInt op, sqInt rs, sqInt rt, sqInt immediate) -{ - assert(((op >= 0) && (op <= 0x3F))); - assert(((rs >= 0) && (rs <= 0x1F))); - assert(((rt >= 0) && (rt <= 0x1F))); - assert(((immediate >= 0) && (immediate <= 0xFFFF))); - return (((((sqInt)((usqInt)(op) << 26))) | (((sqInt)((usqInt)(rs) << 21)))) | (((sqInt)((usqInt)(rt) << 16)))) | immediate; -} - - /* CogMIPSELCompiler>>#jA: */ -static sqInt NoDbgRegParms -jA(AbstractInstruction * self_in_jA, sqInt target) -{ - assert((target & 3) == 0); - return jtypetarget(self_in_jA, J, ((usqInt)((target & 0xFFFFFFF))) >> 2); -} - - /* CogMIPSELCompiler>>#jalA: */ -static sqInt NoDbgRegParms -jalA(AbstractInstruction * self_in_jalA, sqInt target) -{ - assert((target & 3) == 0); - return jtypetarget(self_in_jalA, JAL, ((usqInt)((target & 0xFFFFFFF))) >> 2); -} - - /* CogMIPSELCompiler>>#jalR: */ -static sqInt NoDbgRegParms -jalR(AbstractInstruction * self_in_jalR, sqInt targetReg) -{ - return rtypersrtrdsafunct(self_in_jalR, SPECIAL, targetReg, 0, RA, 0, JALR); -} - - /* CogMIPSELCompiler>>#jR: */ -static sqInt NoDbgRegParms -jR(AbstractInstruction * self_in_jR, sqInt targetReg) -{ - return rtypersrtrdsafunct(self_in_jR, SPECIAL, targetReg, 0, 0, 0, JR); -} - - /* CogMIPSELCompiler>>#jtype:target: */ -static sqInt NoDbgRegParms -jtypetarget(AbstractInstruction * self_in_jtypetarget, sqInt op, sqInt target) -{ - assert(((op >= 0) && (op <= 0x3F))); - assert(((target >= 0) && (target <= 0x7FFFFFF))); - return (((sqInt)((usqInt)(op) << 26))) | target; -} - - /* CogMIPSELCompiler>>#jumpLongByteSize */ -static sqInt NoDbgRegParms -jumpLongByteSize(AbstractInstruction * self_in_jumpLongByteSize) -{ - flag("bogus"); - return 16; -} - - /* CogMIPSELCompiler>>#jumpLongConditionalByteSize */ -static sqInt NoDbgRegParms -jumpLongConditionalByteSize(AbstractInstruction * self_in_jumpLongConditionalByteSize) -{ - return 16; -} - - -/* mcpc - 16: beq/ne Cmp, ZR, +12 - mcpc - 12: nop (delay slot) - mcpc - 8: j psuedo-address - mcpc - 4: nop (delay slot) */ - - /* CogMIPSELCompiler>>#jumpLongConditionalTargetBeforeFollowingAddress: */ -static usqInt NoDbgRegParms -jumpLongConditionalTargetBeforeFollowingAddress(AbstractInstruction * self_in_jumpLongConditionalTargetBeforeFollowingAddress, sqInt mcpc) -{ - assert(((opcodeAtAddress(self_in_jumpLongConditionalTargetBeforeFollowingAddress, mcpc - 16)) == BEQ) - || ((opcodeAtAddress(self_in_jumpLongConditionalTargetBeforeFollowingAddress, mcpc - 16)) == BNE)); - assert((longAt(mcpc - 12)) == (nop(self_in_jumpLongConditionalTargetBeforeFollowingAddress))); - assert((opcodeAtAddress(self_in_jumpLongConditionalTargetBeforeFollowingAddress, mcpc - 8)) == J); - assert((longAt(mcpc - 4)) == (nop(self_in_jumpLongConditionalTargetBeforeFollowingAddress))); - return targetFromJTypeAtAddress(self_in_jumpLongConditionalTargetBeforeFollowingAddress, mcpc - 8); -} - - -/* Answer the target address for the long jump immediately preceding mcpc */ - - /* CogMIPSELCompiler>>#jumpLongTargetBeforeFollowingAddress: */ -static usqInt NoDbgRegParms -jumpLongTargetBeforeFollowingAddress(AbstractInstruction * self_in_jumpLongTargetBeforeFollowingAddress, sqInt mcpc) -{ - assert((longAt(mcpc - 4)) == (nop(self_in_jumpLongTargetBeforeFollowingAddress))); - assert((opcodeAtAddress(self_in_jumpLongTargetBeforeFollowingAddress, mcpc - 8)) == SPECIAL); - assert((functionAtAddress(self_in_jumpLongTargetBeforeFollowingAddress, mcpc - 8)) == JR); - return literalAtAddress(self_in_jumpLongTargetBeforeFollowingAddress, mcpc - 12); -} - - /* CogMIPSELCompiler>>#jumpShortByteSize */ -static sqInt NoDbgRegParms -jumpShortByteSize(AbstractInstruction * self_in_jumpShortByteSize) -{ - return 8; -} - - -/* cogit disassembleFrom: pc to: pc + 4. */ - - /* CogMIPSELCompiler>>#jumpTargetPCAt: */ -static usqInt NoDbgRegParms -jumpTargetPCAt(AbstractInstruction * self_in_jumpTargetPCAt, sqInt pc) -{ - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == J) { - return targetFromJTypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == BEQ) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == BNE) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == BLEZ) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == BGTZ) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((opcodeAtAddress(self_in_jumpTargetPCAt, pc)) == REGIMM) { - if ((rtAtAddress(self_in_jumpTargetPCAt, pc)) == BLTZ) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - if ((rtAtAddress(self_in_jumpTargetPCAt, pc)) == BGEZ) { - return targetFromITypeAtAddress(self_in_jumpTargetPCAt, pc); - } - } - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#lbR:base:offset: */ -static sqInt NoDbgRegParms -lbRbaseoffset(AbstractInstruction * self_in_lbRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_lbRbaseoffset, LB, baseReg, destReg, offset); -} - - /* CogMIPSELCompiler>>#lbuR:base:offset: */ -static sqInt NoDbgRegParms -lbuRbaseoffset(AbstractInstruction * self_in_lbuRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_lbuRbaseoffset, LBU, baseReg, destReg, offset); -} - - /* CogMIPSELCompiler>>#lhR:base:offset: */ -static sqInt NoDbgRegParms -lhRbaseoffset(AbstractInstruction * self_in_lhRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_lhRbaseoffset, LH, baseReg, destReg, offset); -} - - /* CogMIPSELCompiler>>#lhuR:base:offset: */ -static sqInt NoDbgRegParms -lhuRbaseoffset(AbstractInstruction * self_in_lhuRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_lhuRbaseoffset, LHU, baseReg, destReg, offset); -} - - /* CogMIPSELCompiler>>#literalAtAddress: */ -static usqInt NoDbgRegParms -literalAtAddress(AbstractInstruction * self_in_literalAtAddress, sqInt mcpc) -{ - usqInt high; - usqInt low; - - assert((opcodeAtAddress(self_in_literalAtAddress, mcpc)) == ORI); - assert((opcodeAtAddress(self_in_literalAtAddress, mcpc - 4)) == LUI); - low = (longAt(mcpc)) & 0xFFFF; - high = (longAt(mcpc - 4)) & 0xFFFF; - return (high << 16) | low; -} - - /* CogMIPSELCompiler>>#literalAtAddress:put: */ -static sqInt NoDbgRegParms -literalAtAddressput(AbstractInstruction * self_in_literalAtAddressput, sqInt mcpc, sqInt newLiteral) -{ - usqInt newLower; - usqInt newUpper; - usqInt oldLower; - usqInt oldUpper; - - assert((opcodeAtAddress(self_in_literalAtAddressput, mcpc - 4)) == LUI); - assert((opcodeAtAddress(self_in_literalAtAddressput, mcpc)) == ORI); - oldUpper = longAt(mcpc - 4); - newUpper = (oldUpper & 0xFFFF0000U) | (high16BitsOf(self_in_literalAtAddressput, newLiteral)); - longAtput(mcpc - 4, newUpper); - oldLower = longAt(mcpc); - newLower = (oldLower & 0xFFFF0000U) | (low16BitsOf(self_in_literalAtAddressput, newLiteral)); - longAtput(mcpc, newLower); - assert((opcodeAtAddress(self_in_literalAtAddressput, mcpc - 4)) == LUI); - assert((opcodeAtAddress(self_in_literalAtAddressput, mcpc)) == ORI); - assert((literalAtAddress(self_in_literalAtAddressput, mcpc)) == newLiteral); - return newLiteral; -} - - -/* Answer the literal embedded in the instruction immediately preceding - followingAddress. This is used in the MoveCwR, PushCw and CmpCwR cases. */ -/* Cmp/MoveCwR - pc-8 lui rx, uper - pc-4 ori rx, rx, lower */ - - /* CogMIPSELCompiler>>#literalBeforeFollowingAddress: */ -static usqInt NoDbgRegParms -literalBeforeFollowingAddress(AbstractInstruction * self_in_literalBeforeFollowingAddress, sqInt followingAddress) -{ - if ((opcodeAtAddress(self_in_literalBeforeFollowingAddress, followingAddress - 4)) == ORI) { - return literalAtAddress(self_in_literalBeforeFollowingAddress, followingAddress - 4); - } - if (((opcodeAtAddress(self_in_literalBeforeFollowingAddress, followingAddress - 4)) == SW) - && ((opcodeAtAddress(self_in_literalBeforeFollowingAddress, followingAddress - 8)) == ADDIU)) { - return literalAtAddress(self_in_literalBeforeFollowingAddress, followingAddress - 12); - } - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#loadLiteralByteSize */ -static sqInt NoDbgRegParms -loadLiteralByteSize(AbstractInstruction * self_in_loadLiteralByteSize) -{ - return 8; -} - - -/* Answer the byte size of a MoveCwR opcode's corresponding machine code - when the argument is a PIC. This is for the self-reference at the end of a - closed PIC. */ - - /* CogMIPSELCompiler>>#loadPICLiteralByteSize */ -static sqInt NoDbgRegParms -loadPICLiteralByteSize(AbstractInstruction * self_in_loadPICLiteralByteSize) -{ - /* begin loadLiteralByteSize */ - return 8; -} - - /* CogMIPSELCompiler>>#low16BitsOf: */ -static usqInt NoDbgRegParms -low16BitsOf(AbstractInstruction * self_in_low16BitsOf, usqInt word) -{ - return word & 0xFFFF; -} - - /* CogMIPSELCompiler>>#luiR:C: */ -static sqInt NoDbgRegParms -luiRC(AbstractInstruction * self_in_luiRC, sqInt destReg, sqInt imm) -{ - return itypersrteitherImmediate(self_in_luiRC, LUI, 0, destReg, imm); -} - - /* CogMIPSELCompiler>>#lwR:base:offset: */ -static sqInt NoDbgRegParms -lwRbaseoffset(AbstractInstruction * self_in_lwRbaseoffset, sqInt destReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_lwRbaseoffset, LW, baseReg, destReg, offset); -} - - /* CogMIPSELCompiler>>#machineCodeBytes */ -static sqInt NoDbgRegParms -machineCodeBytes(AbstractInstruction * self_in_machineCodeBytes) -{ - return 28; -} - - -/* Answer the maximum number of words of machine code generated for any - abstract instruction. - e.g. AddCheckOverflowCqR */ - - /* CogMIPSELCompiler>>#machineCodeWords */ -static sqInt NoDbgRegParms -machineCodeWords(AbstractInstruction * self_in_machineCodeWords) -{ - return 7; -} - - /* CogMIPSELCompiler>>#mfhiR: */ -static sqInt NoDbgRegParms -mfhiR(AbstractInstruction * self_in_mfhiR, sqInt destReg) -{ - flag("todo"); - return rtypersrtrdsafunct(self_in_mfhiR, SPECIAL, 0, 0, destReg, 0, MFHI); -} - - /* CogMIPSELCompiler>>#mfloR: */ -static sqInt NoDbgRegParms -mfloR(AbstractInstruction * self_in_mfloR, sqInt destReg) -{ - flag("todo"); - return rtypersrtrdsafunct(self_in_mfloR, SPECIAL, 0, 0, destReg, 0, MFLO); -} - - /* CogMIPSELCompiler>>#mipsbreak: */ -static sqInt NoDbgRegParms -mipsbreak(AbstractInstruction * self_in_mipsbreak, sqInt code) -{ - assert(((code >= 0) && (code <= 0xFFFFF))); - return (((sqInt)((usqInt)(code) << 6))) | BREAK; -} - - /* CogMIPSELCompiler>>#multR:R: */ -static sqInt NoDbgRegParms -multRR(AbstractInstruction * self_in_multRR, sqInt leftReg, sqInt rightReg) -{ - flag("todo"); - return rtypersrtrdsafunct(self_in_multRR, SPECIAL, leftReg, rightReg, 0, 0, MULT); -} - - /* CogMIPSELCompiler>>#nop */ -static sqInt NoDbgRegParms -nop(AbstractInstruction * self_in_nop) -{ - return 0; -} - - -/* Support for processors without condition codes, such as the MIPS. - Answer the branch opcode. Modify the receiver and the branch to - implement a suitable conditional branch that doesn't depend on - condition codes being set by the receiver. */ - - /* CogMIPSELCompiler>>#noteFollowingConditionalBranch: */ -static AbstractInstruction * NoDbgRegParms -noteFollowingConditionalBranch(AbstractInstruction * self_in_noteFollowingConditionalBranch, AbstractInstruction *branch) -{ - usqInt newBranchLeft; - sqInt newBranchOpcode; - usqInt newBranchRight; - - if ((((branch->opcode)) == JumpOverflow) - || (((branch->opcode)) == JumpNoOverflow)) { - return noteFollowingOverflowBranch(self_in_noteFollowingConditionalBranch, branch); - } - switch ((branch->opcode)) { - case JumpZero: - newBranchOpcode = BrEqualRR; - break; - - case JumpNonZero: - newBranchOpcode = BrNotEqualRR; - break; - - case JumpBelow: - newBranchOpcode = BrUnsignedLessRR; - break; - - case JumpBelowOrEqual: - newBranchOpcode = BrUnsignedLessEqualRR; - break; - - case JumpAbove: - newBranchOpcode = BrUnsignedGreaterRR; - break; - - case JumpAboveOrEqual: - newBranchOpcode = BrUnsignedGreaterEqualRR; - break; - - case JumpLess: - case JumpNegative: - newBranchOpcode = BrSignedLessRR; - break; - - case JumpLessOrEqual: - newBranchOpcode = BrSignedLessEqualRR; - break; - - case JumpGreater: - newBranchOpcode = BrSignedGreaterRR; - break; - - case JumpGreaterOrEqual: - newBranchOpcode = BrSignedGreaterEqualRR; - break; - - case JumpLongZero: - newBranchOpcode = BrLongEqualRR; - break; - - case JumpLongNonZero: - newBranchOpcode = BrLongNotEqualRR; - break; - - default: - /* begin unreachable */ - error("UNREACHABLE"); - newBranchOpcode = 0;; - } - switch ((self_in_noteFollowingConditionalBranch->opcode)) { - case BrEqualRR: - case BrUnsignedLessRR: - - /* I.e., two jumps after a compare. */ - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[1]; - newBranchRight = ((self_in_noteFollowingConditionalBranch->operands))[2]; - break; - case CmpRR: - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[1]; - newBranchRight = ((self_in_noteFollowingConditionalBranch->operands))[0]; - (self_in_noteFollowingConditionalBranch->opcode) = Label; - break; - case CmpCqR: - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[1]; - newBranchRight = AT; - (self_in_noteFollowingConditionalBranch->opcode) = MoveCqR; - ((self_in_noteFollowingConditionalBranch->operands))[1] = AT; - break; - case CmpCwR: - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[1]; - newBranchRight = AT; - (self_in_noteFollowingConditionalBranch->opcode) = MoveCwR; - ((self_in_noteFollowingConditionalBranch->operands))[1] = AT; - break; - case TstCqR: - newBranchLeft = Cmp; - newBranchRight = ZR; - break; - case AndCqR: - case OrRR: - case XorRR: - case SubCwR: - case SubCqR: - case ArithmeticShiftRightCqR: - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[1]; - newBranchRight = ZR; - break; - case AndCqRR: - case OrCqRR: - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[2]; - newBranchRight = ZR; - break; - case ClzRR: - - /* we test if the destination register is zero */ - newBranchLeft = ((self_in_noteFollowingConditionalBranch->operands))[0]; - newBranchRight = ZR; - break; - default: - /* begin unreachable */ - error("UNREACHABLE"); - - } - /* begin rewriteOpcode:with:with: */ - (branch->opcode) = newBranchOpcode; - ((branch->operands))[1] = newBranchLeft; - ((branch->operands))[2] = newBranchRight; - return branch; -} - - -/* Support for processors without condition codes, such as the MIPS. - Answer the branch opcode. Modify the receiver and the branch to - implement a suitable conditional branch that doesn't depend on - condition codes being set by the receiver. */ - - /* CogMIPSELCompiler>>#noteFollowingOverflowBranch: */ -static AbstractInstruction * NoDbgRegParms -noteFollowingOverflowBranch(AbstractInstruction * self_in_noteFollowingOverflowBranch, AbstractInstruction *branch) -{ - sqInt newBranchOpcode; - - if (((self_in_noteFollowingOverflowBranch->opcode)) == MulRR) { - (self_in_noteFollowingOverflowBranch->opcode) = MulCheckOverflowRR; - switch ((branch->opcode)) { - case JumpOverflow: - newBranchOpcode = BrNotEqualRR; - break; - - case JumpNoOverflow: - newBranchOpcode = BrEqualRR; - break; - - default: - /* begin unreachable */ - error("UNREACHABLE"); - newBranchOpcode = 0;; - } - /* begin rewriteOpcode:with:with: */ - (branch->opcode) = newBranchOpcode; - ((branch->operands))[1] = OverflowTemp1; - ((branch->operands))[2] = OverflowTemp2; - return branch; - } - switch ((self_in_noteFollowingOverflowBranch->opcode)) { - case AddCqR: - (self_in_noteFollowingOverflowBranch->opcode) = AddCheckOverflowCqR; - break; - - case AddRR: - (self_in_noteFollowingOverflowBranch->opcode) = AddCheckOverflowRR; - break; - - case SubCqR: - (self_in_noteFollowingOverflowBranch->opcode) = SubCheckOverflowCqR; - break; - - case SubRR: - (self_in_noteFollowingOverflowBranch->opcode) = SubCheckOverflowRR; - break; - - default: - /* begin unreachable */ - error("UNREACHABLE"); - (self_in_noteFollowingOverflowBranch->opcode) = 0;; - } - switch ((branch->opcode)) { - case JumpOverflow: - newBranchOpcode = BrSignedLessRR; - break; - - case JumpNoOverflow: - newBranchOpcode = BrSignedGreaterEqualRR; - break; - - default: - /* begin unreachable */ - error("UNREACHABLE"); - newBranchOpcode = 0;; - } - /* begin rewriteOpcode:with:with: */ - (branch->opcode) = newBranchOpcode; - ((branch->operands))[1] = Overflow; - ((branch->operands))[2] = ZR; - return branch; -} - - /* CogMIPSELCompiler>>#numIntRegArgs */ -static sqInt NoDbgRegParms -numIntRegArgs(AbstractInstruction * self_in_numIntRegArgs) -{ - flag("OABI"); - return 4; -} - - /* CogMIPSELCompiler>>#opcodeAtAddress: */ -static sqInt NoDbgRegParms -opcodeAtAddress(AbstractInstruction * self_in_opcodeAtAddress, sqInt mcpc) -{ - return ((usqInt)((longAt(mcpc)))) >> 26; -} - - /* CogMIPSELCompiler>>#oriR:R:C: */ -static sqInt NoDbgRegParms -oriRRC(AbstractInstruction * self_in_oriRRC, sqInt destReg, sqInt srcReg, sqInt imm) -{ - return itypersrteitherImmediate(self_in_oriRRC, ORI, srcReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#orR:R:R: */ -static sqInt NoDbgRegParms -orRRR(AbstractInstruction * self_in_orRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_orRRR, SPECIAL, leftReg, rightReg, destReg, 0, OR); -} - - /* CogMIPSELCompiler>>#padIfPossibleWithStopsFrom:to: */ -static void NoDbgRegParms -padIfPossibleWithStopsFromto(AbstractInstruction * self_in_padIfPossibleWithStopsFromto, sqInt startAddr, sqInt endAddr) -{ - sqInt addr; - - for (addr = startAddr; addr < endAddr; addr += 4) { - longAtput(addr, stop(self_in_padIfPossibleWithStopsFromto)); - } -} - - /* CogMIPSELCompiler>>#prefR:offset:hint: */ -static sqInt NoDbgRegParms -prefRoffsethint(AbstractInstruction * self_in_prefRoffsethint, sqInt baseReg, sqInt offset, sqInt hint) -{ - flag("todo"); - assert((hint == HintLoad) - || (hint == HintStore)); - return itypersrtsignedImmediate(self_in_prefRoffsethint, PREF, baseReg, hint, offset); -} - - /* CogMIPSELCompiler>>#pushLinkRegisterByteSize */ -static sqInt NoDbgRegParms -pushLinkRegisterByteSize(AbstractInstruction * self_in_pushLinkRegisterByteSize) -{ - return 8; -} - - /* CogMIPSELCompiler>>#relocateCallBeforeReturnPC:by: */ -static AbstractInstruction * NoDbgRegParms -relocateCallBeforeReturnPCby(AbstractInstruction * self_in_relocateCallBeforeReturnPCby, sqInt retpc, sqInt delta) -{ - usqInt target; - - assert((delta % 4) == 0); - if (delta == 0) { - return self_in_relocateCallBeforeReturnPCby; - } - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 16)) == LUI); - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 12)) == ORI); - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 8)) == SPECIAL); - assert((functionAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 8)) == JALR); - assert((longAt(retpc - 4)) == (nop(self_in_relocateCallBeforeReturnPCby))); - target = literalAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 12); - target += delta; - literalAtAddressput(self_in_relocateCallBeforeReturnPCby, retpc - 12, target); - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 16)) == LUI); - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 12)) == ORI); - assert((opcodeAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 8)) == SPECIAL); - assert((functionAtAddress(self_in_relocateCallBeforeReturnPCby, retpc - 8)) == JALR); - assert((longAt(retpc - 4)) == (nop(self_in_relocateCallBeforeReturnPCby))); - return 0; -} - - -/* lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jr t9 - nop (delay slot) - ... <-- pc */ - - /* CogMIPSELCompiler>>#relocateJumpLongBeforeFollowingAddress:by: */ -static AbstractInstruction * NoDbgRegParms -relocateJumpLongBeforeFollowingAddressby(AbstractInstruction * self_in_relocateJumpLongBeforeFollowingAddressby, sqInt pc, sqInt delta) -{ - usqInt newTarget; - usqInt oldTarget; - - assert((delta % 4) == 0); - if (delta == 0) { - return self_in_relocateJumpLongBeforeFollowingAddressby; - } - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 16)) == LUI); - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 12)) == ORI); - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 8)) == SPECIAL); - assert((functionAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 8)) == JR); - assert((longAt(pc - 4)) == (nop(self_in_relocateJumpLongBeforeFollowingAddressby))); - oldTarget = literalAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 12); - newTarget = oldTarget + delta; - literalAtAddressput(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 12, newTarget); - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 16)) == LUI); - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 12)) == ORI); - assert((opcodeAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 8)) == SPECIAL); - assert((functionAtAddress(self_in_relocateJumpLongBeforeFollowingAddressby, pc - 8)) == JR); - assert((longAt(pc - 4)) == (nop(self_in_relocateJumpLongBeforeFollowingAddressby))); - return 0; -} - - -/* lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jalr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#relocateJumpLongConditionalBeforeFollowingAddress:by: */ -static void NoDbgRegParms -relocateJumpLongConditionalBeforeFollowingAddressby(AbstractInstruction * self_in_relocateJumpLongConditionalBeforeFollowingAddressby, sqInt pc, sqInt delta) -{ - assert((opcodeAtAddress(self_in_relocateJumpLongConditionalBeforeFollowingAddressby, pc - 16)) == BNE); - assert((longAt(pc - 12)) == (nop(self_in_relocateJumpLongConditionalBeforeFollowingAddressby))); - assert((opcodeAtAddress(self_in_relocateJumpLongConditionalBeforeFollowingAddressby, pc - 8)) == J); - assert((longAt(pc - 4)) == (nop(self_in_relocateJumpLongConditionalBeforeFollowingAddressby))); - rewriteJTypeAtAddressdelta(self_in_relocateJumpLongConditionalBeforeFollowingAddressby, pc - 8, delta); - assert((opcodeAtAddress(self_in_relocateJumpLongConditionalBeforeFollowingAddressby, pc - 16)) == BNE); - assert((longAt(pc - 12)) == (nop(self_in_relocateJumpLongConditionalBeforeFollowingAddressby))); - assert((opcodeAtAddress(self_in_relocateJumpLongConditionalBeforeFollowingAddressby, pc - 8)) == J); - assert((longAt(pc - 4)) == (nop(self_in_relocateJumpLongConditionalBeforeFollowingAddressby))); -} - - -/* cogit disassembleFrom: pc - 16 to: pc + 16 a StackToRegisterMappingCogit. */ - - /* CogMIPSELCompiler>>#relocateMethodReferenceBeforeAddress:by: */ -static AbstractInstruction * NoDbgRegParms -relocateMethodReferenceBeforeAddressby(AbstractInstruction * self_in_relocateMethodReferenceBeforeAddressby, sqInt pc, sqInt delta) -{ - usqInt newValue; - usqInt oldValue; - - if (((opcodeAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 8)) == ADDIU) - && ((opcodeAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 4)) == SW)) { - - /* PushCw */ - oldValue = literalAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 12); - newValue = oldValue + delta; - literalAtAddressput(self_in_relocateMethodReferenceBeforeAddressby, pc - 12, newValue); - assert((literalAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 12)) == newValue); - return self_in_relocateMethodReferenceBeforeAddressby; - } - oldValue = literalAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 4); - newValue = oldValue + delta; - literalAtAddressput(self_in_relocateMethodReferenceBeforeAddressby, pc - 4, newValue); - assert((literalAtAddress(self_in_relocateMethodReferenceBeforeAddressby, pc - 4)) == newValue); - return 0; -} - - -/* Rewrite a call instruction to call a different target. This variant is - used to link PICs - in ceSendMiss et al,. - Answer the extent of the code change which is used to compute the range of - the icache to flush. */ -/* lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jalr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#rewriteCallAt:target: */ -static sqInt NoDbgRegParms -rewriteCallAttarget(AbstractInstruction * self_in_rewriteCallAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress) -{ - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteCallAttarget))); - literalAtAddressput(self_in_rewriteCallAttarget, callSiteReturnAddress - 12, callTargetAddress); - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteCallAttarget, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteCallAttarget))); - return 20; -} - - -/* Rewrite a jump instruction to call a different target. This variant is - used to reset the - jumps in the prototype CPIC to suit each use,. - Answer the extent of the code change which is used to compute the range of - the icache to flush. */ - - /* CogMIPSELCompiler>>#rewriteConditionalJumpLongAt:target: */ -static void NoDbgRegParms -rewriteConditionalJumpLongAttarget(AbstractInstruction * self_in_rewriteConditionalJumpLongAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress) -{ - assert((opcodeAtAddress(self_in_rewriteConditionalJumpLongAttarget, callSiteReturnAddress - 8)) == J); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteConditionalJumpLongAttarget))); - rewriteJTypeAtAddresstarget(self_in_rewriteConditionalJumpLongAttarget, callSiteReturnAddress - 8, callTargetAddress); - assert((opcodeAtAddress(self_in_rewriteConditionalJumpLongAttarget, callSiteReturnAddress - 8)) == J); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteConditionalJumpLongAttarget))); -} - - -/* Rewrite a jump instruction to call a different target. This variant is - used to reset the - jumps in the prototype CPIC to suit each use,. - Answer the extent of the code change which is used to compute the range of - the icache to flush. */ -/* self CmpR: ClassReg R: TempReg. - ^self JumpNonZero: 0 */ -/* bne s5, s3, +156 ; =BE7C - nop (delay slot) - .... <-- addressFollowingJump */ - - /* CogMIPSELCompiler>>#rewriteCPICJumpAt:target: */ -static void NoDbgRegParms -rewriteCPICJumpAttarget(AbstractInstruction * self_in_rewriteCPICJumpAttarget, usqInt addressFollowingJump, usqInt jumpTargetAddr) -{ - assert((opcodeAtAddress(self_in_rewriteCPICJumpAttarget, addressFollowingJump - 8)) == BNE); - assert((longAt(addressFollowingJump - 4)) == (nop(self_in_rewriteCPICJumpAttarget))); - rewriteITypeBranchAtAddresstarget(self_in_rewriteCPICJumpAttarget, addressFollowingJump - 8, jumpTargetAddr); - assert((opcodeAtAddress(self_in_rewriteCPICJumpAttarget, addressFollowingJump - 8)) == BNE); - assert((longAt(addressFollowingJump - 4)) == (nop(self_in_rewriteCPICJumpAttarget))); -} - - -/* Rewrite an inline cache to call a different target for a new tag. This - variant is used - to link unlinked sends in ceSend:to:numArgs: et al. Answer the extent of - the code - change which is used to compute the range of the icache to flush. */ -/* MoveCwR ClassReg selectorIndex/expectedClass - Call: unlinked send stub/expectedTarget - Push ReceiverResult <-- callSiteReturnAddress */ -/* lui s3, selector/tagHigh - ori s3, s3, selector/tagLow - lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jalr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#rewriteInlineCacheAt:tag:target: */ -static sqInt NoDbgRegParms -rewriteInlineCacheAttagtarget(AbstractInstruction * self_in_rewriteInlineCacheAttagtarget, usqInt callSiteReturnAddress, sqInt cacheTag, usqInt callTargetAddress) -{ - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 24)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 20)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteInlineCacheAttagtarget))); - literalAtAddressput(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 20, cacheTag); - literalAtAddressput(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 12, callTargetAddress); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 24)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 20)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteInlineCacheAttagtarget, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteInlineCacheAttagtarget))); - return 24; -} - - -/* Rewrite an inline cache with a new tag. This variant is used - by the garbage collector. */ -/* MoveCwR ClassReg selectorIndex/expectedClass - Call: unlinked send stub/expectedTarget - Push ReceiverResult <-- callSiteReturnAddress */ -/* lui s3, selector/tagHigh - ori s3, s3, selector/tagLow - lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jalr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#rewriteInlineCacheTag:at: */ -static void NoDbgRegParms -rewriteInlineCacheTagat(AbstractInstruction * self_in_rewriteInlineCacheTagat, sqInt cacheTag, usqInt callSiteReturnAddress) -{ - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 24)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 20)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteInlineCacheTagat))); - literalAtAddressput(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 20, cacheTag); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 24)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 20)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteInlineCacheTagat, callSiteReturnAddress - 8)) == JALR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteInlineCacheTagat))); -} - - /* CogMIPSELCompiler>>#rewriteITypeBranchAtAddress:target: */ -static void NoDbgRegParms -rewriteITypeBranchAtAddresstarget(AbstractInstruction * self_in_rewriteITypeBranchAtAddresstarget, sqInt mcpc, sqInt newTarget) -{ - sqInt newDisplacement; - unsigned int newInstruction; - sqInt oldInstruction; - - - /* Displacement is relative to delay slot. */ - newDisplacement = newTarget - (mcpc + 4); - - /* Displacement is in words. */ - newDisplacement = (newDisplacement) >> 2; - newDisplacement = newDisplacement & 0xFFFF; - oldInstruction = longAt(mcpc); - newInstruction = (oldInstruction & 0xFFFF0000U) | newDisplacement; - longAtput(mcpc, newInstruction); -} - - /* CogMIPSELCompiler>>#rewriteJTypeAtAddress:delta: */ -static void NoDbgRegParms -rewriteJTypeAtAddressdelta(AbstractInstruction * self_in_rewriteJTypeAtAddressdelta, sqInt mcpc, sqInt delta) -{ - usqInt newTarget; - usqInt oldTarget; - - oldTarget = targetFromJTypeAtAddress(self_in_rewriteJTypeAtAddressdelta, mcpc); - newTarget = oldTarget + delta; - rewriteJTypeAtAddresstarget(self_in_rewriteJTypeAtAddressdelta, mcpc, newTarget); -} - - /* CogMIPSELCompiler>>#rewriteJTypeAtAddress:target: */ -static void NoDbgRegParms -rewriteJTypeAtAddresstarget(AbstractInstruction * self_in_rewriteJTypeAtAddresstarget, sqInt mcpc, sqInt newTarget) -{ - sqInt regionMask; - - assert((opcodeAtAddress(self_in_rewriteJTypeAtAddresstarget, mcpc)) == J); - - /* mcpc + 4: relative to delay slot not j */ - regionMask = 0xF0000000U; - assert(((mcpc + 4) & regionMask) == (newTarget & regionMask)); - longAtput(mcpc, jA(self_in_rewriteJTypeAtAddresstarget, newTarget)); -} - - -/* Rewrite a jump instruction to call a different target. This variant is - used to reset the - jumps in the prototype CPIC to suit each use,. - Answer the extent of the code change which is used to compute the range of - the icache to flush. */ -/* lui t9, stub/targetHigh - ori t9, t9, stub/targetLow - jr t9 - nop (delay slot) - ... <-- callSiteReturnAddress */ - - /* CogMIPSELCompiler>>#rewriteJumpLongAt:target: */ -static sqInt NoDbgRegParms -rewriteJumpLongAttarget(AbstractInstruction * self_in_rewriteJumpLongAttarget, usqInt callSiteReturnAddress, usqInt callTargetAddress) -{ - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 8)) == JR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteJumpLongAttarget))); - literalAtAddressput(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 12, callTargetAddress); - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 16)) == LUI); - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 12)) == ORI); - assert((opcodeAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 8)) == SPECIAL); - assert((functionAtAddress(self_in_rewriteJumpLongAttarget, callSiteReturnAddress - 8)) == JR); - assert((longAt(callSiteReturnAddress - 4)) == (nop(self_in_rewriteJumpLongAttarget))); - return 20; -} - - /* CogMIPSELCompiler>>#rtAtAddress: */ -static sqInt NoDbgRegParms -rtAtAddress(AbstractInstruction * self_in_rtAtAddress, sqInt mcpc) -{ - return (((usqInt)((longAt(mcpc)))) >> 16) & 0x1F; -} - - /* CogMIPSELCompiler>>#rtype:rs:rt:rd:sa:funct: */ -static sqInt NoDbgRegParms -rtypersrtrdsafunct(AbstractInstruction * self_in_rtypersrtrdsafunct, sqInt op, sqInt rs, sqInt rt, sqInt rd, sqInt sa, sqInt funct) -{ - assert(((op >= 0) && (op <= 0x3F))); - assert(((rs >= 0) && (rs <= 0x1F))); - assert(((rt >= 0) && (rt <= 0x1F))); - assert(((rd >= 0) && (rd <= 0x1F))); - assert(((sa >= 0) && (sa <= 0x1F))); - assert(((funct >= 0) && (funct <= 0x3F))); - return (((((((sqInt)((usqInt)(op) << 26))) | (((sqInt)((usqInt)(rs) << 21)))) | (((sqInt)((usqInt)(rt) << 16)))) | (((sqInt)((usqInt)(rd) << 11)))) | (((sqInt)((usqInt)(sa) << 6)))) | funct; -} - - /* CogMIPSELCompiler>>#sbR:base:offset: */ -static sqInt NoDbgRegParms -sbRbaseoffset(AbstractInstruction * self_in_sbRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_sbRbaseoffset, SB, baseReg, srcReg, offset); -} - - -/* Not really, but we can merge this in noteFollowingConditionalBranch:. */ - - /* CogMIPSELCompiler>>#setsConditionCodesFor: */ -static sqInt NoDbgRegParms -setsConditionCodesFor(AbstractInstruction * self_in_setsConditionCodesFor, sqInt aConditionalJumpOpcode) -{ - if (((self_in_setsConditionCodesFor->opcode)) == XorRR) { - return 1; - } - if (((self_in_setsConditionCodesFor->opcode)) == ArithmeticShiftRightCqR) { - return 1; - } - if ((((self_in_setsConditionCodesFor->opcode)) == ClzRR) - && (aConditionalJumpOpcode == JumpZero)) { - return 1; - } - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#shR:base:offset: */ -static sqInt NoDbgRegParms -shRbaseoffset(AbstractInstruction * self_in_shRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_shRbaseoffset, SH, baseReg, srcReg, offset); -} - - -/* Size a jump and set its address. The target may be another instruction - or an absolute address. On entry the address inst var holds our virtual - address. On exit address is set to eventualAbsoluteAddress, which is - where this instruction will be output. The span of a jump to a following - instruction is therefore between that instruction's address and this - instruction's address ((which are both still their virtual addresses), but - the span of a jump to a preceding instruction or to an absolute address is - between that instruction's address (which by now is its eventual absolute - address) or absolute address and eventualAbsoluteAddress. - - ARM is simple; the 26-bit call/jump range means no short jumps. This - routine only has to determine the targets of jumps, not determine sizes. */ - - /* CogMIPSELCompiler>>#sizePCDependentInstructionAt: */ -static usqInt NoDbgRegParms -sizePCDependentInstructionAt(AbstractInstruction * self_in_sizePCDependentInstructionAt, sqInt eventualAbsoluteAddress) -{ - usqInt alignment; - - if (((self_in_sizePCDependentInstructionAt->opcode)) == AlignmentNops) { - (self_in_sizePCDependentInstructionAt->address) = eventualAbsoluteAddress; - alignment = ((self_in_sizePCDependentInstructionAt->operands))[0]; - return ((self_in_sizePCDependentInstructionAt->machineCodeSize) = ((eventualAbsoluteAddress + (alignment - 1)) & (-alignment)) - eventualAbsoluteAddress); - } - assert((isJump(self_in_sizePCDependentInstructionAt)) - || ((((self_in_sizePCDependentInstructionAt->opcode)) == Call) - || (((self_in_sizePCDependentInstructionAt->opcode)) == CallFull))); - if (isJump(self_in_sizePCDependentInstructionAt)) { - resolveJumpTarget(self_in_sizePCDependentInstructionAt); - } - (self_in_sizePCDependentInstructionAt->address) = eventualAbsoluteAddress; - return ((self_in_sizePCDependentInstructionAt->machineCodeSize) = (self_in_sizePCDependentInstructionAt->maxSize)); -} - - /* CogMIPSELCompiler>>#sllR:R:C: */ -static sqInt NoDbgRegParms -sllRRC(AbstractInstruction * self_in_sllRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount) -{ - return rtypersrtrdsafunct(self_in_sllRRC, SPECIAL, 0, sourceReg, destReg, shiftAmount, SLL); -} - - /* CogMIPSELCompiler>>#sllvR:R:R: */ -static sqInt NoDbgRegParms -sllvRRR(AbstractInstruction * self_in_sllvRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_sllvRRR, SPECIAL, rightReg, leftReg, destReg, 0, SLLV); -} - - /* CogMIPSELCompiler>>#sltiR:R:C: */ -static sqInt NoDbgRegParms -sltiRRC(AbstractInstruction * self_in_sltiRRC, sqInt destReg, sqInt leftReg, sqInt imm) -{ - return itypersrtsignedImmediate(self_in_sltiRRC, SLTI, leftReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#sltiuR:R:C: */ -static sqInt NoDbgRegParms -sltiuRRC(AbstractInstruction * self_in_sltiuRRC, sqInt destReg, sqInt leftReg, sqInt imm) -{ - return itypersrtsignedImmediate(self_in_sltiuRRC, SLTIU, leftReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#sltR:R:R: */ -static sqInt NoDbgRegParms -sltRRR(AbstractInstruction * self_in_sltRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_sltRRR, SPECIAL, leftReg, rightReg, destReg, 0, SLT); -} - - /* CogMIPSELCompiler>>#sltuR:R:R: */ -static sqInt NoDbgRegParms -sltuRRR(AbstractInstruction * self_in_sltuRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_sltuRRR, SPECIAL, leftReg, rightReg, destReg, 0, SLTU); -} - - /* CogMIPSELCompiler>>#sraR:R:C: */ -static sqInt NoDbgRegParms -sraRRC(AbstractInstruction * self_in_sraRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount) -{ - return rtypersrtrdsafunct(self_in_sraRRC, SPECIAL, 0, sourceReg, destReg, shiftAmount, SRA); -} - - /* CogMIPSELCompiler>>#sravR:R:R: */ -static sqInt NoDbgRegParms -sravRRR(AbstractInstruction * self_in_sravRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_sravRRR, SPECIAL, rightReg, leftReg, destReg, 0, SRAV); -} - - /* CogMIPSELCompiler>>#srlR:R:C: */ -static sqInt NoDbgRegParms -srlRRC(AbstractInstruction * self_in_srlRRC, sqInt destReg, sqInt sourceReg, sqInt shiftAmount) -{ - return rtypersrtrdsafunct(self_in_srlRRC, SPECIAL, 0, sourceReg, destReg, shiftAmount, SRL); -} - - /* CogMIPSELCompiler>>#srlvR:R:R: */ -static sqInt NoDbgRegParms -srlvRRR(AbstractInstruction * self_in_srlvRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_srlvRRR, SPECIAL, rightReg, leftReg, destReg, 0, SRLV); -} - - /* CogMIPSELCompiler>>#stop */ -static sqInt NoDbgRegParms -stop(AbstractInstruction * self_in_stop) -{ - return mipsbreak(self_in_stop, 0); -} - - /* CogMIPSELCompiler>>#stopsFrom:to: */ -static void NoDbgRegParms -stopsFromto(AbstractInstruction * self_in_stopsFromto, sqInt startAddr, sqInt endAddr) -{ - sqInt addr; - - assert((((endAddr - startAddr) + 1) % 4) == 0); - for (addr = startAddr; addr <= endAddr; addr += 4) { - codeLongAtput(addr, stop(self_in_stopsFromto)); - } -} - - -/* Rewrite the long constant loaded by a MoveCwR or PushCw before the given - address - */ - - /* CogMIPSELCompiler>>#storeLiteral:beforeFollowingAddress: */ -static sqInt NoDbgRegParms -storeLiteralbeforeFollowingAddress(AbstractInstruction * self_in_storeLiteralbeforeFollowingAddress, sqInt literal, sqInt followingAddress) -{ - flag("bogus"); - if ((opcodeAtAddress(self_in_storeLiteralbeforeFollowingAddress, followingAddress - 4)) == ORI) { - return literalAtAddressput(self_in_storeLiteralbeforeFollowingAddress, followingAddress - 4, literal); - } - if (((opcodeAtAddress(self_in_storeLiteralbeforeFollowingAddress, followingAddress - 4)) == SW) - && ((opcodeAtAddress(self_in_storeLiteralbeforeFollowingAddress, followingAddress - 8)) == ADDIU)) { - return literalAtAddressput(self_in_storeLiteralbeforeFollowingAddress, followingAddress - 12, literal); - } - /* begin unreachable */ - error("UNREACHABLE"); - return 0; -} - - /* CogMIPSELCompiler>>#subuR:R:R: */ -static sqInt NoDbgRegParms -subuRRR(AbstractInstruction * self_in_subuRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_subuRRR, SPECIAL, leftReg, rightReg, destReg, 0, SUBU); -} - - /* CogMIPSELCompiler>>#swR:base:offset: */ -static sqInt NoDbgRegParms -swRbaseoffset(AbstractInstruction * self_in_swRbaseoffset, sqInt srcReg, sqInt baseReg, sqInt offset) -{ - return itypersrtsignedImmediate(self_in_swRbaseoffset, SW, baseReg, srcReg, offset); -} - - /* CogMIPSELCompiler>>#targetFromITypeAtAddress: */ -static usqInt NoDbgRegParms -targetFromITypeAtAddress(AbstractInstruction * self_in_targetFromITypeAtAddress, usqInt mcpc) -{ - usqInt offset; - - offset = (longAt(mcpc)) & 0xFFFF; - offset = offset << 2; - return (mcpc + offset) + OneInstruction; -} - - /* CogMIPSELCompiler>>#targetFromJTypeAtAddress: */ -static usqInt NoDbgRegParms -targetFromJTypeAtAddress(AbstractInstruction * self_in_targetFromJTypeAtAddress, usqInt mcpc) -{ - sqInt targetLow; - - - /* mcpc + 4: relative to delay slot not j */ - targetLow = (longAt(mcpc)) & 0x3FFFFFF; - return ((mcpc + 4) & 0xF0000000U) + (((sqInt)((usqInt)(targetLow) << 2))); -} - - /* CogMIPSELCompiler>>#xoriR:R:C: */ -static sqInt NoDbgRegParms -xoriRRC(AbstractInstruction * self_in_xoriRRC, sqInt destReg, sqInt srcReg, sqInt imm) -{ - return itypersrteitherImmediate(self_in_xoriRRC, XORI, srcReg, destReg, imm); -} - - /* CogMIPSELCompiler>>#xorR:R:R: */ -static sqInt NoDbgRegParms -xorRRR(AbstractInstruction * self_in_xorRRR, sqInt destReg, sqInt leftReg, sqInt rightReg) -{ - return rtypersrtrdsafunct(self_in_xorRRR, SPECIAL, leftReg, rightReg, destReg, 0, XOR); -} - - -/* Answer if Call and JumpLong are relative and hence need to take the - caller's relocation delta into account during code compaction, rather than - just the - callee's delta. */ - - /* CogMIPSELCompiler>>#zoneCallsAreRelative */ -static sqInt NoDbgRegParms -zoneCallsAreRelative(AbstractInstruction * self_in_zoneCallsAreRelative) -{ - return 0; -} - - /* CogObjectRepresentation>>#checkValidObjectReference: */ -static sqInt NoDbgRegParms -checkValidObjectReference(sqInt anOop) -{ - return (!(isImmediate(anOop))) - && ((heapMapAtWord(pointerForOop(anOop))) != 0); -} - - /* CogObjectRepresentation>>#genCmpClassFloatCompactIndexR: */ -static AbstractInstruction * NoDbgRegParms -genCmpClassFloatCompactIndexR(sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, ClassFloatCompactIndex, reg); - return anInstruction; -} - - /* CogObjectRepresentation>>#genCmpClassMethodContextCompactIndexR: */ -static AbstractInstruction * NoDbgRegParms -genCmpClassMethodContextCompactIndexR(sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, reg); - return anInstruction; -} - - /* CogObjectRepresentation>>#genLoadSlot:sourceReg:destReg: */ -static sqInt NoDbgRegParms -genLoadSlotsourceRegdestReg(sqInt index, sqInt sourceReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, (index * BytesPerWord) + BaseHeaderSize, sourceReg, destReg); - return 0; -} - - /* CogObjectRepresentation>>#genPrimitiveAdd */ -static sqInt -genPrimitiveAdd(void) -{ - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpOvfl; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genRemoveSmallIntegerTagsInScratchReg(ClassReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, ReceiverResultReg, ClassReg); - /* begin JumpOverflow: */ - jumpOvfl = genConditionalBranchoperand(JumpOverflow, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 1 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpOvfl, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - -/* subclasses override if they can */ - - /* CogObjectRepresentation>>#genPrimitiveAsCharacter */ -static sqInt -genPrimitiveAsCharacter(void) -{ - return UnimplementedPrimitive; -} - - -/* subclasses override if they can */ - - /* CogObjectRepresentation>>#genPrimitiveAtPut */ -static sqInt -genPrimitiveAtPut(void) -{ - return UnimplementedPrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveBitAnd */ -static sqInt -genPrimitiveBitAnd(void) -{ - AbstractInstruction *jumpNotSI; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - /* begin AndR:R: */ - genoperandoperand(AndRR, Arg0Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 1 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveBitOr */ -static sqInt -genPrimitiveBitOr(void) -{ - AbstractInstruction *jumpNotSI; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - /* begin OrR:R: */ - genoperandoperand(OrRR, Arg0Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 1 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - -/* rTemp := rArg0 - rClass := tTemp - rTemp := rTemp & 1 - jz nonInt - rClass >>= 1 - cmp 0,rClass - jge neg - cmp 31,rClass // numSmallIntegerBits, jge for sign - jge tooBig - rTemp := rReceiver - rTemp <<= rClass - rTemp >>= rClass (arithmetic) - cmp rTemp,rReceiver - jnz ovfl - rReceiver := rReceiver - 1 - rReceiver := rReceiver <<= rClass - rReceiver := rReceiver + 1 - ret - neg: - rClass := 0 - rClass - cmp 31,rClass // numSmallIntegerBits - jge inRange - rClass := 31 - inRange - rReceiver := rReceiver >>= rClass. - rReceiver := rReceiver | smallIntegerTags. - ret - ovfl - tooBig - nonInt: - fail - */ - - /* CogObjectRepresentation>>#genPrimitiveBitShift */ -static sqInt -genPrimitiveBitShift(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *jumpInRange; - AbstractInstruction *jumpNegative; - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpOvfl; - AbstractInstruction *jumpTooBig; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genConvertSmallIntegerToIntegerInReg(ClassReg); - if (!(setsConditionCodesFor(lastOpcode(), JumpNegative))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, ClassReg); - } - /* begin JumpNegative: */ - jumpNegative = genConditionalBranchoperand(JumpNegative, ((sqInt)0)); - /* begin CmpCq:R: */ - anInstruction1 = genoperandoperand(CmpCqR, 0x1F /* numSmallIntegerBits */, ClassReg); - /* begin JumpGreaterOrEqual: */ - jumpTooBig = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - /* begin LogicalShiftLeftR:R: */ - genoperandoperand(LogicalShiftLeftRR, ClassReg, TempReg); - /* begin ArithmeticShiftRightR:R: */ - genoperandoperand(ArithmeticShiftRightRR, ClassReg, TempReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, ReceiverResultReg); - /* begin JumpNonZero: */ - jumpOvfl = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genRemoveSmallIntegerTagsInScratchReg(ReceiverResultReg); - /* begin LogicalShiftLeftR:R: */ - genoperandoperand(LogicalShiftLeftRR, ClassReg, ReceiverResultReg); - genAddSmallIntegerTagsTo(ReceiverResultReg); - if (methodOrBlockNumArgs <= 1 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNegative, genoperand(NegateR, ClassReg)); - /* begin CmpCq:R: */ - anInstruction2 = genoperandoperand(CmpCqR, 0x1F /* numSmallIntegerBits */, ClassReg); - /* begin JumpLessOrEqual: */ - jumpInRange = genConditionalBranchoperand(JumpLessOrEqual, ((sqInt)0)); - /* begin MoveCq:R: */ - anInstruction3 = genoperandoperand(MoveCqR, 0x1F /* numSmallIntegerBits */, ClassReg); - jmpTarget(jumpInRange, genoperandoperand(ArithmeticShiftRightRR, ClassReg, ReceiverResultReg)); - genClearAndSetSmallIntegerTagsIn(ReceiverResultReg); - if (methodOrBlockNumArgs <= 1 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotSI, jmpTarget(jumpTooBig, jmpTarget(jumpOvfl, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveBitXor */ -static sqInt -genPrimitiveBitXor(void) -{ - AbstractInstruction *jumpNotSI; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genRemoveSmallIntegerTagsInScratchReg(Arg0Reg); - /* begin XorR:R: */ - genoperandoperand(XorRR, Arg0Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 1 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveClass */ -static sqInt -genPrimitiveClass(void) -{ - sqInt reg; - - reg = ReceiverResultReg; - if (methodOrBlockNumArgs > 0) { - if (methodOrBlockNumArgs > 1) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - reg = Arg0Reg; - assert(0 < (numRegArgs())); - } - if ((genGetClassObjectOfintoscratchRegmayBeAForwarder(reg, ReceiverResultReg, TempReg, reg != ReceiverResultReg)) == BadRegisterSet) { - genGetClassObjectOfintoscratchRegmayBeAForwarder(reg, ClassReg, TempReg, reg != ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, ReceiverResultReg); - } - if (methodOrBlockNumArgs <= 1 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - return UnfailingPrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveDiv */ -static sqInt -genPrimitiveDiv(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *convert; - AbstractInstruction *jumpExact; - AbstractInstruction *jumpIsSI; - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpSameSign; - AbstractInstruction *jumpZero; - - if (!(processorHasDivQuoRemAndMClassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, Arg1Reg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genShiftAwaySmallIntegerTagsInScratchReg(ClassReg); - if (!(setsConditionCodesFor(lastOpcode(), JumpZero))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, ClassReg); - } - /* begin JumpZero: */ - jumpZero = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - genShiftAwaySmallIntegerTagsInScratchReg(TempReg); - gDivRRQuoRem(ClassReg, TempReg, TempReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(CmpCqR, 0, ClassReg); - /* begin JumpZero: */ - jumpExact = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin XorR:R: */ - genoperandoperand(XorRR, ClassReg, Arg1Reg); - if (!(setsConditionCodesFor(lastOpcode(), JumpZero))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, Arg1Reg); - } - /* begin JumpGreaterOrEqual: */ - jumpSameSign = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(SubCqR, 1, TempReg); - jmpTarget(jumpSameSign, (convert = genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - genConvertIntegerInRegtoSmallIntegerInReg(TempReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 1 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpExact, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - jumpIsSI = genJumpIsSmallIntegerValuescratch(TempReg, Arg1Reg); - jmpTarget(jumpIsSI, convert); - jmpTarget(jumpZero, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveDivide */ -static sqInt -genPrimitiveDivide(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *jumpInexact; - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpOverflow; - AbstractInstruction *jumpZero; - - if (!(processorHasDivQuoRemAndMClassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genShiftAwaySmallIntegerTagsInScratchReg(ClassReg); - /* begin JumpZero: */ - jumpZero = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - genShiftAwaySmallIntegerTagsInScratchReg(TempReg); - gDivRRQuoRem(ClassReg, TempReg, TempReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, ClassReg); - /* begin JumpNonZero: */ - jumpInexact = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - jumpOverflow = genJumpNotSmallIntegerValuescratch(TempReg, Arg1Reg); - genConvertIntegerInRegtoSmallIntegerInReg(TempReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 1 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpOverflow, jmpTarget(jumpInexact, jmpTarget(jumpZero, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveEqual */ -static sqInt -genPrimitiveEqual(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpZero, gJumpFPEqual, 0) - : genSmallIntegerComparison(JumpZero)); -} - - /* CogObjectRepresentation>>#genPrimitiveGreaterOrEqual */ -static sqInt -genPrimitiveGreaterOrEqual(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpGreaterOrEqual, gJumpFPGreaterOrEqual, 0) - : genSmallIntegerComparison(JumpGreaterOrEqual)); -} - - /* CogObjectRepresentation>>#genPrimitiveGreaterThan */ -static sqInt -genPrimitiveGreaterThan(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpGreater, gJumpFPGreater, 0) - : genSmallIntegerComparison(JumpGreater)); -} - - -/* Implementation notes: there are two reasons to use TempReg - -1) if primitive fails, ReceiverResultReg must remain unchanged (we - CompletePrimitive) -2) CLZ/BSR only work on 64bits for registers R0-R7 on - Intel X64. But Win64 uses R9 - Normally, this should be backEnd dependent, but for now we have a single - 64bits target... - */ - - /* CogObjectRepresentation>>#genPrimitiveHighBit */ -static sqInt -genPrimitiveHighBit(void) -{ - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *jumpNegativeReceiver; - AbstractInstruction *jumpNegativeReceiver2; - - - /* remove excess tag bits from the receiver oop */ - - /* and use the abstract cogit facility for case of single tag-bit */ - /* begin genHighBitIn:ofSmallIntegerOopWithSingleTagBit: */ - /* begin genHighBitClzIn:ofSmallIntegerOopWithSingleTagBit: */ - genoperandoperand(ClzRR, ReceiverResultReg, TempReg); - if (!(setsConditionCodesFor(lastOpcode(), JumpZero))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(CmpCqR, 0, TempReg); - } - - /* Note the nice bit trick below: - highBit_1based_of_small_int_value = (BytesPerWord * 8) - leadingZeroCout_of_oop - 1 toAccountForTagBit. - This is like 2 complements (- reg - 1) on (BytesPerWord * 8) log2 bits, or exactly a bit invert operation... */ - jumpNegativeReceiver2 = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkLiteral:forInstruction: */ - anInstruction3 = genoperandoperand(XorCwR, (BytesPerWord * 8) - 1, TempReg); - jumpNegativeReceiver = jumpNegativeReceiver2; - goto l4; - l4: /* end genHighBitIn:ofSmallIntegerOopWithSingleTagBit: */; - if (jumpNegativeReceiver == 0) { - return UnimplementedPrimitive; - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - genConvertIntegerToSmallIntegerInReg(ReceiverResultReg); - if (methodOrBlockNumArgs <= 1 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNegativeReceiver, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveIdentical */ -static sqInt -genPrimitiveIdentical(void) -{ - return genPrimitiveIdenticalOrNotIf(0); -} - - -/* subclasses override if they can */ - - /* CogObjectRepresentation>>#genPrimitiveImmediateAsInteger */ -static sqInt -genPrimitiveImmediateAsInteger(void) -{ - return UnimplementedPrimitive; -} - - -/* subclasses override if they can */ - - /* CogObjectRepresentation>>#genPrimitiveIntegerAt */ -static sqInt -genPrimitiveIntegerAt(void) -{ - return UnimplementedPrimitive; -} - - -/* subclasses override if they can */ - - /* CogObjectRepresentation>>#genPrimitiveIntegerAtPut */ -static sqInt -genPrimitiveIntegerAtPut(void) -{ - return UnimplementedPrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveLessOrEqual */ -static sqInt -genPrimitiveLessOrEqual(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpLessOrEqual, gJumpFPGreaterOrEqual, 1) - : genSmallIntegerComparison(JumpLessOrEqual)); -} - - /* CogObjectRepresentation>>#genPrimitiveLessThan */ -static sqInt -genPrimitiveLessThan(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpLess, gJumpFPGreater, 1) - : genSmallIntegerComparison(JumpLess)); -} - - -/* subclasses override if they so desire */ - - /* CogObjectRepresentation>>#genPrimitiveMakePoint */ -static sqInt -genPrimitiveMakePoint(void) -{ - return UnimplementedPrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveMod */ -static sqInt -genPrimitiveMod(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *jumpExact; - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpSameSign; - AbstractInstruction *jumpZero; - - if (!(processorHasDivQuoRemAndMClassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genRemoveSmallIntegerTagsInScratchReg(ClassReg); - /* begin JumpZero: */ - jumpZero = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, Arg1Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - genRemoveSmallIntegerTagsInScratchReg(TempReg); - gDivRRQuoRem(ClassReg, TempReg, TempReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, ClassReg); - /* begin JumpZero: */ - jumpExact = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin XorR:R: */ - genoperandoperand(XorRR, ClassReg, Arg1Reg); - if (!(setsConditionCodesFor(lastOpcode(), JumpZero))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, Arg1Reg); - } - /* begin JumpGreaterOrEqual: */ - jumpSameSign = genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0)); - /* begin XorR:R: */ - genoperandoperand(XorRR, ClassReg, Arg1Reg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg1Reg, ClassReg); - jmpTarget(jumpSameSign, jmpTarget(jumpExact, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - genSetSmallIntegerTagsIn(ClassReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 1 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpZero, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveMultiply */ -static sqInt -genPrimitiveMultiply(void) -{ - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpOvfl; - - if (!(processorHasMultiplyAndMClassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, Arg1Reg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genShiftAwaySmallIntegerTagsInScratchReg(ClassReg); - genRemoveSmallIntegerTagsInScratchReg(Arg1Reg); - /* begin MulOverflowR:R: */ - genMulRR(backEnd, Arg1Reg, ClassReg); - /* begin JumpOverflow: */ - jumpOvfl = genConditionalBranchoperand(JumpOverflow, ((sqInt)0)); - genSetSmallIntegerTagsIn(ClassReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 1 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpOvfl, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - -/* subclasses override if they can */ - - /* CogObjectRepresentation>>#genPrimitiveNew */ -static sqInt -genPrimitiveNew(void) -{ - return UnimplementedPrimitive; -} - - -/* subclasses override if they can */ - - /* CogObjectRepresentation>>#genPrimitiveNewMethod */ -static sqInt -genPrimitiveNewMethod(void) -{ - return UnimplementedPrimitive; -} - - -/* subclasses override if they can */ - - /* CogObjectRepresentation>>#genPrimitiveNewWithArg */ -static sqInt -genPrimitiveNewWithArg(void) -{ - return UnimplementedPrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveNotEqual */ -static sqInt -genPrimitiveNotEqual(void) -{ - return (primitiveDoMixedArithmetic() - ? genSmallIntegerComparisonorDoubleComparisoninvert(JumpNonZero, gJumpFPNotEqual, 0) - : genSmallIntegerComparison(JumpNonZero)); -} - - /* CogObjectRepresentation>>#genPrimitiveNotIdentical */ -static sqInt -genPrimitiveNotIdentical(void) -{ - return genPrimitiveIdenticalOrNotIf(1); -} - - -/* subclasses override if they can */ - - /* CogObjectRepresentation>>#genPrimitiveObjectAt */ -static sqInt -genPrimitiveObjectAt(void) -{ - return UnimplementedPrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveQuo */ -static sqInt -genPrimitiveQuo(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *convert; - AbstractInstruction *jumpExact; - AbstractInstruction *jumpIsSI; - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpZero; - - if (!(processorHasDivQuoRemAndMClassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ClassReg); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - genShiftAwaySmallIntegerTagsInScratchReg(ClassReg); - if (!(setsConditionCodesFor(lastOpcode(), JumpZero))) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, ClassReg); - } - /* begin JumpZero: */ - jumpZero = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - genShiftAwaySmallIntegerTagsInScratchReg(TempReg); - gDivRRQuoRem(ClassReg, TempReg, TempReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, ClassReg); - /* begin JumpZero: */ - jumpExact = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin Label */ - convert = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - genConvertIntegerInRegtoSmallIntegerInReg(TempReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 1 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpExact, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - jumpIsSI = genJumpIsSmallIntegerValuescratch(TempReg, Arg1Reg); - jmpTarget(jumpIsSI, convert); - jmpTarget(jumpZero, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - -/* subclasses override if they can */ - - /* CogObjectRepresentation>>#genPrimitiveShallowCopy */ -static sqInt -genPrimitiveShallowCopy(void) -{ - return UnimplementedPrimitive; -} - - -/* subclasses override if they can */ - - /* CogObjectRepresentation>>#genPrimitiveStringAtPut */ -static sqInt -genPrimitiveStringAtPut(void) -{ - return UnimplementedPrimitive; -} - - -/* subclasses override if they can */ - - /* CogObjectRepresentation>>#genPrimitiveStringCompareWith */ -static sqInt -genPrimitiveStringCompareWith(void) -{ - return UnimplementedPrimitive; -} - - -/* subclasses override if they can */ - - /* CogObjectRepresentation>>#genPrimitiveStringReplace */ -static sqInt -genPrimitiveStringReplace(void) -{ - return UnimplementedPrimitive; -} - - /* CogObjectRepresentation>>#genPrimitiveSubtract */ -static sqInt -genPrimitiveSubtract(void) -{ - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpOvfl; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, Arg0Reg, TempReg); - /* begin JumpOverflow: */ - jumpOvfl = genConditionalBranchoperand(JumpOverflow, ((sqInt)0)); - genAddSmallIntegerTagsTo(TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 1 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpOvfl, jmpTarget(jumpNotSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - /* CogObjectRepresentation>>#genSmallIntegerComparison: */ -static sqInt NoDbgRegParms -genSmallIntegerComparison(sqInt jumpOpcode) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt constant; - AbstractInstruction *jumpFail; - AbstractInstruction *jumpTrue; - - if (!(mclassIsSmallInteger())) { - return UnimplementedPrimitive; - } - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin genJumpNotSmallInteger:scratchReg: */ - jumpFail = genJumpNotSmallInteger(Arg0Reg); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, ReceiverResultReg); - jumpTrue = genConditionalBranchoperand(jumpOpcode, 0); - /* begin genMoveConstant:R: */ - constant = falseObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - if (methodOrBlockNumArgs <= 1 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpTrue, (shouldAnnotateObjectReference(trueObject()) - ? annotateobjRef(checkLiteralforInstruction(trueObject(), genoperandoperand(MoveCwR, trueObject(), ReceiverResultReg)), trueObject()) - : (/* begin checkQuickConstant:forInstruction: */ - trueObject(), - (anInstruction1 = genoperandoperand(MoveCqR, trueObject(), ReceiverResultReg)), - anInstruction1))); - if (methodOrBlockNumArgs <= 1 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpFail, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - -/* Stack looks like - return address */ - - /* CogObjectRepresentation>>#genSmallIntegerComparison:orDoubleComparison:invert: */ -static sqInt NoDbgRegParms -genSmallIntegerComparisonorDoubleComparisoninvert(sqInt jumpOpcode, AbstractInstruction * NoDbgRegParms (*jumpFPOpcodeGenerator)(void *), sqInt invertComparison) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt constant; - AbstractInstruction *jumpCond; - AbstractInstruction * jumpFail; - sqInt r; - - r = genSmallIntegerComparison(jumpOpcode); - if (r < 0) { - return r; - } -# if defined(DPFPReg0) - - /* Fall through on non-SmallInteger argument. Argument may be a Float : let us check or fail */ - genGetCompactClassIndexNonImmOfinto(Arg0Reg, SendNumArgsReg); - genCmpClassFloatCompactIndexR(SendNumArgsReg); - /* begin JumpNonZero: */ - jumpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genConvertSmallIntegerToIntegerInReg(ReceiverResultReg); - /* begin ConvertR:Rd: */ - genoperandoperand(ConvertRRd, ReceiverResultReg, DPFPReg0); - genGetDoubleValueOfinto(Arg0Reg, DPFPReg1); - if (invertComparison) { - - /* May need to invert for NaNs */ - /* begin CmpRd:Rd: */ - genoperandoperand(CmpRdRd, DPFPReg0, DPFPReg1); - } - else { - /* begin CmpRd:Rd: */ - genoperandoperand(CmpRdRd, DPFPReg1, DPFPReg0); - } - - /* FP jumps are a little weird */ - jumpCond = jumpFPOpcodeGenerator(0); - /* begin genMoveConstant:R: */ - constant = falseObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - if (methodOrBlockNumArgs <= 1 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpCond, (shouldAnnotateObjectReference(trueObject()) - ? annotateobjRef(checkLiteralforInstruction(trueObject(), genoperandoperand(MoveCwR, trueObject(), ReceiverResultReg)), trueObject()) - : (/* begin checkQuickConstant:forInstruction: */ - trueObject(), - (anInstruction1 = genoperandoperand(MoveCqR, trueObject(), ReceiverResultReg)), - anInstruction1))); - if (methodOrBlockNumArgs <= 1 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpFail, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); -# endif // defined(DPFPReg0) - return CompletePrimitive; -} - - -/* subclasses override if they want, and will have SendNumArgsReg and - ClassReg available in addition to ReceiverResultReg and TempReg if they - do. - */ - - /* CogObjectRepresentation>>#getActiveContextAllocatesInMachineCode */ -static sqInt -getActiveContextAllocatesInMachineCode(void) -{ - return 0; -} - - /* CogObjectRepresentation>>#isUnannotatableConstant: */ -static sqInt NoDbgRegParms -isUnannotatableConstant(CogSimStackEntry *simStackEntry) -{ - return (((simStackEntry->type)) == SSConstant) - && ((isImmediate((simStackEntry->constant))) - || (!(shouldAnnotateObjectReference((simStackEntry->constant))))); -} - - -/* Answer if the cacheTag is not unmarked, i.e. answer true for compact - class indices and immediates; only answer false for unmarked objects */ - - /* CogObjectRepresentationForSqueakV3>>#cacheTagIsMarked: */ -static sqInt NoDbgRegParms -cacheTagIsMarked(sqInt cacheTag) -{ - if (!(couldBeObject(cacheTag))) { - return 1; - } - assert(addressCouldBeObj(cacheTag)); - return isMarked(cacheTag); -} - - /* CogObjectRepresentationForSqueakV3>>#checkValidOopReference: */ -static sqInt NoDbgRegParms -checkValidOopReference(sqInt anOop) -{ - return ((anOop & 1)) - || ((heapMapAtWord(pointerForOop(anOop))) != 0); -} - - /* CogObjectRepresentationForSqueakV3>>#classForInlineCacheTag: */ -static sqInt NoDbgRegParms -classForInlineCacheTag(sqInt inlineCacheTag) -{ - if ((inlineCacheTag & 1)) { - return classSmallInteger(); - } - if (couldBeObject(inlineCacheTag)) { - return inlineCacheTag; - } - return compactClassAt(((usqInt)(inlineCacheTag)) >> (compactClassFieldLSB())); -} - - -/* This is the mask for the field when shifted into the least significant - bits - */ - - /* CogObjectRepresentationForSqueakV3>>#compactClassFieldMask */ -static sqInt -compactClassFieldMask(void) -{ - return (1U << (compactClassFieldWidth())) - 1; -} - - -/* Note this version filters-out compact class indices via the >= nilObj - clause - */ - - /* CogObjectRepresentationForSqueakV3>>#couldBeObject: */ -static sqInt NoDbgRegParms -couldBeObject(sqInt oop) -{ - return (isNonIntegerObject(oop)) - && (oopisGreaterThanOrEqualTo(oop, nilObject())); -} - - -/* Short-circuit the interpreter call if a frame is already married. */ - - /* CogObjectRepresentationForSqueakV3>>#genActiveContextTrampoline */ -static usqInt -genActiveContextTrampoline(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *jumpSingle; - - zeroOpcodeIndex(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, FoxMethod, FPReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, MFMethodFlagHasContextFlag, TempReg); - /* begin JumpZero: */ - jumpSingle = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveMwrR, FoxThisContext, FPReg, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, 0); - jmpTarget(jumpSingle, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceActiveContext, "ceActiveContextTrampoline", 0, null, null, null, null, 0 /* emptyRegisterMask */, 1, ReceiverResultReg, 1); -} - - /* CogObjectRepresentationForSqueakV3>>#genAddSmallIntegerTagsTo: */ -static sqInt NoDbgRegParms -genAddSmallIntegerTagsTo(sqInt aRegister) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, 1, aRegister); - return 0; -} - - -/* Set the SmallInteger tag bits when the tag bits may be filled with - garbage. - */ - - /* CogObjectRepresentationForSqueakV3>>#genClearAndSetSmallIntegerTagsIn: */ -static sqInt NoDbgRegParms -genClearAndSetSmallIntegerTagsIn(sqInt scratchReg) -{ - return genSetSmallIntegerTagsIn(scratchReg); -} - - /* CogObjectRepresentationForSqueakV3>>#genConvertIntegerInReg:toSmallIntegerInReg: */ -static sqInt NoDbgRegParms -genConvertIntegerInRegtoSmallIntegerInReg(sqInt srcReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - - gLogicalShiftLeftCqRR(1, srcReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, 1, destReg); - return 0; -} - - /* CogObjectRepresentationForSqueakV3>>#genConvertIntegerToSmallIntegerInReg: */ -static sqInt NoDbgRegParms -genConvertIntegerToSmallIntegerInReg(sqInt reg) -{ - AbstractInstruction *anInstruction; - - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, 1, reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, 1, reg); - return 0; -} - - /* CogObjectRepresentationForSqueakV3>>#genConvertSmallIntegerToIntegerInReg: */ -static sqInt NoDbgRegParms -genConvertSmallIntegerToIntegerInReg(sqInt reg) -{ - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, 1, reg); - return 0; -} - - -/* Create a closure with the given startpc, numArgs and numCopied - within a context with ctxtNumArgs, large if isLargeCtxt that is in a - block if isInBlock. If numCopied > 0 pop those values off the stack. */ -/* see ceClosureCopyDescriptor: */ - - /* CogObjectRepresentationForSqueakV3>>#genCreateClosureAt:numArgs:numCopied:contextNumArgs:large:inBlock: */ -static sqInt NoDbgRegParms -genCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(sqInt bcpc, sqInt numArgs, sqInt numCopied, sqInt ctxtNumArgs, sqInt isLargeCtxt, sqInt isInBlock) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, (numArgs + (((sqInt)((usqInt)(numCopied) << 6)))) + (((sqInt)((usqInt)(bcpc) << 12))), SendNumArgsReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceClosureCopyTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - if (numCopied > 0) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, numCopied * BytesPerWord, SPReg); - } - return 0; -} - - -/* Do the store check. Answer the argument for the benefit of the code - generator; ReceiverResultReg may be caller-saved and hence smashed by this - call. Answering - it allows the code generator to reload ReceiverResultReg cheaply. */ - - /* CogObjectRepresentationForSqueakV3>>#generateObjectRepresentationTrampolines */ -static void -generateObjectRepresentationTrampolines(void) -{ - sqInt regMask; - sqInt regMask1; - sqInt regMask2; - sqInt regMask3; - sqInt resultReg; - - /* begin genTrampolineFor:called:arg:regsToSave:result: */ - regMask = ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)); - resultReg = (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) - ? ReceiverResultReg - : ABIResultReg); - ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceStoreCheck, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, regMask, 1, resultReg, 0); - /* begin genTrampolineFor:called:arg:regsToSave:result: */ - regMask1 = ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)); - ceCreateNewArrayTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceNewArraySlotSize, "ceCreateNewArrayTrampoline", 1, SendNumArgsReg, null, null, null, regMask1, 1, ReceiverResultReg, 0); - /* begin genTrampolineFor:called:arg:regsToSave:result: */ - regMask2 = ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)); - cePositive32BitIntegerTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(positive32BitIntegerFor, "cePositive32BitIntegerTrampoline", 1, ReceiverResultReg, null, null, null, regMask2, 1, TempReg, 0); - ceActiveContextTrampoline = genActiveContextTrampoline(); - /* begin genTrampolineFor:called:arg:regsToSave:result: */ - regMask3 = ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)); - ceClosureCopyTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceClosureCopyDescriptor, "ceClosureCopyTrampoline", 1, SendNumArgsReg, null, null, null, regMask3, 1, ReceiverResultReg, 0); - } - - -/* Get the active context into ReceiverResultReg, creating it if necessary. */ - - /* CogObjectRepresentationForSqueakV3>>#genGetActiveContextNumArgs:large:inBlock: */ -static void NoDbgRegParms -genGetActiveContextNumArgslargeinBlock(sqInt numArgs, sqInt isLargeContext, sqInt isInBlock) -{ - AbstractInstruction *abstractInstruction; - - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceActiveContextTrampoline); - (abstractInstruction->annotation = IsRelativeCall); -} - - -/* Fetch the instance's class format into destReg, assuming the object is - non-int. - */ - - /* CogObjectRepresentationForSqueakV3>>#genGetClassFormatOfNonInt:into:scratchReg: */ -static sqInt NoDbgRegParms -genGetClassFormatOfNonIntintoscratchReg(sqInt instReg, sqInt destReg, sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *jumpCompact; - AbstractInstruction *jumpGotClass; - sqInt quickConstant; - sqInt quickConstant1; - - - /* Get header word in destReg */ - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, instReg, destReg); - /* begin LogicalShiftRightCq:R: */ - quickConstant = (compactClassFieldLSB()) - (shiftForWord()); - genoperandoperand(LogicalShiftRightCqR, quickConstant, destReg); - /* begin AndCq:R: */ - quickConstant1 = ((sqInt)((usqInt)(((1U << (compactClassFieldWidth())) - 1)) << (shiftForWord()))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, quickConstant1, destReg); - /* begin JumpNonZero: */ - jumpCompact = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - classFieldOffset(); - anInstruction2 = genoperandoperandoperand(MoveMwrR, classFieldOffset(), instReg, scratchReg); - /* begin checkQuickConstant:forInstruction: */ - ((int) AllButTypeMask); - anInstruction3 = genoperandoperand(AndCqR, ((int) AllButTypeMask), scratchReg); - /* begin Jump: */ - jumpGotClass = genoperand(Jump, ((sqInt)0)); - assert(BaseHeaderSize == BytesPerWord); - jmpTarget(jumpCompact, annotateobjRef(gMoveMwrR(splObj(CompactClasses), destReg, scratchReg), splObj(CompactClasses))); - jmpTarget(jumpGotClass, gMoveMwrR((((int)((usqInt)(InstanceSpecificationIndex) << (shiftForWord())))) + BytesPerWord, scratchReg, destReg)); - return 0; -} - - -/* Fetch the instance's class into destReg. This is almost identical - to genGetClassFormatOfNonInt:into:scratchReg: but because we - put the fetch of SmallInteger between the then and the else for - compact class/non-compact class we cannot easily share code. - instRegIsReceiver is ignored. It is for Spur compatibility where - objects may be forwarded. */ - - /* CogObjectRepresentationForSqueakV3>>#genGetClassObjectOf:into:scratchReg:mayBeAForwarder: */ -static sqInt NoDbgRegParms -genGetClassObjectOfintoscratchRegmayBeAForwarder(sqInt instReg, sqInt destReg, sqInt scratchReg, sqInt mayBeAForwarder) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *jumpCompact; - AbstractInstruction *jumpGotClass; - AbstractInstruction *jumpGotClass2; - AbstractInstruction *jumpIsInt; - sqInt quickConstant; - sqInt quickConstant1; - sqInt quickConstant2; - - /* begin MoveR:R: */ - genoperandoperand(MoveRR, instReg, scratchReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, 1, scratchReg); - /* begin JumpNonZero: */ - jumpIsInt = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveMwrR, 0, instReg, scratchReg); - /* begin LogicalShiftRightCq:R: */ - quickConstant = (compactClassFieldLSB()) - (shiftForWord()); - genoperandoperand(LogicalShiftRightCqR, quickConstant, scratchReg); - /* begin AndCq:R: */ - quickConstant2 = ((sqInt)((usqInt)(((1U << (compactClassFieldWidth())) - 1)) << (shiftForWord()))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(AndCqR, quickConstant2, scratchReg); - /* begin JumpNonZero: */ - jumpCompact = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - classFieldOffset(); - anInstruction4 = genoperandoperandoperand(MoveMwrR, classFieldOffset(), instReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - ((int) AllButTypeMask); - anInstruction5 = genoperandoperand(AndCqR, ((int) AllButTypeMask), destReg); - /* begin Jump: */ - jumpGotClass = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpIsInt, (shouldAnnotateObjectReference(classSmallInteger()) - ? annotateobjRef(gMoveCwR(classSmallInteger(), destReg), classSmallInteger()) - : (/* begin MoveCq:R: */ - (quickConstant1 = classSmallInteger()), - /* begin checkQuickConstant:forInstruction: */ - (anInstruction = genoperandoperand(MoveCqR, quickConstant1, destReg)), - anInstruction))); - /* begin Jump: */ - jumpGotClass2 = genoperand(Jump, ((sqInt)0)); - assert(BaseHeaderSize == BytesPerWord); - jmpTarget(jumpCompact, annotateobjRef(gMoveMwrR(splObj(CompactClasses), scratchReg, destReg), splObj(CompactClasses))); - jmpTarget(jumpGotClass, jmpTarget(jumpGotClass2, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return 0; -} - - -/* Compatibility with SpurObjectRepresentation/SpurMemoryManager. */ - - /* CogObjectRepresentationForSqueakV3>>#genGetClassTagOf:into:scratchReg: */ -static AbstractInstruction * NoDbgRegParms -genGetClassTagOfintoscratchReg(sqInt instReg, sqInt destReg, sqInt scratchReg) -{ - sqInt alignment; - AbstractInstruction *entryLabel; - - /* begin AlignmentNops: */ - alignment = ((BytesPerWord < 8) ? 8 : BytesPerWord); - genoperand(AlignmentNops, alignment); - /* begin Label */ - entryLabel = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - if ((genGetClassObjectOfintoscratchRegmayBeAForwarder(instReg, destReg, scratchReg, null)) != 0) { - error("internal error"); - } - return entryLabel; -} - - -/* Fetch the instance's compact class index into destReg. */ -/* Get header word in scratchReg */ - - /* CogObjectRepresentationForSqueakV3>>#genGetCompactClassIndexNonImmOf:into: */ -static sqInt NoDbgRegParms -genGetCompactClassIndexNonImmOfinto(sqInt instReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt quickConstant; - sqInt quickConstant1; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, instReg, destReg); - /* begin LogicalShiftRightCq:R: */ - quickConstant = compactClassFieldLSB(); - genoperandoperand(LogicalShiftRightCqR, quickConstant, destReg); - /* begin AndCq:R: */ - quickConstant1 = (1U << (compactClassFieldWidth())) - 1; - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, quickConstant1, destReg); - return 0; -} - - /* CogObjectRepresentationForSqueakV3>>#genGetDoubleValueOf:into: */ -static sqInt NoDbgRegParms -genGetDoubleValueOfinto(sqInt srcReg, sqInt destFPReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveM64rRd, BaseHeaderSize, srcReg, destFPReg); - return 0; -} - - -/* Fetch the instance's class format into destReg, assuming the object is - pointers and non-int - */ - - /* CogObjectRepresentationForSqueakV3>>#genGetFixedFieldsOfPointerNonInt:into:scratchReg: */ -static sqInt NoDbgRegParms -genGetFixedFieldsOfPointerNonIntintoscratchReg(sqInt instReg, sqInt destReg, sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - - genGetClassFormatOfNonIntintoscratchReg(instReg, destReg, scratchReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, destReg, scratchReg); - /* begin LogicalShiftRightCq:R: */ - genoperandoperand(LogicalShiftRightCqR, 2, destReg); - /* begin LogicalShiftRightCq:R: */ - genoperandoperand(LogicalShiftRightCqR, 11, scratchReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, 0x3F, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, 192, scratchReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(SubCqR, 1, destReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, scratchReg, destReg); - return 0; -} - - -/* Fetch the instance's identity hash into destReg, encoded as a - SmallInteger. - */ -/* Get header word in scratchReg */ - - /* CogObjectRepresentationForSqueakV3>>#genGetHashFieldNonImmOf:asSmallIntegerInto: */ -static sqInt NoDbgRegParms -genGetHashFieldNonImmOfasSmallIntegerInto(sqInt instReg, sqInt destReg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, instReg, destReg); - /* begin LogicalShiftRightCq:R: */ - genoperandoperand(LogicalShiftRightCqR, HashBitsOffset - 1, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, ((int)((usqInt)(HashMaskUnshifted) << 1)), destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AddCqR, 1, destReg); - return 0; -} - - -/* Extract the inline cache tag for the object in sourceReg into destReg. The - inline cache tag - for a given object is the value loaded in inline caches to distinguish - objects of different - classes. In Spur this is either the tags for immediates, or the receiver's - classIndex. The inline cache tag for a given object is the value loaded in - inline caches to distinguish - objects of different classes. In SqueakV3 the tag is the integer tag bit - for SmallIntegers (1), - the compact class index shifted by log: 2 word size for objects with - compact classes - (1 * 4 to: 31 * 4 by: 4), or the class. These ranges cannot overlap - because the heap - (and hence the lowest class object) is beyond the machine code zone. - If forEntry is true answer the entry label at which control is to enter - (cmEntryOffset). If forEntry is false, control enters at the start. */ - - /* CogObjectRepresentationForSqueakV3>>#genGetInlineCacheClassTagFrom:into:forEntry: */ -static AbstractInstruction * NoDbgRegParms -genGetInlineCacheClassTagFromintoforEntry(sqInt sourceReg, sqInt destReg, sqInt forEntry) -{ - sqInt alignment; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *entryLabel; - AbstractInstruction *jumpCompact; - AbstractInstruction *jumpIsInt; - sqInt quickConstant; - - /* begin AlignmentNops: */ - alignment = ((BytesPerWord < 8) ? 8 : BytesPerWord); - genoperand(AlignmentNops, alignment); - /* begin Label */ - entryLabel = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, sourceReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, 1, destReg); - /* begin JumpNonZero: */ - jumpIsInt = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, 0, sourceReg, destReg); - assert((((sqInt)((usqInt)((compactClassFieldMask())) << (compactClassFieldLSB())))) < (((usqInt)(nilObject())))); - /* begin AndCq:R: */ - quickConstant = ((sqInt)((usqInt)(((1U << (compactClassFieldWidth())) - 1)) << (compactClassFieldLSB()))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AndCqR, quickConstant, destReg); - /* begin JumpNonZero: */ - jumpCompact = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - classFieldOffset(); - anInstruction3 = genoperandoperandoperand(MoveMwrR, classFieldOffset(), sourceReg, destReg); - /* begin checkQuickConstant:forInstruction: */ - ((int) AllButTypeMask); - anInstruction4 = genoperandoperand(AndCqR, ((int) AllButTypeMask), destReg); - jmpTarget(jumpCompact, jmpTarget(jumpIsInt, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return entryLabel; -} - - /* CogObjectRepresentationForSqueakV3>>#genJumpImmediate: */ -static AbstractInstruction * NoDbgRegParms -genJumpImmediate(sqInt aRegister) -{ - return genJumpSmallInteger(aRegister); -} - - -/* Generate a test for aRegister containing an integer value in the - SmallInteger range, and a jump if so, answering the jump. - c.f. ObjectMemory>>isIntegerValue: */ - - /* CogObjectRepresentationForSqueakV3>>#genJumpIsSmallIntegerValue:scratch: */ -static AbstractInstruction * NoDbgRegParms -genJumpIsSmallIntegerValuescratch(sqInt aRegister, sqInt scratchReg) -{ - return (gLogicalShiftLeftCqRR(1, aRegister, scratchReg), - /* begin XorR:R: */ - genoperandoperand(XorRR, aRegister, scratchReg), - /* begin JumpGreaterOrEqual: */ - genConditionalBranchoperand(JumpGreaterOrEqual, ((sqInt)0))); -} - - /* CogObjectRepresentationForSqueakV3>>#genJumpNotSmallIntegerInScratchReg: */ -static AbstractInstruction * NoDbgRegParms -genJumpNotSmallIntegerInScratchReg(sqInt aRegister) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AndCqR, 1, aRegister); - /* begin JumpZero: */ - return genConditionalBranchoperand(JumpZero, ((sqInt)0)); -} - - -/* Generate a test for aRegister containing an integer value outside the - SmallInteger range, and a jump if so, answering the jump. - c.f. ObjectMemory>>isIntegerValue: */ - - /* CogObjectRepresentationForSqueakV3>>#genJumpNotSmallIntegerValue:scratch: */ -static AbstractInstruction * NoDbgRegParms -genJumpNotSmallIntegerValuescratch(sqInt aRegister, sqInt scratchReg) -{ - return (gArithmeticShiftRightCqRR(1, aRegister, scratchReg), - /* begin XorR:R: */ - genoperandoperand(XorRR, aRegister, scratchReg), - /* begin JumpLess: */ - genConditionalBranchoperand(JumpLess, ((sqInt)0))); -} - - /* CogObjectRepresentationForSqueakV3>>#genJumpNotSmallInteger: */ -static AbstractInstruction * NoDbgRegParms -genJumpNotSmallInteger(sqInt aRegister) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(TstCqR, 1, aRegister); - /* begin JumpZero: */ - return genConditionalBranchoperand(JumpZero, ((sqInt)0)); -} - - /* CogObjectRepresentationForSqueakV3>>#genJumpSmallInteger: */ -static AbstractInstruction * NoDbgRegParms -genJumpSmallInteger(sqInt aRegister) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(TstCqR, 1, aRegister); - /* begin JumpNonZero: */ - return genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); -} - - -/* Generate a call to code that allocates a new Array of size. - The Array should be initialized with nils iff initialized is true. - The size arg is passed in SendNumArgsReg, the result - must come back in ReceiverResultReg. */ - - /* CogObjectRepresentationForSqueakV3>>#genNewArrayOfSize:initialized: */ -static void NoDbgRegParms -genNewArrayOfSizeinitialized(sqInt size, sqInt initialize) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, size, SendNumArgsReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceCreateNewArrayTrampoline); - (abstractInstruction->annotation = IsRelativeCall); -} - - -/* c.f. StackInterpreter>>stSizeOf: lengthOf:baseHeader:format: - fixedFieldsOf:format:length: - */ - - /* CogObjectRepresentationForSqueakV3>>#genPrimitiveAt */ -static sqInt -genPrimitiveAt(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction19; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction20; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction22; - AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - AbstractInstruction *jmpFmtGeFirstByte; - AbstractInstruction *jumpBounds; - AbstractInstruction *jumpFmtEq2; - AbstractInstruction *jumpFmtGt11; - AbstractInstruction *jumpFmtGt4; - AbstractInstruction *jumpFmtIsArray; - AbstractInstruction *jumpFmtLeWeakArray; - AbstractInstruction *jumpFmtLt8; - AbstractInstruction *jumpGotByteSize; - AbstractInstruction *jumpGotWordSize; - AbstractInstruction *jumpIsContext; - AbstractInstruction *jumpIsContext1; - AbstractInstruction *jumpLarge; - AbstractInstruction *jumpNotIndexable; - AbstractInstruction *jumpNotIndexable1; - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpShortHeader; - AbstractInstruction *jumpSI; - AbstractInstruction *jumpSkip; - sqInt quickConstant; - sqInt quickConstant1; - sqInt quickConstant2; - sqInt quickConstant3; - sqInt quickConstant4; - sqInt quickConstant5; - - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - jumpSI = genJumpSmallInteger(ReceiverResultReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, Arg1Reg); - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - /* begin genGetSizeOf:into:formatReg:scratchReg:abortJumpsInto: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, ReceiverResultReg, SendNumArgsReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SendNumArgsReg, ClassReg); - /* begin LogicalShiftRightCq:R: */ - quickConstant4 = instFormatFieldLSB(); - genoperandoperand(LogicalShiftRightCqR, quickConstant4, SendNumArgsReg); - /* begin AndCq:R: */ - quickConstant2 = (1U << (instFormatFieldWidth())) - 1; - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, quickConstant2, SendNumArgsReg); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction2 = genoperandoperand(CmpCqR, arrayFormat(), SendNumArgsReg); - /* begin JumpLess: */ - jumpNotIndexable1 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, TempReg); - /* begin LogicalShiftRightCq:R: */ - quickConstant1 = compactClassFieldLSB(); - genoperandoperand(LogicalShiftRightCqR, quickConstant1, TempReg); - /* begin AndCq:R: */ - quickConstant3 = (1U << (compactClassFieldWidth())) - 1; - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(AndCqR, quickConstant3, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, TempReg); - /* begin JumpZero: */ - jumpIsContext1 = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(AndCqR, TypeMask, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(CmpCqR, HeaderTypeSizeAndClass, TempReg); - /* begin JumpNonZero: */ - jumpShortHeader = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - assert(Size4Bit == 0); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, 0 - (2 * BytesPerWord), ReceiverResultReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - ((int) LongSizeMask); - anInstruction8 = genoperandoperand(AndCqR, ((int) LongSizeMask), ClassReg); - /* begin Jump: */ - jumpSkip = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpShortHeader, checkQuickConstantforInstruction(SizeMask, genoperandoperand(AndCqR, SizeMask, ClassReg))); - jmpTarget(jumpSkip, checkQuickConstantforInstruction(BaseHeaderSize, genoperandoperand(SubCqR, BaseHeaderSize, ClassReg))); - /* begin checkQuickConstant:forInstruction: */ - weakArrayFormat(); - anInstruction9 = genoperandoperand(CmpCqR, weakArrayFormat(), SendNumArgsReg); - /* begin JumpLessOrEqual: */ - jumpFmtLeWeakArray = genConditionalBranchoperand(JumpLessOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction10 = genoperandoperand(CmpCqR, firstByteFormat(), SendNumArgsReg); - /* begin JumpLess: */ - jmpFmtGeFirstByte = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperand(AndCqR, 3, SendNumArgsReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, SendNumArgsReg, ClassReg); - /* begin Jump: */ - jumpGotByteSize = genoperand(Jump, ((sqInt)0)); - jmpTarget(jmpFmtGeFirstByte, genoperandoperand(LogicalShiftRightCqR, 2, ClassReg)); - /* begin Jump: */ - jumpGotWordSize = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpFmtLeWeakArray, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin LogicalShiftRightCq:R: */ - genoperandoperand(LogicalShiftRightCqR, shiftForWord(), ClassReg); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction12 = genoperandoperand(CmpCqR, arrayFormat(), SendNumArgsReg); - /* begin JumpZero: */ - jumpFmtIsArray = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - genGetFixedFieldsOfPointerNonIntintoscratchReg(ReceiverResultReg, SendNumArgsReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, SendNumArgsReg, ClassReg); - jmpTarget(jumpFmtIsArray, jmpTarget(jumpGotWordSize, jmpTarget(jumpGotByteSize, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))); - jumpNotIndexable = jumpNotIndexable1; - jumpIsContext = jumpIsContext1; - genConvertSmallIntegerToIntegerInReg(Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperand(SubCqR, 1, Arg1Reg); - /* begin CmpR:R: */ - assert(!((ClassReg == SPReg))); - genoperandoperand(CmpRR, ClassReg, Arg1Reg); - /* begin JumpAboveOrEqual: */ - jumpBounds = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperandoperand(MoveMwrR, 0, ReceiverResultReg, ClassReg); - /* begin LogicalShiftRightCq:R: */ - quickConstant = instFormatFieldLSB(); - genoperandoperand(LogicalShiftRightCqR, quickConstant, ClassReg); - /* begin AndCq:R: */ - quickConstant5 = (1U << (instFormatFieldWidth())) - 1; - /* begin checkQuickConstant:forInstruction: */ - anInstruction15 = genoperandoperand(AndCqR, quickConstant5, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction16 = genoperandoperand(CmpCqR, 4, ClassReg); - /* begin JumpGreater: */ - jumpFmtGt4 = genConditionalBranchoperand(JumpGreater, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction17 = genoperandoperand(CmpCqR, 2, ClassReg); - /* begin JumpZero: */ - jumpFmtEq2 = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin AddR:R: */ - genoperandoperand(AddRR, SendNumArgsReg, Arg1Reg); - jmpTarget(jumpFmtEq2, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction18 = genoperandoperand(AddCqR, BaseHeaderSize / BytesPerWord, Arg1Reg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, Arg1Reg, ReceiverResultReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 1 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpFmtGt4, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperand(CmpCqR, 8, ClassReg); - /* begin JumpLess: */ - jumpFmtLt8 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperand(CmpCqR, 11, ClassReg); - /* begin JumpGreater: */ - jumpFmtGt11 = genConditionalBranchoperand(JumpGreater, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction21 = genoperandoperand(AddCqR, BaseHeaderSize, Arg1Reg); - /* begin MoveXbr:R:R: */ - genoperandoperandoperand(MoveXbrRR, Arg1Reg, ReceiverResultReg, ReceiverResultReg); - genConvertIntegerToSmallIntegerInReg(ReceiverResultReg); - if (methodOrBlockNumArgs <= 1 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpFmtLt8, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(BytesPerWord == 4); - /* begin checkQuickConstant:forInstruction: */ - anInstruction22 = genoperandoperand(AddCqR, BaseHeaderSize / BytesPerWord, Arg1Reg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, Arg1Reg, ReceiverResultReg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction23 = genoperandoperand(CmpCqR, 0x3FFFFFFF, ReceiverResultReg); - /* begin JumpAbove: */ - jumpLarge = genConditionalBranchoperand(JumpAbove, ((sqInt)0)); - genConvertIntegerToSmallIntegerInReg(ReceiverResultReg); - if (methodOrBlockNumArgs <= 1 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpLarge, CallRT(cePositive32BitIntegerTrampoline)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 1 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpSI, jmpTarget(jumpNotSI, jmpTarget(jumpNotIndexable, jmpTarget(jumpIsContext, jmpTarget(jumpBounds, jmpTarget(jumpFmtGt11, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))))); - return 0; -} - - /* CogObjectRepresentationForSqueakV3>>#genPrimitiveIdenticalOrNotIf: */ -static sqInt NoDbgRegParms -genPrimitiveIdenticalOrNotIf(sqInt orNot) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt constant; - AbstractInstruction *jumpCmp; - - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, ReceiverResultReg); - if (orNot) { - /* begin JumpZero: */ - jumpCmp = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - } - else { - /* begin JumpNonZero: */ - jumpCmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - } - /* begin genMoveConstant:R: */ - constant = trueObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - if (methodOrBlockNumArgs <= 1 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpCmp, (shouldAnnotateObjectReference(falseObject()) - ? annotateobjRef(checkLiteralforInstruction(falseObject(), genoperandoperand(MoveCwR, falseObject(), ReceiverResultReg)), falseObject()) - : (/* begin checkQuickConstant:forInstruction: */ - falseObject(), - (anInstruction1 = genoperandoperand(MoveCqR, falseObject(), ReceiverResultReg)), - anInstruction1))); - if (methodOrBlockNumArgs <= 1 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - return UnfailingPrimitive; -} - - /* CogObjectRepresentationForSqueakV3>>#genPrimitiveIdentityHash */ -static sqInt -genPrimitiveIdentityHash(void) -{ - AbstractInstruction *jumpSI; - - jumpSI = genJumpSmallInteger(ReceiverResultReg); - genGetHashFieldNonImmOfasSmallIntegerInto(ReceiverResultReg, TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 1 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpSI, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - -/* c.f. StackInterpreter>>stSizeOf: lengthOf:baseHeader:format: - fixedFieldsOf:format:length: - */ - - /* CogObjectRepresentationForSqueakV3>>#genPrimitiveSize */ -static sqInt -genPrimitiveSize(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - AbstractInstruction *jmpFmtGeFirstByte; - AbstractInstruction *jumpFmtIsArray; - AbstractInstruction *jumpFmtLeWeakArray; - AbstractInstruction *jumpGotByteSize; - AbstractInstruction *jumpGotWordSize; - AbstractInstruction *jumpIsContext; - AbstractInstruction *jumpIsContext1; - AbstractInstruction *jumpNotIndexable; - AbstractInstruction *jumpNotIndexable1; - AbstractInstruction *jumpShortHeader; - AbstractInstruction *jumpSI; - AbstractInstruction *jumpSkip; - sqInt quickConstant; - sqInt quickConstant1; - sqInt quickConstant2; - sqInt quickConstant3; - - jumpSI = genJumpSmallInteger(ReceiverResultReg); - /* begin genGetSizeOf:into:formatReg:scratchReg:abortJumpsInto: */ - anInstruction = genoperandoperandoperand(MoveMwrR, 0, ReceiverResultReg, SendNumArgsReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SendNumArgsReg, ClassReg); - /* begin LogicalShiftRightCq:R: */ - quickConstant = instFormatFieldLSB(); - genoperandoperand(LogicalShiftRightCqR, quickConstant, SendNumArgsReg); - /* begin AndCq:R: */ - quickConstant2 = (1U << (instFormatFieldWidth())) - 1; - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, quickConstant2, SendNumArgsReg); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction2 = genoperandoperand(CmpCqR, arrayFormat(), SendNumArgsReg); - /* begin JumpLess: */ - jumpNotIndexable1 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, TempReg); - /* begin LogicalShiftRightCq:R: */ - quickConstant1 = compactClassFieldLSB(); - genoperandoperand(LogicalShiftRightCqR, quickConstant1, TempReg); - /* begin AndCq:R: */ - quickConstant3 = (1U << (compactClassFieldWidth())) - 1; - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(AndCqR, quickConstant3, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, TempReg); - /* begin JumpZero: */ - jumpIsContext1 = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(AndCqR, TypeMask, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(CmpCqR, HeaderTypeSizeAndClass, TempReg); - /* begin JumpNonZero: */ - jumpShortHeader = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - assert(Size4Bit == 0); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, 0 - (2 * BytesPerWord), ReceiverResultReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - ((int) LongSizeMask); - anInstruction8 = genoperandoperand(AndCqR, ((int) LongSizeMask), ClassReg); - /* begin Jump: */ - jumpSkip = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpShortHeader, checkQuickConstantforInstruction(SizeMask, genoperandoperand(AndCqR, SizeMask, ClassReg))); - jmpTarget(jumpSkip, checkQuickConstantforInstruction(BaseHeaderSize, genoperandoperand(SubCqR, BaseHeaderSize, ClassReg))); - /* begin checkQuickConstant:forInstruction: */ - weakArrayFormat(); - anInstruction9 = genoperandoperand(CmpCqR, weakArrayFormat(), SendNumArgsReg); - /* begin JumpLessOrEqual: */ - jumpFmtLeWeakArray = genConditionalBranchoperand(JumpLessOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - firstByteFormat(); - anInstruction10 = genoperandoperand(CmpCqR, firstByteFormat(), SendNumArgsReg); - /* begin JumpLess: */ - jmpFmtGeFirstByte = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperand(AndCqR, 3, SendNumArgsReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, SendNumArgsReg, ClassReg); - /* begin Jump: */ - jumpGotByteSize = genoperand(Jump, ((sqInt)0)); - jmpTarget(jmpFmtGeFirstByte, genoperandoperand(LogicalShiftRightCqR, 2, ClassReg)); - /* begin Jump: */ - jumpGotWordSize = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpFmtLeWeakArray, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin LogicalShiftRightCq:R: */ - genoperandoperand(LogicalShiftRightCqR, shiftForWord(), ClassReg); - /* begin checkQuickConstant:forInstruction: */ - arrayFormat(); - anInstruction12 = genoperandoperand(CmpCqR, arrayFormat(), SendNumArgsReg); - /* begin JumpZero: */ - jumpFmtIsArray = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - genGetFixedFieldsOfPointerNonIntintoscratchReg(ReceiverResultReg, SendNumArgsReg, TempReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, SendNumArgsReg, ClassReg); - jmpTarget(jumpFmtIsArray, jmpTarget(jumpGotWordSize, jmpTarget(jumpGotByteSize, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))); - jumpNotIndexable = jumpNotIndexable1; - jumpIsContext = jumpIsContext1; - genConvertIntegerInRegtoSmallIntegerInReg(ClassReg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 1 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpSI, jmpTarget(jumpNotIndexable, jmpTarget(jumpIsContext, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))); - return 0; -} - - -/* c.f. StackInterpreter>>stSizeOf: lengthOf:baseHeader:format: - fixedFieldsOf:format:length: - */ - - /* CogObjectRepresentationForSqueakV3>>#genPrimitiveStringAt */ -static sqInt -genPrimitiveStringAt(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - AbstractInstruction *jumpBounds; - AbstractInstruction *jumpNotByteIndexable; - AbstractInstruction *jumpNotSI; - AbstractInstruction *jumpShortHeader; - AbstractInstruction *jumpSkip; - sqInt quickConstant; - sqInt quickConstant1; - sqInt quickConstant2; - - /* begin genLoadArgAtDepth:into: */ - assert(0 < (numRegArgs())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, Arg1Reg); - jumpNotSI = genJumpNotSmallInteger(Arg0Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, 0, ReceiverResultReg, TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, ClassReg); - /* begin LogicalShiftRightCq:R: */ - quickConstant = instFormatFieldLSB(); - genoperandoperand(LogicalShiftRightCqR, quickConstant, TempReg); - /* begin AndCq:R: */ - quickConstant2 = (1U << (instFormatFieldWidth())) - 1; - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AndCqR, quickConstant2, TempReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, TempReg, SendNumArgsReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(AndCqR, 3, SendNumArgsReg); - /* begin SubR:R: */ - genoperandoperand(SubRR, SendNumArgsReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, 8, TempReg); - /* begin JumpNonZero: */ - jumpNotByteIndexable = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(AndCqR, TypeMask, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(CmpCqR, HeaderTypeSizeAndClass, TempReg); - /* begin JumpNonZero: */ - jumpShortHeader = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - assert(Size4Bit == 0); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, 0 - (2 * BytesPerWord), ReceiverResultReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - ((int) LongSizeMask); - anInstruction8 = genoperandoperand(AndCqR, ((int) LongSizeMask), ClassReg); - /* begin Jump: */ - jumpSkip = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpShortHeader, checkQuickConstantforInstruction(SizeMask, genoperandoperand(AndCqR, SizeMask, ClassReg))); - jmpTarget(jumpSkip, checkQuickConstantforInstruction(BaseHeaderSize, genoperandoperand(SubCqR, BaseHeaderSize, ClassReg))); - /* begin SubR:R: */ - genoperandoperand(SubRR, SendNumArgsReg, ClassReg); - genConvertSmallIntegerToIntegerInReg(Arg1Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(SubCqR, 1, Arg1Reg); - /* begin CmpR:R: */ - assert(!((ClassReg == SPReg))); - genoperandoperand(CmpRR, ClassReg, Arg1Reg); - /* begin JumpAboveOrEqual: */ - jumpBounds = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperand(AddCqR, BaseHeaderSize, Arg1Reg); - if (shouldAnnotateObjectReference(characterTable())) { - annotateobjRef(gMoveCwR(characterTable(), Arg0Reg), characterTable()); - } - else { - /* begin MoveCq:R: */ - quickConstant1 = characterTable(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant1, Arg0Reg); - } - /* begin MoveXbr:R:R: */ - genoperandoperandoperand(MoveXbrRR, Arg1Reg, ReceiverResultReg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperand(AddCqR, BaseHeaderSize / BytesPerWord, ReceiverResultReg); - /* begin MoveXwr:R:R: */ - genoperandoperandoperand(MoveXwrRR, ReceiverResultReg, Arg0Reg, ReceiverResultReg); - if (methodOrBlockNumArgs <= 1 /* numRegArgs */) { - /* begin RetN: */ - genoperand(RetN, 0); - } - else { - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - jmpTarget(jumpNotSI, jmpTarget(jumpNotByteIndexable, jmpTarget(jumpBounds, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))); - return 0; -} - - /* CogObjectRepresentationForSqueakV3>>#genRemoveSmallIntegerTagsInScratchReg: */ -static sqInt NoDbgRegParms -genRemoveSmallIntegerTagsInScratchReg(sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, 1, scratchReg); - return 0; -} - - /* CogObjectRepresentationForSqueakV3>>#genSetSmallIntegerTagsIn: */ -static sqInt NoDbgRegParms -genSetSmallIntegerTagsIn(sqInt scratchReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(OrCqR, 1, scratchReg); - return 0; -} - - /* CogObjectRepresentationForSqueakV3>>#genShiftAwaySmallIntegerTagsInScratchReg: */ -static sqInt NoDbgRegParms -genShiftAwaySmallIntegerTagsInScratchReg(sqInt scratchReg) -{ - /* begin ArithmeticShiftRightCq:R: */ - genoperandoperand(ArithmeticShiftRightCqR, 1, scratchReg); - return 0; -} - - /* CogObjectRepresentationForSqueakV3>>#genStoreSourceReg:slotIndex:destReg:scratchReg:inFrame:needsStoreCheck: */ -static sqInt NoDbgRegParms -genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt inFrame, sqInt needsStoreCheck) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction * inst; - AbstractInstruction *jmpAlreadyRoot; - AbstractInstruction *jmpDestYoung; - AbstractInstruction *jmpImmediate; - AbstractInstruction *jmpSourceOld; - sqInt mask; - sqInt rootBitByteOffset; - - /* begin genTraceStores */ - if (traceStores > 0) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, TempReg); - /* begin CallRT: */ - abstractInstruction1 = genoperand(Call, ceTraceStoreTrampoline); - (abstractInstruction1->annotation = IsRelativeCall); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveRMwr, sourceReg, (index * BytesPerWord) + BaseHeaderSize, destReg); - if (!needsStoreCheck) { - return 0; - } - - /* Get the old/new boundary in scratchReg */ - jmpImmediate = genJumpImmediate(sourceReg); - /* begin checkLiteral:forInstruction: */ - youngStartAddress(); - anInstruction1 = genoperandoperand(MoveAwR, youngStartAddress(), scratchReg); - /* begin CmpR:R: */ - assert(!((scratchReg == SPReg))); - genoperandoperand(CmpRR, scratchReg, destReg); - /* begin JumpAboveOrEqual: */ - jmpDestYoung = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); - /* begin CmpR:R: */ - assert(!((scratchReg == SPReg))); - genoperandoperand(CmpRR, scratchReg, sourceReg); - /* begin JumpBelow: */ - jmpSourceOld = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - rootBitByteOffset = RootBitDigitLength - 1; - mask = ((usqInt)(RootBit)) >> ((RootBitDigitLength - 1) * 8); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveMbrR, rootBitByteOffset, destReg, scratchReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(AndCqR, mask, scratchReg); - /* begin JumpNonZero: */ - jmpAlreadyRoot = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - assert(destReg == ReceiverResultReg); - /* begin evaluateTrampolineCallBlock:protectLinkRegIfNot: */ - if (inFrame) { - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceStoreCheckTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - } - else { - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceStoreCheckTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin PopR: */ - genoperand(PopR, LinkReg); - } - jmpTarget(jmpImmediate, jmpTarget(jmpDestYoung, jmpTarget(jmpSourceOld, jmpTarget(jmpAlreadyRoot, genoperandoperand(Label, (labelCounter += 1), bytecodePC))))); - return 0; -} - - /* CogObjectRepresentationForSqueakV3>>#genStoreSourceReg:slotIndex:intoNewObjectInDestReg: */ -static sqInt NoDbgRegParms -genStoreSourceRegslotIndexintoNewObjectInDestReg(sqInt sourceReg, sqInt index, sqInt destReg) -{ - AbstractInstruction *anInstruction; - - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveRMwr, sourceReg, (index * BytesPerWord) + BaseHeaderSize, destReg); - return 0; -} - - -/* Answer the relevant inline cache tag for an instance. - c.f. getInlineCacheClassTagFrom:into: & inlineCacheTagForClass: */ - - /* CogObjectRepresentationForSqueakV3>>#inlineCacheTagForInstance: */ -static sqInt NoDbgRegParms -inlineCacheTagForInstance(sqInt oop) -{ - sqInt cci; - - if ((oop & 1)) { - return (((usqInt)0 << 1) | 1); - } - if (((cci = noShiftCompactClassIndexOf(oop))) > 0) { - return cci; - } - return (classHeader(oop)) & AllButTypeMask; -} - - /* CogObjectRepresentationForSqueakV3>>#inlineCacheTagIsYoung: */ -static sqInt NoDbgRegParms -inlineCacheTagIsYoung(sqInt cacheTag) -{ - return isYoung(cacheTag); -} - - /* CogObjectRepresentationForSqueakV3>>#markAndTraceLiteralIfYoung: */ -static void NoDbgRegParms -markAndTraceLiteralIfYoung(sqInt literal) -{ - if ((couldBeObject(literal)) - && (isYoungObject(literal))) { - assert(addressCouldBeObj(literal)); - markAndTrace(literal); - } -} - - /* CogObjectRepresentationForSqueakV3>>#markAndTraceLiteral: */ -static void NoDbgRegParms -markAndTraceLiteral(sqInt literal) -{ - if (couldBeObject(literal)) { - assert(addressCouldBeObj(literal)); - markAndTrace(literal); - } -} - - -/* Define how many register arguments a StackToRegisterMappingCogit can - and should use with the receiver. The value must be 0, 1 or 2. Note that a - SimpleStackBasedCogit always has 0 register args (although the receiver is - passed in a register). CogObjectRepresentationForSqueakV3 only implements - at most 1-arg primitives, because the complexity of the object - representation makes it difficult to implement at:put:, the most - performance-critical 2-argument - primitive.. The method must be inlined in CoInterpreter, and dead code - eliminated so that the register-popping enilopmarts such as - enterRegisterArgCogMethod:- at:receiver: do not have to be implemented in - SimpleStackBasedCogit. */ - - /* CogObjectRepresentationForSqueakV3>>#numRegArgs */ -sqInt -numRegArgs(void) -{ - return 1; -} - - /* CogObjectRepresentationForSqueakV3>>#remapObject: */ -static sqInt NoDbgRegParms -remapObject(sqInt objOop) -{ - assert(addressCouldBeObj(objOop)); - return remap(objOop); -} - - /* CogObjectRepresentationForSqueakV3>>#remapOop: */ -static sqInt NoDbgRegParms -remapOop(sqInt oop) -{ - return ((oop & 1) - ? oop - : remap(oop)); -} - - -/* self assert: ((objectMemory isIntegerObject: anOop) - or: [objectMemory addressCouldBeObj: anOop]). */ - - /* CogObjectRepresentationForSqueakV3>>#shouldAnnotateObjectReference: */ -static sqInt NoDbgRegParms -shouldAnnotateObjectReference(sqInt anOop) -{ - return (isNonIntegerObject(anOop)) - && (oopisGreaterThan(anOop, trueObject())); -} - - /* CogObjectRepresentationForSqueakV3>>#slotOffsetOfInstVarIndex: */ -static sqInt NoDbgRegParms -slotOffsetOfInstVarIndex(sqInt index) -{ - return (index * BytesPerWord) + BaseHeaderSize; -} - - /* CogObjectRepresentationForSqueakV3>>#validInlineCacheTag: */ -static sqInt NoDbgRegParms -validInlineCacheTag(sqInt cacheTag) -{ - return (cacheTag == ConstZero) - || ((((cacheTag & ((1U << (shiftForWord())) - 1)) == 0) - && (((cacheTag >= (1U << (compactClassFieldLSB()))) && (cacheTag <= (((sqInt)((usqInt)((compactClassIndexOfHeader(-1))) << (compactClassFieldLSB())))))))) - || (checkValidObjectReference(cacheTag))); -} - - /* CogSimStackEntry>>#ensureSpilledAt:from: */ -static SimStackEntry * NoDbgRegParms -ensureSpilledAtfrom(SimStackEntry * self_in_ensureSpilledAtfrom, sqInt baseOffset, sqInt baseRegister) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *inst; - sqInt reg; - sqInt wordConstant; - - if ((self_in_ensureSpilledAtfrom->spilled)) { - if (((self_in_ensureSpilledAtfrom->type)) == SSSpill) { - assert(((((self_in_ensureSpilledAtfrom->offset)) == baseOffset) - && (((self_in_ensureSpilledAtfrom->registerr)) == baseRegister)) - || (violatesEnsureSpilledSpillAssert())); - return self_in_ensureSpilledAtfrom; - } - } - assert(((self_in_ensureSpilledAtfrom->type)) != SSSpill); - traceSpill(self_in_ensureSpilledAtfrom); - if (((self_in_ensureSpilledAtfrom->type)) == SSConstant) { - if (shouldAnnotateObjectReference((self_in_ensureSpilledAtfrom->constant))) { - inst = annotateobjRef(gPushCw((self_in_ensureSpilledAtfrom->constant)), (self_in_ensureSpilledAtfrom->constant)); - } - else { - /* begin PushCq: */ - wordConstant = (self_in_ensureSpilledAtfrom->constant); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperand(PushCq, wordConstant); - inst = anInstruction; - } - } - else { - if (((self_in_ensureSpilledAtfrom->type)) == SSBaseOffset) { - /* begin checkQuickConstant:forInstruction: */ - (self_in_ensureSpilledAtfrom->offset); - anInstruction1 = genoperandoperandoperand(MoveMwrR, (self_in_ensureSpilledAtfrom->offset), (self_in_ensureSpilledAtfrom->registerr), TempReg); - /* begin PushR: */ - inst = genoperand(PushR, TempReg); - } - else { - assert(((self_in_ensureSpilledAtfrom->type)) == SSRegister); - /* begin PushR: */ - reg = (self_in_ensureSpilledAtfrom->registerr); - inst = genoperand(PushR, reg); - } - (self_in_ensureSpilledAtfrom->type) = SSSpill; - (self_in_ensureSpilledAtfrom->offset) = baseOffset; - (self_in_ensureSpilledAtfrom->registerr) = baseRegister; - } - (self_in_ensureSpilledAtfrom->spilled) = 1; - return 0; -} - - /* CogSimStackEntry>>#isSameEntryAs: */ -static sqInt NoDbgRegParms -isSameEntryAs(SimStackEntry * self_in_isSameEntryAs, CogSimStackEntry *ssEntry) -{ - return (((self_in_isSameEntryAs->type)) == ((ssEntry->type))) - && ((((((self_in_isSameEntryAs->type)) == SSBaseOffset) - || (((self_in_isSameEntryAs->type)) == SSSpill)) - && ((((self_in_isSameEntryAs->offset)) == ((ssEntry->offset))) - && (((self_in_isSameEntryAs->registerr)) == ((ssEntry->registerr))))) - || (((((self_in_isSameEntryAs->type)) == SSRegister) - && (((self_in_isSameEntryAs->registerr)) == ((ssEntry->registerr)))) - || ((((self_in_isSameEntryAs->type)) == SSConstant) - && (((self_in_isSameEntryAs->constant)) == ((ssEntry->constant)))))); -} - - -/* Receiver is not a forwarder, except in blocks with no inst var access. - For now we optimize only the case where receiver is accessed in a method. */ - - /* CogSimStackEntry>>#mayBeAForwarder */ -static sqInt NoDbgRegParms -mayBeAForwarder(SimStackEntry * self_in_mayBeAForwarder) -{ - if ((((self_in_mayBeAForwarder->type)) == SSRegister) - && (isNonForwarderReceiver((self_in_mayBeAForwarder->registerr)))) { - return 0; - } - return ((self_in_mayBeAForwarder->type)) != SSConstant; -} - - /* CogSimStackEntry>>#popToReg: */ -static void NoDbgRegParms -popToReg(SimStackEntry * self_in_popToReg, sqInt reg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt quickConstant; - sqInt reg1; - - if ((self_in_popToReg->spilled)) { - /* begin PopR: */ - genoperand(PopR, reg); - } - else { - switch ((self_in_popToReg->type)) { - case SSBaseOffset: - /* begin checkQuickConstant:forInstruction: */ - (self_in_popToReg->offset); - anInstruction = genoperandoperandoperand(MoveMwrR, (self_in_popToReg->offset), (self_in_popToReg->registerr), reg); - break; - case SSConstant: - if (shouldAnnotateObjectReference((self_in_popToReg->constant))) { - annotateobjRef(gMoveCwR((self_in_popToReg->constant), reg), (self_in_popToReg->constant)); - } - else { - /* begin MoveCq:R: */ - quickConstant = (self_in_popToReg->constant); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, quickConstant, reg); - } - break; - case SSRegister: - if (reg != ((self_in_popToReg->registerr))) { - /* begin MoveR:R: */ - reg1 = (self_in_popToReg->registerr); - genoperandoperand(MoveRR, reg1, reg); - } - else { - /* begin Label */ - genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - break; - default: - error("Case not found and no otherwise clause"); - } - } -} - - -/* Answer a bit mask for the receiver's register, if any. */ - - /* CogSimStackEntry>>#registerMask */ -static sqInt NoDbgRegParms -registerMask(SimStackEntry * self_in_registerMask) -{ - sqInt reg; - - return ((((self_in_registerMask->type)) == SSBaseOffset) - || (((self_in_registerMask->type)) == SSRegister) - ? (/* begin registerMaskFor: */ - (reg = (self_in_registerMask->registerr)), - 1U << reg) - : 0); -} - - /* CogSimStackEntry>>#registerMaskOrNone */ -static sqInt NoDbgRegParms -registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone) -{ - sqInt reg; - - return (((self_in_registerMaskOrNone->type)) == SSRegister - ? (/* begin registerMaskFor: */ - (reg = (self_in_registerMaskOrNone->registerr)), - 1U << reg) - : 0); -} - - /* CogSimStackEntry>>#registerOrNone */ -static sqInt NoDbgRegParms -registerOrNone(SimStackEntry * self_in_registerOrNone) -{ - return (((self_in_registerOrNone->type)) == SSRegister - ? (self_in_registerOrNone->registerr) - : NoReg); -} - - /* CogSimStackEntry>>#storeToReg: */ -static void NoDbgRegParms -storeToReg(SimStackEntry * self_in_storeToReg, sqInt reg) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt quickConstant; - sqInt reg1; - - switch ((self_in_storeToReg->type)) { - case SSBaseOffset: - case SSSpill: - /* begin checkQuickConstant:forInstruction: */ - (self_in_storeToReg->offset); - anInstruction = genoperandoperandoperand(MoveMwrR, (self_in_storeToReg->offset), (self_in_storeToReg->registerr), reg); - break; - case SSConstant: - if (shouldAnnotateObjectReference((self_in_storeToReg->constant))) { - annotateobjRef(gMoveCwR((self_in_storeToReg->constant), reg), (self_in_storeToReg->constant)); - } - else { - /* begin MoveCq:R: */ - quickConstant = (self_in_storeToReg->constant); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, quickConstant, reg); - } - break; - case SSRegister: - if (reg != ((self_in_storeToReg->registerr))) { - /* begin MoveR:R: */ - reg1 = (self_in_storeToReg->registerr); - genoperandoperand(MoveRR, reg1, reg); - } - else { - /* begin Label */ - genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - break; - default: - error("Case not found and no otherwise clause"); - } -} - - /* CogSSBytecodeFixup>>#isMergeFixup */ -static sqInt NoDbgRegParms -isMergeFixup(BytecodeFixup * self_in_isMergeFixup) -{ - return (((usqInt)((self_in_isMergeFixup->targetInstruction)))) == NeedsMergeFixupFlag; -} - - /* InLineLiteralsManager>>#checkLiteral:forInstruction: */ -static AbstractInstruction * NoDbgRegParms -checkLiteralforInstruction(sqInt literal, AbstractInstruction *anInstruction) -{ - return anInstruction; -} - - /* InLineLiteralsManager>>#checkQuickConstant:forInstruction: */ -static AbstractInstruction * NoDbgRegParms -checkQuickConstantforInstruction(sqInt literal, AbstractInstruction *anInstruction) -{ - return anInstruction; -} - - -/* */ - - /* SimpleStackBasedCogit>>#ceClosureCopyDescriptor: */ -static sqInt NoDbgRegParms -ceClosureCopyDescriptor(sqInt descriptor) -{ - return createClosureNumArgsnumCopiedstartpc(descriptor & 0x3F, (((usqInt)(descriptor)) >> 6) & 0x3F, ((usqInt)(descriptor)) >> 12); -} - - /* SimpleStackBasedCogit>>#cogMethodHasExternalPrim: */ -sqInt -cogMethodHasExternalPrim(CogMethod *aCogMethod) -{ - sqInt primIndex; - - primIndex = primitiveIndexOfMethodheader((aCogMethod->methodObject), (aCogMethod->methodHeader)); - return (primIndex == PrimNumberExternalCall) - || (primIndex == PrimNumberFFICall); -} - - /* SimpleStackBasedCogit>>#cogMethodHasMachineCodePrim: */ -sqInt -cogMethodHasMachineCodePrim(CogMethod *aCogMethod) -{ - sqInt primIndex; - - primIndex = primitiveIndexOfMethodheader((aCogMethod->methodObject), (aCogMethod->objectHeader)); - return (((primIndex >= 1) && (primIndex <= MaxCompiledPrimitiveIndex))) - && ((((primitiveGeneratorTable[primIndex]).primitiveGenerator)) != null); -} - - -/* Compile the jump instruction(s) at the end of the method that dispatch to - each block body. - */ - - /* SimpleStackBasedCogit>>#compileBlockDispatch */ -static sqInt -compileBlockDispatch(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *jumpSkip; - - assert(blockCount > 0); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, 0, SendNumArgsReg); - blockEntryNoContextSwitch = anInstruction; - /* begin Jump: */ - jumpSkip = genoperand(Jump, ((sqInt)0)); - /* begin MoveR:R: */ - blockEntryLabel = genoperandoperand(MoveRR, ReceiverResultReg, SendNumArgsReg); - jmpTarget(jumpSkip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (blockCount > 1) { - genLoadSlotsourceRegdestReg(ClosureStartPCIndex, ReceiverResultReg, TempReg); - } - compileBlockDispatchFromto(0, blockCount - 1); - return 0; -} - - -/* After pushing the temporaries but before the stack limit check a primitive - method needs to fetch the error code, if any. If the primitive has failed, - call the trampoline - that will assign it to the last temp. */ - - /* SimpleStackBasedCogit>>#compileGetErrorCode */ -static void -compileGetErrorCode(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *jmpNoError; - - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpZero: */ - jmpNoError = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceReapAndResetErrorCodeTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - jmpTarget(jmpNoError, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); -} - - -/* Compile a call to an interpreter primitive. Call the C routine with the - usual stack-switching dance, test the primFailCode and then either - return on success or continue to the method body. */ - - /* SimpleStackBasedCogit>>#compileInterpreterPrimitive:flags: */ -static sqInt NoDbgRegParms -compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) -{ - sqInt address; - sqInt address1; - sqInt address2; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction17; - AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction24; - AbstractInstruction *anInstruction25; - AbstractInstruction *anInstruction26; - AbstractInstruction *anInstruction28; - AbstractInstruction *anInstruction30; - AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction33; - AbstractInstruction *anInstruction34; - AbstractInstruction *anInstruction35; - AbstractInstruction *anInstruction36; - AbstractInstruction *anInstruction37; - AbstractInstruction *anInstruction38; - AbstractInstruction *anInstruction39; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction * continuePostSampleNonPrim; - AbstractInstruction * continuePostSamplePrim; - AbstractInstruction * jmp; - AbstractInstruction * jmpSampleNonPrim; - AbstractInstruction * jmpSamplePrim; - sqInt offset; - sqInt offset1; - sqInt offset2; - sqInt operand1; - sqInt operand3; - sqInt reg; - sqInt retpc; - - continuePostSampleNonPrim = ((AbstractInstruction *) 0); - continuePostSamplePrim = ((AbstractInstruction *) 0); - jmpSampleNonPrim = ((AbstractInstruction *) 0); - jmpSamplePrim = ((AbstractInstruction *) 0); - assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); - genExternalizePointersForPrimitiveCall(); - /* begin genLoadCStackPointersForPrimCall */ - if (cFramePointerInUse) { - genLoadCStackPointers(backEnd); - } - else { - genLoadCStackPointer(backEnd); - } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick if so */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin MoveAw:R: */ - address = (nextProfileTickAddress()) + BytesPerWord; - /* begin checkLiteral:forInstruction: */ - anInstruction1 = genoperandoperand(MoveAwR, address, ClassReg); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSampleNonPrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSampleNonPrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - if (recordPrimTraceForMethod(methodObj)) { - genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction36 = genoperandoperand(MoveCqR, 0, TempReg); - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction37 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); - if (methodOrBlockNumArgs != 0) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); - } - /* begin checkLiteral:forInstruction: */ - argumentCountAddress(); - anInstruction38 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); - if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { - /* begin checkLiteral:forInstruction: */ - ((sqInt)primitiveRoutine); - anInstruction5 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); - /* begin checkLiteral:forInstruction: */ - primitiveFunctionPointerAddress(); - anInstruction6 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); - } - if (((flags & (PrimCallNeedsNewMethod + PrimCallMayEndureCodeCompaction)) != 0)) { - - /* The ceActivateFailingPrimitiveMethod: machinery can't handle framelessness. */ - if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - needsFrame = 1; - } - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); - /* begin MoveMw:r:R: */ - offset = offsetof(CogMethod, methodObject); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - /* begin checkLiteral:forInstruction: */ - newMethodAddress(); - anInstruction8 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); - } - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction39 = genoperand(PrefetchAw, primFailCodeAddress()); - if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - - /* Sideways call the C primitive routine so that we return through cePrimReturnEnterCogCode. */ - /* On Spur ceActivateFailingPrimitiveMethod: would like to retry if forwarders - are found. So insist on PrimCallNeedsPrimitiveFunction being set too. */ - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l32; - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction11 = genoperandoperand(MoveCqR, -2 - null, A0); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A0); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction12 = genoperandoperand(MoveCqR, -2 - null, A1); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A1); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction21 = genoperandoperand(MoveCqR, -2 - null, A2); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A2); - } - if (null < NoReg) { - /* begin MoveCq:R: */ - anInstruction31 = genoperandoperand(MoveCqR, -2 - null, A3); - } - else { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, null, A3); - } - l32: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin genSubstituteReturnAddress: */ - retpc = (((flags & PrimCallCollectsProfileSamples) != 0) - ? cePrimReturnEnterCogCodeProfiling - : cePrimReturnEnterCogCode); - /* begin checkLiteral:forInstruction: */ - anInstruction13 = genoperandoperand(MoveCwR, retpc, RA); - /* begin gen:literal: */ - anInstruction10 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); - jmp = (jmpSamplePrim = (continuePostSamplePrim = null)); - } - else { - - /* Call the C primitive routine. */ - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l48; - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, A0); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, A1); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, A2); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, A3); - l48: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin gen:literal: */ - anInstruction15 = genoperand(CallFull, ((sqInt)primitiveRoutine)); - /* begin genRemoveNArgsFromStack: */ - assert(0 <= 4); - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction16 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin MoveAw:R: */ - address1 = (nextProfileTickAddress()) + BytesPerWord; - /* begin checkLiteral:forInstruction: */ - anInstruction17 = genoperandoperand(MoveAwR, address1, ClassReg); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSamplePrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSamplePrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - /* begin MoveAw:R: */ - address2 = instructionPointerAddress(); - reg = LinkReg; - /* begin checkLiteral:forInstruction: */ - anInstruction23 = genoperandoperand(MoveAwR, address2, reg); - genLoadStackPointers(backEnd); - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction24 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction25 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset1 = 0; - /* begin checkQuickConstant:forInstruction: */ - anInstruction26 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, BytesPerWord); - } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* The sample is collected by cePrimReturnEnterCogCode for external calls */ - if (!(jmpSamplePrim == null)) { - - /* Call ceCheckProfileTick: to record sample and then continue. */ - jmpTarget(jmpSamplePrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin gen:literal: */ - operand1 = ((usqIntptr_t)ceCheckProfileTick); - /* begin checkLiteral:forInstruction: */ - anInstruction28 = genoperand(CallFull, operand1); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSamplePrim)); - } - jmpTarget(jmpSampleNonPrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction33 = genoperandoperand(MoveCqR, 0, TempReg); - /* begin checkLiteral:forInstruction: */ - newMethodAddress(); - anInstruction34 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); - /* begin gen:literal: */ - operand3 = ((usqIntptr_t)ceCheckProfileTick); - /* begin checkLiteral:forInstruction: */ - anInstruction30 = genoperand(CallFull, operand3); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSampleNonPrim)); - } - if (!(jmp == null)) { - - /* Jump to restore of receiver reg and proceed to frame build for failure. */ - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin MoveMw:r:R: */ - offset2 = BytesPerWord * (methodOrBlockNumArgs + (0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction35 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); - } - return 0; -} - - -/* Compile a call to a machine-code convention interpreter primitive. Call - the C routine - on the Smalltalk stack, assuming it consumes little or no stack space. */ -/* for now handle functions with less than 4 arguments; our C call - marshalling machinery - extends up to 4 arguments only, and the first argument of an mcprim is the - receiver. - */ - - /* SimpleStackBasedCogit>>#compileMachineCodeInterpreterPrimitive: */ -static sqInt NoDbgRegParms -compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)) -{ - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction5; - AbstractInstruction * jmpFail; - sqInt liveRegsMask; - sqInt n; - sqInt offset; - - assert(methodOrBlockNumArgs <= 3); - if ((methodOrBlockNumArgs > 1 /* numRegArgs */) - || (methodOrBlockNumArgs == 0)) { - /* begin registerMaskFor: */ - liveRegsMask = 1U << ReceiverResultReg; - } - else { - /* begin registerMaskFor:and: */ - liveRegsMask = (1U << ReceiverResultReg) | (1U << Arg0Reg); - } - genSaveRegs(backEnd, liveRegsMask & CallerSavedRegisterMask); - if (methodOrBlockNumArgs > 1 /* numRegArgs */) { - - /* Wrangle args into Arg0Reg, Arg1Reg, SendNumArgsReg & ClassReg */ - /* offset := self bitCountOf: (liveRegsMask bitAnd: CallerSavedRegisterMask). */ - error("shouldBeImplemented"); - } - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - if ((methodOrBlockNumArgs + 1) == 0) { - goto l18; - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, A0); - if ((methodOrBlockNumArgs + 1) == 1) { - goto l18; - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, A1); - if ((methodOrBlockNumArgs + 1) == 2) { - goto l18; - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, A2); - if ((methodOrBlockNumArgs + 1) == 3) { - goto l18; - } - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SendNumArgsReg, A3); - l18: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin saveAndRestoreLinkRegUsingCalleeSavedRegNotLiveAtPointOfSendAround: */ - /* begin gen:literal: */ - anInstruction1 = genoperand(CallFull, ((sqInt)primitiveRoutine)); - /* begin genRemoveNArgsFromStack: */ - n = methodOrBlockNumArgs + 1; - assert(n <= 4); - genRestoreRegs(backEnd, liveRegsMask & CallerSavedRegisterMask); - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(CmpCqR, 0, ABIResultReg); - /* begin JumpZero: */ - jmpFail = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - genWriteCResultIntoReg(backEnd, ReceiverResultReg); - /* begin RetN: */ - offset = (methodOrBlockNumArgs > 1 /* numRegArgs */ - ? (methodOrBlockNumArgs + 1) * BytesPerWord - : 0); - genoperand(RetN, offset); - jmpTarget(jmpFail, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - -/* Compile one method cache probe in an OpenPIC's lookup of selector. - Answer the jump taken if the selector probe fails. - The class tag of the receiver must be in SendNumArgsReg. ClassReg and - TempReg are used as scratch registers. - On a hit, the offset of the entry is in ClassReg. */ - - /* SimpleStackBasedCogit>>#compileOpenPICMethodCacheProbeFor:withShift:baseRegOrNone: */ -static AbstractInstruction * NoDbgRegParms -compileOpenPICMethodCacheProbeForwithShiftbaseRegOrNone(sqInt selector, sqInt shift, sqInt baseRegOrNone) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *jumpSelectorMiss; - sqInt offset; - sqInt offset1; - - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SendNumArgsReg, ClassReg); - /* begin maybeShiftClassTagRegisterForMethodCacheProbe: */ - annotateobjRef(checkLiteralforInstruction(selector, genoperandoperand(XorCwR, selector, ClassReg)), selector); - assert(shift <= (shiftForWord())); - if (shift < (shiftForWord())) { - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (shiftForWord()) - shift, ClassReg); - } - /* begin AndCq:R: */ - anInstruction4 = genoperandoperand(AndCqR, ((int)((usqInt)(MethodCacheMask) << (shiftForWord()))), ClassReg); - if (baseRegOrNone == NoReg) { - /* begin MoveMw:r:R: */ - offset = (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheSelector) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - } - else { - /* begin AddR:R: */ - genoperandoperand(AddRR, baseRegOrNone, ClassReg); - /* begin MoveMw:r:R: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, ((int)((usqInt)(MethodCacheSelector) << (shiftForWord()))), ClassReg, TempReg); - } - annotateobjRef(checkLiteralforInstruction(selector, genoperandoperand(CmpCwR, selector, TempReg)), selector); - /* begin JumpNonZero: */ - jumpSelectorMiss = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - if (baseRegOrNone == NoReg) { - /* begin MoveMw:r:R: */ - offset1 = (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheClass) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveMwrR, offset1, ClassReg, TempReg); - } - else { - /* begin MoveMw:r:R: */ - anInstruction3 = genoperandoperandoperand(MoveMwrR, ((int)((usqInt)(MethodCacheClass) << (shiftForWord()))), ClassReg, TempReg); - } - /* begin CmpR:R: */ - assert(!((SendNumArgsReg == SPReg))); - genoperandoperand(CmpRR, SendNumArgsReg, TempReg); - return jumpSelectorMiss; -} - - -/* Compile the code for an open PIC. Perform a probe of the first-level - method lookup cache followed by a call of ceSendFromInLineCacheMiss: if - the probe fails. */ - - /* SimpleStackBasedCogit>>#compileOpenPIC:numArgs: */ -static void NoDbgRegParms -compileOpenPICnumArgs(sqInt selector, sqInt numArgs) -{ - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - sqInt cacheBaseReg; - AbstractInstruction *itsAHit; - AbstractInstruction *jumpBCMethod; - AbstractInstruction *jumpClassMiss; - AbstractInstruction *jumpSelectorMiss; - sqInt offset; - - /* begin preenMethodLabel */ - (((((AbstractInstruction *) methodLabel))->operands))[1] = 0; - compilePICAbort(numArgs); - entry = genGetClassTagOfintoscratchReg(ReceiverResultReg, SendNumArgsReg, TempReg); - flag("lookupInMethodCacheSel:classTag:"); - cacheBaseReg = NoReg; - jumpSelectorMiss = compileOpenPICMethodCacheProbeForwithShiftbaseRegOrNone(selector, 0, cacheBaseReg); - /* begin JumpNonZero: */ - jumpClassMiss = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset = (cacheBaseReg == NoReg - ? (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheMethod) << (shiftForWord())))) - : ((int)((usqInt)(MethodCacheMethod) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, SendNumArgsReg); - itsAHit = anInstruction1; - genLoadSlotsourceRegdestReg(HeaderIndex, SendNumArgsReg, ClassReg); - jumpBCMethod = genJumpImmediate(ClassReg); - jmpTarget(jumpBCMethod, picInterpretAbort); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AddCqR, cmNoCheckEntryOffset, ClassReg); - /* begin JumpR: */ - genoperand(JumpR, ClassReg); - jmpTarget(jumpSelectorMiss, jmpTarget(jumpClassMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - jumpSelectorMiss = compileOpenPICMethodCacheProbeForwithShiftbaseRegOrNone(selector, 1, cacheBaseReg); - /* begin JumpZero: */ - genConditionalBranchoperand(JumpZero, ((sqInt)itsAHit)); - jmpTarget(jumpSelectorMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - jumpSelectorMiss = compileOpenPICMethodCacheProbeForwithShiftbaseRegOrNone(selector, 2, cacheBaseReg); - /* begin JumpZero: */ - genConditionalBranchoperand(JumpZero, ((sqInt)itsAHit)); - jmpTarget(jumpSelectorMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genPushRegisterArgsForNumArgsscratchReg(backEnd, numArgs, SendNumArgsReg); - genSmalltalkToCStackSwitch(1); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), SendNumArgsReg)))); - compileCallFornumArgsargargargargresultRegregsToSave(ceSendFromInLineCacheMiss, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); -} - - -/* Compile one method cache probe in a perform: primitive's lookup of - selector. Answer the jump taken if the selector probe fails. */ - - /* SimpleStackBasedCogit>>#compilePerformMethodCacheProbeFor:withShift:baseRegOrNone: */ -static AbstractInstruction * NoDbgRegParms -compilePerformMethodCacheProbeForwithShiftbaseRegOrNone(sqInt selectorReg, sqInt shift, sqInt baseRegOrNone) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *jumpSelectorMiss; - sqInt offset; - sqInt offset1; - - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SendNumArgsReg, ClassReg); - /* begin maybeShiftClassTagRegisterForMethodCacheProbe: */ - /* begin XorR:R: */ - genoperandoperand(XorRR, selectorReg, ClassReg); - assert(shift <= (shiftForWord())); - if (shift < (shiftForWord())) { - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (shiftForWord()) - shift, ClassReg); - } - /* begin AndCq:R: */ - anInstruction4 = genoperandoperand(AndCqR, ((int)((usqInt)(MethodCacheMask) << (shiftForWord()))), ClassReg); - if (baseRegOrNone == NoReg) { - /* begin MoveMw:r:R: */ - offset = (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheSelector) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - } - else { - /* begin AddR:R: */ - genoperandoperand(AddRR, baseRegOrNone, ClassReg); - /* begin MoveMw:r:R: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, ((int)((usqInt)(MethodCacheSelector) << (shiftForWord()))), ClassReg, TempReg); - } - /* begin CmpR:R: */ - assert(!((selectorReg == SPReg))); - genoperandoperand(CmpRR, selectorReg, TempReg); - /* begin JumpNonZero: */ - jumpSelectorMiss = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - if (baseRegOrNone == NoReg) { - /* begin MoveMw:r:R: */ - offset1 = (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheClass) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveMwrR, offset1, ClassReg, TempReg); - } - else { - /* begin MoveMw:r:R: */ - anInstruction3 = genoperandoperandoperand(MoveMwrR, ((int)((usqInt)(MethodCacheClass) << (shiftForWord()))), ClassReg, TempReg); - } - /* begin CmpR:R: */ - assert(!((SendNumArgsReg == SPReg))); - genoperandoperand(CmpRR, SendNumArgsReg, TempReg); - return jumpSelectorMiss; -} - - -/* Compile a primitive. If possible, performance-critical primitives will - be generated by their own routines (primitiveGenerator). Otherwise, - if there is a primitive at all, we call the C routine with the usual - stack-switching dance, test the primFailCode and then either return - on success or continue to the method body. */ - - /* SimpleStackBasedCogit>>#compilePrimitive */ -static sqInt -compilePrimitive(void) -{ - sqInt code; - sqInt flags; - sqInt opcodeIndexAtPrimitive; - PrimitiveDescriptor *primitiveDescriptor; - void (*primitiveRoutine)(void); - - flags = 0; - if (primitiveIndex == 0) { - return 0; - } - if ((((primitiveDescriptor = primitiveGeneratorOrNil())) != null) - && ((((primitiveDescriptor->primitiveGenerator)) != null) - && ((((primitiveDescriptor->primNumArgs)) < 0) - || (((primitiveDescriptor->primNumArgs)) == (argumentCountOf(methodObj)))))) { - - /* Note opcodeIndex so that any arg load instructions - for unimplemented primitives can be discarded. */ - opcodeIndexAtPrimitive = opcodeIndex; - code = ((primitiveDescriptor->primitiveGenerator))(); - if ((code < 0) - && (code != UnimplementedPrimitive)) { - - /* Generator failed, so no point continuing... */ - return code; - } - if (code == UnfailingPrimitive) { - return 0; - } - if ((code == CompletePrimitive) - && (!(((primitiveIndexOfMethodheader(methodObj, methodHeader)) > 0) - && ((longStoreBytecodeForHeader(methodHeader)) == (fetchByteofObject((startPCOfMethod(methodObj)) + (sizeOfCallPrimitiveBytecode(methodHeader)), methodObj)))))) { - return 0; - } - if (code == UnimplementedPrimitive) { - opcodeIndex = opcodeIndexAtPrimitive; - } - } - primitiveRoutine = functionPointerForCompiledMethodprimitiveIndexprimitivePropertyFlagsInto(methodObj, primitiveIndex, (&flags)); - if (((flags & PrimCallDoNotJIT) != 0)) { - return ShouldNotJIT; - } - if ((primitiveRoutine == 0) - || (primitiveRoutine == (((void (*)(void)) primitiveFail)))) { - return genFastPrimFail(); - } - if (((flags & PrimCallOnSmalltalkStack) != 0)) { - assert(!(((((flags & FastCPrimitiveUseCABIFlag) != 0)) - && (((flags & PrimCallOnSmalltalkStackAlign2x) != 0))))); - if (((flags & FastCPrimitiveUseCABIFlag) != 0)) { - return compileMachineCodeInterpreterPrimitive(((void (*)(void)) (mcprimFunctionForPrimitiveIndex(primitiveIndex)))); - } - } - minValidCallAddress = ((minValidCallAddress < (((usqInt)primitiveRoutine))) ? minValidCallAddress : (((usqInt)primitiveRoutine))); - return compileInterpreterPrimitiveflags(primitiveRoutine, flags); -} - - /* SimpleStackBasedCogit>>#extendedPushBytecode */ -static sqInt -extendedPushBytecode(void) -{ - sqInt variableIndex; - sqInt variableType; - - variableType = (((usqInt)(byte1)) >> 6) & 3; - variableIndex = byte1 & 0x3F; - if (variableType == 0) { - return genPushReceiverVariable(variableIndex); - } - if (variableType == 1) { - return genPushTemporaryVariable(variableIndex); - } - if (variableType == 2) { - return genPushLiteralIndex(variableIndex); - } - return genPushLiteralVariable(variableIndex); -} - - /* SimpleStackBasedCogit>>#extendedStoreAndPopBytecode */ -static sqInt -extendedStoreAndPopBytecode(void) -{ - AbstractInstruction *abstractInstruction; - sqInt variableIndex; - sqInt variableType; - - variableType = (((usqInt)(byte1)) >> 6) & 3; - variableIndex = byte1 & 0x3F; - if (variableType == 0) { - return genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(1, variableIndex, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } - if (variableType == 1) { - genStorePopTemporaryVariable(1, variableIndex); -# if IMMUTABILITY - /* begin annotateBytecode: */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction->annotation = HasBytecodePC); -# endif // IMMUTABILITY - return 0; - } - if (variableType == 3) { - return genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(1, variableIndex, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } - return EncounteredUnknownBytecode; -} - - /* SimpleStackBasedCogit>>#extendedStoreBytecode */ -static sqInt -extendedStoreBytecode(void) -{ - AbstractInstruction *abstractInstruction; - sqInt variableIndex; - sqInt variableType; - - variableType = (((usqInt)(byte1)) >> 6) & 3; - variableIndex = byte1 & 0x3F; - if (variableType == 0) { - return genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(0, variableIndex, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } - if (variableType == 1) { - genStorePopTemporaryVariable(0, variableIndex); -# if IMMUTABILITY - /* begin annotateBytecode: */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction->annotation = HasBytecodePC); -# endif // IMMUTABILITY - return 0; - } - if (variableType == 3) { - return genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(0, variableIndex, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } - return EncounteredUnknownBytecode; -} - - /* SimpleStackBasedCogit>>#frameOffsetOfTemporary: */ -static sqInt NoDbgRegParms -frameOffsetOfTemporary(sqInt index) -{ - return (index < methodOrBlockNumArgs - ? FoxCallerSavedIP + ((methodOrBlockNumArgs - index) * BytesPerWord) - : (FoxMFReceiver - BytesPerWord) + ((methodOrBlockNumArgs - index) * BytesPerWord)); -} - - -/* Can use any of the first 32 literals for the selector and pass up to 7 - arguments. - */ - - /* SimpleStackBasedCogit>>#genExtendedSendBytecode */ -static sqInt -genExtendedSendBytecode(void) -{ - return genSendnumArgs(byte1 & 0x1F, ((usqInt)(byte1)) >> 5); -} - - /* SimpleStackBasedCogit>>#genExtendedSuperBytecode */ -static sqInt -genExtendedSuperBytecode(void) -{ - return genSendSupernumArgs(byte1 & 0x1F, ((usqInt)(byte1)) >> 5); -} - - -/* 239 11101111 i i i i i j j j Send To Superclass Literal Selector #iiiii - (+ Extend A * 32) with jjj (+ Extend B * 8) Arguments - */ - - /* SimpleStackBasedCogit>>#genExtSendSuperBytecode */ -static sqInt -genExtSendSuperBytecode(void) -{ - int isDirected; - sqInt litIndex; - sqInt nArgs; - - if ((isDirected = extB >= 64)) { - extB = extB & 0x3F; - } - litIndex = (((usqInt)(byte1)) >> 3) + (((sqInt)((usqInt)(extA) << 5))); - extA = 0; - nArgs = (byte1 & 7) + (((sqInt)((usqInt)(extB) << 3))); - extB = 0; - numExtB = 0; - assert(!(isDirected)); - return genSendSupernumArgs(litIndex, nArgs); -} - - /* SimpleStackBasedCogit>>#genFastPrimFail */ -static sqInt -genFastPrimFail(void) -{ - primitiveIndex = 0; - return UnfailingPrimitive; -} - - -/* Suport for compileInterpreterPrimitive. Generate inline code so as to - record the primitive - trace as fast as possible. */ - - /* SimpleStackBasedCogit>>#genFastPrimTraceUsing:and: */ -static void NoDbgRegParms -genFastPrimTraceUsingand(sqInt r1, sqInt r2) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - sqInt offset; - - /* begin MoveCq:R: */ - anInstruction = genoperandoperand(MoveCqR, 0, r2); - /* begin checkLiteral:forInstruction: */ - primTraceLogIndexAddress(); - anInstruction1 = genoperandoperand(MoveAbR, primTraceLogIndexAddress(), r2); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(LoadEffectiveAddressMwrR, 1, r2, r1); - /* begin checkLiteral:forInstruction: */ - primTraceLogIndexAddress(); - anInstruction3 = genoperandoperand(MoveRAb, r1, primTraceLogIndexAddress()); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), r1)))); - /* begin MoveMw:r:R: */ - offset = offsetof(CogMethod, selector); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperandoperand(MoveMwrR, offset, r1, TempReg); - /* begin checkLiteral:forInstruction: */ - ((sqInt)(primTraceLogAddress())); - anInstruction5 = genoperandoperand(MoveCwR, ((sqInt)(primTraceLogAddress())), r1); - /* begin MoveR:Xwr:R: */ - genoperandoperandoperand(MoveRXwrR, TempReg, r2, r1); -} - - /* SimpleStackBasedCogit>>#genLongJumpIfFalse */ -static sqInt -genLongJumpIfFalse(void) -{ - sqInt distance; - sqInt target; - - distance = v3LongForwardBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - target = (distance + 2) + bytecodePC; - return genJumpIfto(falseObject(), target); -} - - /* SimpleStackBasedCogit>>#genLongJumpIfTrue */ -static sqInt -genLongJumpIfTrue(void) -{ - sqInt distance; - sqInt target; - - distance = v3LongForwardBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - target = (distance + 2) + bytecodePC; - return genJumpIfto(trueObject(), target); -} - - -/* 237 11101101 i i i i i i i i Pop and Store Temporary Variable #iiiiiiii */ - - /* SimpleStackBasedCogit>>#genLongStoreAndPopTemporaryVariableBytecode */ -static sqInt -genLongStoreAndPopTemporaryVariableBytecode(void) -{ - return genStorePopTemporaryVariable(1, byte1); -} - - /* SimpleStackBasedCogit>>#genLongUnconditionalBackwardJump */ -static sqInt -genLongUnconditionalBackwardJump(void) -{ - sqInt distance; - - distance = v3LongBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - assert(distance < 0); - return genJumpBackTo((distance + 2) + bytecodePC); -} - - /* SimpleStackBasedCogit>>#genLongUnconditionalForwardJump */ -static sqInt -genLongUnconditionalForwardJump(void) -{ - sqInt distance; - sqInt targetpc; - - distance = v3LongBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - assert(distance >= 0); - targetpc = (distance + 2) + bytecodePC; - return genJumpTo(targetpc); -} - - -/* Compile the code for a probe of the first-level method cache for a perform - primitive. The selector is assumed to be in Arg0Reg. Defer to - adjustArgumentsForPerform: to - adjust the arguments before the jump to the method. */ - - /* SimpleStackBasedCogit>>#genLookupForPerformNumArgs: */ -static sqInt NoDbgRegParms -genLookupForPerformNumArgs(sqInt numArgs) -{ - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - sqInt cacheBaseReg; - AbstractInstruction *itsAHit; - AbstractInstruction *jumpClassMiss; - AbstractInstruction *jumpInterpret; - AbstractInstruction *jumpSelectorMiss; - sqInt offset; - - - /* N.B. Can't assume TempReg already contains the tag because a method can - of course be invoked via the unchecked entry-point, e.g. as does perform:. */ - genGetInlineCacheClassTagFromintoforEntry(ReceiverResultReg, SendNumArgsReg, 0); - flag("lookupInMethodCacheSel:classTag:"); - cacheBaseReg = NoReg; - jumpSelectorMiss = compilePerformMethodCacheProbeForwithShiftbaseRegOrNone(Arg0Reg, 0, cacheBaseReg); - /* begin JumpNonZero: */ - jumpClassMiss = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset = (cacheBaseReg == NoReg - ? (((usqInt)(methodCacheAddress()))) + (((int)((usqInt)(MethodCacheMethod) << (shiftForWord())))) - : ((int)((usqInt)(MethodCacheMethod) << (shiftForWord())))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, SendNumArgsReg); - itsAHit = anInstruction1; - genLoadSlotsourceRegdestReg(HeaderIndex, SendNumArgsReg, ClassReg); - - /* Adjust arguments and jump to the method's unchecked entry-point. */ - jumpInterpret = genJumpImmediate(ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AddCqR, cmNoCheckEntryOffset, ClassReg); - adjustArgumentsForPerform(numArgs); - /* begin JumpR: */ - genoperand(JumpR, ClassReg); - jmpTarget(jumpSelectorMiss, jmpTarget(jumpClassMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - jumpSelectorMiss = compilePerformMethodCacheProbeForwithShiftbaseRegOrNone(Arg0Reg, 1, cacheBaseReg); - /* begin JumpZero: */ - genConditionalBranchoperand(JumpZero, ((sqInt)itsAHit)); - jmpTarget(jumpSelectorMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - jumpSelectorMiss = compilePerformMethodCacheProbeForwithShiftbaseRegOrNone(Arg0Reg, 2, cacheBaseReg); - /* begin JumpZero: */ - genConditionalBranchoperand(JumpZero, ((sqInt)itsAHit)); - jmpTarget(jumpSelectorMiss, jmpTarget(jumpInterpret, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return 0; -} - - /* SimpleStackBasedCogit>>#genMustBeBooleanTrampolineFor:called: */ -static usqInt NoDbgRegParms -genMustBeBooleanTrampolineForcalled(sqInt boolean, char *trampolineName) -{ - AbstractInstruction *anInstruction; - - zeroOpcodeIndex(); - assert(!(shouldAnnotateObjectReference(boolean))); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, boolean, TempReg); - return genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceSendMustBeBoolean, trampolineName, 1, TempReg, null, null, null, 0 /* emptyRegisterMask */, 1, NoReg, 1); -} - - -/* Implement 28-bit hashMultiply for SmallInteger and LargePositiveInteger - receivers. - */ - - /* SimpleStackBasedCogit>>#genPrimitiveHashMultiply */ -static sqInt -genPrimitiveHashMultiply(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction * jmpFailImm; - AbstractInstruction * jmpFailNotPositiveLargeInt; - - return UnimplementedPrimitive; - if (mclassIsSmallInteger()) { - genConvertSmallIntegerToIntegerInReg(ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, HashMultiplyConstant, TempReg); - /* begin MulR:R: */ - genMulRR(backEnd, TempReg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(AndCqR, HashMultiplyMask, ReceiverResultReg); - genConvertIntegerToSmallIntegerInReg(ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, 0); - return CompletePrimitive; - } - jmpFailImm = genJumpImmediate(ReceiverResultReg); - genGetCompactClassIndexNonImmOfinto(ReceiverResultReg, ClassReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(CmpCqR, ClassLargePositiveIntegerCompactIndex, ClassReg); - /* begin JumpNonZero: */ - jmpFailNotPositiveLargeInt = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(0, ReceiverResultReg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(MoveCqR, HashMultiplyConstant, TempReg); - /* begin MulR:R: */ - genMulRR(backEnd, TempReg, ReceiverResultReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(AndCqR, HashMultiplyMask, ReceiverResultReg); - genConvertIntegerToSmallIntegerInReg(ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, 0); - jmpTarget(jmpFailImm, jmpTarget(jmpFailNotPositiveLargeInt, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return CompletePrimitive; -} - - -/* Generate the substitute return code for an external or FFI primitive call. - On success simply return, extracting numArgs from newMethod. - On primitive failure call ceActivateFailingPrimitiveMethod: newMethod. */ - - /* SimpleStackBasedCogit>>#genPrimReturnEnterCogCodeEnilopmart: */ -static void NoDbgRegParms -genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) -{ - sqInt address; - sqInt address1; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; - AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - sqInt callTarget; - AbstractInstruction *continuePostSample; - AbstractInstruction * inst; - AbstractInstruction *jmpFail; - AbstractInstruction *jmpSample; - sqInt quickConstant; - sqInt reg; - - continuePostSample = ((AbstractInstruction *) 0); - jmpSample = ((AbstractInstruction *) 0); - zeroOpcodeIndex(); - /* begin MoveCq:R: */ - quickConstant = varBaseAddress(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - if (profiling) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick: if so. - N.B. nextProfileTick is 64-bits so 32-bit systems need to test both halves. */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction1 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin MoveAw:R: */ - address = (nextProfileTickAddress()) + BytesPerWord; - /* begin checkLiteral:forInstruction: */ - anInstruction2 = genoperandoperand(MoveAwR, address, ClassReg); - /* begin OrR:R: */ - genoperandoperand(OrRR, TempReg, ClassReg); - /* begin JumpNonZero: */ - jmpSample = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction13 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadStackPointers(backEnd); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); - /* begin checkLiteral:forInstruction: */ - instructionPointerAddress(); - anInstruction7 = genoperandoperand(MoveAwR, instructionPointerAddress(), LinkReg); - /* begin RetN: */ - genoperand(RetN, BytesPerWord); - jmpTarget(jmpFail, checkLiteralforInstruction(newMethodAddress(), genoperandoperand(MoveAwR, newMethodAddress(), SendNumArgsReg))); - /* begin checkLiteral:forInstruction: */ - cStackPointerAddress(); - anInstruction15 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); - compileCallFornumArgsargargargargresultRegregsToSave(ceActivateFailingPrimitiveMethod, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); - /* begin MoveAw:R: */ - address1 = instructionPointerAddress(); - reg = LinkReg; - /* begin checkLiteral:forInstruction: */ - anInstruction16 = genoperandoperand(MoveAwR, address1, reg); - genLoadStackPointers(backEnd); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, BytesPerWord); - if (profiling) { - - /* Call ceCheckProfileTick: to record sample and then continue. newMethod - should be up-to-date. Need to save and restore the link reg around this call. */ - jmpTarget(jmpSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - /* begin CallFullRT: */ - callTarget = (usqIntptr_t)ceCheckProfileTick; - /* begin checkLiteral:forInstruction: */ - anInstruction18 = genoperand(CallFull, callTarget); - /* begin PopR: */ - genoperand(PopR, LinkReg); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSample)); - } -} - - /* SimpleStackBasedCogit>>#genPushConstantFalseBytecode */ -static sqInt -genPushConstantFalseBytecode(void) -{ - return genPushLiteral(falseObject()); -} - - /* SimpleStackBasedCogit>>#genPushConstantNilBytecode */ -static sqInt -genPushConstantNilBytecode(void) -{ - return genPushLiteral(nilObject()); -} - - /* SimpleStackBasedCogit>>#genPushConstantTrueBytecode */ -static sqInt -genPushConstantTrueBytecode(void) -{ - return genPushLiteral(trueObject()); -} - - /* SimpleStackBasedCogit>>#genPushLiteralConstantBytecode */ -static sqInt -genPushLiteralConstantBytecode(void) -{ - return genPushLiteralIndex(byte0 & 0x1F); -} - - /* SimpleStackBasedCogit>>#genPushLiteralVariableBytecode */ -static sqInt -genPushLiteralVariableBytecode(void) -{ - return genPushLiteralVariable(byte0 & 0x1F); -} - - /* SimpleStackBasedCogit>>#genPushQuickIntegerConstantBytecode */ -static sqInt -genPushQuickIntegerConstantBytecode(void) -{ - return genPushLiteral((((usqInt)(byte0 - 117) << 1) | 1)); -} - - /* SimpleStackBasedCogit>>#genPushReceiverVariableBytecode */ -static sqInt -genPushReceiverVariableBytecode(void) -{ - return genPushReceiverVariable(byte0 & 15); -} - - /* SimpleStackBasedCogit>>#genPushTemporaryVariableBytecode */ -static sqInt -genPushTemporaryVariableBytecode(void) -{ - return genPushTemporaryVariable(byte0 & 15); -} - - -/* because selected by CoInterpreter>>quickPrimitiveGeneratorFor: */ - - /* SimpleStackBasedCogit>>#genQuickReturnConst */ -sqInt -genQuickReturnConst(void) -{ - AbstractInstruction *anInstruction; - sqInt constant; - - constant = quickPrimitiveConstantFor(primitiveIndex); - /* begin genMoveConstant:R: */ - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - genUpArrowReturn(); - return UnfailingPrimitive; -} - - -/* because selected by CoInterpreter>>quickPrimitiveGeneratorFor: */ - - /* SimpleStackBasedCogit>>#genQuickReturnInstVar */ -sqInt -genQuickReturnInstVar(void) -{ - sqInt index; - - index = quickPrimitiveInstVarIndexFor(primitiveIndex); - genLoadSlotsourceRegdestReg(index, ReceiverResultReg, ReceiverResultReg); - genUpArrowReturn(); - return UnfailingPrimitive; -} - - -/* because selected by CoInterpreter>>quickPrimitiveGeneratorFor: */ - - /* SimpleStackBasedCogit>>#genQuickReturnSelf */ -sqInt -genQuickReturnSelf(void) -{ - genUpArrowReturn(); - return UnfailingPrimitive; -} - - /* SimpleStackBasedCogit>>#genReturnFalse */ -static sqInt -genReturnFalse(void) -{ - AbstractInstruction *anInstruction; - sqInt constant; - - /* begin genMoveFalseR: */ - constant = falseObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - return genUpArrowReturn(); -} - - /* SimpleStackBasedCogit>>#genReturnNil */ -static sqInt -genReturnNil(void) -{ - AbstractInstruction *anInstruction; - sqInt constant; - - /* begin genMoveNilR: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - return genUpArrowReturn(); -} - - /* SimpleStackBasedCogit>>#genReturnTrue */ -static sqInt -genReturnTrue(void) -{ - AbstractInstruction *anInstruction; - sqInt constant; - - /* begin genMoveTrueR: */ - constant = trueObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, ReceiverResultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg); - } - return genUpArrowReturn(); -} - - -/* Can use any of the first 64 literals for the selector and pass up to 3 - arguments. - */ - - /* SimpleStackBasedCogit>>#genSecondExtendedSendBytecode */ -static sqInt -genSecondExtendedSendBytecode(void) -{ - return genSendnumArgs(byte1 & 0x3F, ((usqInt)(byte1)) >> 6); -} - - /* SimpleStackBasedCogit>>#genSendLiteralSelector0ArgsBytecode */ -static sqInt -genSendLiteralSelector0ArgsBytecode(void) -{ - return genSendnumArgs(byte0 & 15, 0); -} - - /* SimpleStackBasedCogit>>#genSendLiteralSelector1ArgBytecode */ -static sqInt -genSendLiteralSelector1ArgBytecode(void) -{ - return genSendnumArgs(byte0 & 15, 1); -} - - /* SimpleStackBasedCogit>>#genSendLiteralSelector2ArgsBytecode */ -static sqInt -genSendLiteralSelector2ArgsBytecode(void) -{ - return genSendnumArgs(byte0 & 15, 2); -} - - /* SimpleStackBasedCogit>>#genShortJumpIfFalse */ -static sqInt -genShortJumpIfFalse(void) -{ - sqInt distance; - sqInt target; - - distance = v3ShortForwardBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - target = (distance + 1) + bytecodePC; - return genJumpIfto(falseObject(), target); -} - - /* SimpleStackBasedCogit>>#genShortUnconditionalJump */ -static sqInt -genShortUnconditionalJump(void) -{ - sqInt distance; - sqInt target; - - distance = v3ShortForwardBranchDistance(generatorAt(byte0), bytecodePC, 0, methodObj); - target = (distance + 1) + bytecodePC; - return genJumpTo(target); -} - - /* SimpleStackBasedCogit>>#genSpecialSelectorEqualsEquals */ -static sqInt -genSpecialSelectorEqualsEquals(void) -{ - return genInlinedIdenticalOrNotIf(0); -} - - /* SimpleStackBasedCogit>>#genSpecialSelectorNotEqualsEquals */ -static sqInt -genSpecialSelectorNotEqualsEquals(void) -{ - return genInlinedIdenticalOrNotIf(1); -} - - /* SimpleStackBasedCogit>>#genSpecialSelectorSend */ -static sqInt -genSpecialSelectorSend(void) -{ - sqInt index; - sqInt numArgs; - - index = byte0 - ( -#if MULTIPLEBYTECODESETS - (bytecodeSetOffset == 0x100 - ? AltFirstSpecialSelector + 0x100 - : FirstSpecialSelector) -#else - FirstSpecialSelector -#endif - ); - numArgs = specialSelectorNumArgs(index); - return genSendnumArgs((-index) - 1, numArgs); -} - - /* SimpleStackBasedCogit>>#genStoreAndPopReceiverVariableBytecode */ -static sqInt -genStoreAndPopReceiverVariableBytecode(void) -{ - return genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(1, byte0 & 7, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); -} - - /* SimpleStackBasedCogit>>#genStoreAndPopRemoteTempLongBytecode */ -static sqInt -genStoreAndPopRemoteTempLongBytecode(void) -{ - return genStorePopRemoteTempAtneedsStoreCheck(1, byte1, byte2, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant))))); -} - - /* SimpleStackBasedCogit>>#genStoreAndPopTemporaryVariableBytecode */ -static sqInt -genStoreAndPopTemporaryVariableBytecode(void) -{ - return genStorePopTemporaryVariable(1, byte0 & 7); -} - - /* SimpleStackBasedCogit>>#genStoreRemoteTempLongBytecode */ -static sqInt -genStoreRemoteTempLongBytecode(void) -{ - return genStorePopRemoteTempAtneedsStoreCheck(0, byte1, byte2, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant))))); -} - - -/* Collect the branch and send data for cogMethod, storing it into arrayObj. */ - - /* SimpleStackBasedCogit>>#mapPCDataFor:into: */ -sqInt -mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj) -{ - sqInt aMethodObj; - sqInt annotation; - sqInt bcpc; - sqInt bsOffset; - sqInt byte; - BytecodeDescriptor *descriptor; - sqInt distance; - sqInt endbcpc; - sqInt errCode; - CogMethod *homeMethod; - sqInt isBackwardBranch; - sqInt isInBlock; - sqInt latestContinuation; - usqInt map; - sqInt mapByte; - usqInt mcpc; - sqInt nExts; - sqInt nextBcpc; - sqInt result; - sqInt startbcpc; - sqInt targetPC; - - latestContinuation = 0; - introspectionDataIndex = 0; - introspectionData = arrayObj; - if (((cogMethod->stackCheckOffset)) == 0) { - assert(introspectionDataIndex == 0); - storePointerUncheckedofObjectwithValue(0, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(1, introspectionData, (((usqInt)cmEntryOffset << 1) | 1)); - storePointerUncheckedofObjectwithValue(2, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(3, introspectionData, (((usqInt)cmNoCheckEntryOffset << 1) | 1)); - return 4; - } - /* begin mapFor:bcpc:performUntil:arg: */ - startbcpc = startPCOfMethod((cogMethod->methodObject)); - assert((((((CogBlockMethod *) cogMethod))->stackCheckOffset)) > 0); - - /* The stack check maps to the start of the first bytecode, - the first bytecode being effectively after frame build. */ - mcpc = (((usqInt)(((CogBlockMethod *) cogMethod)))) + (((((CogBlockMethod *) cogMethod))->stackCheckOffset)); - result = pcDataForAnnotationMcpcBcpcMethod(null, (0 + (((int)((usqInt)(HasBytecodePC) << 1)))), (((char *) mcpc)), startbcpc, (((void *)cogMethod))); - if (result != 0) { - errCode = result; - goto l7; - } - - /* In both CMMethod and CMBlock cases find the start of the map and - skip forward to the bytecode pc map entry for the stack check. */ - bcpc = startbcpc; - if ((((((CogBlockMethod *) cogMethod))->cmType)) == CMMethod) { - /* begin cmIsFullBlock */ - isInBlock = 0; - homeMethod = ((CogMethod *) (((CogBlockMethod *) cogMethod))); - assert(startbcpc == (startPCOfMethodHeader((homeMethod->methodHeader)))); - map = ((((usqInt)homeMethod)) + ((homeMethod->blockSize))) - 1; - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert((annotation == IsAbsPCReference) - || ((annotation == IsObjectReference) - || ((annotation == IsRelativeCall) - || (annotation == IsDisplacementX2N)))); - latestContinuation = startbcpc; - aMethodObj = (homeMethod->methodObject); - endbcpc = (numBytesOf(aMethodObj)) - 1; - /* begin bytecodeSetOffsetForHeader: */ - (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader) - ? 0x100 - : 0) -# else - 0 -# endif - ; - bcpc += deltaToSkipPrimAndErrorStoreInheader(aMethodObj, (homeMethod->methodHeader)); - } - else { - isInBlock = 1; - assert(bcpc == (((((CogBlockMethod *) cogMethod))->startpc))); - homeMethod = cmHomeMethod(((CogBlockMethod *) cogMethod)); - map = findMapLocationForMcpcinMethod((((usqInt)(((CogBlockMethod *) cogMethod)))) + (sizeof(CogBlockMethod)), homeMethod); - assert(map != 0); - annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift; - assert(((((usqInt)(annotation)) >> AnnotationShift) == HasBytecodePC) - || ((((usqInt)(annotation)) >> AnnotationShift) == IsDisplacementX2N)); - while (((annotation = ((usqInt)((byteAt(map)))) >> AnnotationShift)) != HasBytecodePC) { - map -= 1; - } - - /* skip fiducial; i.e. the map entry for the pc immediately following the method header. */ - map -= 1; - aMethodObj = (homeMethod->methodObject); - bcpc = startbcpc - ( -#if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet((homeMethod->methodHeader)) - ? AltBlockCreationBytecodeSize - : BlockCreationBytecodeSize) -#else // MULTIPLEBYTECODESETS - BlockCreationBytecodeSize -#endif - ); - /* begin bytecodeSetOffsetForHeader: */ - (homeMethod->methodHeader); - bsOffset = -# if MULTIPLEBYTECODESETS - (headerIndicatesAlternateBytecodeSet(aMethodHeader1) - ? 0x100 - : 0) -# else - 0 -# endif - ; - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - endbcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, -1, aMethodObj)) - : 0)); - bcpc = startbcpc; - } - nExts = 0; - while ((((usqInt)((byteAt(map)))) >> AnnotationShift) != HasBytecodePC) { - map -= 1; - } - map -= 1; - while (((mapByte = byteAt(map))) != MapEnd) { - - /* defensive; we exit on bcpc */ - if (mapByte >= FirstAnnotation) { - annotation = ((usqInt)(mapByte)) >> AnnotationShift; - mcpc += (mapByte & DisplacementMask) * 4 /* codeGranularity */; - if (annotation >= HasBytecodePC) { - if ((annotation == IsSendCall) - && ((((usqInt)(((mapByte = byteAt(map - 1))))) >> AnnotationShift) == IsAnnotationExtension)) { - annotation += mapByte & DisplacementMask; - map -= 1; - } - while (1) { - byte = (fetchByteofObject(bcpc, aMethodObj)) + bsOffset; - descriptor = generatorAt(byte); - if (isInBlock) { - if (bcpc >= endbcpc) { - errCode = 0; - goto l7; - } - } - else { - if (((descriptor->isReturn)) - && (bcpc >= latestContinuation)) { - errCode = 0; - goto l7; - } - if ((isBranch(descriptor)) - || ((descriptor->isBlockCreation))) { - /* begin latestContinuationPCFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj); - targetPC = (bcpc + ((descriptor->numBytes))) + (((distance < 0) ? 0 : distance)); - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - /* latestContinuation = */ latestContinuation; - } - nextBcpc = (bcpc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? (/* begin spanFor:at:exts:in: */ - ((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) - : 0)); - if (((descriptor->isMapped)) - || (isInBlock - && ((descriptor->isMappedInBlock)))) break; - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - isBackwardBranch = (isBranch(descriptor)) - && ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, bcpc, nExts, aMethodObj)) < 0)); - result = pcDataForAnnotationMcpcBcpcMethod(descriptor, ((isBackwardBranch - ? (((sqInt)((usqInt)(annotation) << 1))) + 1 - : ((sqInt)((usqInt)(annotation) << 1)))), (((char *) mcpc)), ((isBackwardBranch - ? bcpc - (2 * nExts) - : bcpc)), (((void *)cogMethod))); - if (result != 0) { - errCode = result; - goto l7; - } - bcpc = nextBcpc; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - } - else { - assert(((((usqInt)(mapByte)) >> AnnotationShift) == IsDisplacementX2N) - || ((((usqInt)(mapByte)) >> AnnotationShift) == IsAnnotationExtension)); - if (mapByte < (((int)((usqInt)(IsAnnotationExtension) << AnnotationShift)))) { - mcpc += (((sqInt)((usqInt)((mapByte - DisplacementX2N)) << AnnotationShift))) * 4 /* codeGranularity */; - } - } - map -= 1; - } - errCode = 0; - l7: /* end mapFor:bcpc:performUntil:arg: */; - if (errCode != 0) { - assert(errCode == PrimErrNoMemory); - return -1; - } - if (((cogMethod->blockEntryOffset)) != 0) { - errCode = blockDispatchTargetsForperformarg(cogMethod, pcDataForBlockEntryMethod, ((sqInt)cogMethod)); - if (errCode != 0) { - assert(errCode == PrimErrNoMemory); - return -1; - } - } - return introspectionDataIndex; -} - - /* SimpleStackBasedCogit>>#numSpecialSelectors */ -static sqInt -numSpecialSelectors(void) -{ - return -# if MULTIPLEBYTECODESETS - (bytecodeSetOffset == 0x100 - ? AltNumSpecialSelectors - : NumSpecialSelectors) -# else - NumSpecialSelectors -# endif - ; -} - - -/* Collect the branch and send data for the block method starting at - blockEntryMcpc, storing it into picData. - */ - - /* SimpleStackBasedCogit>>#pcDataForBlockEntry:Method: */ -static usqInt NoDbgRegParms -pcDataForBlockEntryMethod(sqInt blockEntryMcpc, sqInt cogMethod) -{ - storePointerUncheckedofObjectwithValue(introspectionDataIndex, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 1, introspectionData, (((usqInt)(blockEntryMcpc - blockNoContextSwitchOffset) << 1) | 1)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 2, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 3, introspectionData, (((usqInt)blockEntryMcpc << 1) | 1)); - introspectionDataIndex += 4; - return 0; -} - - /* SimpleStackBasedCogit>>#pcDataFor:Annotation:Mcpc:Bcpc:Method: */ -static sqInt NoDbgRegParms -pcDataForAnnotationMcpcBcpcMethod(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *cogMethodArg) -{ - sqInt actualBcpc; - sqInt actualMcpc; - - if (!descriptor) { - - /* this is the stackCheck offset */ - assert(introspectionDataIndex == 0); - storePointerUncheckedofObjectwithValue(introspectionDataIndex, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 1, introspectionData, (((usqInt)cmEntryOffset << 1) | 1)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 2, introspectionData, nilObject()); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 3, introspectionData, (((usqInt)cmNoCheckEntryOffset << 1) | 1)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 4, introspectionData, (((usqInt)(bcpc + 1) << 1) | 1)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 5, introspectionData, (((((((CogMethod *) cogMethodArg))->stackCheckOffset)) << 1) | 1)); - introspectionDataIndex += 6; - return 0; - } - if ((((usqInt)(isBackwardBranchAndAnnotation)) >> 1) >= HasBytecodePC) { - actualBcpc = (((isBackwardBranchAndAnnotation & 1) != 0) - ? bcpc + 1 - : (bcpc + ((descriptor->numBytes))) + 1); - actualMcpc = (((usqInt)mcpc)) - (((usqInt)cogMethodArg)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex, introspectionData, (((usqInt)actualBcpc << 1) | 1)); - storePointerUncheckedofObjectwithValue(introspectionDataIndex + 1, introspectionData, (((usqInt)actualMcpc << 1) | 1)); - introspectionDataIndex += 2; - } - return 0; -} - - -/* If there is a generator for the current primitive then answer it; - otherwise answer nil. */ - - /* SimpleStackBasedCogit>>#primitiveGeneratorOrNil */ -static PrimitiveDescriptor * -primitiveGeneratorOrNil(void) -{ - PrimitiveDescriptor *primitiveDescriptor; - - if (isQuickPrimitiveIndex(primitiveIndex)) { - - /* an unused one */ - primitiveDescriptor = (&(primitiveGeneratorTable[0])); - (primitiveDescriptor->primitiveGenerator = quickPrimitiveGeneratorFor(primitiveIndex)); - return primitiveDescriptor; - } - if (((primitiveIndex >= 1) && (primitiveIndex <= MaxCompiledPrimitiveIndex))) { - return (&(primitiveGeneratorTable[primitiveIndex])); - } - return null; -} - - /* SimpleStackBasedCogit>>#register:isInMask: */ -static sqInt NoDbgRegParms -registerisInMask(sqInt reg, sqInt mask) -{ - return ((mask & (1U << reg)) != 0); -} - - /* SimpleStackBasedCogit>>#v3:Block:Code:Size: */ -static sqInt NoDbgRegParms -v3BlockCodeSize(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - assert(nExts <= 0); - return (((sqInt)((usqInt)((fetchByteofObject(pc + 2, aMethodObj))) << 8))) + (fetchByteofObject(pc + 3, aMethodObj)); -} - - -/* Answer the distance of a two byte forward long jump. */ - - /* SimpleStackBasedCogit>>#v3:LongForward:Branch:Distance: */ -static sqInt NoDbgRegParms -v3LongForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - assert(nExts == 0); - return (((sqInt)((usqInt)(((fetchByteofObject(pc, aMethodObj)) & 3)) << 8))) + (fetchByteofObject(pc + 1, aMethodObj)); -} - - -/* Answer the distance of a two byte forward long jump. */ - - /* SimpleStackBasedCogit>>#v3:Long:Branch:Distance: */ -static sqInt NoDbgRegParms -v3LongBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - assert(nExts == 0); - return (((sqInt)((usqInt)((((fetchByteofObject(pc, aMethodObj)) & 7) - 4)) << 8))) + (fetchByteofObject(pc + 1, aMethodObj)); -} - - -/* N.B. This serves for both BlueBook/V3 and V4 short jumps. */ - - /* SimpleStackBasedCogit>>#v3:ShortForward:Branch:Distance: */ -static sqInt NoDbgRegParms -v3ShortForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - assert(nExts == 0); - return ((fetchByteofObject(pc, aMethodObj)) & 7) + 1; -} - - -/* Add a blockStart for an embedded block. For a binary tree walk block - dispatch blocks must be compiled in pc/depth-first order but are scanned - in breadth-first - order, so do an insertion sort (which of course is really a bubble sort - because we - have to move everything higher to make room). */ - - /* StackToRegisterMappingCogit>>#addBlockStartAt:numArgs:numCopied:span: */ -static BlockStart * NoDbgRegParms -addBlockStartAtnumArgsnumCopiedspan(sqInt bytecodepc, sqInt numArgs, sqInt numCopied, sqInt span) -{ - BlockStart *blockStart; - sqInt i; - sqInt j; - - - /* Transcript ensureCr; nextPutAll: 'addBlockStartAt: '; print: bytecodepc; cr; flush. */ - if (blockCount > 0) { - i = blockCount - 1; - while (1) { - - /* check for repeat addition during recompilation due to initialNil miscount. */ - blockStart = (&(blockStarts[i])); - if (((blockStart->startpc)) == bytecodepc) { - return blockStart; - } - if (!((((blockStart->startpc)) > bytecodepc) - && (i > 0))) break; - i -= 1; - } - for (j = blockCount; j >= (i + 1); j += -1) { - blockStarts[j] = (blockStarts[j - 1]); - } - blockStart = (&(blockStarts[i + 1])); - } - else { - blockStart = (&(blockStarts[blockCount])); - } - blockCount += 1; - (blockStart->startpc = bytecodepc); - (blockStart->numArgs = numArgs); - (blockStart->numCopied = numCopied); - (blockStart->numInitialNils = 0); - (blockStart->stackCheckLabel = null); - (blockStart->hasInstVarRef = 0); - (blockStart->span = span); - return blockStart; -} - - -/* e.g. Receiver Receiver or Receiver Receiver (RISC) - Selector/Arg0 => Arg1 Selector/Arg0 => Arg1 - Arg1 Arg2 Arg1 Arg2 - Arg2 Arg3 Arg2 sp-> Arg3 - Arg3 sp-> retpc sp-> Arg3 - sp-> retpc */ -/* Generate code to adjust the possibly stacked arguments immediately - before jumping to a method looked up by a perform primitive. */ - - /* StackToRegisterMappingCogit>>#adjustArgumentsForPerform: */ -static void NoDbgRegParms -adjustArgumentsForPerform(sqInt numArgs) -{ - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - sqInt index; - - assert((numRegArgs()) <= 2); - assert(numArgs >= 1); - if (numArgs <= 1 /* numRegArgs */) { - if (numArgs == 2) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg1Reg, Arg0Reg); - } - return; - } - if ((2) == numArgs) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveMwrR, 0, SPReg, Arg0Reg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(AddCqR, (numArgs + 1) * BytesPerWord, SPReg); - return; - } - for (index = (numArgs - 2); index >= 0; index += -1) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction10 = genoperandoperandoperand(MoveMwrR, index * BytesPerWord, SPReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperandoperand(MoveRMwr, TempReg, (index + 1) * BytesPerWord, SPReg); - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction12 = genoperandoperand(AddCqR, BytesPerWord, SPReg); -} - - -/* If the stack entry is already in a register not conflicting with regMask, - answers it, - else allocate a new register not conflicting with reg mask - */ - - /* StackToRegisterMappingCogit>>#allocateRegForStackEntryAt:notConflictingWith: */ -static sqInt NoDbgRegParms -allocateRegForStackEntryAtnotConflictingWith(sqInt index, sqInt regMask) -{ - sqInt mask; - CogSimStackEntry *stackEntry; - - stackEntry = ssValue(index); - mask = registerMaskOrNone(stackEntry); - if ((mask != 0) - && ((!(mask & regMask)))) { - flag("TODO"); - return registerOrNone(stackEntry); - } - return allocateRegNotConflictingWith(regMask); -} - - -/* if there's a free register, use it */ - - /* StackToRegisterMappingCogit>>#allocateRegNotConflictingWith: */ -static sqInt NoDbgRegParms -allocateRegNotConflictingWith(sqInt regMask) -{ - sqInt reg; - - reg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); - if (reg == NoReg) { - - /* No free register, choose one that does not conflict with regMask */ - reg = freeAnyRegNotConflictingWith(regMask); - } - if (reg == ReceiverResultReg) { - - /* If we've allocated RcvrResultReg, it's not live anymore */ - voidReceiverResultRegContainsSelf(); - } - return reg; -} - - /* StackToRegisterMappingCogit>>#anyReferencesToRegister:inTopNItems: */ -static sqInt NoDbgRegParms -anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n) -{ - sqInt i; - sqInt regMask; - - /* begin registerMaskFor: */ - regMask = 1U << reg; - for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { - if ((((registerMask(simStackAt(i))) & regMask) != 0)) { - return 1; - } - } - return 0; -} - - -/* This is a static version of ceCallCogCodePopReceiverArg0Regs - for break-pointing when debugging in C. */ -/* This exists only for break-pointing. */ - - /* StackToRegisterMappingCogit>>#callCogCodePopReceiverArg0Regs */ -void -callCogCodePopReceiverArg0Regs(void) -{ - realCECallCogCodePopReceiverArg0Regs(); -} - - -/* This is a static version of ceCallCogCodePopReceiverArg1Arg0Regs - for break-pointing when debugging in C. */ -/* This exists only for break-pointing. */ - - /* StackToRegisterMappingCogit>>#callCogCodePopReceiverArg1Arg0Regs */ -void -callCogCodePopReceiverArg1Arg0Regs(void) -{ - realCECallCogCodePopReceiverArg1Arg0Regs(); -} - - -/* Loop over bytecodes, dispatching to the generator for each bytecode, - handling fixups in due course. - */ - - /* StackToRegisterMappingCogit>>#compileAbstractInstructionsFrom:through: */ -static sqInt NoDbgRegParms -compileAbstractInstructionsFromthrough(sqInt start, sqInt end) -{ - BytecodeDescriptor *descriptor; - BytecodeFixup *fixup; - sqInt nExts; - sqInt nextOpcodeIndex; - sqInt result; - - traceSimStack(); - bytecodePC = start; - nExts = (result = 0); - descriptor = null; - deadCode = 0; - while (1) { - maybeHaltIfDebugPC(); - mergeWithFixupIfRequired((fixup = fixupAt(bytecodePC))); - descriptor = loadBytesAndGetDescriptor(); - nextOpcodeIndex = opcodeIndex; - result = (deadCode - ? mapDeadDescriptorIfNeeded(descriptor) - : ((descriptor->generator))()); - if (result == 0) { - /* begin assertExtsAreConsumed: */ - if (!((descriptor->isExtension))) { - assert((extA == 0) - && ((extB == 0) - && (numExtB == 0))); - } - } - traceDescriptor(descriptor); - traceSimStack(); - /* begin patchFixupTargetIfNeeded:nextOpcodeIndex: */ - if ((((((usqInt)((fixup->targetInstruction)))) >= NeedsNonMergeFixupFlag) && ((((usqInt)((fixup->targetInstruction)))) <= NeedsMergeFixupFlag))) { - - /* There is a fixup for this bytecode. It must point to the first generated - instruction for this bytecode. If there isn't one we need to add a label. */ - if (opcodeIndex == nextOpcodeIndex) { - /* begin Label */ - genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (fixup->targetInstruction = abstractInstructionAt(nextOpcodeIndex)); - } - /* begin maybeDumpLiterals: */ - if (((isBranch(descriptor)) - && (!(((descriptor->isBranchTrue)) - || ((descriptor->isBranchFalse))))) - || ((descriptor->isReturn))) { - /* begin dumpLiterals: */ - !(((isBranch(descriptor)) - && (!(((descriptor->isBranchTrue)) - || ((descriptor->isBranchFalse))))) - || ((descriptor->isReturn))); - } - /* begin nextBytecodePCFor:exts: */ - bytecodePC = (bytecodePC + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? ((descriptor->spanFunction))(descriptor, bytecodePC, nExts, methodObj) - : 0)); - if (!((result == 0) - && (bytecodePC <= end))) break; - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } - /* begin checkEnoughOpcodes */ - if (opcodeIndex > numAbstractOpcodes) { - error("Cog JIT internal error. Too many abstract opcodes. Num opcodes heuristic is too optimistic."); - } - return result; -} - - /* StackToRegisterMappingCogit>>#compileBlockBodies */ -static sqInt -compileBlockBodies(void) -{ - BlockStart *blockStart; - sqInt compiledBlocksCount; - sqInt initialCounterIndex; - sqInt initialOpcodeIndex; - sqInt initialStackPtr; - sqInt (* const pushNilSizeFunction)(sqInt,sqInt) = v3PushNilSizenumInitialNils; - sqInt result; - sqInt savedNeedsFrame; - sqInt savedNumArgs; - sqInt savedNumTemps; - - assert(blockCount > 0); - savedNeedsFrame = needsFrame; - savedNumArgs = methodOrBlockNumArgs; - savedNumTemps = methodOrBlockNumTemps; - inBlock = InVanillaBlock; - compiledBlocksCount = 0; - while (compiledBlocksCount < blockCount) { - compilationPass = 1; - blockStart = blockStartAt(compiledBlocksCount); - if (((result = scanBlock(blockStart))) < 0) { - return result; - } - initialOpcodeIndex = opcodeIndex; - - /* for SistaCogit */ - initialCounterIndex = 0 /* maybeCounterIndex */; - while (1) { - compileBlockEntry(blockStart); - initialStackPtr = simStackPtr; - if (((result = compileAbstractInstructionsFromthrough(((blockStart->startpc)) + (pushNilSizeFunction(methodObj, ((blockStart->numInitialNils)))), (((blockStart->startpc)) + ((blockStart->span))) - 1))) < 0) { - return result; - } - if (initialStackPtr == simStackPtr) break; - assert((initialStackPtr > simStackPtr) - || (deadCode)); - - /* for asserts */ - compilationPass += 1; - (blockStart->numInitialNils = (((blockStart->numInitialNils)) + simStackPtr) - initialStackPtr); - (((blockStart->fakeHeader))->dependent = null); - reinitializeFixupsFromthrough(((blockStart->startpc)) + ((blockStart->numInitialNils)), (((blockStart->startpc)) + ((blockStart->span))) - 1); - bzero(abstractOpcodes + initialOpcodeIndex, - (opcodeIndex - initialOpcodeIndex) * sizeof(AbstractInstruction)); - opcodeIndex = initialOpcodeIndex; - } - compiledBlocksCount += 1; - } - needsFrame = savedNeedsFrame; - methodOrBlockNumArgs = savedNumArgs; - methodOrBlockNumTemps = savedNumTemps; - return 0; -} - - -/* Build a frame for a block activation. See CoInterpreter - class>>initializeFrameIndices. closure (in ReceiverResultReg) - arg0 - ... - argN - caller's saved ip/this stackPage (for a base frame) - fp-> saved fp - method - context (uninitialized?) - receiver - first temp - ... - sp-> Nth temp - Avoid use of SendNumArgsReg which is the flag determining whether - context switch is allowed on stack-overflow. */ -/* Build a frame for a block activation. See CoInterpreter - class>>initializeFrameIndices. Override to push the register receiver and - register arguments, if any, and to correctly - initialize the explicitly nilled/pushed temp entries (they are /not/ of - type constant nil). */ - - /* StackToRegisterMappingCogit>>#compileBlockFrameBuild: */ -static void NoDbgRegParms -compileBlockFrameBuild(BlockStart *blockStart) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction * cascade0; - sqInt constant; - sqInt constant1; - sqInt i; - sqInt ign; - - /* begin annotateBytecode: */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction->annotation = HasBytecodePC); - /* begin PushR: */ - genoperand(PushR, LinkReg); - /* begin PushR: */ - genoperand(PushR, FPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SPReg, FPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ReceiverResultReg, ClassReg); - cascade0 = (blockStart->fakeHeader); - addDependent(cascade0, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)((blockStart->fakeHeader))), genoperand(PushCw, ((sqInt)((blockStart->fakeHeader))))))); - /* begin setLabelOffset: */ - ((cascade0->operands))[1] = MFMethodFlagIsBlockFlag; - annotateobjRef(checkLiteralforInstruction(nilObject(), genoperand(PushCw, nilObject())), nilObject()); - if ((blockStart->hasInstVarRef)) { - - /* Use ReceiverResultReg for Context to agree with store check trampoline */ - genLoadSlotsourceRegdestReg(ClosureOuterContextIndex, ClassReg, ReceiverResultReg); - genLoadSlotsourceRegdestReg(ReceiverIndex, ReceiverResultReg, Arg0Reg); - /* begin genEnsureOopInRegNotForwarded:scratchReg:updatingSlot:in: */ - assert(0); - /* begin genEnsureOopInRegNotForwarded:scratchReg:updatingMw:r: */ - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ReceiverResultReg); - } - else { - genLoadSlotsourceRegdestReg(ClosureOuterContextIndex, ClassReg, Arg0Reg); - genLoadSlotsourceRegdestReg(ReceiverIndex, Arg0Reg, ReceiverResultReg); - } - /* begin PushR: */ - genoperand(PushR, ReceiverResultReg); - for (i = 0; i < ((blockStart->numCopied)); i += 1) { - genLoadSlotsourceRegdestReg(i + ClosureFirstCopiedValueIndex, ClassReg, TempReg); - /* begin PushR: */ - genoperand(PushR, TempReg); - } - (blockStart->stackCheckLabel = compileStackOverflowCheck(1)); - methodOrBlockNumTemps = (((blockStart->numArgs)) + ((blockStart->numCopied))) + ((blockStart->numInitialNils)); - initSimStackForFramefulMethod((blockStart->startpc)); - if (((blockStart->numInitialNils)) > 0) { - if (((blockStart->numInitialNils)) > 1) { - /* begin genMoveNilR: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, TempReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, TempReg); - } - for (ign = 1; ign <= ((blockStart->numInitialNils)); ign += 1) { - /* begin PushR: */ - genoperand(PushR, TempReg); - } - } - else { - /* begin genPushConstant: */ - constant1 = nilObject(); - if (shouldAnnotateObjectReference(constant1)) { - annotateobjRef(checkLiteralforInstruction(constant1, genoperand(PushCw, constant1)), constant1); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperand(PushCq, constant1); - } - } - } -} - - -/* Make sure ReceiverResultReg holds the receiver, loaded from the closure, - which is what is initially in ReceiverResultReg. We must annotate the - first instruction in vanilla blocks so that - findMethodForStartBcpc:inHomeMethod: can function. We need two annotations - because the first is a fiducial. */ -/* Make sure ReceiverResultReg holds the receiver, loaded from - the closure, which is what is initially in ReceiverResultReg */ - - /* StackToRegisterMappingCogit>>#compileBlockFramelessEntry: */ -static void NoDbgRegParms -compileBlockFramelessEntry(BlockStart *blockStart) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - - methodOrBlockNumTemps = (((blockStart->numArgs)) + ((blockStart->numCopied))) + ((blockStart->numInitialNils)); - initSimStackForFramelessBlock((blockStart->startpc)); - if (!(((blockStart->entryLabel)) == null)) { - /* begin annotateBytecode: */ - abstractInstruction = (blockStart->entryLabel); - (abstractInstruction->annotation = HasBytecodePC); - /* begin annotateBytecode: */ - abstractInstruction1 = (blockStart->entryLabel); - (abstractInstruction1->annotation = HasBytecodePC); - } - if ((blockStart->hasInstVarRef)) { - - /* Use ReceiverResultReg for Context to agree with store check trampoline */ - genLoadSlotsourceRegdestReg(ClosureOuterContextIndex, ReceiverResultReg, ReceiverResultReg); - genLoadSlotsourceRegdestReg(ReceiverIndex, ReceiverResultReg, Arg0Reg); - /* begin genEnsureOopInRegNotForwarded:scratchReg:updatingSlot:in: */ - assert(0); - /* begin genEnsureOopInRegNotForwarded:scratchReg:updatingMw:r: */ - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Arg0Reg, ReceiverResultReg); - } - else { - genLoadSlotsourceRegdestReg(ClosureOuterContextIndex, ReceiverResultReg, TempReg); - genLoadSlotsourceRegdestReg(ReceiverIndex, TempReg, ReceiverResultReg); - } -} - - /* StackToRegisterMappingCogit>>#compileCogMethod: */ -static CogMethod * NoDbgRegParms -compileCogMethod(sqInt selector) -{ - sqInt allocBytes; - int extra; - sqInt fixupBytes; - sqInt numBlocks; - sqInt numBytecodes; - sqInt numberOfAbstractOpcodes; - sqInt numCleanBlocks; - sqInt opcodeBytes; - sqInt result; - - methodOrBlockNumTemps = tempCountOf(methodObj); - setHasMovableLiteral(0); - setHasYoungReferent((isYoungObject(methodObj)) - || (isYoung(selector))); - methodOrBlockNumArgs = argumentCountOf(methodObj); - inBlock = 0; - maxLitIndex = -1; - extra = ((((primitiveIndex = primitiveIndexOf(methodObj))) > 0) - && (!(isQuickPrimitiveIndex(primitiveIndex))) - ? 30 - : 10); - - /* initial estimate. Actual endPC is determined in scanMethod. */ - initialPC = startPCOfMethod(methodObj); - endPC = (isQuickPrimitiveIndex(primitiveIndex) - ? initialPC - 1 - : numBytesOf(methodObj)); - numBytecodes = (endPC - initialPC) + 1; - /* begin allocateOpcodes:bytecodes:ifFail: */ - numberOfAbstractOpcodes = (numBytecodes + extra) * 10 /* estimateOfAbstractOpcodesPerBytecodes */; - numAbstractOpcodes = numberOfAbstractOpcodes; - opcodeBytes = (sizeof(CogAbstractInstruction)) * numAbstractOpcodes; - fixupBytes = (sizeof(CogBytecodeFixup)) * numAbstractOpcodes; - - /* Document the fact that the MaxStackAllocSize ensures that the number of abstract - opcodes fits in a 16 bit integer (e.g. CogBytecodeFixup's instructionIndex). */ - allocBytes = opcodeBytes + fixupBytes; - assert((((sizeof(CogAbstractInstruction)) + (sizeof(CogBytecodeFixup))) * 0xC000) > MaxStackAllocSize); - if (allocBytes > MaxStackAllocSize) { - return ((CogMethod *) MethodTooBig); - goto l1; - } - abstractOpcodes = alloca(allocBytes); - bzero(abstractOpcodes, allocBytes); - fixups = ((void *)((((usqInt)abstractOpcodes)) + opcodeBytes)); - zeroOpcodeIndexForNewOpcodes(); - labelCounter = 0; - l1: /* end allocateOpcodes:bytecodes:ifFail: */; - if (((numBlocks = scanMethod())) < 0) { - return ((CogMethod *) numBlocks); - } - numCleanBlocks = scanForCleanBlocks(); - if (methodFoundInvalidPostScan()) { - return ((CogMethod *) ShouldNotJIT); - } - allocateBlockStarts(numBlocks + numCleanBlocks); - blockCount = 0; - if (numCleanBlocks > 0) { - addCleanBlockStarts(); - } - if (!(maybeAllocAndInitIRCs())) { - - /* Inaccurate error code, but it'll do. This will likely never fail. */ - return ((CogMethod *) InsufficientCodeSpace); - } - blockEntryLabel = null; - (methodLabel->dependent = null); - if (((result = compileEntireMethod())) < 0) { - return ((CogMethod *) result); - } - return generateCogMethod(selector); -} - - -/* Compile the abstract instructions for the entire method, including blocks. */ -/* Compile the abstract instructions for the entire method, including blocks. */ - - /* StackToRegisterMappingCogit>>#compileEntireMethod */ -static sqInt -compileEntireMethod(void) -{ - sqInt result; - - regArgsHaveBeenPushed = 0; - /* begin preenMethodLabel */ - (((((AbstractInstruction *) methodLabel))->operands))[1] = 0; - compileAbort(); - compileEntry(); - if (((result = compilePrimitive())) < 0) { - return result; - } - compileFrameBuild(); - if (((result = compileMethodBody())) < 0) { - return result; - } - if (blockCount == 0) { - return 0; - } - if (((result = compileBlockBodies())) < 0) { - return result; - } - return compileBlockDispatch(); -} - - -/* Build a frame for a CogMethod activation. See CoInterpreter - class>>initializeFrameIndices. receiver (in ReceiverResultReg) - arg0 - ... - argN - caller's saved ip/this stackPage (for a base frame) - fp-> saved fp - method - context (uninitialized?) - receiver - first temp - ... - sp-> Nth temp - If there is a primitive and an error code the Nth temp is the error code. - Ensure SendNumArgsReg is set early on (incidentally to nilObj) because - it is the flag determining whether context switch is allowed on - stack-overflow. */ -/* Build a frame for a CogMethod activation. See CoInterpreter - class>>initializeFrameIndices. Override to push the register receiver and - register arguments, if any. */ - - /* StackToRegisterMappingCogit>>#compileFrameBuild */ -static void -compileFrameBuild(void) -{ - AbstractInstruction *anInstruction; - sqInt constant; - sqInt i; - sqInt iLimiT; - - -# if IMMUTABILITY - if (useTwoPaths) { - compileTwoPathFrameBuild(); - return; - } -# endif - if (!needsFrame) { - if (useTwoPaths) { - compileTwoPathFramelessInit(); - } - initSimStackForFramelessMethod(initialPC); - return; - } - assert(!(useTwoPaths)); - genPushRegisterArgs(); - if (!needsFrame) { - return; - } - /* begin PushR: */ - genoperand(PushR, LinkReg); - /* begin PushR: */ - genoperand(PushR, FPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SPReg, FPReg); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperand(PushCw, ((sqInt)methodLabel))))); - /* begin genMoveNilR: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, SendNumArgsReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, constant, SendNumArgsReg); - } - /* begin PushR: */ - genoperand(PushR, SendNumArgsReg); - /* begin PushR: */ - genoperand(PushR, ReceiverResultReg); - for (i = (methodOrBlockNumArgs + 1), iLimiT = (temporaryCountOfMethodHeader(methodHeader)); i <= iLimiT; i += 1) { - /* begin PushR: */ - genoperand(PushR, SendNumArgsReg); - } - if (((primitiveIndexOfMethodheader(methodObj, methodHeader)) > 0) - && ((longStoreBytecodeForHeader(methodHeader)) == (fetchByteofObject((startPCOfMethod(methodObj)) + (sizeOfCallPrimitiveBytecode(methodHeader)), methodObj)))) { - compileGetErrorCode(); - } - stackCheckLabel = compileStackOverflowCheck(canContextSwitchIfActivatingheader(methodObj, methodHeader)); - initSimStackForFramefulMethod(initialPC); -} - - -/* Build a frame for a CogMethod activation. See CoInterpreter - class>>initializeFrameIndices. receiver (in ReceiverResultReg) - arg0 - ... - argN - caller's saved ip/this stackPage (for a base frame) - fp-> saved fp - method - context (uninitialized?) - receiver - first temp - ... - sp-> Nth temp - If there is a primitive and an error code the Nth temp is the error code. - Ensure SendNumArgsReg is set early on (incidentally to nilObj) because - it is the flag determining whether context switch is allowed on - stack-overflow. */ -/* We are in a method where the frame is needed *only* for instance variable - store, typically a setter method. - This case has 20% overhead with Immutability compared to setter without - immutability because of the stack - frame creation. We compile two path, one where the object is immutable, - one where it isn't. At the beginning - of the frame build, we take one path or the other depending on the - receiver mutability. - - Note: this specific case happens only where there are only instance - variabel stores. We could do something - similar for literal variable stores, but we don't as it's too uncommon. - */ - - /* StackToRegisterMappingCogit>>#compileTwoPathFrameBuild */ -#if IMMUTABILITY -static void -compileTwoPathFrameBuild(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt constant; - sqInt i; - sqInt iLimiT; - sqInt jumpImmutable; - AbstractInstruction * jumpOld; - - assert(useTwoPaths); - assert(blockCount == 0); - jumpImmutable = genJumpImmutablescratchReg(ReceiverResultReg, TempReg); - - /* first path. The receiver is mutable */ - - /* N.B. FLAGS := destReg - scratchReg */ - /* begin checkLiteral:forInstruction: */ - youngStartAddress(); - anInstruction = genoperandoperand(MoveAwR, youngStartAddress(), TempReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, ReceiverResultReg); - /* begin JumpBelow: */ - jumpOld = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - assert(!needsFrame); - initSimStackForFramelessMethod(initialPC); - /* begin compileMethodBody */ - if (endPC < initialPC) { - goto l3; - } - compileAbstractInstructionsFromthrough(initialPC + (deltaToSkipPrimAndErrorStoreInheader(methodObj, methodHeader)), endPC); - l3: /* end compileMethodBody */; - - /* reset because it impacts inst var store compilation */ - useTwoPaths = 0; - needsFrame = 1; - jmpTarget(jumpOld, jmpTarget(jumpImmutable, genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - genPushRegisterArgs(); - if (!needsFrame) { - return; - } - /* begin PushR: */ - genoperand(PushR, LinkReg); - /* begin PushR: */ - genoperand(PushR, FPReg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SPReg, FPReg); - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperand(PushCw, ((sqInt)methodLabel))))); - /* begin genMoveNilR: */ - constant = nilObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, SendNumArgsReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, constant, SendNumArgsReg); - } - /* begin PushR: */ - genoperand(PushR, SendNumArgsReg); - /* begin PushR: */ - genoperand(PushR, ReceiverResultReg); - for (i = (methodOrBlockNumArgs + 1), iLimiT = (temporaryCountOfMethodHeader(methodHeader)); i <= iLimiT; i += 1) { - /* begin PushR: */ - genoperand(PushR, SendNumArgsReg); - } - if (((primitiveIndexOfMethodheader(methodObj, methodHeader)) > 0) - && ((longStoreBytecodeForHeader(methodHeader)) == (fetchByteofObject((startPCOfMethod(methodObj)) + (sizeOfCallPrimitiveBytecode(methodHeader)), methodObj)))) { - compileGetErrorCode(); - } - stackCheckLabel = compileStackOverflowCheck(canContextSwitchIfActivatingheader(methodObj, methodHeader)); - initSimStackForFramefulMethod(initialPC); -} -#endif /* IMMUTABILITY */ - - -/* We are in a frameless method with at least two inst var stores. We compile - two paths, - one where the object is in new space, and one where it isn't. At the - beginning - of the method, we take one path or the other depending on the receiver - being in newSpace. - */ - - /* StackToRegisterMappingCogit>>#compileTwoPathFramelessInit */ -static void -compileTwoPathFramelessInit(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction * jumpOld; - - assert(!(IMMUTABILITY)); - assert(!(needsFrame)); - assert(useTwoPaths); - - /* first path. The receiver is young */ - - /* N.B. FLAGS := destReg - scratchReg */ - /* begin checkLiteral:forInstruction: */ - youngStartAddress(); - anInstruction = genoperandoperand(MoveAwR, youngStartAddress(), TempReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, ReceiverResultReg); - /* begin JumpBelow: */ - jumpOld = genConditionalBranchoperand(JumpBelow, ((sqInt)0)); - initSimStackForFramelessMethod(initialPC); - /* begin compileMethodBody */ - if (endPC < initialPC) { - goto l1; - } - compileAbstractInstructionsFromthrough(initialPC + (deltaToSkipPrimAndErrorStoreInheader(methodObj, methodHeader)), endPC); - l1: /* end compileMethodBody */; - - /* reset because it impacts inst var store compilation */ - useTwoPaths = 0; - jmpTarget(jumpOld, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); -} - - /* StackToRegisterMappingCogit>>#cPICMissTrampolineFor: */ -static sqInt NoDbgRegParms -cPICMissTrampolineFor(sqInt numArgs) -{ - return picMissTrampolines[((numArgs < (2)) ? numArgs : (2))]; -} - - -/* Replaces the Blue Book double-extended send [132], in which the first byte - was wasted on 8 bits of argument count. - Here we use 3 bits for the operation sub-type (opType), and the remaining - 5 bits for argument count where needed. - The last byte give access to 256 instVars or literals. - See also secondExtendedSendBytecode - */ - - /* StackToRegisterMappingCogit>>#doubleExtendedDoAnythingBytecode */ -static sqInt -doubleExtendedDoAnythingBytecode(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *abstractInstruction2; - sqInt opType; - - opType = ((usqInt)(byte1)) >> 5; - if (opType == 0) { - return genSendnumArgs(byte2, byte1 & 0x1F); - } - if (opType == 1) { - return genSendSupernumArgs(byte2, byte1 & 0x1F); - } - switch (opType) { - case 2: - if (isReadMediatedContextInstVarIndex(byte2)) { - genPushMaybeContextReceiverVariable(byte2); - } - else { - genPushReceiverVariable(byte2); - /* begin annotateInstructionForBytecode */ - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (abstractInstruction->annotation = HasBytecodePC); - return 0; - } - break; - case 3: - genPushLiteralIndex(byte2); - /* begin annotateInstructionForBytecode */ - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction1 = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction1 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (abstractInstruction1->annotation = HasBytecodePC); - return 0; - - case 4: - genPushLiteralVariable(byte2); - break; - case 7: - genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(0, byte2, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); -# if IMMUTABILITY - - /* genStorePop:LiteralVariable: annotates; don't annotate twice */ - return 0; -# endif - break; - default: - - /* 5 & 6 */ - if (isWriteMediatedContextInstVarIndex(byte2)) { - genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(opType == 6, byte2, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } - else { - genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(opType == 6, byte2, ((((ssTop())->type)) != SSConstant) - || ((isNonImmediate(((ssTop())->constant))) - && (shouldAnnotateObjectReference(((ssTop())->constant)))), 1); - } -# if IMMUTABILITY - - /* genStorePop:...ReceiverVariable: annotate; don't annotate twice */ - return 0; -# endif -; - } - assert(needsFrame); - assert(!(prevInstIsPCAnnotated())); - /* begin annotateBytecode: */ - abstractInstruction2 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction2->annotation = HasBytecodePC); - return 0; -} - - /* StackToRegisterMappingCogit>>#duplicateTopBytecode */ -static sqInt -duplicateTopBytecode(void) -{ - SimStackEntry desc; - - /* begin ssTopDescriptor */ - desc = simStack[simStackPtr]; - return ssPushDesc(desc); -} - - -/* Make sure there's a flagged fixup at the target pc in fixups. - Initially a fixup's target is just a flag. Later on it is replaced with a - proper instruction. */ - - /* StackToRegisterMappingCogit>>#ensureFixupAt: */ -static BytecodeFixup * NoDbgRegParms -ensureFixupAt(sqInt targetPC) -{ - BytecodeFixup *fixup; - - /* begin fixupAt: */ - fixup = fixupAtIndex(targetPC - initialPC); - traceFixupmerge(fixup, 1); - if ((((usqInt)((fixup->targetInstruction)))) <= NeedsNonMergeFixupFlag) { - - /* convert a non-merge into a merge */ - /* begin becomeMergeFixup */ - (fixup->targetInstruction) = ((AbstractInstruction *) NeedsMergeFixupFlag); - (fixup->simStackPtr = simStackPtr); - } - else { - if ((fixup->isTargetOfBackwardBranch)) { - - /* this is the target of a backward branch and - so doesn't have a simStackPtr assigned yet. */ - (fixup->simStackPtr = simStackPtr); - } - else { - assert(((fixup->simStackPtr)) == simStackPtr); - } - } - /* begin recordBcpc: */ - return fixup; -} - - -/* Make sure there's a flagged fixup at the target pc in fixups. - Initially a fixup's target is just a flag. Later on it is replaced with a - proper instruction. */ - - /* StackToRegisterMappingCogit>>#ensureNonMergeFixupAt: */ -static BytecodeFixup * NoDbgRegParms -ensureNonMergeFixupAt(sqInt targetPC) -{ - BytecodeFixup *fixup; - - /* begin fixupAt: */ - fixup = fixupAtIndex(targetPC - initialPC); - traceFixupmerge(fixup, 1); - if (((fixup->targetInstruction)) == 0) { - /* begin becomeNonMergeFixup */ - (fixup->targetInstruction) = ((AbstractInstruction *) NeedsNonMergeFixupFlag); - } - /* begin recordBcpc: */ - return fixup; -} - - /* StackToRegisterMappingCogit>>#ensureReceiverResultRegContainsSelf */ -static void -ensureReceiverResultRegContainsSelf(void) -{ - if (needsFrame) { - if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); - /* begin putSelfInReceiverResultReg */ - storeToReg(simSelf(), ReceiverResultReg); - ((simSelf())->liveRegister = ReceiverResultReg); - } - } - else { - assert(((((simSelf())->type)) == SSRegister) - && (((((simSelf())->registerr)) == ReceiverResultReg) - && (receiverIsInReceiverResultReg()))); - } -} - - /* StackToRegisterMappingCogit>>#evaluate:at: */ -static void NoDbgRegParms -evaluateat(BytecodeDescriptor *descriptor, sqInt pc) -{ - byte0 = fetchByteofObject(pc, methodObj); - assert(descriptor == (generatorAt(bytecodeSetOffset + byte0))); - loadSubsequentBytesForDescriptorat(descriptor, pc); - ((descriptor->generator))(); -} - - -/* Attempt to follow a branch to a pc. Handle branches to unconditional jumps - and branches to push: aBoolean; conditional branch pairs. If the branch - cannot be - followed answer targetBytecodePC. It is not possible to follow jumps to - conditional branches because the stack changes depth. That following is - left to the genJumpIf:to: - clients. */ - - /* StackToRegisterMappingCogit>>#eventualTargetOf: */ -static sqInt NoDbgRegParms -eventualTargetOf(sqInt targetBytecodePC) -{ - sqInt cond; - sqInt currentTarget; - BytecodeDescriptor *descriptor; - sqInt nExts; - sqInt nextPC; - sqInt span; - - cond = 0; - nextPC = (currentTarget = targetBytecodePC); - while (1) { - nExts = 0; - while (1) { - /* begin generatorForPC: */ - descriptor = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC, methodObj))); - if ((descriptor->isReturn)) { - return currentTarget; - } - if (!((descriptor->isExtension))) break; - nExts += 1; - nextPC += (descriptor->numBytes); - } - if ((isBranch(descriptor)) - && (!(((descriptor->isBranchTrue)) - || ((descriptor->isBranchFalse))))) { - /* begin spanFor:at:exts:in: */ - span = ((descriptor->spanFunction))(descriptor, nextPC, nExts, methodObj); - if (span < 0) { - - /* Do *not* follow backward branches; these are interrupt points and should not be elided. */ - return currentTarget; - } - nextPC = (nextPC + ((descriptor->numBytes))) + span; - } - else { - if (((descriptor->generator)) == genPushConstantTrueBytecode) { - cond = 1; - } - else { - if (((descriptor->generator)) == genPushConstantFalseBytecode) { - cond = 0; - } - else { - return currentTarget; - } - } - if (((fixupAt(nextPC))->isTargetOfBackwardBranch)) { - return currentTarget; - } - nextPC = eventualTargetOf(nextPC + ((descriptor->numBytes))); - nExts = 0; - while (1) { - /* begin generatorForPC: */ - descriptor = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC, methodObj))); - if ((descriptor->isReturn)) { - return currentTarget; - } - if (!((descriptor->isExtension))) break; - nExts += 1; - nextPC += (descriptor->numBytes); - } - if (!(isBranch(descriptor))) { - return currentTarget; - } - if ((isBranch(descriptor)) - && (!(((descriptor->isBranchTrue)) - || ((descriptor->isBranchFalse))))) { - return currentTarget; - } - nextPC = (cond == ((descriptor->isBranchTrue)) - ? (nextPC + ((descriptor->numBytes))) + (((descriptor->spanFunction))(descriptor, nextPC, nExts, methodObj)) - : nextPC + ((descriptor->numBytes))); - } - currentTarget = nextPC; - } - return 0; -} - - -/* Spill the closest register on stack not conflicting with regMask. - Assertion Failure if regMask has already all the registers */ - - /* StackToRegisterMappingCogit>>#freeAnyRegNotConflictingWith: */ -static sqInt NoDbgRegParms -freeAnyRegNotConflictingWith(sqInt regMask) -{ - CogSimStackEntry *desc; - sqInt index; - sqInt reg; - - assert(needsFrame); - reg = NoReg; - index = ((simSpillBase < 0) ? 0 : simSpillBase); - while ((reg == NoReg) - && (index < simStackPtr)) { - desc = simStackAt(index); - if (((desc->type)) == SSRegister) { - if (!(((regMask & (1U << ((desc->registerr)))) != 0))) { - reg = (desc->registerr); - } - } - index += 1; - } - assert(!((reg == NoReg))); - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << reg, simStackPtr, simNativeStackPtr); - return reg; -} - - -/* Return from block, assuming result already loaded into ReceiverResultReg. */ -/* Return from block, assuming result already loaded into ReceiverResultReg. */ - - /* StackToRegisterMappingCogit>>#genBlockReturn */ -static sqInt -genBlockReturn(void) -{ - if (needsFrame) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, FPReg, SPReg); - /* begin PopR: */ - genoperand(PopR, FPReg); - /* begin PopR: */ - genoperand(PopR, LinkReg); - } - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - - /* can't fall through */ - deadCode = 1; - return 0; -} - - -/* Generate special versions of the ceCallCogCodePopReceiverAndClassRegs - enilopmart that also pop register args from the stack to undo the pushing - of register args in the abort/miss trampolines. */ - - /* StackToRegisterMappingCogit>>#genCallPICEnilopmartNumArgs: */ -static void (*genCallPICEnilopmartNumArgs(sqInt numArgs))(void) - -{ - AbstractInstruction *anInstruction; - sqInt endAddress; - usqInt enilopmart; - sqInt quickConstant; - sqInt reg; - sqInt size; - - zeroOpcodeIndex(); - /* begin MoveCq:R: */ - quickConstant = varBaseAddress(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - genLoadStackPointers(backEnd); - /* begin PopR: */ - genoperand(PopR, ClassReg); - /* begin PopR: */ - genoperand(PopR, TempReg); - /* begin PopR: */ - reg = LinkReg; - genoperand(PopR, reg); - if (numArgs > 0) { - if (numArgs > 1) { - /* begin PopR: */ - genoperand(PopR, Arg1Reg); - assert((numRegArgs()) == 2); - } - /* begin PopR: */ - genoperand(PopR, Arg0Reg); - } - /* begin PopR: */ - genoperand(PopR, ReceiverResultReg); - /* begin JumpR: */ - genoperand(JumpR, TempReg); - computeMaximumSizes(); - size = generateInstructionsAt(methodZoneBase); - endAddress = outputInstructionsAt(methodZoneBase); - assert((methodZoneBase + size) == endAddress); - enilopmart = methodZoneBase; - methodZoneBase = alignUptoRoutineBoundary(endAddress); - stopsFromto(backEnd, endAddress, methodZoneBase - 1); - recordGeneratedRunTimeaddress(trampolineNamenumRegArgs("ceCallPIC", numArgs), enilopmart); - return ((void (*)(void)) enilopmart); -} - - -/* Override to push the register receiver and register arguments, if any. */ - - /* StackToRegisterMappingCogit>>#genExternalizePointersForPrimitiveCall */ -static sqInt -genExternalizePointersForPrimitiveCall(void) -{ - AbstractInstruction *anInstruction; - - genPushRegisterArgs(); - /* begin checkLiteral:forInstruction: */ - instructionPointerAddress(); - anInstruction = genoperandoperand(MoveRAw, LinkReg, instructionPointerAddress()); - return genSaveStackPointers(backEnd); -} - - -/* Enilopmarts transfer control from C into machine code (backwards - trampolines). - */ -/* Enilopmarts transfer control from C into machine code (backwards - trampolines). Override to add version for generic and PIC-specific entry - with reg args. */ - - /* StackToRegisterMappingCogit>>#generateEnilopmarts */ -static void -generateEnilopmarts(void) -{ - -# if Debug - /* begin genEnilopmartFor:forCall:called: */ - realCEEnterCogCodePopReceiverReg = genEnilopmartForandandforCallcalled(ReceiverResultReg, NoReg, NoReg, 0, "realCEEnterCogCodePopReceiverReg"); - ceEnterCogCodePopReceiverReg = enterCogCodePopReceiver; - /* begin genEnilopmartFor:forCall:called: */ - realCECallCogCodePopReceiverReg = genEnilopmartForandandforCallcalled(ReceiverResultReg, NoReg, NoReg, 1, "realCECallCogCodePopReceiverReg"); - ceCallCogCodePopReceiverReg = callCogCodePopReceiver; - /* begin genEnilopmartFor:and:forCall:called: */ - realCECallCogCodePopReceiverAndClassRegs = genEnilopmartForandandforCallcalled(ReceiverResultReg, ClassReg, NoReg, 1, "realCECallCogCodePopReceiverAndClassRegs"); - ceCallCogCodePopReceiverAndClassRegs = callCogCodePopReceiverAndClassRegs; -# else // Debug - /* begin genEnilopmartFor:forCall:called: */ - ceEnterCogCodePopReceiverReg = genEnilopmartForandandforCallcalled(ReceiverResultReg, NoReg, NoReg, 0, "ceEnterCogCodePopReceiverReg"); - /* begin genEnilopmartFor:forCall:called: */ - ceCallCogCodePopReceiverReg = genEnilopmartForandandforCallcalled(ReceiverResultReg, NoReg, NoReg, 1, "ceCallCogCodePopReceiverReg"); - /* begin genEnilopmartFor:and:forCall:called: */ - ceCallCogCodePopReceiverAndClassRegs = genEnilopmartForandandforCallcalled(ReceiverResultReg, ClassReg, NoReg, 1, "ceCallCogCodePopReceiverAndClassRegs"); -# endif // Debug - genPrimReturnEnterCogCodeEnilopmart(0); - cePrimReturnEnterCogCode = methodZoneBase; - outputInstructionsForGeneratedRuntimeAt(cePrimReturnEnterCogCode); - recordGeneratedRunTimeaddress("cePrimReturnEnterCogCode", cePrimReturnEnterCogCode); - genPrimReturnEnterCogCodeEnilopmart(1); - cePrimReturnEnterCogCodeProfiling = methodZoneBase; - outputInstructionsForGeneratedRuntimeAt(cePrimReturnEnterCogCodeProfiling); - recordGeneratedRunTimeaddress("cePrimReturnEnterCogCodeProfiling", cePrimReturnEnterCogCodeProfiling); -# if Debug - /* begin genEnilopmartFor:and:forCall:called: */ - realCECallCogCodePopReceiverArg0Regs = genEnilopmartForandandforCallcalled(ReceiverResultReg, Arg0Reg, NoReg, 1, "realCECallCogCodePopReceiverArg0Regs"); - ceCallCogCodePopReceiverArg0Regs = callCogCodePopReceiverArg0Regs; - realCECallCogCodePopReceiverArg1Arg0Regs = genEnilopmartForandandforCallcalled(ReceiverResultReg, Arg0Reg, Arg1Reg, 1, "realCECallCogCodePopReceiverArg1Arg0Regs"); - ceCallCogCodePopReceiverArg1Arg0Regs = callCogCodePopReceiverArg1Arg0Regs; -# else // Debug - /* begin genEnilopmartFor:and:forCall:called: */ - ceCallCogCodePopReceiverArg0Regs = genEnilopmartForandandforCallcalled(ReceiverResultReg, Arg0Reg, NoReg, 1, "ceCallCogCodePopReceiverArg0Regs"); - ceCallCogCodePopReceiverArg1Arg0Regs = genEnilopmartForandandforCallcalled(ReceiverResultReg, Arg0Reg, Arg1Reg, 1, "ceCallCogCodePopReceiverArg1Arg0Regs"); -# endif // Debug - ceCall0ArgsPIC = genCallPICEnilopmartNumArgs(0); - ceCall1ArgsPIC = genCallPICEnilopmartNumArgs(1); - -} - - -/* Size pc-dependent instructions and assign eventual addresses to all - instructions. Answer the size of the code. - Compute forward branches based on virtual address (abstract code starts at - 0), assuming that any branches branched over are long. - Compute backward branches based on actual address. - Reuse the fixups array to record the pc-dependent instructions that need - to have - their code generation postponed until after the others. - - Override to add handling for null branches (branches to the immediately - following instruction) occasioned by StackToRegisterMapping's following of - jumps. */ - - /* StackToRegisterMappingCogit>>#generateInstructionsAt: */ -static sqInt NoDbgRegParms -generateInstructionsAt(sqInt eventualAbsoluteAddress) -{ - sqInt absoluteAddress; - AbstractInstruction *abstractInstruction; - BytecodeFixup *fixup; - sqInt i; - sqInt j; - sqInt pcDependentIndex; - - absoluteAddress = eventualAbsoluteAddress; - pcDependentIndex = 0; - for (i = 0; i < opcodeIndex; i += 1) { - - /* N.B. if you want to break in resizing, break here, note the instruction index, back up to the - sender, restart, and step into computeMaximumSizes, breaking at this instruction's index. */ - abstractInstruction = abstractInstructionAt(i); - maybeBreakGeneratingFromto(absoluteAddress, absoluteAddress + ((abstractInstruction->maxSize))); - if (isPCDependent(abstractInstruction)) { - sizePCDependentInstructionAt(abstractInstruction, absoluteAddress); - if ((isJump(abstractInstruction)) - && ((((i + 1) < opcodeIndex) - && ((((AbstractInstruction *) (((abstractInstruction->operands))[0]))) == (abstractInstructionAt(i + 1)))) - || (((i + 2) < opcodeIndex) - && (((((AbstractInstruction *) (((abstractInstruction->operands))[0]))) == (abstractInstructionAt(i + 2))) - && ((((abstractInstructionAt(i + 1))->opcode)) == Nop))))) { - (abstractInstruction->opcode = Nop); - concretizeAt(abstractInstruction, absoluteAddress); - } - else { - fixup = fixupAtIndex(pcDependentIndex); - pcDependentIndex += 1; - (fixup->instructionIndex = i); - } - absoluteAddress += (abstractInstruction->machineCodeSize); - } - else { - - /* N.B. if you want to break in resizing, break here, note the instruction index, back up to the - sender, restart, and step into computeMaximumSizes, breaking at this instruction's index. */ - absoluteAddress = concretizeAt(abstractInstruction, absoluteAddress); - assert(((abstractInstruction->machineCodeSize)) == ((abstractInstruction->maxSize))); - } - } - for (j = 0; j < pcDependentIndex; j += 1) { - fixup = fixupAtIndex(j); - abstractInstruction = abstractInstructionAt((fixup->instructionIndex)); - maybeBreakGeneratingFromto((abstractInstruction->address), (((abstractInstruction->address)) + ((abstractInstruction->maxSize))) - 1); - concretizeAt(abstractInstruction, (abstractInstruction->address)); - } - return absoluteAddress - eventualAbsoluteAddress; -} - - -/* Generate the run-time entries for the various method and PIC entry misses - and aborts. - Read the class-side method trampolines for documentation on the various - trampolines - */ - - /* StackToRegisterMappingCogit>>#generateMissAbortTrampolines */ -static void -generateMissAbortTrampolines(void) -{ - sqInt numArgs; - sqInt numArgsLimiT; - - for (numArgs = 0, numArgsLimiT = (2); numArgs <= numArgsLimiT; numArgs += 1) { - methodAbortTrampolines[numArgs] = (genMethodAbortTrampolineFor(numArgs)); - } - for (numArgs = 0, numArgsLimiT = (2); numArgs <= numArgsLimiT; numArgs += 1) { - picAbortTrampolines[numArgs] = (genPICAbortTrampolineFor(numArgs)); - } - for (numArgs = 0, numArgsLimiT = (2); numArgs <= numArgsLimiT; numArgs += 1) { - picMissTrampolines[numArgs] = (genPICMissTrampolineFor(numArgs)); - } - /* begin genTrampolineFor:called:arg: */ - ceReapAndResetErrorCodeTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceReapAndResetErrorCodeFor, "ceReapAndResetErrorCodeTrampoline", 1, ClassReg, null, null, null, 0 /* emptyRegisterMask */, 1, NoReg, 0); -} - - -/* Override to generate code to push the register arg(s) for <= numRegArg - arity sends. - */ - - /* StackToRegisterMappingCogit>>#generateSendTrampolines */ -static void -generateSendTrampolines(void) -{ - sqInt numArgs; - - for (numArgs = 0; numArgs < NumSendTrampolines; numArgs += 1) { - ordinarySendTrampolines[numArgs] = (genSendTrampolineFornumArgscalledargargargarg(ceSendsupertonumArgs, numArgs, trampolineNamenumArgs("ceSend", numArgs), ClassReg, trampolineArgConstant(0), ReceiverResultReg, (numArgs <= (NumSendTrampolines - 2) - ? (/* begin trampolineArgConstant: */ - assert(numArgs >= 0), - -2 - numArgs) - : SendNumArgsReg))); - } - for (numArgs = 0; numArgs < NumSendTrampolines; numArgs += 1) { - superSendTrampolines[numArgs] = (genSendTrampolineFornumArgscalledargargargarg(ceSendsupertonumArgs, numArgs, trampolineNamenumArgs("ceSuperSend", numArgs), ClassReg, trampolineArgConstant(1), ReceiverResultReg, (numArgs <= (NumSendTrampolines - 2) - ? (/* begin trampolineArgConstant: */ - assert(numArgs >= 0), - -2 - numArgs) - : SendNumArgsReg))); - } - firstSend = ordinarySendTrampolines[0]; - lastSend = superSendTrampolines[NumSendTrampolines - 1]; -} - - -/* Generate trampolines for tracing. In the simulator we can save a lot of - time and avoid noise instructions in the lastNInstructions log by - short-cutting these - trampolines, but we need them in the real vm. */ - - /* StackToRegisterMappingCogit>>#generateTracingTrampolines */ -static void -generateTracingTrampolines(void) -{ - /* begin genTrampolineFor:called:arg:regsToSave: */ - ceTraceLinkedSendTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceTraceLinkedSend, "ceTraceLinkedSendTrampoline", 1, ReceiverResultReg, null, null, null, CallerSavedRegisterMask, 1, NoReg, 0); - /* begin genTrampolineFor:called:regsToSave: */ - ceTraceBlockActivationTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceTraceBlockActivation, "ceTraceBlockActivationTrampoline", 0, null, null, null, null, CallerSavedRegisterMask, 1, NoReg, 0); - /* begin genTrampolineFor:called:arg:arg:regsToSave: */ - ceTraceStoreTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceTraceStoreOfinto, "ceTraceStoreTrampoline", 2, TempReg, ReceiverResultReg, null, null, CallerSavedRegisterMask, 1, NoReg, 0); -} - - -/* Generates the machine code for #== in the case where the instruction is - not followed by a branch - */ - - /* StackToRegisterMappingCogit>>#genIdenticalNoBranchArgIsConstant:rcvrIsConstant:argReg:rcvrReg:orNotIf: */ -static sqInt NoDbgRegParms -genIdenticalNoBranchArgIsConstantrcvrIsConstantargRegrcvrRegorNotIf(sqInt argIsConstant, sqInt rcvrIsConstant, sqInt argReg, sqInt rcvrRegOrNone, sqInt orNot) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - sqInt constant; - sqInt constant1; - sqInt constant11; - sqInt constant2; - sqInt constant3; - sqInt constant4; - AbstractInstruction *jumpEqual; - AbstractInstruction *jumpNotEqual; - AbstractInstruction *label; - sqInt resultReg; - - /* begin Label */ - label = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - /* begin genCmpArgIsConstant:rcvrIsConstant:argReg:rcvrReg: */ - assert((argReg != NoReg) - || (rcvrRegOrNone != NoReg)); - if (argIsConstant) { - /* begin genCmpConstant:R: */ - constant4 = ((ssTop())->constant); - if (shouldAnnotateObjectReference(constant4)) { - annotateobjRef(checkLiteralforInstruction(constant4, genoperandoperand(CmpCwR, constant4, rcvrRegOrNone)), constant4); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, constant4, rcvrRegOrNone); - } - } - else { - if (rcvrIsConstant) { - /* begin genCmpConstant:R: */ - constant11 = ((ssValue(1))->constant); - if (shouldAnnotateObjectReference(constant11)) { - annotateobjRef(checkLiteralforInstruction(constant11, genoperandoperand(CmpCwR, constant11, argReg)), constant11); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, constant11, argReg); - } - } - else { - /* begin CmpR:R: */ - assert(!((argReg == SPReg))); - genoperandoperand(CmpRR, argReg, rcvrRegOrNone); - } - } - ssPop(2); - resultReg = (rcvrRegOrNone == NoReg - ? argReg - : rcvrRegOrNone); - /* begin JumpZero: */ - jumpEqual = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - if (!argIsConstant) { - /* begin genEnsureOopInRegNotForwarded:scratchReg:jumpBackTo: */ - } - if (!rcvrIsConstant) { - /* begin genEnsureOopInRegNotForwarded:scratchReg:jumpBackTo: */ - } - if (orNot) { - /* begin genMoveTrueR: */ - constant = trueObject(); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(MoveCwR, constant, resultReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, constant, resultReg); - } - } - else { - /* begin genMoveFalseR: */ - constant1 = falseObject(); - if (shouldAnnotateObjectReference(constant1)) { - annotateobjRef(checkLiteralforInstruction(constant1, genoperandoperand(MoveCwR, constant1, resultReg)), constant1); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(MoveCqR, constant1, resultReg); - } - } - /* begin Jump: */ - jumpNotEqual = genoperand(Jump, ((sqInt)0)); - jmpTarget(jumpEqual, (orNot - ? (/* begin genMoveFalseR: */ - (constant2 = falseObject()), - (shouldAnnotateObjectReference(constant2) - ? annotateobjRef(checkLiteralforInstruction(constant2, genoperandoperand(MoveCwR, constant2, resultReg)), constant2) - : (/* begin checkQuickConstant:forInstruction: */ - (anInstruction4 = genoperandoperand(MoveCqR, constant2, resultReg)), - anInstruction4))) - : (/* begin genMoveTrueR: */ - (constant3 = trueObject()), - (shouldAnnotateObjectReference(constant3) - ? annotateobjRef(checkLiteralforInstruction(constant3, genoperandoperand(MoveCwR, constant3, resultReg)), constant3) - : (/* begin checkQuickConstant:forInstruction: */ - (anInstruction5 = genoperandoperand(MoveCqR, constant3, resultReg)), - anInstruction5))))); - jmpTarget(jumpNotEqual, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - ssPushRegister(resultReg); - return 0; -} - - -/* Decompose code generation for #== into a common constant-folding version, - followed by a double dispatch through the objectRepresentation to a - version that doesn't deal with forwarders and a version that does. */ - - /* StackToRegisterMappingCogit>>#genInlinedIdenticalOrNotIf: */ -static sqInt NoDbgRegParms -genInlinedIdenticalOrNotIf(sqInt orNot) -{ - BytecodeDescriptor *primDescriptor; - sqInt result; - - primDescriptor = generatorAt(byte0); - if ((isUnannotatableConstant(ssTop())) - && (isUnannotatableConstant(ssValue(1)))) { - assert(!((primDescriptor->isMapped))); - result = ((orNot - ? (((ssTop())->constant)) != (((ssValue(1))->constant)) - : (((ssTop())->constant)) == (((ssValue(1))->constant))) - ? trueObject() - : falseObject()); - ssPop(2); - return ssPushConstant(result); - } - /* begin genInlinedIdenticalOrNotIfGuts: */ - return genVanillaInlinedIdenticalOrNotIf(orNot); -} - - /* StackToRegisterMappingCogit>>#genJumpBackTo: */ -static sqInt NoDbgRegParms -genJumpBackTo(sqInt targetBytecodePC) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *anInstruction; - sqInt i; - void *jumpTarget; - void *jumpTarget1; - - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - - /* can't fall through */ - deadCode = 1; - /* begin checkLiteral:forInstruction: */ - stackLimitAddress(); - anInstruction = genoperandoperand(MoveAwR, stackLimitAddress(), TempReg); - /* begin CmpR:R: */ - assert(!((TempReg == SPReg))); - genoperandoperand(CmpRR, TempReg, SPReg); - /* begin JumpAboveOrEqual: */ - jumpTarget = fixupAtIndex(targetBytecodePC - initialPC); - genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)jumpTarget)); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceCheckForInterruptTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin annotateBytecode: */ - abstractInstruction1 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction1->annotation = HasBytecodePC); - /* begin Jump: */ - jumpTarget1 = fixupAtIndex(targetBytecodePC - initialPC); - genoperand(Jump, ((sqInt)jumpTarget1)); - return 0; -} - - /* StackToRegisterMappingCogit>>#genJumpIf:to: */ -static sqInt NoDbgRegParms -genJumpIfto(sqInt boolean, sqInt targetBytecodePC) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - CogSimStackEntry *desc; - sqInt eventualTarget; - BytecodeFixup *fixup; - sqInt i; - void *jumpTarget; - AbstractInstruction *ok; - sqInt quickConstant; - - eventualTarget = eventualTargetOf(targetBytecodePC); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 1)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 1)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 1))); i < simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 1) + 1; - } - desc = ssTop(); - ssPop(1); - if ((((desc->type)) == SSConstant) - && ((((desc->constant)) == (trueObject())) - || (((desc->constant)) == (falseObject())))) { - - /* Must arrange there's a fixup at the target whether it is jumped to or - not so that the simStackPtr can be kept correct. */ - - /* Must annotate the bytecode for correct pc mapping. */ - fixup = ensureFixupAt(eventualTarget); - /* begin annotateBytecode: */ - if (((desc->constant)) == boolean) { - /* begin Jump: */ - abstractInstruction = genoperand(Jump, ((sqInt)fixup)); - } - else { - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - } - (abstractInstruction->annotation = HasBytecodePC); - extA = 0; - return 0; - } - popToReg(desc, TempReg); - assert((objectAfter(falseObject())) == (trueObject())); - /* begin genSubConstant:R: */ - if (shouldAnnotateObjectReference(boolean)) { - annotateobjRef(checkLiteralforInstruction(boolean, genoperandoperand(SubCwR, boolean, TempReg)), TempReg); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, boolean, TempReg); - } - /* begin JumpZero: */ - jumpTarget = ensureFixupAt(eventualTarget); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget)); - if (((extA & 1) != 0)) { - extA = 0; - /* begin annotateBytecode: */ - abstractInstruction1 = lastOpcode(); - (abstractInstruction1->annotation = HasBytecodePC); - return 0; - } - extA = 0; - /* begin CmpCq:R: */ - quickConstant = (boolean == (falseObject()) - ? (trueObject()) - (falseObject()) - : (falseObject()) - (trueObject())); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, quickConstant, TempReg); - /* begin JumpZero: */ - ok = genConditionalBranchoperand(JumpZero, ((sqInt)0)); - genCallMustBeBooleanFor(boolean); - jmpTarget(ok, annotateBytecode(genoperandoperand(Label, (labelCounter += 1), bytecodePC))); - return 0; -} - - /* StackToRegisterMappingCogit>>#genJumpTo: */ -static sqInt NoDbgRegParms -genJumpTo(sqInt targetBytecodePC) -{ - sqInt eventualTarget; - BytecodeFixup * fixup; - BytecodeDescriptor * generator; - sqInt i; - sqInt i1; - - eventualTarget = eventualTargetOf(targetBytecodePC); - if ((eventualTarget > bytecodePC) - && (((simStackPtr >= methodOrBlockNumArgs) - && (stackEntryIsBoolean(ssTop()))) - && ((((generator = generatorForPC(eventualTarget))->isBranchTrue)) - || (((generator = generatorForPC(eventualTarget))->isBranchFalse))))) { - eventualTarget = (eventualTarget + ((generator->numBytes))) + ((((generator->isBranchTrue)) == ((((ssTop())->constant)) == (trueObject())) - ? (/* begin spanFor:at:exts:in: */ - ((generator->spanFunction))(generator, eventualTarget, 0, methodObj)) - : 0)); - ssPop(1); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - fixup = ensureFixupAt(eventualTarget); - ssPop(-1); - } - else { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i1 <= simStackPtr; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - fixup = ensureFixupAt(eventualTarget); - } - - /* can't fall through */ - deadCode = 1; - /* begin Jump: */ - genoperand(Jump, ((sqInt)fixup)); - return 0; -} - - /* StackToRegisterMappingCogit>>#genMarshalledSend:numArgs:sendTable: */ -static sqInt NoDbgRegParms -genMarshalledSendnumArgssendTable(sqInt selectorIndex, sqInt numArgs, sqInt *sendTable) -{ - AbstractInstruction *anInstruction; - sqInt annotation; - - assert(needsFrame); - /* begin annotationForSendTable: */ - if (sendTable == ordinarySendTrampolines) { - annotation = IsSendCall; - goto l3; - } - assert(sendTable == superSendTrampolines); - annotation = IsSuperSend; - l3: /* end annotationForSendTable: */; - if ((annotation == IsSuperSend) - || (0)) { - /* begin genEnsureOopInRegNotForwarded:scratchReg: */ - } - if (numArgs >= (NumSendTrampolines - 1)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, numArgs, SendNumArgsReg); - } - genLoadInlineCacheWithSelector(selectorIndex); - ((genoperand(Call, sendTable[((numArgs < (NumSendTrampolines - 1)) ? numArgs : (NumSendTrampolines - 1))]))->annotation = annotation); - /* begin voidReceiverOptStatus */ - ((simSelf())->liveRegister = NoReg); - return ssPushRegister(ReceiverResultReg); -} - - -/* Generate the abort for a method. This abort performs either a call of - ceSICMiss: to handle a single-in-line cache miss or a call of - ceStackOverflow: to handle a - stack overflow. It distinguishes the two by testing ResultReceiverReg. If - the register is zero then this is a stack-overflow because a) the receiver - has already - been pushed and so can be set to zero before calling the abort, and b) the - receiver must always contain an object (and hence be non-zero) on SIC - miss. */ - - /* StackToRegisterMappingCogit>>#genMethodAbortTrampolineFor: */ -static usqInt NoDbgRegParms -genMethodAbortTrampolineFor(sqInt numArgs) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *jumpSICMiss; - - zeroOpcodeIndex(); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, ReceiverResultReg); - /* begin JumpNonZero: */ - jumpSICMiss = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveR:Mw:r: */ - anInstruction = genoperandoperandoperand(MoveRMwr, LinkReg, 0, SPReg); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(ceStackOverflow, 1, SendNumArgsReg, null, null, null, 0 /* emptyRegisterMask */, 0, NoReg); - jmpTarget(jumpSICMiss, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genPushRegisterArgsForAbortMissNumArgs(backEnd, numArgs); - return genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceSICMiss, trampolineNamenumRegArgs("ceMethodAbort", numArgs), 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 0, NoReg, 1); -} - - -/* Generate the abort for a PIC. This abort performs either a call of - ceInterpretMethodFromPIC:receiver: to handle invoking an uncogged - target or a call of ceMNUFromPICMNUMethod:receiver: to handle an - MNU dispatch in a closed PIC. It distinguishes the two by testing - ClassReg. If the register is zero then this is an MNU. */ - - /* StackToRegisterMappingCogit>>#genPICAbortTrampolineFor: */ -static usqInt NoDbgRegParms -genPICAbortTrampolineFor(sqInt numArgs) -{ - zeroOpcodeIndex(); - genPushRegisterArgsForAbortMissNumArgs(backEnd, numArgs); - return genInnerPICAbortTrampoline(trampolineNamenumRegArgs("cePICAbort", numArgs)); -} - - /* StackToRegisterMappingCogit>>#genPICMissTrampolineFor: */ -static usqInt NoDbgRegParms -genPICMissTrampolineFor(sqInt numArgs) -{ - usqInt startAddress; - - startAddress = methodZoneBase; - zeroOpcodeIndex(); - genPushRegisterArgsForNumArgsscratchReg(backEnd, numArgs, SendNumArgsReg); - genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(ceCPICMissreceiver, trampolineNamenumRegArgs("cePICMiss", numArgs), 2, ClassReg, ReceiverResultReg, null, null, 0 /* emptyRegisterMask */, 1, NoReg, 1); - return startAddress; -} - - /* StackToRegisterMappingCogit>>#genPopStackBytecode */ -static sqInt -genPopStackBytecode(void) -{ - AbstractInstruction *anInstruction; - - if (((ssTop())->spilled)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, BytesPerWord, SPReg); - } - ssPop(1); - return 0; -} - - -/* Check the argument count. Fail if wrong. - Get the method from the outerContext and see if it is cogged. If so, jump - to the - block entry or the no-context-switch entry, as appropriate, and we're - done. If not, - invoke the interpreter primitive. */ -/* Check the argument count. Fail if wrong. - Get the method from the outerContext and see if it is cogged. If so, jump - to the - block entry or the no-context-switch entry, as appropriate, and we're - done. If not, - invoke the interpreter primitive. - Override to push the register args first. */ - - /* StackToRegisterMappingCogit>>#genPrimitiveClosureValue */ -static sqInt -genPrimitiveClosureValue(void) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *jumpBCMethod; - AbstractInstruction *jumpFail1; - AbstractInstruction *jumpFail2; - AbstractInstruction *jumpFail3; - AbstractInstruction *jumpFail4; - AbstractInstruction *jumpFailNArgs; - sqInt offset1; - void (*primitiveRoutine)(void); - sqInt quickConstant; - sqInt quickConstant1; - sqInt result; - - genPushRegisterArgs(); - genLoadSlotsourceRegdestReg(ClosureNumArgsIndex, ReceiverResultReg, TempReg); - /* begin checkQuickConstant:forInstruction: */ - (((usqInt)methodOrBlockNumArgs << 1) | 1); - anInstruction1 = genoperandoperand(CmpCqR, (((usqInt)methodOrBlockNumArgs << 1) | 1), TempReg); - /* begin JumpNonZero: */ - jumpFailNArgs = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(ClosureOuterContextIndex, ReceiverResultReg, ClassReg); - jumpFail1 = genJumpImmediate(ClassReg); - genGetCompactClassIndexNonImmOfinto(ClassReg, TempReg); - genCmpClassMethodContextCompactIndexR(TempReg); - /* begin JumpNonZero: */ - jumpFail2 = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - genLoadSlotsourceRegdestReg(MethodIndex, ClassReg, SendNumArgsReg); - jumpFail3 = genJumpImmediate(SendNumArgsReg); - /* begin genGetFormatOf:into: */ - anInstruction2 = genoperandoperandoperand(MoveMwrR, 0, SendNumArgsReg, TempReg); - /* begin LogicalShiftRightCq:R: */ - quickConstant = instFormatFieldLSB(); - genoperandoperand(LogicalShiftRightCqR, quickConstant, TempReg); - /* begin AndCq:R: */ - quickConstant1 = (1U << (instFormatFieldWidth())) - 1; - /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperand(AndCqR, quickConstant1, TempReg); - /* begin checkQuickConstant:forInstruction: */ - firstCompiledMethodFormat(); - anInstruction3 = genoperandoperand(CmpCqR, firstCompiledMethodFormat(), TempReg); - /* begin JumpLess: */ - jumpFail4 = genConditionalBranchoperand(JumpLess, ((sqInt)0)); - genLoadSlotsourceRegdestReg(HeaderIndex, SendNumArgsReg, ClassReg); - jumpBCMethod = genJumpImmediate(ClassReg); - /* begin MoveM16:r:R: */ - offset1 = offsetof(CogMethod, blockEntryOffset); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperandoperand(MoveM16rR, offset1, ClassReg, TempReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, ClassReg, TempReg); - primitiveRoutine = functionPointerForCompiledMethodprimitiveIndexprimitivePropertyFlagsInto(methodObj, primitiveIndex, null); - if (primitiveRoutine == primitiveClosureValueNoContextSwitch) { - if (blockNoContextSwitchOffset == null) { - return NotFullyInitialized; - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(SubCqR, blockNoContextSwitchOffset, TempReg); - } - /* begin JumpR: */ - genoperand(JumpR, TempReg); - jmpTarget(jumpBCMethod, jmpTarget(jumpFail1, jmpTarget(jumpFail2, jmpTarget(jumpFail3, jmpTarget(jumpFail4, genoperandoperand(Label, (labelCounter += 1), bytecodePC)))))); - if (((result = compileInterpreterPrimitiveflags(primitiveRoutine, primitivePropertyFlags(primitiveIndex)))) < 0) { - return result; - } - jmpTarget(jumpFailNArgs, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return CompletePrimitive; -} - - -/* Generate an in-line perform primitive. The lookup code requires the - selector to be in Arg0Reg. - adjustArgumentsForPerform: adjusts the arguments once - genLookupForPerformNumArgs: has generated the code for the lookup. */ - - /* StackToRegisterMappingCogit>>#genPrimitivePerform */ -static sqInt -genPrimitivePerform(void) -{ - AbstractInstruction *anInstruction; - sqInt offset; - - if (methodOrBlockNumArgs > 1 /* numRegArgs */) { - /* begin MoveMw:r:R: */ - offset = (methodOrBlockNumArgs - 1) * BytesPerWord; - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, SPReg, Arg0Reg); - } - return genLookupForPerformNumArgs(methodOrBlockNumArgs); -} - - /* StackToRegisterMappingCogit>>#genPushActiveContextBytecode */ -static sqInt -genPushActiveContextBytecode(void) -{ - assert(needsFrame); - voidReceiverResultRegContainsSelf(); - /* begin ssAllocateCallReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); - genGetActiveContextNumArgslargeinBlock(methodOrBlockNumArgs, methodNeedsLargeContext(methodObj), inBlock); - return ssPushRegister(ReceiverResultReg); -} - - -/* Block compilation. At this point in the method create the block. Note its - start and defer generating code for it until after the method and any - other preceding - blocks. The block's actual code will be compiled later. */ -/* 143 10001111 llllkkkk jjjjjjjj iiiiiiii Push Closure Num Copied llll Num - Args kkkk BlockSize jjjjjjjjiiiiiiii */ - - /* StackToRegisterMappingCogit>>#genPushClosureCopyCopiedValuesBytecode */ -static sqInt -genPushClosureCopyCopiedValuesBytecode(void) -{ - sqInt i1; - sqInt numArgs; - sqInt numCopied; - sqInt startpc; - - assert(needsFrame); - startpc = bytecodePC + (((generatorAt(byte0))->numBytes)); - addBlockStartAtnumArgsnumCopiedspan(startpc, (numArgs = byte1 & 15), (numCopied = ((usqInt)(byte1)) >> 4), (((sqInt)((usqInt)(byte2) << 8))) + byte3); - /* begin genOutlineClosure:numArgs:numCopied: */ - if (numCopied > 0) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i1 <= simStackPtr; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - } - voidReceiverResultRegContainsSelf(); - /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); - genCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(startpc + 1, numArgs, numCopied, methodOrBlockNumArgs, methodNeedsLargeContext(methodObj), inBlock); - if (numCopied > 0) { - ssPop(numCopied); - } - ssPushRegister(ReceiverResultReg); - return 0; -} - - -/* */ -/* Override to avoid the BytecodeSetHasDirectedSuperSend check, which is - unnecessary here given the simulation stack. */ - - /* StackToRegisterMappingCogit>>#genPushLiteralIndex: */ -static sqInt NoDbgRegParms -genPushLiteralIndex(sqInt literalIndex) -{ - sqInt literal; - - literal = getLiteral(literalIndex); - return genPushLiteral(literal); -} - - /* StackToRegisterMappingCogit>>#genPushLiteralVariable: */ -static sqInt NoDbgRegParms -genPushLiteralVariable(sqInt literalIndex) -{ - AbstractInstruction *anInstruction; - sqInt association; - sqInt freeReg; - - - /* If followed by a directed super send bytecode, avoid generating any code yet. - The association will be passed to the directed send trampoline in a register - and fully dereferenced only when first linked. It will be ignored in later sends. */ - association = getLiteral(literalIndex); - - /* N.B. Do _not_ use ReceiverResultReg to avoid overwriting receiver in assignment in frameless methods. */ - /* So far descriptors are not rich enough to describe the entire dereference so generate the register - load but don't push the result. There is an order-of-evaluation issue if we defer the dereference. */ - freeReg = allocateRegNotConflictingWith(0); - /* begin genMoveConstant:R: */ - if (shouldAnnotateObjectReference(association)) { - annotateobjRef(checkLiteralforInstruction(association, genoperandoperand(MoveCwR, association, TempReg)), association); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, association, TempReg); - } - genLoadSlotsourceRegdestReg(ValueIndex, TempReg, freeReg); - ssPushRegister(freeReg); - return 0; -} - - /* StackToRegisterMappingCogit>>#genPushLiteral: */ -static sqInt NoDbgRegParms -genPushLiteral(sqInt literal) -{ - return ssPushConstant(literal); -} - - /* StackToRegisterMappingCogit>>#genPushMaybeContextReceiverVariable: */ -static sqInt NoDbgRegParms -genPushMaybeContextReceiverVariable(sqInt slotIndex) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *jmpDone; - AbstractInstruction *jmpSingle; - - /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); - ensureReceiverResultRegContainsSelf(); - /* begin genPushMaybeContextSlotIndex: */ - assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { - - /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ - voidReceiverResultRegContainsSelf(); - } - if (slotIndex == InstructionPointerIndex) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, slotIndex, SendNumArgsReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceFetchContextInstVarTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - return ssPushRegister(SendNumArgsReg); - } - genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); - jmpSingle = genJumpNotSmallIntegerInScratchReg(TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, slotIndex, SendNumArgsReg); - /* begin CallRT: */ - abstractInstruction1 = genoperand(Call, ceFetchContextInstVarTrampoline); - (abstractInstruction1->annotation = IsRelativeCall); - /* begin Jump: */ - jmpDone = genoperand(Jump, ((sqInt)0)); - jmpTarget(jmpSingle, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - genLoadSlotsourceRegdestReg(slotIndex, ReceiverResultReg, SendNumArgsReg); - jmpTarget(jmpDone, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return ssPushRegister(SendNumArgsReg); -} - - /* StackToRegisterMappingCogit>>#genPushNewArrayBytecode */ -static sqInt -genPushNewArrayBytecode(void) -{ - sqInt i; - sqInt i1; - int popValues; - sqInt size; - - assert(needsFrame); - voidReceiverResultRegContainsSelf(); - if ((popValues = byte1 > 0x7F)) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i1 <= simStackPtr; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - } - else { - /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); - } - size = byte1 & 0x7F; - if (!popValues) { - if (tryCollapseTempVectorInitializationOfSize(size)) { - return 0; - } - } - genNewArrayOfSizeinitialized(size, !popValues); - if (popValues) { - for (i = (size - 1); i >= 0; i += -1) { - /* begin PopR: */ - genoperand(PopR, TempReg); - genStoreSourceRegslotIndexintoNewObjectInDestReg(TempReg, i, ReceiverResultReg); - } - ssPop(size); - } - return ssPushRegister(ReceiverResultReg); -} - - /* StackToRegisterMappingCogit>>#genPushReceiverBytecode */ -static sqInt -genPushReceiverBytecode(void) -{ - if ((((simSelf())->liveRegister)) == ReceiverResultReg) { - return ssPushRegister(ReceiverResultReg); - } - return ssPushDesc(ssSelfDescriptor()); -} - - /* StackToRegisterMappingCogit>>#genPushReceiverVariable: */ -static sqInt NoDbgRegParms -genPushReceiverVariable(sqInt index) -{ - ensureReceiverResultRegContainsSelf(); - return ssPushBaseoffset(ReceiverResultReg, slotOffsetOfInstVarIndex(index)); -} - - -/* Ensure that the register args are pushed before the retpc for methods with - arity <= self numRegArgs. - */ -/* This isn't as clumsy on a RISC. But putting the receiver and - args above the return address means the CoInterpreter has a - single machine-code frame format which saves us a lot of work. */ - - /* StackToRegisterMappingCogit>>#genPushRegisterArgs */ -static void -genPushRegisterArgs(void) -{ - if (!(regArgsHaveBeenPushed - || (methodOrBlockNumArgs > 1 /* numRegArgs */))) { - genPushRegisterArgsForNumArgsscratchReg(backEnd, methodOrBlockNumArgs, SendNumArgsReg); - regArgsHaveBeenPushed = 1; - } -} - - /* StackToRegisterMappingCogit>>#genPushRemoteTempLongBytecode */ -static sqInt -genPushRemoteTempLongBytecode(void) -{ - AbstractInstruction *anInstruction; - sqInt offset; - sqInt regMask; - sqInt remoteTempReg; - sqInt tempVectReg; - - tempVectReg = allocateRegNotConflictingWith(0); - /* begin MoveMw:r:R: */ - offset = frameOffsetOfTemporary(byte2); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, FPReg, tempVectReg); - /* begin availableRegOrNoneNotConflictingWith: */ - regMask = 1U << tempVectReg; - remoteTempReg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); - if (remoteTempReg == NoReg) { - remoteTempReg = tempVectReg; - } - genLoadSlotsourceRegdestReg(byte1, tempVectReg, remoteTempReg); - return ssPushRegister(remoteTempReg); -} - - -/* If a frameless method (not a block), only argument temps can be accessed. - This is assured by the use of needsFrameIfMod16GENumArgs: in pushTemp. */ - - /* StackToRegisterMappingCogit>>#genPushTemporaryVariable: */ -static sqInt NoDbgRegParms -genPushTemporaryVariable(sqInt index) -{ - assert((inBlock > 0) - || (needsFrame - || (index < methodOrBlockNumArgs))); - return ssPushDesc(simStack[index + 1]); -} - - -/* In a frameless method ReceiverResultReg already contains self. - In a frameful method, ReceiverResultReg /may/ contain self. */ - - /* StackToRegisterMappingCogit>>#genReturnReceiver */ -static sqInt -genReturnReceiver(void) -{ - if (needsFrame) { - if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { - /* begin putSelfInReceiverResultReg */ - storeToReg(simSelf(), ReceiverResultReg); - } - } - return genUpArrowReturn(); -} - - /* StackToRegisterMappingCogit>>#genReturnTopFromBlock */ -static sqInt -genReturnTopFromBlock(void) -{ - assert(inBlock > 0); - popToReg(ssTop(), ReceiverResultReg); - ssPop(1); - return genBlockReturn(); -} - - /* StackToRegisterMappingCogit>>#genReturnTopFromMethod */ -static sqInt -genReturnTopFromMethod(void) -{ - popToReg(ssTop(), ReceiverResultReg); - ssPop(1); - return genUpArrowReturn(); -} - - /* StackToRegisterMappingCogit>>#genSendSuper:numArgs: */ -static sqInt NoDbgRegParms -genSendSupernumArgs(sqInt selectorIndex, sqInt numArgs) -{ - marshallSendArguments(numArgs); - return genMarshalledSendnumArgssendTable(selectorIndex, numArgs, superSendTrampolines); -} - - -/* Generate a trampoline with four arguments. - Hack: a negative value indicates an abstract register, a non-negative - value indicates a constant. */ - - /* StackToRegisterMappingCogit>>#genSendTrampolineFor:numArgs:called:arg:arg:arg:arg: */ -static usqInt NoDbgRegParms -genSendTrampolineFornumArgscalledargargargarg(void *aRoutine, sqInt numArgs, char *aString, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3) -{ - sqInt routine; - usqInt startAddress; - - startAddress = methodZoneBase; - zeroOpcodeIndex(); - genPushRegisterArgsForNumArgsscratchReg(backEnd, numArgs, SendNumArgsReg); - /* begin selectorIndexDereferenceRoutine */ - routine = null; - if (!(routine == null)) { - - /* Explicitly save LinkReg via ExtraReg2; it's presumably faster than pushing/popping */ - /* begin MoveR:R: */ - genoperandoperand(MoveRR, LinkReg, Extra2Reg); - /* begin Call: */ - genoperand(Call, routine); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, Extra2Reg, LinkReg); - } - genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(aRoutine, aString, 4, regOrConst0, regOrConst1, regOrConst2, regOrConst3, 0 /* emptyRegisterMask */, 1, NoReg, 1); - return startAddress; -} - - /* StackToRegisterMappingCogit>>#genSend:numArgs: */ -static sqInt NoDbgRegParms -genSendnumArgs(sqInt selectorIndex, sqInt numArgs) -{ - marshallSendArguments(numArgs); - return genMarshalledSendnumArgssendTable(selectorIndex, numArgs, ordinarySendTrampolines); -} - - /* StackToRegisterMappingCogit>>#genSpecialSelectorArithmetic */ -static sqInt -genSpecialSelectorArithmetic(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - sqInt argInt; - int argIsConst; - sqInt argIsInt; - sqInt i; - sqInt index; - AbstractInstruction *jumpContinue; - AbstractInstruction *jumpNotSmallInts; - BytecodeDescriptor *primDescriptor; - sqInt rcvrInt; - int rcvrIsConst; - sqInt rcvrIsInt; - sqInt result; - - primDescriptor = generatorAt(byte0); - argIsInt = ((argIsConst = (((ssTop())->type)) == SSConstant)) - && ((((argInt = ((ssTop())->constant))) & 1)); - rcvrIsInt = (((rcvrIsConst = (((ssValue(1))->type)) == SSConstant)) - && ((((rcvrInt = ((ssValue(1))->constant))) & 1))) - || ((mclassIsSmallInteger()) - && (isSameEntryAs(ssValue(1), simSelf()))); - if (argIsInt - && (rcvrIsInt - && (rcvrIsConst))) { - rcvrInt = (rcvrInt >> 1); - argInt = (argInt >> 1); - switch ((primDescriptor->opcode)) { - case AddRR: - result = rcvrInt + argInt; - break; - case SubRR: - result = rcvrInt - argInt; - break; - case AndRR: - result = rcvrInt & argInt; - break; - case OrRR: - result = rcvrInt | argInt; - break; - default: - error("Case not found and no otherwise clause"); - } - if (isIntegerValue(result)) { - - /* Must annotate the bytecode for correct pc mapping. */ - return (ssPop(2), - ssPushAnnotatedConstant((((usqInt)result << 1) | 1))); - } - return genSpecialSelectorSend(); - } - if ((rcvrIsConst - && (!rcvrIsInt)) - || (argIsConst - && (!argIsInt))) { - return genSpecialSelectorSend(); - } - if (!(argIsInt - || (rcvrIsInt))) { - return genSpecialSelectorSend(); - } - if (argIsInt) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 2)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 2)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 2))); i <= (simStackPtr - 2); i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 2) + 1; - } - popToReg(ssValue(1), ReceiverResultReg); - ssPop(2); - } - else { - marshallSendArguments(1); - } - jumpNotSmallInts = (!(rcvrIsInt - && (argIsInt)) - ? (argIsInt - ? genJumpNotSmallInteger(ReceiverResultReg) - : (rcvrIsInt - ? genJumpNotSmallInteger(Arg0Reg) - : (/* begin genJumpNotSmallIntegersIn:and:scratch: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg), - /* begin AndR:R: */ - genoperandoperand(AndRR, Arg0Reg, TempReg), - genJumpNotSmallIntegerInScratchReg(TempReg)))) - : 0); - switch ((primDescriptor->opcode)) { - case AddRR: - if (argIsInt) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(AddCqR, argInt - ConstZero, ReceiverResultReg); - /* begin JumpNoOverflow: */ - jumpContinue = genConditionalBranchoperand(JumpNoOverflow, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(SubCqR, argInt - ConstZero, ReceiverResultReg); - } - else { - genRemoveSmallIntegerTagsInScratchReg(ReceiverResultReg); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - /* begin JumpNoOverflow: */ - jumpContinue = genConditionalBranchoperand(JumpNoOverflow, ((sqInt)0)); - if (rcvrIsInt - && (rcvrIsConst)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(MoveCqR, rcvrInt, ReceiverResultReg); - } - else { - /* begin SubR:R: */ - genoperandoperand(SubRR, Arg0Reg, ReceiverResultReg); - genSetSmallIntegerTagsIn(ReceiverResultReg); - } - } - break; - case SubRR: - if (argIsInt) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(SubCqR, argInt - ConstZero, ReceiverResultReg); - /* begin JumpNoOverflow: */ - jumpContinue = genConditionalBranchoperand(JumpNoOverflow, ((sqInt)0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(AddCqR, argInt - ConstZero, ReceiverResultReg); - } - else { - genRemoveSmallIntegerTagsInScratchReg(Arg0Reg); - /* begin SubR:R: */ - genoperandoperand(SubRR, Arg0Reg, ReceiverResultReg); - /* begin JumpNoOverflow: */ - jumpContinue = genConditionalBranchoperand(JumpNoOverflow, ((sqInt)0)); - /* begin AddR:R: */ - genoperandoperand(AddRR, Arg0Reg, ReceiverResultReg); - genSetSmallIntegerTagsIn(Arg0Reg); - } - break; - case AndRR: - if (argIsInt) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperand(AndCqR, argInt, ReceiverResultReg); - } - else { - /* begin AndR:R: */ - genoperandoperand(AndRR, Arg0Reg, ReceiverResultReg); - } - jumpContinue = (!(jumpNotSmallInts == null) - ? (/* begin Jump: */ - genoperand(Jump, ((sqInt)0))) - : 0); - break; - case OrRR: - if (argIsInt) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(OrCqR, argInt, ReceiverResultReg); - } - else { - /* begin OrR:R: */ - genoperandoperand(OrRR, Arg0Reg, ReceiverResultReg); - } - jumpContinue = (!(jumpNotSmallInts == null) - ? (/* begin Jump: */ - genoperand(Jump, ((sqInt)0))) - : 0); - break; - default: - error("Case not found and no otherwise clause"); - } - if (jumpNotSmallInts == null) { - if (!jumpContinue) { - - /* overflow cannot happen */ - /* begin annotateInstructionForBytecode */ - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (abstractInstruction->annotation = HasBytecodePC); - ssPushRegister(ReceiverResultReg); - return 0; - } - } - else { - jmpTarget(jumpNotSmallInts, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } - if (argIsInt) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperand(MoveCqR, argInt, Arg0Reg); - } - index = byte0 - ( -#if MULTIPLEBYTECODESETS - (bytecodeSetOffset == 0x100 - ? AltFirstSpecialSelector + 0x100 - : FirstSpecialSelector) -#else - FirstSpecialSelector -#endif - ); - genMarshalledSendnumArgssendTable((-index) - 1, 1, ordinarySendTrampolines); - jmpTarget(jumpContinue, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - return 0; -} - - /* StackToRegisterMappingCogit>>#genSpecialSelectorClass */ -static sqInt -genSpecialSelectorClass(void) -{ - sqInt requiredReg1; - sqInt topReg; - - topReg = registerOrNone(ssTop()); - ssPop(1); - if ((topReg == NoReg) - || (topReg == ClassReg)) { - /* begin ssAllocateRequiredReg:and: */ - requiredReg1 = (topReg = SendNumArgsReg); - ssAllocateRequiredRegMaskupThroughupThroughNative((1U << requiredReg1) | (1U << ClassReg), simStackPtr, simNativeStackPtr); - } - else { - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr, simNativeStackPtr); - } - ssPush(1); - popToReg(ssTop(), topReg); - genGetClassObjectOfintoscratchRegmayBeAForwarder(topReg, ClassReg, TempReg, mayBeAForwarder(ssTop())); - return (ssPop(1), - ssPushRegister(ClassReg)); -} - - /* StackToRegisterMappingCogit>>#genSpecialSelectorComparison */ -static sqInt -genSpecialSelectorComparison(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - sqInt argInt; - sqInt argIsIntConst; - BytecodeDescriptor *branchDescriptor; - BytecodeDescriptor *branchDescriptor1; - sqInt i; - sqInt index; - sqInt inlineCAB; - AbstractInstruction *jumpNotSmallInts; - void *jumpTarget; - sqInt nExts; - sqInt nextPC; - sqInt nextPC1; - sqInt postBranchPC; - sqInt postBranchPC1; - BytecodeDescriptor *primDescriptor; - BytecodeDescriptor *primDescriptor1; - int rcvrIsConst; - sqInt rcvrIsInt; - sqInt targetBytecodePC; - sqInt targetPC; - - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 2)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 2)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 2))); i <= (simStackPtr - 2); i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 2) + 1; - } - primDescriptor = generatorAt(byte0); - argIsIntConst = ((((ssTop())->type)) == SSConstant) - && ((((argInt = ((ssTop())->constant))) & 1)); - rcvrIsInt = (((rcvrIsConst = (((ssValue(1))->type)) == SSConstant)) - && (((((ssValue(1))->constant)) & 1))) - || ((mclassIsSmallInteger()) - && (isSameEntryAs(ssValue(1), simSelf()))); - if (argIsIntConst - && (rcvrIsInt - && (rcvrIsConst))) { - return genStaticallyResolvedSpecialSelectorComparison(); - } - /* begin extractMaybeBranchDescriptorInto: */ - primDescriptor1 = generatorAt(byte0); - nextPC1 = bytecodePC + ((primDescriptor1->numBytes)); - nExts = 0; - while (1) { - while (1) { - /* begin generatorForPC: */ - branchDescriptor1 = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC1, methodObj))); - if (!((branchDescriptor1->isExtension))) break; - nExts += 1; - nextPC1 += (branchDescriptor1->numBytes); - } - /* begin isUnconditionalBranch */ - if (!((isBranch(branchDescriptor1)) - && (!(((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse)))))) break; - nextPC1 = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - } - targetBytecodePC = (postBranchPC1 = 0); - if (((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse))) { - targetBytecodePC = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - postBranchPC1 = eventualTargetOf(nextPC1 + ((branchDescriptor1->numBytes))); - } - else { - nextPC1 = bytecodePC + ((primDescriptor1->numBytes)); - } - branchDescriptor = branchDescriptor1; - nextPC = nextPC1; - postBranchPC = postBranchPC1; - targetPC = targetBytecodePC; - - /* Further, only interested in inlining = and ~= if there's a SmallInteger constant involved. - The relational operators successfully statically predict SmallIntegers; the equality operators do not. */ - inlineCAB = ((branchDescriptor->isBranchTrue)) - || ((branchDescriptor->isBranchFalse)); - if (inlineCAB - && ((((primDescriptor->opcode)) == JumpZero) - || (((primDescriptor->opcode)) == JumpNonZero))) { - inlineCAB = argIsIntConst - || (rcvrIsInt); - } - if (!inlineCAB) { - return genSpecialSelectorSend(); - } - if (argIsIntConst) { - popToReg(ssValue(1), ReceiverResultReg); - ssPop(2); - } - else { - marshallSendArguments(1); - } - jumpNotSmallInts = (!(rcvrIsInt - && (argIsIntConst)) - ? (argIsIntConst - ? genJumpNotSmallInteger(ReceiverResultReg) - : (rcvrIsInt - ? genJumpNotSmallInteger(Arg0Reg) - : (/* begin genJumpNotSmallIntegersIn:and:scratch: */ - genoperandoperand(MoveRR, ReceiverResultReg, TempReg), - /* begin AndR:R: */ - genoperandoperand(AndRR, Arg0Reg, TempReg), - genJumpNotSmallIntegerInScratchReg(TempReg)))) - : 0); - if (argIsIntConst) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, argInt, ReceiverResultReg); - } - else { - /* begin CmpR:R: */ - assert(!((Arg0Reg == SPReg))); - genoperandoperand(CmpRR, Arg0Reg, ReceiverResultReg); - } - genConditionalBranchoperand(((branchDescriptor->isBranchTrue) - ? (primDescriptor->opcode) - : inverseBranchFor((primDescriptor->opcode))), ((usqInt)(ensureNonMergeFixupAt(targetPC)))); - /* begin Jump: */ - jumpTarget = ensureNonMergeFixupAt(postBranchPC); - genoperand(Jump, ((sqInt)jumpTarget)); - if (!jumpNotSmallInts) { - /* begin annotateInstructionForBytecode */ - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (abstractInstruction->annotation = HasBytecodePC); - ensureFixupAt(postBranchPC); - ensureFixupAt(targetPC); - deadCode = 1; - return 0; - } - jmpTarget(jumpNotSmallInts, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - if (argIsIntConst) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, argInt, Arg0Reg); - } - index = byte0 - ( -#if MULTIPLEBYTECODESETS - (bytecodeSetOffset == 0x100 - ? AltFirstSpecialSelector + 0x100 - : FirstSpecialSelector) -#else - FirstSpecialSelector -#endif - ); - return genMarshalledSendnumArgssendTable((-index) - 1, 1, ordinarySendTrampolines); -} - - -/* Assumes both operands are ints */ - - /* StackToRegisterMappingCogit>>#genStaticallyResolvedSpecialSelectorComparison */ -static sqInt -genStaticallyResolvedSpecialSelectorComparison(void) -{ - sqInt argInt; - BytecodeDescriptor *primDescriptor; - sqInt rcvrInt; - int result; - - primDescriptor = generatorAt(byte0); - argInt = ((ssTop())->constant); - rcvrInt = ((ssValue(1))->constant); - switch ((primDescriptor->opcode)) { - case JumpLess: - result = rcvrInt < argInt; - break; - case JumpLessOrEqual: - result = rcvrInt <= argInt; - break; - case JumpGreater: - result = rcvrInt > argInt; - break; - case JumpGreaterOrEqual: - result = rcvrInt >= argInt; - break; - case JumpZero: - result = rcvrInt == argInt; - break; - case JumpNonZero: - result = rcvrInt != argInt; - break; - default: - error("Case not found and no otherwise clause"); - } - ssPop(2); - return ssPushAnnotatedConstant((result - ? trueObject() - : falseObject())); -} - - -/* We need a frame because the association has to be in ReceiverResultReg for - the various trampolines - and ReceiverResultReg holds only the receiver in frameless methods. - */ - - /* StackToRegisterMappingCogit>>#genStorePop:LiteralVariable:needsStoreCheck:needsImmutabilityCheck: */ -static sqInt NoDbgRegParms -genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt litVarIndex, sqInt needsStoreCheck, sqInt needsImmCheck) -{ - AbstractInstruction *anInstruction; - sqInt association; - sqInt i; - sqInt topReg; - - assert(needsFrame); - /* begin genLoadLiteralVariable:in: */ - association = getLiteral(litVarIndex); - voidReceiverResultRegContainsSelf(); - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); - /* begin genMoveConstant:R: */ - if (shouldAnnotateObjectReference(association)) { - annotateobjRef(checkLiteralforInstruction(association, genoperandoperand(MoveCwR, association, ReceiverResultReg)), association); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, association, ReceiverResultReg); - } - /* begin genGenericStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr:needsImmutabilityCheck: */ -# if IMMUTABILITY - if (needsImmCheck) { - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); - ssStoreAndReplacePoptoReg(popBoolean, ClassReg); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0); - } -# endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); - ssStorePoptoReg(popBoolean, topReg); - return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); -} - - -/* The reason we need a frame here is that assigning to an inst var of a - context may - involve wholesale reorganization of stack pages, and the only way to - preserve the - execution state of an activation in that case is if it has a frame. */ - - /* StackToRegisterMappingCogit>>#genStorePop:MaybeContextReceiverVariable:needsStoreCheck:needsImmutabilityCheck: */ -static sqInt NoDbgRegParms -genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt slotIndex, sqInt needsStoreCheck, sqInt needsImmCheck) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *anInstruction; - sqInt i; - AbstractInstruction *immutabilityFailure; - AbstractInstruction *mutableJump; - - immutabilityFailure = ((AbstractInstruction *) 0); - assert(needsFrame); - ssFlushUpThroughReceiverVariable(slotIndex); - ensureReceiverResultRegContainsSelf(); - /* begin genGenericStorePop:MaybeContextSlotIndex:needsStoreCheck:needsRestoreRcvr:needsImmutabilityCheck: */ - assert(needsFrame); -# if IMMUTABILITY - if (needsImmCheck) { - mutableJump = genJumpMutablescratchReg(ReceiverResultReg, TempReg); - genStoreTrampolineCall(slotIndex); - /* begin putSelfInReceiverResultReg */ - storeToReg(simSelf(), ReceiverResultReg); - /* begin Jump: */ - immutabilityFailure = genoperand(Jump, ((sqInt)0)); - jmpTarget(mutableJump, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } -# endif // IMMUTABILITY - ssPop(1); - /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); - ssPush(1); - genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); - ssStoreAndReplacePoptoReg(popBoolean, ClassReg); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, slotIndex, SendNumArgsReg); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceStoreContextInstVarTrampoline); - (abstractInstruction->annotation = IsRelativeCall); -# if IMMUTABILITY - if (needsImmCheck) { - jmpTarget(immutabilityFailure, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - } -# endif - return 0; -} - - /* StackToRegisterMappingCogit>>#genStorePop:ReceiverVariable:needsStoreCheck:needsImmutabilityCheck: */ -static sqInt NoDbgRegParms -genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean, sqInt slotIndex, sqInt needsStoreCheck, sqInt needsImmCheck) -{ - sqInt i; - sqInt needsImmCheck1; - sqInt needsStoreCheck1; - sqInt topReg; - - ssFlushUpThroughReceiverVariable(slotIndex); - ensureReceiverResultRegContainsSelf(); - /* begin genGenericStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr:needsImmutabilityCheck: */ - needsStoreCheck1 = (!useTwoPaths) - && (needsStoreCheck); - needsImmCheck1 = needsImmCheck - && (!useTwoPaths); -# if IMMUTABILITY - if (needsImmCheck1) { - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); - ssStoreAndReplacePoptoReg(popBoolean, ClassReg); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck1, 1); - } -# endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); - ssStorePoptoReg(popBoolean, topReg); - return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck1); -} - - -/* The only reason we assert needsFrame here is that in a frameless method - ReceiverResultReg must and does contain only self, but the ceStoreCheck - trampoline expects the target of the store to be in ReceiverResultReg. So - in a frameless method we would have a conflict between the receiver and - the temote temp store, unless we we smart enough to realise that - ReceiverResultReg was unused after the literal variable store, unlikely - given that methods return self by default. */ - - /* StackToRegisterMappingCogit>>#genStorePop:RemoteTemp:At:needsStoreCheck: */ -static sqInt NoDbgRegParms -genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt remoteTempIndex, sqInt needsStoreCheck) -{ - AbstractInstruction *anInstruction; - sqInt offset; - sqInt topReg; - - assert(needsFrame); - /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); - voidReceiverResultRegContainsSelf(); - /* begin MoveMw:r:R: */ - offset = frameOffsetOfTemporary(remoteTempIndex); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveMwrR, offset, FPReg, ReceiverResultReg); - /* begin genGenericStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr:needsImmutabilityCheck: */ -# if IMMUTABILITY - -# endif - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); - ssStorePoptoReg(popBoolean, topReg); - return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); -} - - /* StackToRegisterMappingCogit>>#genStorePop:TemporaryVariable: */ -static sqInt NoDbgRegParms -genStorePopTemporaryVariable(sqInt popBoolean, sqInt tempIndex) -{ - AbstractInstruction *anInstruction; - sqInt offset; - sqInt reg; - - ssFlushUpThroughTemporaryVariable(tempIndex); - reg = ssStorePoptoPreferredReg(popBoolean, TempReg); - /* begin MoveR:Mw:r: */ - offset = frameOffsetOfTemporary(tempIndex); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperandoperand(MoveRMwr, reg, offset, FPReg); - ((simStackAt(tempIndex + 1))->bcptr = bytecodePC); - return 0; -} - - -/* Generate a method return from within a method or a block. - Frameless method activation looks like - CISCs (x86): - receiver - args - sp-> ret pc. - RISCs (ARM): - receiver - args - ret pc in LR. - A fully framed activation is described in CoInterpreter - class>initializeFrameIndices. Return pops receiver and arguments off the - stack. Callee pushes the result. */ - - /* StackToRegisterMappingCogit>>#genUpArrowReturn */ -static sqInt -genUpArrowReturn(void) -{ - AbstractInstruction *abstractInstruction; - AbstractInstruction *abstractInstruction1; - sqInt i; - sqInt offset; - - - /* can't fall through */ - deadCode = 1; - if (inBlock > 0) { - assert(needsFrame); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceNonLocalReturnTrampoline); - (abstractInstruction->annotation = IsRelativeCall); - /* begin annotateBytecode: */ - abstractInstruction1 = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - (abstractInstruction1->annotation = HasBytecodePC); - return 0; - } - if ( -# if IMMUTABILITY - needsFrame - && (!useTwoPaths) -# else - needsFrame -# endif - ) { - /* begin MoveR:R: */ - genoperandoperand(MoveRR, FPReg, SPReg); - /* begin PopR: */ - genoperand(PopR, FPReg); - /* begin PopR: */ - genoperand(PopR, LinkReg); - /* begin RetN: */ - genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord); - } - else { - /* begin RetN: */ - offset = ((methodOrBlockNumArgs > 1 /* numRegArgs */) - || (regArgsHaveBeenPushed) - ? (methodOrBlockNumArgs + 1) * BytesPerWord - : 0); - genoperand(RetN, offset); - } - return 0; -} - - /* StackToRegisterMappingCogit>>#genVanillaInlinedIdenticalOrNotIf: */ -static sqInt NoDbgRegParms -genVanillaInlinedIdenticalOrNotIf(sqInt orNot) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - int argIsConstant; - sqInt argNeedsReg; - sqInt argReg; - sqInt argReg1; - BytecodeDescriptor *branchDescriptor; - BytecodeDescriptor *branchDescriptor1; - sqInt constant; - sqInt constant1; - sqInt i; - void *jumpTarget; - void *jumpTarget1; - void *jumpTarget2; - void *jumpTarget3; - sqInt nExts; - sqInt nextPC; - sqInt nextPC1; - sqInt postBranchPC; - sqInt postBranchPC1; - BytecodeDescriptor *primDescriptor; - sqInt rcvrIsConstant; - sqInt rcvrNeedsReg; - sqInt rcvrReg; - sqInt rcvrReg1; - sqInt reg; - sqInt rNext1; - sqInt rTop1; - sqInt targetBytecodePC; - sqInt targetPC; - sqInt topRegistersMask; - - /* begin extractMaybeBranchDescriptorInto: */ - primDescriptor = generatorAt(byte0); - nextPC1 = bytecodePC + ((primDescriptor->numBytes)); - nExts = 0; - while (1) { - while (1) { - /* begin generatorForPC: */ - branchDescriptor1 = generatorAt(bytecodeSetOffset + (fetchByteofObject(nextPC1, methodObj))); - if (!((branchDescriptor1->isExtension))) break; - nExts += 1; - nextPC1 += (branchDescriptor1->numBytes); - } - /* begin isUnconditionalBranch */ - if (!((isBranch(branchDescriptor1)) - && (!(((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse)))))) break; - nextPC1 = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - } - targetBytecodePC = (postBranchPC1 = 0); - if (((branchDescriptor1->isBranchTrue)) - || ((branchDescriptor1->isBranchFalse))) { - targetBytecodePC = eventualTargetOf((nextPC1 + ((branchDescriptor1->numBytes))) + (((branchDescriptor1->spanFunction))(branchDescriptor1, nextPC1, nExts, methodObj))); - postBranchPC1 = eventualTargetOf(nextPC1 + ((branchDescriptor1->numBytes))); - } - else { - nextPC1 = bytecodePC + ((primDescriptor->numBytes)); - } - branchDescriptor = branchDescriptor1; - nextPC = nextPC1; - postBranchPC = postBranchPC1; - targetPC = targetBytecodePC; - - /* They can't be both constants to use correct machine opcodes. - However annotable constants can't be resolved statically, hence we need to careful. */ - argIsConstant = (((ssTop())->type)) == SSConstant; - rcvrIsConstant = (!argIsConstant) - && ((((ssValue(1))->type)) == SSConstant); - /* begin allocateEqualsEqualsRegistersArgNeedsReg:rcvrNeedsReg:into: */ - argNeedsReg = !argIsConstant; - rcvrNeedsReg = !rcvrIsConstant; - assert(argNeedsReg - || (rcvrNeedsReg)); - argReg1 = (rcvrReg1 = NoReg); - if (argNeedsReg) { - if (rcvrNeedsReg) { - /* begin allocateRegForStackTopTwoEntriesInto: */ - topRegistersMask = 0; - rTop1 = (rNext1 = NoReg); - if ((registerOrNone(ssTop())) != NoReg) { - rTop1 = registerOrNone(ssTop()); - } - if ((registerOrNone(ssValue(1))) != NoReg) { - /* begin registerMaskFor: */ - reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1U << reg; - } - if (rTop1 == NoReg) { - rTop1 = allocateRegNotConflictingWith(topRegistersMask); - } - if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1U << rTop1); - } - assert(!(((rTop1 == NoReg) - || (rNext1 == NoReg)))); - argReg1 = rTop1; - rcvrReg1 = rNext1; - popToReg(ssTop(), argReg1); - popToReg(ssValue(1), rcvrReg1); - } - else { - argReg1 = allocateRegForStackEntryAtnotConflictingWith(0, 0); - popToReg(ssTop(), argReg1); - if (((ssValue(1))->spilled)) { - /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(AddCqR, BytesPerWord, SPReg); - } - } - } - else { - assert(rcvrNeedsReg); - assert(!((((ssTop())->spilled)))); - rcvrReg1 = allocateRegForStackEntryAtnotConflictingWith(1, 0); - popToReg(ssValue(1), rcvrReg1); - } - assert(!((argNeedsReg - && (argReg1 == NoReg)))); - assert(!((rcvrNeedsReg - && (rcvrReg1 == NoReg)))); - rcvrReg = rcvrReg1; - argReg = argReg1; - if (!(((branchDescriptor->isBranchTrue)) - || ((branchDescriptor->isBranchFalse)))) { - return genIdenticalNoBranchArgIsConstantrcvrIsConstantargRegrcvrRegorNotIf(argIsConstant, rcvrIsConstant, argReg, rcvrReg, orNot); - } - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= (simStackPtr - 2)) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < (simStackPtr - 2)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : (simStackPtr - 2))); i <= (simStackPtr - 2); i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = (simStackPtr - 2) + 1; - } - /* begin genCmpArgIsConstant:rcvrIsConstant:argReg:rcvrReg: */ - assert((argReg != NoReg) - || (rcvrReg != NoReg)); - if (argIsConstant) { - /* begin genCmpConstant:R: */ - constant = ((ssTop())->constant); - if (shouldAnnotateObjectReference(constant)) { - annotateobjRef(checkLiteralforInstruction(constant, genoperandoperand(CmpCwR, constant, rcvrReg)), constant); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, constant, rcvrReg); - } - } - else { - if (rcvrIsConstant) { - /* begin genCmpConstant:R: */ - constant1 = ((ssValue(1))->constant); - if (shouldAnnotateObjectReference(constant1)) { - annotateobjRef(checkLiteralforInstruction(constant1, genoperandoperand(CmpCwR, constant1, argReg)), constant1); - } - else { - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, constant1, argReg); - } - } - else { - /* begin CmpR:R: */ - assert(!((argReg == SPReg))); - genoperandoperand(CmpRR, argReg, rcvrReg); - } - } - ssPop(2); - if ((((fixupAt(nextPC))->targetInstruction)) == 0) { - - /* The next instruction is dead. we can skip it. */ - deadCode = 1; - ensureFixupAt(targetPC); - ensureFixupAt(postBranchPC); - } - else { - assert(!(deadCode)); - } - if (orNot == ((branchDescriptor->isBranchTrue))) { - - /* a == b ifFalse: ... or a ~~ b ifTrue: ... jump on equal to post-branch pc */ - ensureNonMergeFixupAt(targetPC); - /* begin JumpZero: */ - jumpTarget = ensureNonMergeFixupAt(postBranchPC); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget)); - /* begin Jump: */ - jumpTarget1 = ensureNonMergeFixupAt(targetPC); - genoperand(Jump, ((sqInt)jumpTarget1)); - } - else { - - /* orNot is true for ~~ */ - /* a == b ifTrue: ... or a ~~ b ifFalse: ... jump on equal to target pc */ - /* begin JumpZero: */ - jumpTarget2 = ensureNonMergeFixupAt(targetPC); - genConditionalBranchoperand(JumpZero, ((sqInt)jumpTarget2)); - /* begin Jump: */ - jumpTarget3 = ensureNonMergeFixupAt(postBranchPC); - genoperand(Jump, ((sqInt)jumpTarget3)); - } - if (!deadCode) { - ssPushConstant(trueObject()); - } - return 0; -} - - /* StackToRegisterMappingCogit>>#initSimStackForFramefulMethod: */ -static void NoDbgRegParms -initSimStackForFramefulMethod(sqInt startpc) -{ - CogSimStackEntry * cascade0; - CogSimStackEntry *desc; - sqInt i; - - - /* N.B. Includes num args */ - simStackPtr = methodOrBlockNumTemps; - simSpillBase = methodOrBlockNumTemps + 1; - cascade0 = simSelf(); - (cascade0->type = SSBaseOffset); - (cascade0->spilled = 1); - (cascade0->registerr = FPReg); - (cascade0->offset = FoxMFReceiver); - (cascade0->liveRegister = NoReg); - for (i = 1; i <= methodOrBlockNumArgs; i += 1) { - desc = simStackAt(i); - (desc->type = SSBaseOffset); - (desc->spilled = 1); - (desc->registerr = FPReg); - (desc->offset = FoxCallerSavedIP + (((methodOrBlockNumArgs - i) + 1) * BytesPerWord)); - (desc->bcptr = startpc); - } - for (i = (methodOrBlockNumArgs + 1); i <= simStackPtr; i += 1) { - desc = simStackAt(i); - (desc->type = SSBaseOffset); - (desc->spilled = 1); - (desc->registerr = FPReg); - (desc->offset = FoxMFReceiver - ((i - methodOrBlockNumArgs) * BytesPerWord)); - (desc->bcptr = startpc); - } -} - - -/* The register receiver (the closure itself) and args are pushed by the - closure value primitive(s) - and hence a frameless block has all arguments and copied values pushed to - the stack. However, - the method receiver (self) is put in the ReceiverResultReg by the block - entry. - */ - - /* StackToRegisterMappingCogit>>#initSimStackForFramelessBlock: */ -static void NoDbgRegParms -initSimStackForFramelessBlock(sqInt startpc) -{ - CogSimStackEntry * cascade0; - CogSimStackEntry *desc; - sqInt i; - - cascade0 = simSelf(); - (cascade0->type = SSRegister); - (cascade0->spilled = 0); - (cascade0->registerr = ReceiverResultReg); - (cascade0->liveRegister = ReceiverResultReg); - assert(methodOrBlockNumTemps >= methodOrBlockNumArgs); - for (i = 1; i <= methodOrBlockNumTemps; i += 1) { - desc = simStackAt(i); - (desc->type = SSBaseOffset); - (desc->spilled = 1); - (desc->registerr = SPReg); - (desc->offset = (methodOrBlockNumArgs - i) * BytesPerWord); - (desc->bcptr = startpc); - } - - /* N.B. Includes num args */ - simStackPtr = methodOrBlockNumTemps; - simSpillBase = methodOrBlockNumTemps + 1; - } - - /* StackToRegisterMappingCogit>>#initSimStackForFramelessMethod: */ -static void NoDbgRegParms -initSimStackForFramelessMethod(sqInt startpc) -{ - CogSimStackEntry * cascade0; - CogSimStackEntry *desc; - sqInt i; - - cascade0 = simSelf(); - (cascade0->type = SSRegister); - (cascade0->spilled = 0); - (cascade0->registerr = ReceiverResultReg); - (cascade0->liveRegister = ReceiverResultReg); - assert(methodOrBlockNumTemps == methodOrBlockNumArgs); - assert((numRegArgs()) <= 2); - if (((methodOrBlockNumArgs >= 1) && (methodOrBlockNumArgs <= 1 /* numRegArgs */))) { - desc = simStackAt(1); - (desc->type = SSRegister); - (desc->spilled = 0); - (desc->registerr = Arg0Reg); - (desc->bcptr = startpc); - if (methodOrBlockNumArgs > 1) { - desc = simStackAt(2); - (desc->type = SSRegister); - (desc->spilled = 0); - (desc->registerr = Arg1Reg); - (desc->bcptr = startpc); - } - } - else { - for (i = 1; i <= methodOrBlockNumArgs; i += 1) { - desc = simStackAt(i); - (desc->type = SSBaseOffset); - (desc->registerr = SPReg); - (desc->spilled = 1); - (desc->offset = (methodOrBlockNumArgs - i) * BytesPerWord); - (desc->bcptr = startpc); - } - } - simStackPtr = methodOrBlockNumArgs; - simSpillBase = methodOrBlockNumArgs + 1; - } - - -/* Do not inline (inBlock access) */ - - /* StackToRegisterMappingCogit>>#isNonForwarderReceiver: */ -static sqInt NoDbgRegParms -isNonForwarderReceiver(sqInt reg) -{ - return ((((simSelf())->liveRegister)) == ReceiverResultReg) - && ((inBlock == 0) - && (reg == ReceiverResultReg)); -} - - /* StackToRegisterMappingCogit>>#liveRegisters */ -static sqInt -liveRegisters(void) -{ - sqInt i; - sqInt regsSet; - - if (needsFrame) { - regsSet = 0; - } - else { - /* begin registerMaskFor: */ - regsSet = 1U << ReceiverResultReg; - if ((methodOrBlockNumArgs <= 1 /* numRegArgs */) - && (methodOrBlockNumArgs > 0)) { - regsSet = regsSet | (1U << Arg0Reg); - } - } - for (i = (((simSpillBase < 0) ? 0 : simSpillBase)); i <= simStackPtr; i += 1) { - regsSet = regsSet | (registerMask(simStackAt(i))); - } - return regsSet; -} - - -/* insert nops for dead code that is mapped so that bc - to mc mapping is not many to one */ - - /* StackToRegisterMappingCogit>>#mapDeadDescriptorIfNeeded: */ -static sqInt NoDbgRegParms -mapDeadDescriptorIfNeeded(BytecodeDescriptor *descriptor) -{ - AbstractInstruction *abstractInstruction; - - flag("annotateInstruction"); - if (((descriptor->isMapped)) - || ((inBlock > 0) - && ((descriptor->isMappedInBlock)))) { - /* begin annotateBytecode: */ - abstractInstruction = gen(Nop); - (abstractInstruction->annotation = HasBytecodePC); - } - return 0; -} - - -/* Spill everything on the simulated stack that needs spilling (that below - receiver and arguments). - Marshall receiver and arguments to stack and/or registers depending on arg - count. If the args don't fit in registers push receiver and args (spill - everything), but still assign - the receiver to ReceiverResultReg. */ - - /* StackToRegisterMappingCogit>>#marshallSendArguments: */ -static void NoDbgRegParms -marshallSendArguments(sqInt numArgs) -{ - sqInt anyRefs; - CogSimStackEntry * cascade0; - sqInt i; - sqInt i1; - sqInt i2; - sqInt numSpilled; - - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= ((simStackPtr - numArgs) - 1)) { - for (i2 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < ((simStackPtr - numArgs) - 1)) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : ((simStackPtr - numArgs) - 1))); i2 < (simStackPtr - numArgs); i2 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i2), frameOffsetOfTemporary(i2 - 1), FPReg); - } - simSpillBase = ((simStackPtr - numArgs) - 1) + 1; - } - if (numArgs > 1 /* numRegArgs */) { - - /* If there are no spills and no references to ReceiverResultReg - the fetch of ReceiverResultReg from the stack can be avoided - by assigning directly to ReceiverResultReg and pushing it. */ - numSpilled = numberOfSpillsInTopNItems(numArgs + 1); - anyRefs = anyReferencesToRegisterinTopNItems(ReceiverResultReg, numArgs + 1); - if ((numSpilled > 0) - || (anyRefs)) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - storeToReg(simStackAt(simStackPtr - numArgs), ReceiverResultReg); - } - else { - cascade0 = simStackAt(simStackPtr - numArgs); - storeToReg(cascade0, ReceiverResultReg); - (cascade0->type = SSRegister); - (cascade0->registerr = ReceiverResultReg); - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i1 <= simStackPtr; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - } - } - else { - - /* Move the args to the register arguments, being careful to do - so last to first so e.g. previous contents don't get overwritten. - Also check for any arg registers in use by other args. */ - if (numArgs > 0) { - /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); - } - if (numArgs > 0) { - popToReg(simStackAt((simStackPtr - numArgs) + 1), Arg0Reg); - } - popToReg(simStackAt(simStackPtr - numArgs), ReceiverResultReg); - } - ssPop(numArgs + 1); -} - - -/* For assert checking; or rather for avoiding assert fails when dealing with - the hack for block temps in the SqueakV3PlusClosures bytecode set. - */ - - /* StackToRegisterMappingCogit>>#maybeCompilingFirstPassOfBlockWithInitialPushNil */ -static sqInt -maybeCompilingFirstPassOfBlockWithInitialPushNil(void) -{ - return (inBlock == InVanillaBlock) - && ((methodOrBlockNumTemps > methodOrBlockNumArgs) - && (compilationPass == 1)); -} - - -/* If this bytecode has a fixup, some kind of merge needs to be done. There - are 4 cases: - 1) the bytecode has no fixup (fixup isNotAFixup) - do nothing - 2) the bytecode has a non merge fixup - the fixup has needsNonMergeFixup. - The code generating non merge fixup (currently only special selector code) - is responsible - for the merge so no need to do it. - We set deadCode to false as the instruction can be reached from jumps. - 3) the bytecode has a merge fixup, but execution flow *cannot* fall - through to the merge point. - the fixup has needsMergeFixup and deadCode = true. - ignores the current simStack as it does not mean anything - restores the simStack to the state the jumps to the merge point expects it - to be. - 4) the bytecode has a merge fixup and execution flow *can* fall through to - the merge point. - the fixup has needsMergeFixup and deadCode = false. - flushes the stack to the stack pointer so the fall through execution path - simStack is - in the state the merge point expects it to be. - restores the simStack to the state the jumps to the merge point expects it - to be. - - In addition, if this is a backjump merge point, we patch the fixup to hold - the current simStackPtr - for later assertions. */ - - /* StackToRegisterMappingCogit>>#mergeWithFixupIfRequired: */ -static sqInt NoDbgRegParms -mergeWithFixupIfRequired(BytecodeFixup *fixup) -{ - CogSimStackEntry * cascade0; - sqInt i; - sqInt i1; - - /* begin assertCorrectSimStackPtr */ - assert((simSpillBase >= methodOrBlockNumTemps) - || ((maybeCompilingFirstPassOfBlockWithInitialPushNil()) - && (simSpillBase > methodOrBlockNumArgs))); - if (needsFrame - && (simSpillBase > 0)) { - assert((((simStackAt(simSpillBase - 1))->spilled)) == 1); - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); - } - if (((fixup->targetInstruction)) == 0) { - return 0; - } - if ((((usqInt)((fixup->targetInstruction)))) == NeedsNonMergeFixupFlag) { - deadCode = 0; - return 0; - } - assert(isMergeFixup(fixup)); - traceMerge(fixup); - if (deadCode) { - - /* case 3 */ - /* Would like to assert fixup simStackPtr >= methodOrBlockNumTemps - but can't because of the initialNils hack. */ - assert((((fixup->simStackPtr)) >= methodOrBlockNumTemps) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - simStackPtr = (fixup->simStackPtr); - } - else { - - /* case 4 */ - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= simStackPtr) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < simStackPtr) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : simStackPtr)); i <= simStackPtr; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = simStackPtr + 1; - } - } - deadCode = 0; - if ((fixup->isTargetOfBackwardBranch)) { - (fixup->simStackPtr = simStackPtr); - } - (fixup->targetInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(simStackPtr == ((fixup->simStackPtr))); - /* begin restoreSimStackAtMergePoint: */ - ((simSelf())->liveRegister = NoReg); - for (i1 = (methodOrBlockNumTemps + 1); i1 <= simStackPtr; i1 += 1) { - cascade0 = simStackAt(i1); - (cascade0->type = SSSpill); - (cascade0->offset = FoxMFReceiver - ((i1 - methodOrBlockNumArgs) * BytesPerOop)); - (cascade0->registerr = FPReg); - (cascade0->spilled = 1); - } - simSpillBase = simStackPtr + 1; - return 0; -} - - /* StackToRegisterMappingCogit>>#methodAbortTrampolineFor: */ -static sqInt NoDbgRegParms -methodAbortTrampolineFor(sqInt numArgs) -{ - return methodAbortTrampolines[((numArgs < (2)) ? numArgs : (2))]; -} - - -/* This is a hook for subclasses to filter out methods they can't deal with. */ -/* Frameless methods with local temporaries cause problems, - mostly in asserts, and yet they matter not at all for performance. - Shun them. */ - - /* StackToRegisterMappingCogit>>#methodFoundInvalidPostScan */ -static sqInt -methodFoundInvalidPostScan(void) -{ - if (!needsFrame) { - return methodOrBlockNumTemps > methodOrBlockNumArgs; - } - return 0; -} - - /* StackToRegisterMappingCogit>>#needsFrameIfMod16GENumArgs: */ -static sqInt NoDbgRegParms -needsFrameIfMod16GENumArgs(sqInt stackDelta) -{ - return (byte0 % 16) >= methodOrBlockNumArgs; -} - - -/* As of August 2013, the code generator can't deal with spills in frameless - methods (the - issue is to do with the stack offset to get at an argument, which is - changed when there's a spill). - In e.g. TextColor>>#dominates: other ^other class == self class the second - send of class - needs also rto allocate a register that the first one used, but the first - one's register can't be - spilled. So avoid this by only allowing class to be sent if the stack - contains a single element. */ - - /* StackToRegisterMappingCogit>>#needsFrameIfStackGreaterThanOne: */ -static sqInt NoDbgRegParms -needsFrameIfStackGreaterThanOne(sqInt stackDelta) -{ - return stackDelta > 1; -} - - /* StackToRegisterMappingCogit>>#numberOfSpillsInTopNItems: */ -static sqInt NoDbgRegParms -numberOfSpillsInTopNItems(sqInt n) -{ - sqInt i; - - for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { - if ((((simStackAt(i))->type)) == SSSpill) { - return n - (simStackPtr - i); - } - } - return 0; -} - - /* StackToRegisterMappingCogit>>#picAbortTrampolineFor: */ -static sqInt NoDbgRegParms -picAbortTrampolineFor(sqInt numArgs) -{ - return picAbortTrampolines[((numArgs < (2)) ? numArgs : (2))]; -} - - /* StackToRegisterMappingCogit>>#prevInstIsPCAnnotated */ -static sqInt -prevInstIsPCAnnotated(void) -{ - sqInt prevIndex; - AbstractInstruction *prevInst; - - if (!(opcodeIndex > 0)) { - return 0; - } - prevIndex = opcodeIndex - 1; - while (1) { - if (prevIndex <= 0) { - return 0; - } - prevInst = abstractInstructionAt(prevIndex); - if (isPCMappedAnnotation((!((prevInst->annotation)) - ? 0 - : (prevInst->annotation)))) { - return 1; - } - if (!(((prevInst->opcode)) == Label)) break; - prevIndex -= 1; - } - return 0; -} - - -/* Used to mark ReceiverResultReg as dead or not containing simSelf. - Used when the simStack has already been flushed, e.g. for sends. */ - - /* StackToRegisterMappingCogit>>#receiverIsInReceiverResultReg */ -static sqInt -receiverIsInReceiverResultReg(void) -{ - return (((simSelf())->liveRegister)) == ReceiverResultReg; -} - - -/* When a block must be recompiled due to overestimating the - numInitialNils fixups must be restored, which means rescannning - since backward branches need their targets initialized. */ - - /* StackToRegisterMappingCogit>>#reinitializeFixupsFrom:through: */ -static void NoDbgRegParms -reinitializeFixupsFromthrough(sqInt start, sqInt end) -{ - BytecodeDescriptor *descriptor; - sqInt distance; - BytecodeFixup * fixup; - sqInt nExts; - sqInt pc; - BytecodeFixup * self_in_reinitialize; - sqInt targetPC; - - pc = start; - nExts = 0; - while (pc <= end) { - /* begin reinitialize */ - self_in_reinitialize = fixupAtIndex(pc - initialPC); - (self_in_reinitialize->targetInstruction) = 0; - (self_in_reinitialize->simStackPtr) = 0; - byte0 = (fetchByteofObject(pc, methodObj)) + bytecodeSetOffset; - descriptor = generatorAt(byte0); - if ((isBranch(descriptor)) - && ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, pc, nExts, methodObj)) < 0))) { - /* begin spanFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, pc, nExts, methodObj); - targetPC = (pc + ((descriptor->numBytes))) + distance; - /* begin initializeFixupAt: */ - fixup = fixupAtIndex(targetPC - initialPC); - /* begin initializeFixup: */ - (fixup->targetInstruction) = ((AbstractInstruction *) NeedsMergeFixupFlag); - /* begin setIsBackwardBranchFixup */ - (fixup->isTargetOfBackwardBranch) = 1; - } - if ((descriptor->isBlockCreation)) { - /* begin spanFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, pc, nExts, methodObj); - pc = (pc + ((descriptor->numBytes))) + distance; - } - else { - pc += (descriptor->numBytes); - } - nExts = ((descriptor->isExtension) - ? nExts + 1 - : 0); - } -} - - -/* Scan the block to determine if the block needs a frame or not */ - - /* StackToRegisterMappingCogit>>#scanBlock: */ -static sqInt NoDbgRegParms -scanBlock(BlockStart *blockStart) -{ - BytecodeDescriptor *descriptor; - sqInt end; - sqInt framelessStackDelta; - sqInt nExts; - sqInt numPushNils; - sqInt (* const numPushNilsFunction)(struct _BytecodeDescriptor *,sqInt,sqInt,sqInt) = v3NumPushNils; - sqInt pc; - sqInt pushingNils; - - needsFrame = 0; - prevBCDescriptor = null; - methodOrBlockNumArgs = (blockStart->numArgs); - inBlock = InVanillaBlock; - pc = (blockStart->startpc); - end = ((blockStart->startpc)) + ((blockStart->span)); - framelessStackDelta = (nExts = (extA = (numExtB = (extB = 0)))); - pushingNils = 1; - while (pc < end) { - byte0 = (fetchByteofObject(pc, methodObj)) + bytecodeSetOffset; - descriptor = generatorAt(byte0); - if ((descriptor->isExtension)) { - loadSubsequentBytesForDescriptorat(descriptor, pc); - ((descriptor->generator))(); - } - if (!needsFrame) { - if ((((descriptor->needsFrameFunction)) == null) - || (((descriptor->needsFrameFunction))(framelessStackDelta))) { - needsFrame = 1; - } - else { - framelessStackDelta += (descriptor->stackDelta); - } - } - if (pushingNils - && (!((descriptor->isExtension)))) { - - /* Count the initial number of pushed nils acting as temp initializers. We can't tell - whether an initial pushNil is an operand reference or a temp initializer, except - when the pushNil is a jump target (has a fixup), which never happens: - self systemNavigation browseAllSelect: - [:m| | ebc | - (ebc := m embeddedBlockClosures - select: [:ea| ea decompile statements first isMessage] - thenCollect: [:ea| ea decompile statements first selector]) notEmpty - and: [(#(whileTrue whileFalse whileTrue: whileFalse:) intersection: ebc) notEmpty]] - or if the bytecode set has a push multiple nils bytecode. We simply count initial nils. - Rarely we may end up over-estimating. We will correct by checking the stack depth - at the end of the block in compileBlockBodies. */ - if (((numPushNils = numPushNilsFunction(descriptor, pc, nExts, methodObj))) > 0) { - assert(((descriptor->numBytes)) == 1); - (blockStart->numInitialNils = ((blockStart->numInitialNils)) + numPushNils); - } - else { - pushingNils = 0; - } - } - /* begin nextBytecodePCFor:at:exts:in: */ - pc = (pc + ((descriptor->numBytes))) + (((descriptor->isBlockCreation) - ? ((descriptor->spanFunction))(descriptor, pc, nExts, methodObj) - : 0)); - if ((descriptor->isExtension)) { - nExts += 1; - } - else { - nExts = (extA = (numExtB = (extB = 0))); - } - prevBCDescriptor = descriptor; - } - if (!needsFrame) { - assert((framelessStackDelta >= 0) - && (((blockStart->numInitialNils)) >= framelessStackDelta)); - (blockStart->numInitialNils = ((blockStart->numInitialNils)) - framelessStackDelta); - } - return 0; -} - - -/* Scan the method (and all embedded blocks) to determine - - what the last bytecode is; extra bytes at the end of a method are used - to encode things like source pointers or temp names - - if the method needs a frame or not - - what are the targets of any backward branches. - - how many blocks it creates - Answer the block count or on error a negative error code */ - - /* StackToRegisterMappingCogit>>#scanMethod */ -static sqInt -scanMethod(void) -{ - BytecodeDescriptor *descriptor; - sqInt distance; - BytecodeFixup * fixup; - sqInt framelessStackDelta; - sqInt latestContinuation; - sqInt nExts; - sqInt numBlocks; - sqInt pc; - sqInt seenInstVarStore; - sqInt targetPC; - - needsFrame = (useTwoPaths = (seenInstVarStore = 0)); - prevBCDescriptor = null; - if ((primitiveIndex > 0) - && (isQuickPrimitiveIndex(primitiveIndex))) { - return 0; - } - pc = (latestContinuation = initialPC); - numBlocks = (framelessStackDelta = (nExts = (extA = (numExtB = (extB = 0))))); - while (pc <= endPC) { - byte0 = (fetchByteofObject(pc, methodObj)) + bytecodeSetOffset; - descriptor = generatorAt(byte0); - if ((descriptor->isExtension)) { - if (((descriptor->opcode)) == Nop) { - - /* unknown bytecode tag; see Cogit class>>#generatorTableFrom: */ - return EncounteredUnknownBytecode; - } - loadSubsequentBytesForDescriptorat(descriptor, pc); - ((descriptor->generator))(); - } - if (((descriptor->isReturn)) - && (pc >= latestContinuation)) { - endPC = pc; - } - if (!needsFrame) { - if ((((descriptor->needsFrameFunction)) == null) - || (((descriptor->needsFrameFunction))(framelessStackDelta))) { - - /* With immutability we win simply by avoiding a frame build if the receiver is young and not immutable. */ -# if IMMUTABILITY - if ((descriptor->is1ByteInstVarStore)) { - useTwoPaths = 1; - } - else { - needsFrame = 1; - useTwoPaths = 0; - } -# else // IMMUTABILITY - needsFrame = 1; - useTwoPaths = 0; -# endif - } - else { - - /* Without immutability we win if there are two or more stores and the receiver is new. */ - framelessStackDelta += (descriptor->stackDelta); -# if IMMUTABILITY -# else - if ((descriptor->is1ByteInstVarStore)) { - if (seenInstVarStore) { - useTwoPaths = 1; - } - else { - seenInstVarStore = 1; - } - } -# endif // IMMUTABILITY - } - } - if (isBranch(descriptor)) { - /* begin spanFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, pc, nExts, methodObj); - targetPC = (pc + ((descriptor->numBytes))) + distance; - if ((assert(((descriptor->spanFunction)) != null), - (((descriptor->spanFunction))(descriptor, pc, nExts, methodObj)) < 0)) { - /* begin initializeFixupAt: */ - fixup = fixupAtIndex(targetPC - initialPC); - /* begin initializeFixup: */ - (fixup->targetInstruction) = ((AbstractInstruction *) NeedsMergeFixupFlag); - /* begin setIsBackwardBranchFixup */ - (fixup->isTargetOfBackwardBranch) = 1; - } - else { - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - } - /* begin maybeDealWithUnsafeJumpForDescriptor:pc:latestContinuation: */ - /* latestContinuation = */ latestContinuation; - if ((descriptor->isBlockCreation)) { - numBlocks += 1; - /* begin spanFor:at:exts:in: */ - distance = ((descriptor->spanFunction))(descriptor, pc, nExts, methodObj); - targetPC = (pc + ((descriptor->numBytes))) + distance; - latestContinuation = ((latestContinuation < targetPC) ? targetPC : latestContinuation); - } - pc += (descriptor->numBytes); - nExts = ((descriptor->isExtension) - ? nExts + 1 - : (extA = (numExtB = (extB = 0)))); - prevBCDescriptor = descriptor; - } - return numBlocks; -} - - /* StackToRegisterMappingCogit>>#ssAllocateRequiredRegMask:upThrough:upThroughNative: */ -static void NoDbgRegParms -ssAllocateRequiredRegMaskupThroughupThroughNative(sqInt requiredRegsMask, sqInt stackPtr, sqInt nativeStackPtr) -{ - sqInt i; - sqInt i1; - sqInt lastRequired; - sqInt lastRequiredNative; - sqInt liveRegs; - - lastRequired = -1; - - /* compute live regs while noting the last occurrence of required regs. - If these are not free we must spill from simSpillBase to last occurrence. - Note we are conservative here; we could allocate FPReg in frameless methods. */ - lastRequiredNative = -1; - /* begin registerMaskFor:and: */ - liveRegs = (1U << FPReg) | (1U << SPReg); - for (i = (((simSpillBase < 0) ? 0 : simSpillBase)); i <= stackPtr; i += 1) { - liveRegs = liveRegs | (registerMask(simStackAt(i))); - if ((((registerMask(simStackAt(i))) & requiredRegsMask) != 0)) { - lastRequired = i; - } - } - if (((liveRegs & requiredRegsMask) != 0)) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= lastRequired) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < lastRequired) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : lastRequired)); i1 <= lastRequired; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = lastRequired + 1; - } - assert(!(((((liveRegisters()) & requiredRegsMask) != 0)))); - } -} - - -/* Any occurrences on the stack of the value being stored (which is the top - of stack) - must be flushed, and hence any values colder than them stack. */ - - /* StackToRegisterMappingCogit>>#ssFlushUpThroughReceiverVariable: */ -static void NoDbgRegParms -ssFlushUpThroughReceiverVariable(sqInt slotIndex) -{ - sqInt i; - sqInt index; - - /* begin ssFlushUpThrough: */ - assert(simSpillBase >= 0); - for (index = (simStackPtr - 1); index >= simSpillBase; index += -1) { - if (((((simStackAt(index))->type)) == SSBaseOffset) - && (((((simStackAt(index))->registerr)) == ReceiverResultReg) - && ((((simStackAt(index))->offset)) == (slotOffsetOfInstVarIndex(slotIndex))))) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= index) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < index) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : index)); i <= index; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = index + 1; - } - goto l1; - } - } - l1: /* end ssFlushUpThrough: */; -} - - -/* Any occurrences on the stack of the value being stored (which is the top - of stack) - must be flushed, and hence any values colder than them stack. */ - - /* StackToRegisterMappingCogit>>#ssFlushUpThroughTemporaryVariable: */ -static void NoDbgRegParms -ssFlushUpThroughTemporaryVariable(sqInt tempIndex) -{ - sqInt i; - sqInt index; - sqInt offset; - - offset = ((simStackAt(tempIndex + 1))->offset); - assert(offset == (frameOffsetOfTemporary(tempIndex))); - /* begin ssFlushUpThrough: */ - assert(simSpillBase >= 0); - for (index = (simStackPtr - 1); index >= simSpillBase; index += -1) { - if (((((simStackAt(index))->type)) == SSBaseOffset) - && (((((simStackAt(index))->registerr)) == FPReg) - && ((((simStackAt(index))->offset)) == offset))) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= index) { - for (i = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < index) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : index)); i <= index; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i - 1), FPReg); - } - simSpillBase = index + 1; - } - goto l1; - } - } - l1: /* end ssFlushUpThrough: */; -} - - /* StackToRegisterMappingCogit>>#ssPop: */ -static void NoDbgRegParms -ssPop(sqInt n) -{ - sqInt i; - - assert(((simStackPtr - n) >= methodOrBlockNumTemps) - || (((!needsFrame) - && ((simStackPtr - n) >= 0)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil()))); - simStackPtr -= n; - /* begin updateSimSpillBase */ - assert(((simSpillBase > methodOrBlockNumTemps) - && (simStackPtr >= methodOrBlockNumTemps)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - if (simSpillBase > simStackPtr) { - simSpillBase = simStackPtr + 1; - while (((simSpillBase - 1) > methodOrBlockNumTemps) - && (!(((simStackAt(simSpillBase - 1))->spilled)))) { - simSpillBase -= 1; - } - } - else { - while ((((simStackAt(simSpillBase))->spilled)) - && (simSpillBase <= simStackPtr)) { - simSpillBase += 1; - } - } - for (i = (methodOrBlockNumTemps + 1); i <= ((((simSpillBase - 1) < simStackPtr) ? (simSpillBase - 1) : simStackPtr)); i += 1) { - assert((((simStackAt(i))->spilled)) == 1); - } - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); -} - - /* StackToRegisterMappingCogit>>#ssPushAnnotatedConstant: */ -static sqInt NoDbgRegParms -ssPushAnnotatedConstant(sqInt literal) -{ - AbstractInstruction *abstractInstruction; - - ssPushConstant(literal); - /* begin annotateInstructionForBytecode */ - if (prevInstIsPCAnnotated()) { - /* begin Nop */ - abstractInstruction = gen(Nop); - } - else { - /* begin Label */ - abstractInstruction = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - (abstractInstruction->annotation = HasBytecodePC); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushBase:offset: */ -static sqInt NoDbgRegParms -ssPushBaseoffset(sqInt reg, sqInt offset) -{ - CogSimStackEntry * cascade0; - sqInt i; - - ssPush(1); - cascade0 = ssTop(); - (cascade0->type = SSBaseOffset); - (cascade0->spilled = 0); - (cascade0->registerr = reg); - (cascade0->offset = offset); - (cascade0->bcptr = bytecodePC); - /* begin updateSimSpillBase */ - assert(((simSpillBase > methodOrBlockNumTemps) - && (simStackPtr >= methodOrBlockNumTemps)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - if (simSpillBase > simStackPtr) { - simSpillBase = simStackPtr + 1; - while (((simSpillBase - 1) > methodOrBlockNumTemps) - && (!(((simStackAt(simSpillBase - 1))->spilled)))) { - simSpillBase -= 1; - } - } - else { - while ((((simStackAt(simSpillBase))->spilled)) - && (simSpillBase <= simStackPtr)) { - simSpillBase += 1; - } - } - for (i = (methodOrBlockNumTemps + 1); i <= ((((simSpillBase - 1) < simStackPtr) ? (simSpillBase - 1) : simStackPtr)); i += 1) { - assert((((simStackAt(i))->spilled)) == 1); - } - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushConstant: */ -static sqInt NoDbgRegParms -ssPushConstant(sqInt literal) -{ - CogSimStackEntry * cascade0; - sqInt i; - - ssPush(1); - cascade0 = ssTop(); - (cascade0->type = SSConstant); - (cascade0->spilled = 0); - (cascade0->constant = literal); - (cascade0->bcptr = bytecodePC); - /* begin updateSimSpillBase */ - assert(((simSpillBase > methodOrBlockNumTemps) - && (simStackPtr >= methodOrBlockNumTemps)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - if (simSpillBase > simStackPtr) { - simSpillBase = simStackPtr + 1; - while (((simSpillBase - 1) > methodOrBlockNumTemps) - && (!(((simStackAt(simSpillBase - 1))->spilled)))) { - simSpillBase -= 1; - } - } - else { - while ((((simStackAt(simSpillBase))->spilled)) - && (simSpillBase <= simStackPtr)) { - simSpillBase += 1; - } - } - for (i = (methodOrBlockNumTemps + 1); i <= ((((simSpillBase - 1) < simStackPtr) ? (simSpillBase - 1) : simStackPtr)); i += 1) { - assert((((simStackAt(i))->spilled)) == 1); - } - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushDesc: */ -static sqInt NoDbgRegParms -ssPushDesc(SimStackEntry simStackEntry) -{ - sqInt i; - - if (((simStackEntry.type)) == SSSpill) { - (simStackEntry.type = SSBaseOffset); - } - (simStackEntry.spilled = 0); - (simStackEntry.bcptr = bytecodePC); - simStack[(simStackPtr += 1)] = simStackEntry; - /* begin updateSimSpillBase */ - assert(((simSpillBase > methodOrBlockNumTemps) - && (simStackPtr >= methodOrBlockNumTemps)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - if (simSpillBase > simStackPtr) { - simSpillBase = simStackPtr + 1; - while (((simSpillBase - 1) > methodOrBlockNumTemps) - && (!(((simStackAt(simSpillBase - 1))->spilled)))) { - simSpillBase -= 1; - } - } - else { - while ((((simStackAt(simSpillBase))->spilled)) - && (simSpillBase <= simStackPtr)) { - simSpillBase += 1; - } - } - for (i = (methodOrBlockNumTemps + 1); i <= ((((simSpillBase - 1) < simStackPtr) ? (simSpillBase - 1) : simStackPtr)); i += 1) { - assert((((simStackAt(i))->spilled)) == 1); - } - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPushRegister: */ -static sqInt NoDbgRegParms -ssPushRegister(sqInt reg) -{ - CogSimStackEntry * cascade0; - sqInt i; - - ssPush(1); - cascade0 = ssTop(); - (cascade0->type = SSRegister); - (cascade0->spilled = 0); - (cascade0->registerr = reg); - (cascade0->bcptr = bytecodePC); - /* begin updateSimSpillBase */ - assert(((simSpillBase > methodOrBlockNumTemps) - && (simStackPtr >= methodOrBlockNumTemps)) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil())); - if (simSpillBase > simStackPtr) { - simSpillBase = simStackPtr + 1; - while (((simSpillBase - 1) > methodOrBlockNumTemps) - && (!(((simStackAt(simSpillBase - 1))->spilled)))) { - simSpillBase -= 1; - } - } - else { - while ((((simStackAt(simSpillBase))->spilled)) - && (simSpillBase <= simStackPtr)) { - simSpillBase += 1; - } - } - for (i = (methodOrBlockNumTemps + 1); i <= ((((simSpillBase - 1) < simStackPtr) ? (simSpillBase - 1) : simStackPtr)); i += 1) { - assert((((simStackAt(i))->spilled)) == 1); - } - assert((simSpillBase > simStackPtr) - || ((((simStackAt(simSpillBase))->spilled)) == 0)); - return 0; -} - - /* StackToRegisterMappingCogit>>#ssPush: */ -static void NoDbgRegParms -ssPush(sqInt n) -{ - simStackPtr += n; -} - - /* StackToRegisterMappingCogit>>#ssSelfDescriptor */ -static SimStackEntry -ssSelfDescriptor(void) -{ - return simStack[0]; -} - - -/* In addition to ssStorePop:toReg:, if this is a store and not - a popInto I change the simulated stack to use the register - for the top value */ - - /* StackToRegisterMappingCogit>>#ssStoreAndReplacePop:toReg: */ -static void NoDbgRegParms -ssStoreAndReplacePoptoReg(sqInt popBoolean, sqInt reg) -{ - char topSpilled; - - topSpilled = ((ssTop())->spilled); - ssStorePoptoReg(popBoolean - || (topSpilled), reg); - if (!popBoolean) { - if (!topSpilled) { - ssPop(1); - } - ssPushRegister(reg); - } -} - - -/* Store or pop the top simulated stack entry to a register. - Use preferredReg if the entry is not itself a register. - Answer the actual register the result ends up in. */ - - /* StackToRegisterMappingCogit>>#ssStorePop:toPreferredReg: */ -static sqInt NoDbgRegParms -ssStorePoptoPreferredReg(sqInt popBoolean, sqInt preferredReg) -{ - sqInt actualReg; - - actualReg = preferredReg; - if ((((ssTop())->type)) == SSRegister) { - assert(!(((ssTop())->spilled))); - actualReg = ((ssTop())->registerr); - } - ssStorePoptoReg(popBoolean, actualReg); - return actualReg; -} - - -/* Store or pop the top simulated stack entry to a register. - N.B.: popToReg: and storeToReg: does not generate anything if - it moves a register to the same register. */ - - /* StackToRegisterMappingCogit>>#ssStorePop:toReg: */ -static void NoDbgRegParms -ssStorePoptoReg(sqInt popBoolean, sqInt reg) -{ - if (popBoolean) { - popToReg(ssTop(), reg); - ssPop(1); - } - else { - storeToReg(ssTop(), reg); - } -} - - /* StackToRegisterMappingCogit>>#ssTop */ -static CogSimStackEntry * -ssTop(void) -{ - return simStackAt(simStackPtr); -} - - /* StackToRegisterMappingCogit>>#ssValue: */ -static CogSimStackEntry * NoDbgRegParms -ssValue(sqInt n) -{ - return simStackAt(simStackPtr - n); -} - - /* StackToRegisterMappingCogit>>#stackEntryIsBoolean: */ -static sqInt NoDbgRegParms -stackEntryIsBoolean(CogSimStackEntry *simStackEntry) -{ - return (((simStackEntry->type)) == SSConstant) - && ((((simStackEntry->constant)) == (trueObject())) - || (((simStackEntry->constant)) == (falseObject()))); -} - - -/* Answer if the stack is valid up to, but not including, simSpillBase. */ - - /* StackToRegisterMappingCogit>>#tempsValidAndVolatileEntriesSpilled */ -static sqInt -tempsValidAndVolatileEntriesSpilled(void) -{ - sqInt culprit; - sqInt i; - - culprit = 0; - for (i = 1; i <= methodOrBlockNumTemps; i += 1) { - if (!(((((simStackAt(i))->type)) == SSBaseOffset) - || (maybeCompilingFirstPassOfBlockWithInitialPushNil()))) { - if (!culprit) { - culprit = i; - } - return 0; - } - } - for (i = (methodOrBlockNumTemps + 1); i < simSpillBase; i += 1) { - if (!(((simStackAt(i))->spilled))) { - if (!culprit) { - culprit = i; - } - return 0; - } - } - return 1; -} - - -/* If the sequence of bytecodes is - push: (Array new: 1) - popIntoTemp: tempIndex - pushConstant: const or pushTemp: n - popIntoTemp: 0 inVectorAt: tempIndex - collapse this into - tempAt: tempIndex put: {const or temp} - and answer true, otherwise answer false. - One might think that we should look for a sequence of more than - one pushes and pops but this is extremely rare. - Exclude pushRcvr: n to avoid potential complications with context inst - vars. */ - - /* StackToRegisterMappingCogit>>#tryCollapseTempVectorInitializationOfSize: */ -static sqInt NoDbgRegParms -tryCollapseTempVectorInitializationOfSize(sqInt slots) -{ - sqInt pc; - sqInt pc1; - sqInt pc2; - BytecodeDescriptor *pushArrayDesc; - BytecodeDescriptor *pushValueDesc; - sqInt reg; - sqInt remoteTempIndex; - BytecodeDescriptor *storeArrayDesc; - BytecodeDescriptor *storeValueDesc; - sqInt tempIndex; - - if (slots != 1) { - return 0; - } - /* begin generatorForPC: */ - pushArrayDesc = generatorAt(bytecodeSetOffset + (fetchByteofObject(bytecodePC, methodObj))); - assert(((pushArrayDesc->generator)) == genPushNewArrayBytecode); - /* begin generatorForPC: */ - pc = bytecodePC + ((pushArrayDesc->numBytes)); - storeArrayDesc = generatorAt(bytecodeSetOffset + (fetchByteofObject(pc, methodObj))); - if (((storeArrayDesc->generator)) == genStoreAndPopTemporaryVariableBytecode) { - tempIndex = (fetchByteofObject(bytecodePC + ((pushArrayDesc->numBytes)), methodObj)) & 7; - } - else { - if (!(((storeArrayDesc->generator)) == genLongStoreAndPopTemporaryVariableBytecode)) { - return 0; - } - tempIndex = fetchByteofObject((bytecodePC + ((pushArrayDesc->numBytes))) + 1, methodObj); - } - /* begin generatorForPC: */ - pc1 = (bytecodePC + ((pushArrayDesc->numBytes))) + ((storeArrayDesc->numBytes)); - pushValueDesc = generatorAt(bytecodeSetOffset + (fetchByteofObject(pc1, methodObj))); - if (!((((pushValueDesc->generator)) == genPushLiteralConstantBytecode) - || ((((pushValueDesc->generator)) == genPushQuickIntegerConstantBytecode) - || (((pushValueDesc->generator)) == genPushTemporaryVariableBytecode)))) { - return 0; - } - /* begin generatorForPC: */ - pc2 = ((bytecodePC + ((pushArrayDesc->numBytes))) + ((storeArrayDesc->numBytes))) + ((pushValueDesc->numBytes)); - storeValueDesc = generatorAt(bytecodeSetOffset + (fetchByteofObject(pc2, methodObj))); - remoteTempIndex = fetchByteofObject((((bytecodePC + ((pushArrayDesc->numBytes))) + ((storeArrayDesc->numBytes))) + ((pushValueDesc->numBytes))) + 2, methodObj); - if (!((((storeValueDesc->generator)) == genStoreAndPopRemoteTempLongBytecode) - && (tempIndex == remoteTempIndex))) { - return 0; - } - genNewArrayOfSizeinitialized(1, 0); - evaluateat(pushValueDesc, (bytecodePC + ((pushArrayDesc->numBytes))) + ((storeArrayDesc->numBytes))); - reg = ssStorePoptoPreferredReg(1, TempReg); - genStoreSourceRegslotIndexintoNewObjectInDestReg(reg, 0, ReceiverResultReg); - ssPushRegister(ReceiverResultReg); - evaluateat(storeArrayDesc, bytecodePC + ((pushArrayDesc->numBytes))); - - /* + pushArrayDesc numBytes this gets added by nextBytecodePCFor:at:exts:in: */ - bytecodePC = ((bytecodePC + ((storeArrayDesc->numBytes))) + ((pushValueDesc->numBytes))) + ((storeValueDesc->numBytes)); - return 1; -} - - /* StackToRegisterMappingCogit>>#v3PushNilSize:numInitialNils: */ -static sqInt NoDbgRegParms -v3PushNilSizenumInitialNils(sqInt aMethodObj, sqInt numInitialNils) -{ - return numInitialNils; -} - - /* StackToRegisterMappingCogit>>#v3:Num:Push:Nils: */ -static sqInt NoDbgRegParms -v3NumPushNils(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) -{ - return (((descriptor->generator)) == genPushConstantNilBytecode - ? 1 - : 0); -} - - /* StackToRegisterMappingCogit>>#violatesEnsureSpilledSpillAssert */ -static sqInt -violatesEnsureSpilledSpillAssert(void) -{ - return 1; -} - - -/* Used when ReceiverResultReg is allocated for other than simSelf, and - there may be references to ReceiverResultReg which need to be spilled. */ - - /* StackToRegisterMappingCogit>>#voidReceiverResultRegContainsSelf */ -static void -voidReceiverResultRegContainsSelf(void) -{ - sqInt i; - sqInt i1; - sqInt spillIndex; - - /* begin voidReceiverOptStatus */ - ((simSelf())->liveRegister = NoReg); - spillIndex = 0; - for (i = ((((methodOrBlockNumTemps + 1) < simSpillBase) ? simSpillBase : (methodOrBlockNumTemps + 1))); i <= simStackPtr; i += 1) { - if ((registerOrNone(simStackAt(i))) == ReceiverResultReg) { - spillIndex = i; - } - } - if (spillIndex > 0) { - /* begin ssFlushTo: */ - assert(tempsValidAndVolatileEntriesSpilled()); - if (simSpillBase <= spillIndex) { - for (i1 = (((((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) < spillIndex) ? ((((((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) < simStackPtr) ? (((simSpillBase < (methodOrBlockNumTemps + 1)) ? (methodOrBlockNumTemps + 1) : simSpillBase)) : simStackPtr)) : spillIndex)); i1 <= spillIndex; i1 += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i1), frameOffsetOfTemporary(i1 - 1), FPReg); - } - simSpillBase = spillIndex + 1; - } - } -} diff --git a/src/vm/cointerp.c b/src/vm/cointerp.c index 1ae00b53bb..9b8fb3d9eb 100644 --- a/src/vm/cointerp.c +++ b/src/vm/cointerp.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - CoInterpreter VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CoInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 " __DATE__ ; +static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -437,6 +437,7 @@ extern sqInt ceSendMustBeBooleanTointerpretingAtDelta(sqInt aNonBooleanObject, s extern sqInt ceSendMustBeBoolean(sqInt anObject); extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethod); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); @@ -607,7 +608,6 @@ static void primitiveExitCriticalSection(void); static void primitiveFlushCacheByMethod(void); static void primitiveFlushCacheBySelector(void); extern usqInt primitiveFunctionPointerAddress(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); EXPORT(sqInt) primitiveMethodPCData(void); static void primitiveMethodXray(void); EXPORT(void) primitiveMinimumUnusedHeadroom(void); @@ -1042,7 +1042,6 @@ extern sqInt isOopMutable(sqInt anOop); extern sqInt isPinned(sqInt objOop); extern sqInt isPointers(sqInt oop); static sqInt NoDbgRegParms isPureBitsFormat(sqInt format); -static sqInt NoDbgRegParms isSemaphoreOop(sqInt anOop); extern sqInt isShorts(sqInt oop); static sqInt NoDbgRegParms isWeakNonImm(sqInt oop); extern sqInt isWeak(sqInt oop); @@ -1114,7 +1113,6 @@ EXPORT(sqInt) callbackLeave(sqInt cbID); extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHeader); extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkForEventsMayContextSwitch(sqInt mayContextSwitch); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); @@ -1389,7 +1387,6 @@ static sqInt NoDbgRegParms updateDisplayLeftTopRightBottom(sqInt l, sqInt t, sqI static sqInt NoDbgRegParms validBCPCinMethod(sqInt thePC, usqInt aMethod); static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, char *fp); static sqInt validStackPageBaseFrames(void); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt wakeHighestPriority(void); static usqLong NoDbgRegParms wordSwapped(sqInt w); static sqInt NeverInline writeImageFileIO(void); @@ -1412,7 +1409,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1472,15 +1468,13 @@ _iss sqInt numStackPages; _iss sqInt tempOop; _iss sqInt jmpDepth; _iss sqInt lkupClass; -_iss sqInt longRunningPrimitiveCheckSemaphore; -_iss usqInt fwdTableNext; _iss sqInt profileProcess; -_iss sqInt profileSemaphore; +_iss usqInt fwdTableNext; _iss sqInt profileMethod; +_iss sqInt profileSemaphore; _iss usqInt compStart; _iss sqInt extraRootCount; _iss sqInt growHeadroom; -_iss sqInt longRunningPrimitiveCheckMethod; _iss sqInt tempOop2; _iss sqInt statGrowMemory; _iss sqInt weakRootCount; @@ -1524,7 +1518,6 @@ _iss sqInt flagInterpretedMethods; _iss usqInt gcBiasToGrowThreshold; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss sqInt methodDictLinearSearchLimit; _iss sqInt savedWindowSize; _iss sqInt statMaxPageCountWhenMapping; @@ -1538,7 +1531,6 @@ _iss sqInt gcBiasToGrowGCLimit; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; _iss sqInt inFFIFlags; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss usqInt memory; _iss sqInt newFinalization; @@ -1567,16 +1559,14 @@ _iss sqInt numExtB; _iss sqInt oldSpaceStart; _iss sqInt theUnknownShort; _iss usqLong nextWakeupUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; -_iss usqLong statCheckForEvents; _iss usqLong statGCEndUsecs; -_iss usqLong gcStartUsecs; _iss usqLong statIOProcessEvents; _iss usqLong statFullGCUsecs; _iss usqLong statIncrGCUsecs; +_iss usqLong gcStartUsecs; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statForceInterruptCheck; _iss usqLong statIGCDeltaUsecs; _iss usqLong statIdleUsecs; @@ -1584,8 +1574,10 @@ _iss usqLong statProcessSwitch; _iss usqLong statStackOverflow; _iss usqLong statStackPageDivorce; _iss usqLong statCodeCompactionUsecs; -_iss usqLong longRunningPrimitiveGCUsecs; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; #undef _iss #if SQ_USE_GLOBAL_STRUCT } fum; @@ -2223,7 +2215,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Open Smalltalk Cog[SqueakV3] VM [CoInterpreterPrimitives VMMaker.oscog-eem.3024]"; +const char *interpreterVersion = "Open Smalltalk Cog[SqueakV3] VM [CoInterpreterPrimitives VMMaker.oscog-eem.3031]"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */; char primitiveDoMixedArithmetic = 1; char expensiveAsserts = 0; @@ -10636,6 +10628,27 @@ ceStackOverflow(sqInt contextSwitchIfNotNil) error("should not be reached"); } + +/* A primitive has succeeded and the nextProfileTick has been reached (all + done in machine code). + Now take a sample. c.f. checkProfileTick: */ + + /* CoInterpreter>>#ceTakeProfileSample: */ +void +ceTakeProfileSample(CogMethod *aCogMethod) +{ DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt oop; + sqInt oop1; + + /* begin fetchPointer:ofObject: */ + oop1 = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(SchedulerAssociation) << (shiftForWord()))))); + oop = longAt((oop1 + BaseHeaderSize) + (((int)((usqInt)(ValueIndex) << (shiftForWord()))))); + GIV(profileProcess) = longAt((oop + BaseHeaderSize) + (((int)((usqInt)(ActiveProcessIndex) << (shiftForWord()))))); + GIV(profileMethod) = (aCogMethod->methodObject); + forceInterruptCheck(); + GIV(nextProfileTick) = 0; +} + /* CoInterpreter>>#ceTraceBlockActivation */ void ceTraceBlockActivation(void) @@ -12279,24 +12292,6 @@ void forceInterruptCheckFromHeartbeat(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; sqLowLevelMFence(); if (GIV(deferSmash)) { GIV(deferredSmash) = 1; @@ -14709,9 +14704,6 @@ primitivePropertyFlags(sqInt primIndex) baseFlags1 = (GIV(profileSemaphore) != GIV(nilObj) ? PrimCallNeedsNewMethod + PrimCallCollectsProfileSamples : 0); - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - baseFlags1 = baseFlags1 | PrimCallNeedsNewMethod; - } if (isCalloutPrimitiveIndex(primIndex)) { /* For callbacks & module unloading */ @@ -14992,7 +14984,7 @@ printFrameWithSP(char *theFP, char *theSP) usqInt index; sqInt methodField; usqInt numArgs; - sqInt numTemps; + usqInt numTemps; sqInt oop; char *rcvrAddress; sqInt rcvrOrClosure; @@ -18141,62 +18133,6 @@ primitiveFunctionPointerAddress(void) return ((usqInt)((&primitiveFunctionPointer))); } - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* CoInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; - sqInt ccIndex; - int flushState; - sqInt oop; - sqInt sema; - char *sp; - - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (sema == GIV(nilObj)) { - flushState = GIV(longRunningPrimitiveCheckSemaphore) != null; - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - flushState = GIV(longRunningPrimitiveCheckSemaphore) == null; - if (!(((sema & 1) == 0) - && (((((ccIndex = (((usqInt)((longAt(sema)))) >> (compactClassFieldLSB())) & 0x1F)) == 0 - ? (longAt(sema - BaseHeaderSize)) & AllButTypeMask - : (/* begin fetchPointer:ofObject: */ - (oop = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(CompactClasses) << (shiftForWord())))))), - longAt((oop + BaseHeaderSize) + (((sqInt)((usqInt)((ccIndex - 1)) << (shiftForWord())))))))) == (longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(ClassSemaphore) << (shiftForWord()))))))))) { - return (GIV(primFailCode) = PrimErrBadArgument); - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(longRunningPrimitiveCheckSemaphore) == null)) - || (((stackValue(0)) == GIV(longRunningPrimitiveCheckSemaphore)) - && (isSemaphoreOop(sema)))); - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - if (flushState) { - ceInvokeInterpret(); - } - return 0; -} - /* CoInterpreterPrimitives>>#primitiveMethodPCData */ EXPORT(sqInt) primitiveMethodPCData(void) @@ -18509,16 +18445,11 @@ primitiveObjectAtPut(void) EXPORT(sqInt) primitiveProfileSemaphore(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; sqInt ccIndex; int flushState; sqInt oop; sqInt sema; - char *sp; - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); if (sema == GIV(nilObj)) { flushState = GIV(profileSemaphore) != GIV(nilObj); @@ -18534,28 +18465,21 @@ primitiveProfileSemaphore(void) return (GIV(primFailCode) = PrimErrBadArgument); } } + GIV(profileSemaphore) = sema; /* If we've switched profiling on or off we must void machine code (and machine code pcs in contexts) since we will start or stop testing the profile clock in machine code primitive invocations, and so generate slightly different code from here on in. */ - GIV(profileSemaphore) = sema; - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(profileSemaphore) == (nilObject()))) - || (((stackValue(0)) == GIV(profileSemaphore)) - && (isSemaphoreOop(sema)))); - } GIV(profileProcess) = (GIV(profileMethod) = GIV(nilObj)); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; if (flushState) { - ceInvokeInterpret(); + flushExternalPrimitives(); + } + else { + /* begin methodReturnReceiver */ + assert(!((failed()))); + /* begin pop: */ + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; } return 0; } @@ -25694,26 +25618,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -28063,15 +27989,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -28089,15 +28010,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -28121,39 +28037,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((integerPointer & 1)) { - deltaTicks = (integerPointer >> 1); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((deltaTicks & 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 1)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -33088,7 +32983,7 @@ static sqInt NoDbgRegParms eeInstantiateMethodContextSlots(sqInt numSlots) { DECL_MAYBE_SQ_GLOBAL_STRUCT usqInt hash; - sqInt header1; + usqInt header1; usqInt newChunk; usqInt newFreeStart; sqInt newObj; @@ -39112,21 +39007,6 @@ isPureBitsFormat(sqInt format) && (format < (firstCompiledMethodFormat())); } - /* ObjectMemory>>#isSemaphoreOop: */ -static sqInt NoDbgRegParms -isSemaphoreOop(sqInt anOop) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt ccIndex; - sqInt oop; - - return ((anOop & 1) == 0) - && (((((ccIndex = (((usqInt)((longAt(anOop)))) >> (compactClassFieldLSB())) & 0x1F)) == 0 - ? (longAt(anOop - BaseHeaderSize)) & AllButTypeMask - : (/* begin fetchPointer:ofObject: */ - (oop = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(CompactClasses) << (shiftForWord())))))), - longAt((oop + BaseHeaderSize) + (((sqInt)((usqInt)((ccIndex - 1)) << (shiftForWord())))))))) == (longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(ClassSemaphore) << (shiftForWord()))))))); -} - /* forward compatibility with Spur */ @@ -41458,33 +41338,6 @@ checkAllAccessibleObjectsOkay(void) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -41575,9 +41428,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { /* begin signalLowSpace: */ GIV(signalLowSpace) = 0; @@ -46007,23 +45857,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i = 1; i <= GIV(jmpDepth); i += 1) { oop = GIV(suspendedCallbacks)[i]; @@ -46103,14 +45936,6 @@ markAndTraceInterpreterOops(sqInt fullGCFlag) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -49985,8 +49810,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -50018,18 +49843,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -52343,22 +52170,6 @@ validStackPageBaseFrames(void) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Return the highest priority process that is ready to run. To save time looking at many empty lists before finding a runnable process the VM maintains a variable holding the @@ -54627,65 +54438,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((((lrpcm & 3) == 0) - && (((((usqInt)lrpcm)) >= (startOfMemory())) - && (((((usqInt)lrpcm)) < GIV(freeStart)) - && (((longAt(lrpcm)) & TypeMask) != HeaderTypeGC)))) - && ((!(((longAt(lrpcm)) & TypeMask) == HeaderTypeFree)) - && (((((usqInt)((longAt(lrpcm)))) >> (instFormatFieldLSB())) & 15) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - if (oopisLessThan(result, GIV(youngStart))) { - possibleRootStoreIntovalue(result, lrpcm); - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 1) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 1) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -56855,8 +56607,6 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveIsYoung", (void*)primitiveIsYoung}, {(void*)_m, "primitiveLessOrEqualLargeIntegers", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore", (void*)primitiveLongRunningPrimitiveSemaphore}, {(void*)_m, "primitiveMethodPCData", (void*)primitiveMethodPCData}, {(void*)_m, "primitiveMillisecondClockMask", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveMinimumUnusedHeadroom", (void*)primitiveMinimumUnusedHeadroom}, diff --git a/src/vm/cointerp.h b/src/vm/cointerp.h index 1d3c1bf27b..1562cf8a84 100644 --- a/src/vm/cointerp.h +++ b/src/vm/cointerp.h @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ @@ -45,6 +45,7 @@ extern sqInt ceSendMustBeBooleanTointerpretingAtDelta(sqInt aNonBooleanObject, s extern sqInt ceSendMustBeBoolean(sqInt anObject); extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethod); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); diff --git a/src/vm/gcc3x-cointerp.c b/src/vm/gcc3x-cointerp.c index 9e715a5c4c..851bc4cbf5 100644 --- a/src/vm/gcc3x-cointerp.c +++ b/src/vm/gcc3x-cointerp.c @@ -2,11 +2,11 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - CoInterpreter VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 + CoInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3024 uuid: 417aa150-be4e-4631-b35b-948afa18e190 " __DATE__ ; +static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -440,6 +440,7 @@ extern sqInt ceSendMustBeBooleanTointerpretingAtDelta(sqInt aNonBooleanObject, s extern sqInt ceSendMustBeBoolean(sqInt anObject); extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethod); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); @@ -610,7 +611,6 @@ static void primitiveExitCriticalSection(void); static void primitiveFlushCacheByMethod(void); static void primitiveFlushCacheBySelector(void); extern usqInt primitiveFunctionPointerAddress(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); EXPORT(sqInt) primitiveMethodPCData(void); static void primitiveMethodXray(void); EXPORT(void) primitiveMinimumUnusedHeadroom(void); @@ -1045,7 +1045,6 @@ extern sqInt isOopMutable(sqInt anOop); extern sqInt isPinned(sqInt objOop); extern sqInt isPointers(sqInt oop); static sqInt NoDbgRegParms isPureBitsFormat(sqInt format); -static sqInt NoDbgRegParms isSemaphoreOop(sqInt anOop); extern sqInt isShorts(sqInt oop); static sqInt NoDbgRegParms isWeakNonImm(sqInt oop); extern sqInt isWeak(sqInt oop); @@ -1117,7 +1116,6 @@ EXPORT(sqInt) callbackLeave(sqInt cbID); extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHeader); extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkForEventsMayContextSwitch(sqInt mayContextSwitch); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); @@ -1392,7 +1390,6 @@ static sqInt NoDbgRegParms updateDisplayLeftTopRightBottom(sqInt l, sqInt t, sqI static sqInt NoDbgRegParms validBCPCinMethod(sqInt thePC, usqInt aMethod); static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, char *fp); static sqInt validStackPageBaseFrames(void); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt wakeHighestPriority(void); static usqLong NoDbgRegParms wordSwapped(sqInt w); static sqInt NeverInline writeImageFileIO(void); @@ -1415,7 +1412,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1475,15 +1471,13 @@ _iss sqInt numStackPages; _iss sqInt tempOop; _iss sqInt jmpDepth; _iss sqInt lkupClass; -_iss sqInt longRunningPrimitiveCheckSemaphore; -_iss usqInt fwdTableNext; _iss sqInt profileProcess; -_iss sqInt profileSemaphore; +_iss usqInt fwdTableNext; _iss sqInt profileMethod; +_iss sqInt profileSemaphore; _iss usqInt compStart; _iss sqInt extraRootCount; _iss sqInt growHeadroom; -_iss sqInt longRunningPrimitiveCheckMethod; _iss sqInt tempOop2; _iss sqInt statGrowMemory; _iss sqInt weakRootCount; @@ -1527,7 +1521,6 @@ _iss sqInt flagInterpretedMethods; _iss usqInt gcBiasToGrowThreshold; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss sqInt methodDictLinearSearchLimit; _iss sqInt savedWindowSize; _iss sqInt statMaxPageCountWhenMapping; @@ -1541,7 +1534,6 @@ _iss sqInt gcBiasToGrowGCLimit; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; _iss sqInt inFFIFlags; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss usqInt memory; _iss sqInt newFinalization; @@ -1570,16 +1562,14 @@ _iss sqInt numExtB; _iss sqInt oldSpaceStart; _iss sqInt theUnknownShort; _iss usqLong nextWakeupUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; -_iss usqLong statCheckForEvents; _iss usqLong statGCEndUsecs; -_iss usqLong gcStartUsecs; _iss usqLong statIOProcessEvents; _iss usqLong statFullGCUsecs; _iss usqLong statIncrGCUsecs; +_iss usqLong gcStartUsecs; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statForceInterruptCheck; _iss usqLong statIGCDeltaUsecs; _iss usqLong statIdleUsecs; @@ -1587,8 +1577,10 @@ _iss usqLong statProcessSwitch; _iss usqLong statStackOverflow; _iss usqLong statStackPageDivorce; _iss usqLong statCodeCompactionUsecs; -_iss usqLong longRunningPrimitiveGCUsecs; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; #undef _iss #if SQ_USE_GLOBAL_STRUCT } fum; @@ -2226,7 +2218,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Open Smalltalk Cog[SqueakV3] VM [CoInterpreterPrimitives VMMaker.oscog-eem.3024]"; +const char *interpreterVersion = "Open Smalltalk Cog[SqueakV3] VM [CoInterpreterPrimitives VMMaker.oscog-eem.3031]"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */; char primitiveDoMixedArithmetic = 1; char expensiveAsserts = 0; @@ -10645,6 +10637,27 @@ ceStackOverflow(sqInt contextSwitchIfNotNil) error("should not be reached"); } + +/* A primitive has succeeded and the nextProfileTick has been reached (all + done in machine code). + Now take a sample. c.f. checkProfileTick: */ + + /* CoInterpreter>>#ceTakeProfileSample: */ +void +ceTakeProfileSample(CogMethod *aCogMethod) +{ DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt oop; + sqInt oop1; + + /* begin fetchPointer:ofObject: */ + oop1 = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(SchedulerAssociation) << (shiftForWord()))))); + oop = longAt((oop1 + BaseHeaderSize) + (((int)((usqInt)(ValueIndex) << (shiftForWord()))))); + GIV(profileProcess) = longAt((oop + BaseHeaderSize) + (((int)((usqInt)(ActiveProcessIndex) << (shiftForWord()))))); + GIV(profileMethod) = (aCogMethod->methodObject); + forceInterruptCheck(); + GIV(nextProfileTick) = 0; +} + /* CoInterpreter>>#ceTraceBlockActivation */ void ceTraceBlockActivation(void) @@ -12288,24 +12301,6 @@ void forceInterruptCheckFromHeartbeat(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; sqLowLevelMFence(); if (GIV(deferSmash)) { GIV(deferredSmash) = 1; @@ -14718,9 +14713,6 @@ primitivePropertyFlags(sqInt primIndex) baseFlags1 = (GIV(profileSemaphore) != GIV(nilObj) ? PrimCallNeedsNewMethod + PrimCallCollectsProfileSamples : 0); - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - baseFlags1 = baseFlags1 | PrimCallNeedsNewMethod; - } if (isCalloutPrimitiveIndex(primIndex)) { /* For callbacks & module unloading */ @@ -15001,7 +14993,7 @@ printFrameWithSP(char *theFP, char *theSP) usqInt index; sqInt methodField; usqInt numArgs; - sqInt numTemps; + usqInt numTemps; sqInt oop; char *rcvrAddress; sqInt rcvrOrClosure; @@ -18150,62 +18142,6 @@ primitiveFunctionPointerAddress(void) return ((usqInt)((&primitiveFunctionPointer))); } - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* CoInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; - sqInt ccIndex; - int flushState; - sqInt oop; - sqInt sema; - char *sp; - - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (sema == GIV(nilObj)) { - flushState = GIV(longRunningPrimitiveCheckSemaphore) != null; - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - flushState = GIV(longRunningPrimitiveCheckSemaphore) == null; - if (!(((sema & 1) == 0) - && (((((ccIndex = (((usqInt)((longAt(sema)))) >> (compactClassFieldLSB())) & 0x1F)) == 0 - ? (longAt(sema - BaseHeaderSize)) & AllButTypeMask - : (/* begin fetchPointer:ofObject: */ - (oop = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(CompactClasses) << (shiftForWord())))))), - longAt((oop + BaseHeaderSize) + (((sqInt)((usqInt)((ccIndex - 1)) << (shiftForWord())))))))) == (longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(ClassSemaphore) << (shiftForWord()))))))))) { - return (GIV(primFailCode) = PrimErrBadArgument); - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(longRunningPrimitiveCheckSemaphore) == null)) - || (((stackValue(0)) == GIV(longRunningPrimitiveCheckSemaphore)) - && (isSemaphoreOop(sema)))); - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - if (flushState) { - ceInvokeInterpret(); - } - return 0; -} - /* CoInterpreterPrimitives>>#primitiveMethodPCData */ EXPORT(sqInt) primitiveMethodPCData(void) @@ -18518,16 +18454,11 @@ primitiveObjectAtPut(void) EXPORT(sqInt) primitiveProfileSemaphore(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; sqInt ccIndex; int flushState; sqInt oop; sqInt sema; - char *sp; - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); if (sema == GIV(nilObj)) { flushState = GIV(profileSemaphore) != GIV(nilObj); @@ -18543,28 +18474,21 @@ primitiveProfileSemaphore(void) return (GIV(primFailCode) = PrimErrBadArgument); } } + GIV(profileSemaphore) = sema; /* If we've switched profiling on or off we must void machine code (and machine code pcs in contexts) since we will start or stop testing the profile clock in machine code primitive invocations, and so generate slightly different code from here on in. */ - GIV(profileSemaphore) = sema; - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(profileSemaphore) == (nilObject()))) - || (((stackValue(0)) == GIV(profileSemaphore)) - && (isSemaphoreOop(sema)))); - } GIV(profileProcess) = (GIV(profileMethod) = GIV(nilObj)); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; if (flushState) { - ceInvokeInterpret(); + flushExternalPrimitives(); + } + else { + /* begin methodReturnReceiver */ + assert(!((failed()))); + /* begin pop: */ + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; } return 0; } @@ -25703,26 +25627,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -28072,15 +27998,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -28098,15 +28019,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -28130,39 +28046,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((integerPointer & 1)) { - deltaTicks = (integerPointer >> 1); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((deltaTicks & 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 1)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -33097,7 +32992,7 @@ static sqInt NoDbgRegParms eeInstantiateMethodContextSlots(sqInt numSlots) { DECL_MAYBE_SQ_GLOBAL_STRUCT usqInt hash; - sqInt header1; + usqInt header1; usqInt newChunk; usqInt newFreeStart; sqInt newObj; @@ -39121,21 +39016,6 @@ isPureBitsFormat(sqInt format) && (format < (firstCompiledMethodFormat())); } - /* ObjectMemory>>#isSemaphoreOop: */ -static sqInt NoDbgRegParms -isSemaphoreOop(sqInt anOop) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt ccIndex; - sqInt oop; - - return ((anOop & 1) == 0) - && (((((ccIndex = (((usqInt)((longAt(anOop)))) >> (compactClassFieldLSB())) & 0x1F)) == 0 - ? (longAt(anOop - BaseHeaderSize)) & AllButTypeMask - : (/* begin fetchPointer:ofObject: */ - (oop = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(CompactClasses) << (shiftForWord())))))), - longAt((oop + BaseHeaderSize) + (((sqInt)((usqInt)((ccIndex - 1)) << (shiftForWord())))))))) == (longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(ClassSemaphore) << (shiftForWord()))))))); -} - /* forward compatibility with Spur */ @@ -41467,33 +41347,6 @@ checkAllAccessibleObjectsOkay(void) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -41584,9 +41437,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { /* begin signalLowSpace: */ GIV(signalLowSpace) = 0; @@ -46016,23 +45866,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i = 1; i <= GIV(jmpDepth); i += 1) { oop = GIV(suspendedCallbacks)[i]; @@ -46112,14 +45945,6 @@ markAndTraceInterpreterOops(sqInt fullGCFlag) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -49994,8 +49819,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -50027,18 +49852,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -52352,22 +52179,6 @@ validStackPageBaseFrames(void) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Return the highest priority process that is ready to run. To save time looking at many empty lists before finding a runnable process the VM maintains a variable holding the @@ -54636,65 +54447,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((((lrpcm & 3) == 0) - && (((((usqInt)lrpcm)) >= (startOfMemory())) - && (((((usqInt)lrpcm)) < GIV(freeStart)) - && (((longAt(lrpcm)) & TypeMask) != HeaderTypeGC)))) - && ((!(((longAt(lrpcm)) & TypeMask) == HeaderTypeFree)) - && (((((usqInt)((longAt(lrpcm)))) >> (instFormatFieldLSB())) & 15) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - if (oopisLessThan(result, GIV(youngStart))) { - possibleRootStoreIntovalue(result, lrpcm); - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 1) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 1) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -56864,8 +56616,6 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveIsYoung", (void*)primitiveIsYoung}, {(void*)_m, "primitiveLessOrEqualLargeIntegers", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore", (void*)primitiveLongRunningPrimitiveSemaphore}, {(void*)_m, "primitiveMethodPCData", (void*)primitiveMethodPCData}, {(void*)_m, "primitiveMillisecondClockMask", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveMinimumUnusedHeadroom", (void*)primitiveMinimumUnusedHeadroom}, diff --git a/stacksrc/vm/gcc3x-interp.c b/stacksrc/vm/gcc3x-interp.c index 8212ffc229..ab072fc54d 100644 --- a/stacksrc/vm/gcc3x-interp.c +++ b/stacksrc/vm/gcc3x-interp.c @@ -2,11 +2,11 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - StackInterpreter VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 + StackInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 " __DATE__ ; +static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -834,7 +834,6 @@ extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHea extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); static sqInt NoDbgRegParms checkCodeIntegrity(sqInt fullGCFlag); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkForEventsMayContextSwitch(sqInt mayContextSwitch); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); @@ -1141,7 +1140,6 @@ static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, extern sqInt validInstructionPointerinMethodframePointer(usqInt theInstrPointer, usqInt aMethod, char *fp); static sqInt validStackPageBaseFrames(void); static sqInt NoDbgRegParms validStackPageBaseFrame(StackPage *aPage); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt NoDbgRegParms voidVMStateForSnapshotFlushingExternalPrimitivesIf(sqInt flushExtPrims); static sqInt wakeHighestPriority(void); EXPORT(char *) whereIs(sqInt anOop); @@ -1172,8 +1170,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1235,8 +1231,6 @@ _iss sqInt profileMethod; _iss usqInt compStart; _iss sqInt extraRootCount; _iss sqInt growHeadroom; -_iss sqInt longRunningPrimitiveCheckMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; _iss sqInt tempOop2; _iss sqInt statGrowMemory; _iss sqInt weakRootCount; @@ -1276,7 +1270,6 @@ _iss sqInt totalObjectCount; _iss usqInt gcBiasToGrowThreshold; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss sqInt savedWindowSize; _iss sqInt statMaxPageCountWhenMapping; _iss sqInt statPageCountWhenMappingSum; @@ -1288,7 +1281,6 @@ _iss sqInt gcSemaphoreIndex; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; _iss sqInt inFFIFlags; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss sqInt methodDictLinearSearchLimit; _iss sqInt newFinalization; @@ -1316,24 +1308,24 @@ _iss sqInt numExtB; _iss sqInt oldSpaceStart; _iss sqLong nextProfileTick; _iss usqLong nextWakeupUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; -_iss usqLong statCheckForEvents; _iss usqLong statGCEndUsecs; -_iss usqLong gcStartUsecs; _iss usqLong statIOProcessEvents; _iss usqLong statFullGCUsecs; _iss usqLong statIncrGCUsecs; +_iss usqLong gcStartUsecs; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statForceInterruptCheck; _iss usqLong statIGCDeltaUsecs; _iss usqLong statIdleUsecs; _iss usqLong statProcessSwitch; _iss usqLong statStackOverflow; _iss usqLong statStackPageDivorce; -_iss usqLong longRunningPrimitiveGCUsecs; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; _iss jmp_buf reenterInterpreter; #undef _iss #if SQ_USE_GLOBAL_STRUCT @@ -1967,7 +1959,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Open Smalltalk Stack VM [StackInterpreterPrimitives VMMaker.oscog-eem.3022]"; +const char *interpreterVersion = "Open Smalltalk Stack VM [StackInterpreterPrimitives VMMaker.oscog-eem.3031]"; sqInt suppressHeartbeatFlag; char primitiveDoMixedArithmetic = 1; char expensiveAsserts = 0; @@ -14273,26 +14265,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -17015,15 +17009,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -17041,15 +17030,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -17108,39 +17092,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((integerPointer & 1)) { - deltaTicks = (integerPointer >> 1); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((deltaTicks & 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 1)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -30609,33 +30572,6 @@ checkCodeIntegrity(sqInt fullGCFlag) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -30722,9 +30658,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { /* begin signalLowSpace: */ GIV(signalLowSpace) = 0; @@ -33171,26 +33104,8 @@ forceInterruptCheck(void) /* StackInterpreter>>#forceInterruptCheckFromHeartbeat */ void forceInterruptCheckFromHeartbeat(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT +{ if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; forceInterruptCheck(); } } @@ -35261,23 +35176,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i = 1; i <= GIV(jmpDepth); i += 1) { oop = GIV(suspendedCallbacks)[i]; @@ -35441,14 +35339,6 @@ markAndTraceInterpreterOops(sqInt fullGCFlag) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -39393,8 +39283,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -39426,18 +39316,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -42873,22 +42765,6 @@ validStackPageBaseFrame(StackPage *aPage) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Make sure that all VM state that affects the heap contents is voided so that the heap is ready to be snapshotted. If flushExtPrims is true, flush references to @@ -45672,112 +45548,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((((lrpcm & 3) == 0) - && (((((usqInt)lrpcm)) >= (startOfMemory())) - && (((((usqInt)lrpcm)) < GIV(freeStart)) - && (((longAt(lrpcm)) & TypeMask) != HeaderTypeGC)))) - && ((!(((longAt(lrpcm)) & TypeMask) == HeaderTypeFree)) - && (((((usqInt)((longAt(lrpcm)))) >> (instFormatFieldLSB())) & 15) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - if (oopisLessThan(result, GIV(youngStart))) { - possibleRootStoreIntovalue(result, lrpcm); - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 1) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 1) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt ccIndex; - sqInt oop; - sqInt sema; - - /* begin stackValue: */ - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (((sema & 1)) - || (GIV(argumentCount) != 1)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - if (sema == GIV(nilObj)) { - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - if (!(((sema & 1) == 0) - && (((((ccIndex = (((usqInt)((longAt(sema)))) >> (compactClassFieldLSB())) & 0x1F)) == 0 - ? (longAt(sema - BaseHeaderSize)) & AllButTypeMask - : (/* begin fetchPointer:ofObject: */ - (oop = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(CompactClasses) << (shiftForWord())))))), - longAt((oop + BaseHeaderSize) + (((sqInt)((usqInt)((ccIndex - 1)) << (shiftForWord())))))))) == (longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(ClassSemaphore) << (shiftForWord()))))))))) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -48382,8 +48152,6 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveIsYoung", (void*)primitiveIsYoung}, {(void*)_m, "primitiveLessOrEqualLargeIntegers", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore", (void*)primitiveLongRunningPrimitiveSemaphore}, {(void*)_m, "primitiveMillisecondClockMask", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveModLargeIntegers", (void*)primitiveModLargeIntegers}, {(void*)_m, "primitiveMultiplyLargeIntegers", (void*)primitiveMultiplyLargeIntegers}, diff --git a/stacksrc/vm/interp.c b/stacksrc/vm/interp.c index b300881f38..5916b7d611 100644 --- a/stacksrc/vm/interp.c +++ b/stacksrc/vm/interp.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab from - StackInterpreter VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 + StackInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab */ -static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.3022 uuid: 0f8fef46-0ddf-4c88-96d8-a682a0493727 " __DATE__ ; +static char __buildInfo[] = "StackInterpreter VMMaker.oscog-eem.3031 uuid: 51e5e6bf-af1a-465a-bcff-a8874301d2ab " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -831,7 +831,6 @@ extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHea extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); static sqInt NoDbgRegParms checkCodeIntegrity(sqInt fullGCFlag); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkForEventsMayContextSwitch(sqInt mayContextSwitch); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); @@ -1138,7 +1137,6 @@ static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, extern sqInt validInstructionPointerinMethodframePointer(usqInt theInstrPointer, usqInt aMethod, char *fp); static sqInt validStackPageBaseFrames(void); static sqInt NoDbgRegParms validStackPageBaseFrame(StackPage *aPage); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt NoDbgRegParms voidVMStateForSnapshotFlushingExternalPrimitivesIf(sqInt flushExtPrims); static sqInt wakeHighestPriority(void); EXPORT(char *) whereIs(sqInt anOop); @@ -1169,8 +1167,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1232,8 +1228,6 @@ _iss sqInt profileMethod; _iss usqInt compStart; _iss sqInt extraRootCount; _iss sqInt growHeadroom; -_iss sqInt longRunningPrimitiveCheckMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; _iss sqInt tempOop2; _iss sqInt statGrowMemory; _iss sqInt weakRootCount; @@ -1273,7 +1267,6 @@ _iss sqInt totalObjectCount; _iss usqInt gcBiasToGrowThreshold; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss sqInt savedWindowSize; _iss sqInt statMaxPageCountWhenMapping; _iss sqInt statPageCountWhenMappingSum; @@ -1285,7 +1278,6 @@ _iss sqInt gcSemaphoreIndex; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; _iss sqInt inFFIFlags; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss sqInt methodDictLinearSearchLimit; _iss sqInt newFinalization; @@ -1313,24 +1305,24 @@ _iss sqInt numExtB; _iss sqInt oldSpaceStart; _iss sqLong nextProfileTick; _iss usqLong nextWakeupUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; -_iss usqLong statCheckForEvents; _iss usqLong statGCEndUsecs; -_iss usqLong gcStartUsecs; _iss usqLong statIOProcessEvents; _iss usqLong statFullGCUsecs; _iss usqLong statIncrGCUsecs; +_iss usqLong gcStartUsecs; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statForceInterruptCheck; _iss usqLong statIGCDeltaUsecs; _iss usqLong statIdleUsecs; _iss usqLong statProcessSwitch; _iss usqLong statStackOverflow; _iss usqLong statStackPageDivorce; -_iss usqLong longRunningPrimitiveGCUsecs; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; _iss jmp_buf reenterInterpreter; #undef _iss #if SQ_USE_GLOBAL_STRUCT @@ -1964,7 +1956,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Open Smalltalk Stack VM [StackInterpreterPrimitives VMMaker.oscog-eem.3022]"; +const char *interpreterVersion = "Open Smalltalk Stack VM [StackInterpreterPrimitives VMMaker.oscog-eem.3031]"; sqInt suppressHeartbeatFlag; char primitiveDoMixedArithmetic = 1; char expensiveAsserts = 0; @@ -14264,26 +14256,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -17006,15 +17000,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -17032,15 +17021,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -17099,39 +17083,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((integerPointer & 1)) { - deltaTicks = (integerPointer >> 1); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((deltaTicks & 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 1)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -30600,33 +30563,6 @@ checkCodeIntegrity(sqInt fullGCFlag) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -30713,9 +30649,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { /* begin signalLowSpace: */ GIV(signalLowSpace) = 0; @@ -33162,26 +33095,8 @@ forceInterruptCheck(void) /* StackInterpreter>>#forceInterruptCheckFromHeartbeat */ void forceInterruptCheckFromHeartbeat(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT +{ if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; forceInterruptCheck(); } } @@ -35252,23 +35167,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i = 1; i <= GIV(jmpDepth); i += 1) { oop = GIV(suspendedCallbacks)[i]; @@ -35432,14 +35330,6 @@ markAndTraceInterpreterOops(sqInt fullGCFlag) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -39384,8 +39274,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -39417,18 +39307,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -42864,22 +42756,6 @@ validStackPageBaseFrame(StackPage *aPage) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Make sure that all VM state that affects the heap contents is voided so that the heap is ready to be snapshotted. If flushExtPrims is true, flush references to @@ -45663,112 +45539,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((((lrpcm & 3) == 0) - && (((((usqInt)lrpcm)) >= (startOfMemory())) - && (((((usqInt)lrpcm)) < GIV(freeStart)) - && (((longAt(lrpcm)) & TypeMask) != HeaderTypeGC)))) - && ((!(((longAt(lrpcm)) & TypeMask) == HeaderTypeFree)) - && (((((usqInt)((longAt(lrpcm)))) >> (instFormatFieldLSB())) & 15) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - if (oopisLessThan(result, GIV(youngStart))) { - possibleRootStoreIntovalue(result, lrpcm); - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 1) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 1) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt ccIndex; - sqInt oop; - sqInt sema; - - /* begin stackValue: */ - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (((sema & 1)) - || (GIV(argumentCount) != 1)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - if (sema == GIV(nilObj)) { - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - if (!(((sema & 1) == 0) - && (((((ccIndex = (((usqInt)((longAt(sema)))) >> (compactClassFieldLSB())) & 0x1F)) == 0 - ? (longAt(sema - BaseHeaderSize)) & AllButTypeMask - : (/* begin fetchPointer:ofObject: */ - (oop = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(CompactClasses) << (shiftForWord())))))), - longAt((oop + BaseHeaderSize) + (((sqInt)((usqInt)((ccIndex - 1)) << (shiftForWord())))))))) == (longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((int)((usqInt)(ClassSemaphore) << (shiftForWord()))))))))) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -48373,8 +48143,6 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveIsYoung", (void*)primitiveIsYoung}, {(void*)_m, "primitiveLessOrEqualLargeIntegers", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore", (void*)primitiveLongRunningPrimitiveSemaphore}, {(void*)_m, "primitiveMillisecondClockMask", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveModLargeIntegers", (void*)primitiveModLargeIntegers}, {(void*)_m, "primitiveMultiplyLargeIntegers", (void*)primitiveMultiplyLargeIntegers},